summaryrefslogtreecommitdiffstats
path: root/cui
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /cui
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'cui')
-rw-r--r--cui/AllLangMoTarget_cui.mk11
-rw-r--r--cui/CppunitTest_cui_dialogs_test.mk71
-rw-r--r--cui/CppunitTest_cui_dialogs_test_2.mk71
-rw-r--r--cui/CppunitTest_cui_dialogs_test_3.mk71
-rw-r--r--cui/CppunitTest_cui_dialogs_test_4.mk71
-rw-r--r--cui/IwyuFilter_cui.yaml44
-rw-r--r--cui/Library_cui.mk245
-rw-r--r--cui/Makefile14
-rw-r--r--cui/Module_cui.mk35
-rw-r--r--cui/Package_cui.mk17
-rw-r--r--cui/README.md8
-rw-r--r--cui/UIConfig_cui.mk232
-rw-r--r--cui/UITest_cui_dialogs.mk16
-rw-r--r--cui/UITest_cui_tabpages.mk16
-rw-r--r--cui/inc/bitmaps.hlst75
-rw-r--r--cui/inc/numcategories.hrc31
-rw-r--r--cui/inc/pch/precompiled_cui.cxx12
-rw-r--r--cui/inc/pch/precompiled_cui.hxx447
-rw-r--r--cui/inc/strings.hrc406
-rw-r--r--cui/inc/strings.hxx14
-rw-r--r--cui/inc/tipoftheday.hrc289
-rw-r--r--cui/inc/toolbarmode.hrc38
-rw-r--r--cui/inc/treeopt.hrc160
-rw-r--r--cui/inc/twolines.hrc46
-rw-r--r--cui/qa/uitest/dialogs/chardlg.py167
-rw-r--r--cui/qa/uitest/dialogs/pastedlg.py43
-rw-r--r--cui/qa/uitest/dialogs/shortcuts.py39
-rw-r--r--cui/qa/uitest/tabpages/themepage.py87
-rw-r--r--cui/qa/uitest/tabpages/tpcolor.py69
-rw-r--r--cui/qa/unit/cui-dialogs-test.cxx101
-rw-r--r--cui/qa/unit/cui-dialogs-test_2.cxx58
-rw-r--r--cui/qa/unit/cui-dialogs-test_3.cxx58
-rw-r--r--cui/qa/unit/cui-dialogs-test_4.cxx58
-rw-r--r--cui/qa/unit/data/cui-dialogs-test.txt96
-rw-r--r--cui/qa/unit/data/cui-dialogs-test_2.txt61
-rw-r--r--cui/qa/unit/data/cui-dialogs-test_3.txt43
-rw-r--r--cui/qa/unit/data/cui-dialogs-test_4.txt72
-rw-r--r--cui/source/customize/CommandCategoryListBox.cxx607
-rw-r--r--cui/source/customize/CustomNotebookbarGenerator.cxx278
-rw-r--r--cui/source/customize/SvxConfigPageHelper.cxx424
-rw-r--r--cui/source/customize/SvxMenuConfigPage.cxx595
-rw-r--r--cui/source/customize/SvxNotebookbarConfigPage.cxx543
-rw-r--r--cui/source/customize/SvxToolbarConfigPage.cxx929
-rw-r--r--cui/source/customize/acccfg.cxx1600
-rw-r--r--cui/source/customize/cfg.cxx3221
-rw-r--r--cui/source/customize/cfgutil.cxx1270
-rw-r--r--cui/source/customize/eventdlg.cxx159
-rw-r--r--cui/source/customize/eventdlg.hxx52
-rw-r--r--cui/source/customize/macropg.cxx663
-rw-r--r--cui/source/customize/macropg_impl.hxx55
-rw-r--r--cui/source/dialogs/AdditionsDialog.cxx871
-rw-r--r--cui/source/dialogs/DiagramDialog.cxx156
-rw-r--r--cui/source/dialogs/FontFeaturesDialog.cxx233
-rw-r--r--cui/source/dialogs/GraphicTestsDialog.cxx115
-rw-r--r--cui/source/dialogs/ImageViewerDialog.cxx24
-rw-r--r--cui/source/dialogs/QrCodeGenDialog.cxx394
-rw-r--r--cui/source/dialogs/SignSignatureLineDialog.cxx258
-rw-r--r--cui/source/dialogs/SignatureLineDialog.cxx194
-rw-r--r--cui/source/dialogs/SignatureLineDialogBase.cxx40
-rw-r--r--cui/source/dialogs/SpellAttrib.hxx118
-rw-r--r--cui/source/dialogs/SpellDialog.cxx2099
-rw-r--r--cui/source/dialogs/about.cxx278
-rw-r--r--cui/source/dialogs/colorpicker.cxx1363
-rw-r--r--cui/source/dialogs/cuicharmap.cxx1283
-rw-r--r--cui/source/dialogs/cuifmsearch.cxx759
-rw-r--r--cui/source/dialogs/cuigaldlg.cxx1009
-rw-r--r--cui/source/dialogs/cuigrfflt.cxx469
-rw-r--r--cui/source/dialogs/cuihyperdlg.cxx294
-rw-r--r--cui/source/dialogs/cuiimapwnd.cxx57
-rw-r--r--cui/source/dialogs/cuitbxform.cxx31
-rw-r--r--cui/source/dialogs/dlgname.cxx105
-rw-r--r--cui/source/dialogs/fileextcheckdlg.cxx55
-rw-r--r--cui/source/dialogs/hangulhanjadlg.cxx1508
-rw-r--r--cui/source/dialogs/hldocntp.cxx450
-rw-r--r--cui/source/dialogs/hldoctp.cxx317
-rw-r--r--cui/source/dialogs/hlinettp.cxx389
-rw-r--r--cui/source/dialogs/hlmailtp.cxx222
-rw-r--r--cui/source/dialogs/hlmarkwn.cxx520
-rw-r--r--cui/source/dialogs/hltpbase.cxx537
-rw-r--r--cui/source/dialogs/hyphen.cxx472
-rw-r--r--cui/source/dialogs/iconcdlg.cxx308
-rw-r--r--cui/source/dialogs/insdlg.cxx635
-rw-r--r--cui/source/dialogs/insrc.cxx59
-rw-r--r--cui/source/dialogs/linkdlg.cxx644
-rw-r--r--cui/source/dialogs/multipat.cxx316
-rw-r--r--cui/source/dialogs/newtabledlg.cxx39
-rw-r--r--cui/source/dialogs/passwdomdlg.cxx171
-rw-r--r--cui/source/dialogs/pastedlg.cxx339
-rw-r--r--cui/source/dialogs/postdlg.cxx162
-rw-r--r--cui/source/dialogs/screenshotannotationdlg.cxx581
-rw-r--r--cui/source/dialogs/scriptdlg.cxx1338
-rw-r--r--cui/source/dialogs/sdrcelldlg.cxx69
-rw-r--r--cui/source/dialogs/showcols.cxx109
-rw-r--r--cui/source/dialogs/signature-line-draw.svg36
-rw-r--r--cui/source/dialogs/signature-line.svg30
-rw-r--r--cui/source/dialogs/splitcelldlg.cxx114
-rw-r--r--cui/source/dialogs/srchxtra.cxx232
-rw-r--r--cui/source/dialogs/thesdlg.cxx352
-rw-r--r--cui/source/dialogs/tipofthedaydlg.cxx254
-rw-r--r--cui/source/dialogs/toolbarmodedlg.cxx210
-rw-r--r--cui/source/dialogs/zoom.cxx397
-rw-r--r--cui/source/factory/cuiexp.cxx36
-rw-r--r--cui/source/factory/cuiresmgr.cxx25
-rw-r--r--cui/source/factory/dlgfact.cxx1547
-rw-r--r--cui/source/factory/dlgfact.hxx621
-rw-r--r--cui/source/factory/init.cxx44
-rw-r--r--cui/source/inc/AdditionsDialog.hxx183
-rw-r--r--cui/source/inc/CommandCategoryListBox.hxx82
-rw-r--r--cui/source/inc/CustomNotebookbarGenerator.hxx42
-rw-r--r--cui/source/inc/DiagramDialog.hxx42
-rw-r--r--cui/source/inc/FontFeatures.hxx17
-rw-r--r--cui/source/inc/FontFeaturesDialog.hxx76
-rw-r--r--cui/source/inc/GraphicsTestsDialog.hxx54
-rw-r--r--cui/source/inc/ImageViewerDialog.hxx20
-rw-r--r--cui/source/inc/QrCodeGenDialog.hxx46
-rw-r--r--cui/source/inc/SignSignatureLineDialog.hxx53
-rw-r--r--cui/source/inc/SignatureLineDialog.hxx36
-rw-r--r--cui/source/inc/SignatureLineDialogBase.hxx34
-rw-r--r--cui/source/inc/SpellDialog.hxx228
-rw-r--r--cui/source/inc/SvxConfigPageHelper.hxx76
-rw-r--r--cui/source/inc/SvxMenuConfigPage.hxx69
-rw-r--r--cui/source/inc/SvxNotebookbarConfigPage.hxx86
-rw-r--r--cui/source/inc/SvxToolbarConfigPage.hxx84
-rw-r--r--cui/source/inc/TextColumnsPage.hxx40
-rw-r--r--cui/source/inc/about.hxx58
-rw-r--r--cui/source/inc/acccfg.hxx160
-rw-r--r--cui/source/inc/align.hxx121
-rw-r--r--cui/source/inc/autocdlg.hxx420
-rw-r--r--cui/source/inc/backgrnd.hxx67
-rw-r--r--cui/source/inc/bbdlg.hxx41
-rw-r--r--cui/source/inc/border.hxx196
-rw-r--r--cui/source/inc/cfg.hxx672
-rw-r--r--cui/source/inc/cfgutil.hxx269
-rw-r--r--cui/source/inc/chardlg.hxx341
-rw-r--r--cui/source/inc/connect.hxx83
-rw-r--r--cui/source/inc/cuifmsearch.hxx180
-rw-r--r--cui/source/inc/cuigaldlg.hxx276
-rw-r--r--cui/source/inc/cuigrfflt.hxx180
-rw-r--r--cui/source/inc/cuihyperdlg.hxx139
-rw-r--r--cui/source/inc/cuiimapwnd.hxx47
-rw-r--r--cui/source/inc/cuioptgenrl.hxx72
-rw-r--r--cui/source/inc/cuisrchdlg.hxx41
-rw-r--r--cui/source/inc/cuitabarea.hxx742
-rw-r--r--cui/source/inc/cuitabline.hxx376
-rw-r--r--cui/source/inc/cuitbxform.hxx35
-rw-r--r--cui/source/inc/dbregister.hxx110
-rw-r--r--cui/source/inc/defdlgname.hxx27
-rw-r--r--cui/source/inc/dialmgr.hxx27
-rw-r--r--cui/source/inc/dlgname.hxx119
-rw-r--r--cui/source/inc/fileextcheckdlg.hxx39
-rw-r--r--cui/source/inc/grfpage.hxx107
-rw-r--r--cui/source/inc/hangulhanjadlg.hxx301
-rw-r--r--cui/source/inc/headertablistbox.hxx37
-rw-r--r--cui/source/inc/helpids.h52
-rw-r--r--cui/source/inc/hldocntp.hxx60
-rw-r--r--cui/source/inc/hldoctp.hxx73
-rw-r--r--cui/source/inc/hlinettp.hxx92
-rw-r--r--cui/source/inc/hlmailtp.hxx62
-rw-r--r--cui/source/inc/hlmarkwn.hxx67
-rw-r--r--cui/source/inc/hlmarkwn_def.hxx26
-rw-r--r--cui/source/inc/hltpbase.hxx134
-rw-r--r--cui/source/inc/hyphen.hxx85
-rw-r--r--cui/source/inc/iconcdlg.hxx82
-rw-r--r--cui/source/inc/insdlg.hxx114
-rw-r--r--cui/source/inc/insrc.hxx41
-rw-r--r--cui/source/inc/labdlg.hxx116
-rw-r--r--cui/source/inc/linkdlg.hxx81
-rw-r--r--cui/source/inc/macroass.hxx90
-rw-r--r--cui/source/inc/macropg.hxx128
-rw-r--r--cui/source/inc/measure.hxx95
-rw-r--r--cui/source/inc/multipat.hxx66
-rw-r--r--cui/source/inc/newtabledlg.hxx72
-rw-r--r--cui/source/inc/numfmt.hxx154
-rw-r--r--cui/source/inc/numpages.hxx384
-rw-r--r--cui/source/inc/optasian.hxx60
-rw-r--r--cui/source/inc/optdict.hxx109
-rw-r--r--cui/source/inc/optlingu.hxx148
-rw-r--r--cui/source/inc/optpath.hxx70
-rw-r--r--cui/source/inc/page.hxx190
-rw-r--r--cui/source/inc/paragrph.hxx305
-rw-r--r--cui/source/inc/passwdomdlg.hxx67
-rw-r--r--cui/source/inc/pastedlg.hxx73
-rw-r--r--cui/source/inc/postdlg.hxx104
-rw-r--r--cui/source/inc/screenshotannotationdlg.hxx39
-rw-r--r--cui/source/inc/scriptdlg.hxx167
-rw-r--r--cui/source/inc/sdrcelldlg.hxx48
-rw-r--r--cui/source/inc/showcols.hxx45
-rw-r--r--cui/source/inc/splitcelldlg.hxx64
-rw-r--r--cui/source/inc/srchxtra.hxx81
-rw-r--r--cui/source/inc/swpossizetabpage.hxx130
-rw-r--r--cui/source/inc/tabstpge.hxx146
-rw-r--r--cui/source/inc/textanim.hxx105
-rw-r--r--cui/source/inc/textattr.hxx92
-rw-r--r--cui/source/inc/themepage.hxx53
-rw-r--r--cui/source/inc/thesdlg.hxx82
-rw-r--r--cui/source/inc/tipofthedaydlg.hxx50
-rw-r--r--cui/source/inc/toolbarmodedlg.hxx37
-rw-r--r--cui/source/inc/transfrm.hxx248
-rw-r--r--cui/source/inc/treeopt.hxx239
-rw-r--r--cui/source/inc/zoom.hxx67
-rw-r--r--cui/source/options/certpath.cxx237
-rw-r--r--cui/source/options/certpath.hxx42
-rw-r--r--cui/source/options/cfgchart.cxx280
-rw-r--r--cui/source/options/cfgchart.hxx100
-rw-r--r--cui/source/options/connpoolconfig.cxx196
-rw-r--r--cui/source/options/connpoolconfig.hxx38
-rw-r--r--cui/source/options/connpooloptions.cxx261
-rw-r--r--cui/source/options/connpooloptions.hxx71
-rw-r--r--cui/source/options/connpoolsettings.cxx84
-rw-r--r--cui/source/options/connpoolsettings.hxx86
-rw-r--r--cui/source/options/cuisrchdlg.cxx50
-rw-r--r--cui/source/options/dbregister.cxx315
-rw-r--r--cui/source/options/dbregisterednamesconfig.cxx122
-rw-r--r--cui/source/options/dbregisterednamesconfig.hxx38
-rw-r--r--cui/source/options/dbregistersettings.cxx55
-rw-r--r--cui/source/options/dbregistersettings.hxx80
-rw-r--r--cui/source/options/doclinkdialog.cxx199
-rw-r--r--cui/source/options/doclinkdialog.hxx61
-rw-r--r--cui/source/options/fontsubs.cxx405
-rw-r--r--cui/source/options/fontsubs.hxx61
-rw-r--r--cui/source/options/optaboutconfig.cxx965
-rw-r--r--cui/source/options/optaboutconfig.hxx95
-rw-r--r--cui/source/options/optaccessibility.cxx111
-rw-r--r--cui/source/options/optaccessibility.hxx42
-rw-r--r--cui/source/options/optasian.cxx383
-rw-r--r--cui/source/options/optbasic.cxx131
-rw-r--r--cui/source/options/optbasic.hxx47
-rw-r--r--cui/source/options/optchart.cxx274
-rw-r--r--cui/source/options/optchart.hxx79
-rw-r--r--cui/source/options/optcolor.cxx896
-rw-r--r--cui/source/options/optcolor.hxx68
-rw-r--r--cui/source/options/optctl.cxx146
-rw-r--r--cui/source/options/optctl.hxx45
-rw-r--r--cui/source/options/optdict.cxx774
-rw-r--r--cui/source/options/optfltr.cxx346
-rw-r--r--cui/source/options/optfltr.hxx80
-rw-r--r--cui/source/options/optgdlg.cxx1806
-rw-r--r--cui/source/options/optgdlg.hxx181
-rw-r--r--cui/source/options/optgenrl.cxx507
-rw-r--r--cui/source/options/opthtml.cxx169
-rw-r--r--cui/source/options/opthtml.hxx59
-rw-r--r--cui/source/options/optinet2.cxx938
-rw-r--r--cui/source/options/optinet2.hxx158
-rw-r--r--cui/source/options/optjava.cxx960
-rw-r--r--cui/source/options/optjava.hxx206
-rw-r--r--cui/source/options/optjsearch.cxx358
-rw-r--r--cui/source/options/optjsearch.hxx71
-rw-r--r--cui/source/options/optlanguagetool.cxx76
-rw-r--r--cui/source/options/optlanguagetool.hxx44
-rw-r--r--cui/source/options/optlingu.cxx1974
-rw-r--r--cui/source/options/optopencl.cxx88
-rw-r--r--cui/source/options/optopencl.hxx42
-rw-r--r--cui/source/options/optpath.cxx697
-rw-r--r--cui/source/options/optsave.cxx635
-rw-r--r--cui/source/options/optsave.hxx78
-rw-r--r--cui/source/options/optupdt.cxx405
-rw-r--r--cui/source/options/optupdt.hxx70
-rw-r--r--cui/source/options/personalization.cxx166
-rw-r--r--cui/source/options/personalization.hxx62
-rw-r--r--cui/source/options/sdbcdriverenum.cxx99
-rw-r--r--cui/source/options/sdbcdriverenum.hxx54
-rw-r--r--cui/source/options/securityoptions.cxx79
-rw-r--r--cui/source/options/securityoptions.hxx61
-rw-r--r--cui/source/options/treeopt.cxx2115
-rw-r--r--cui/source/options/tsaurls.cxx128
-rw-r--r--cui/source/options/tsaurls.hxx41
-rw-r--r--cui/source/options/webconninfo.cxx229
-rw-r--r--cui/source/options/webconninfo.hxx51
-rw-r--r--cui/source/tabpages/TextColumnsPage.cxx82
-rw-r--r--cui/source/tabpages/align.cxx790
-rw-r--r--cui/source/tabpages/autocdlg.cxx2364
-rw-r--r--cui/source/tabpages/backgrnd.cxx338
-rw-r--r--cui/source/tabpages/bbdlg.cxx89
-rw-r--r--cui/source/tabpages/border.cxx1704
-rw-r--r--cui/source/tabpages/chardlg.cxx3230
-rw-r--r--cui/source/tabpages/chardlg.h26
-rw-r--r--cui/source/tabpages/connect.cxx415
-rw-r--r--cui/source/tabpages/grfpage.cxx806
-rw-r--r--cui/source/tabpages/labdlg.cxx507
-rw-r--r--cui/source/tabpages/macroass.cxx397
-rw-r--r--cui/source/tabpages/measure.cxx755
-rw-r--r--cui/source/tabpages/numfmt.cxx1746
-rw-r--r--cui/source/tabpages/numpages.cxx3355
-rw-r--r--cui/source/tabpages/page.cxx1667
-rw-r--r--cui/source/tabpages/paragrph.cxx2330
-rw-r--r--cui/source/tabpages/swpossizetabpage.cxx1878
-rw-r--r--cui/source/tabpages/tabarea.cxx252
-rw-r--r--cui/source/tabpages/tabline.cxx207
-rw-r--r--cui/source/tabpages/tabstpge.cxx663
-rw-r--r--cui/source/tabpages/textanim.cxx534
-rw-r--r--cui/source/tabpages/textattr.cxx665
-rw-r--r--cui/source/tabpages/themepage.cxx176
-rw-r--r--cui/source/tabpages/tparea.cxx510
-rw-r--r--cui/source/tabpages/tpbitmap.cxx824
-rw-r--r--cui/source/tabpages/tpcolor.cxx794
-rw-r--r--cui/source/tabpages/tpgradnt.cxx633
-rw-r--r--cui/source/tabpages/tphatch.cxx562
-rw-r--r--cui/source/tabpages/tpline.cxx1695
-rw-r--r--cui/source/tabpages/tplnedef.cxx840
-rw-r--r--cui/source/tabpages/tplneend.cxx610
-rw-r--r--cui/source/tabpages/tppattern.cxx553
-rw-r--r--cui/source/tabpages/tpshadow.cxx515
-rw-r--r--cui/source/tabpages/tptrans.cxx519
-rw-r--r--cui/source/tabpages/transfrm.cxx1562
-rw-r--r--cui/source/util/FontFeatures.cxx30
-rw-r--r--cui/uiconfig/ui/aboutconfigdialog.ui301
-rw-r--r--cui/uiconfig/ui/aboutconfigvaluedialog.ui131
-rw-r--r--cui/uiconfig/ui/aboutdialog.ui462
-rw-r--r--cui/uiconfig/ui/accelconfigpage.ui581
-rw-r--r--cui/uiconfig/ui/acorexceptpage.ui426
-rw-r--r--cui/uiconfig/ui/acoroptionspage.ui88
-rw-r--r--cui/uiconfig/ui/acorreplacepage.ui258
-rw-r--r--cui/uiconfig/ui/additionsdialog.ui282
-rw-r--r--cui/uiconfig/ui/additionsfragment.ui426
-rw-r--r--cui/uiconfig/ui/agingdialog.ui208
-rw-r--r--cui/uiconfig/ui/applyautofmtpage.ui215
-rw-r--r--cui/uiconfig/ui/applylocalizedpage.ui630
-rw-r--r--cui/uiconfig/ui/areadialog.ui261
-rw-r--r--cui/uiconfig/ui/areatabpage.ui224
-rw-r--r--cui/uiconfig/ui/asiantypography.ui80
-rw-r--r--cui/uiconfig/ui/assigncomponentdialog.ui134
-rw-r--r--cui/uiconfig/ui/autocorrectdialog.ui519
-rw-r--r--cui/uiconfig/ui/baselinksdialog.ui429
-rw-r--r--cui/uiconfig/ui/borderareatransparencydialog.ui180
-rw-r--r--cui/uiconfig/ui/borderbackgrounddialog.ui159
-rw-r--r--cui/uiconfig/ui/borderpage.ui739
-rw-r--r--cui/uiconfig/ui/breaknumberoption.ui222
-rw-r--r--cui/uiconfig/ui/bulletandposition.ui1150
-rw-r--r--cui/uiconfig/ui/calloutdialog.ui254
-rw-r--r--cui/uiconfig/ui/calloutpage.ui365
-rw-r--r--cui/uiconfig/ui/cellalignment.ui564
-rw-r--r--cui/uiconfig/ui/certdialog.ui279
-rw-r--r--cui/uiconfig/ui/chapterfragment.ui31
-rw-r--r--cui/uiconfig/ui/charnamepage.ui920
-rw-r--r--cui/uiconfig/ui/colorconfigwin.ui2002
-rw-r--r--cui/uiconfig/ui/colorfragment.ui48
-rw-r--r--cui/uiconfig/ui/colorpage.ui994
-rw-r--r--cui/uiconfig/ui/colorpickerdialog.ui831
-rw-r--r--cui/uiconfig/ui/comment.ui317
-rw-r--r--cui/uiconfig/ui/connectortabpage.ui470
-rw-r--r--cui/uiconfig/ui/connpooloptions.ui302
-rw-r--r--cui/uiconfig/ui/croppage.ui545
-rw-r--r--cui/uiconfig/ui/cuiimapdlg.ui366
-rw-r--r--cui/uiconfig/ui/customizedialog.ui400
-rw-r--r--cui/uiconfig/ui/databaselinkdialog.ui229
-rw-r--r--cui/uiconfig/ui/dbregisterpage.ui198
-rw-r--r--cui/uiconfig/ui/diagramdialog.ui160
-rw-r--r--cui/uiconfig/ui/dimensionlinestabpage.ui557
-rw-r--r--cui/uiconfig/ui/editdictionarydialog.ui419
-rw-r--r--cui/uiconfig/ui/editmodulesdialog.ui353
-rw-r--r--cui/uiconfig/ui/effectspage.ui716
-rw-r--r--cui/uiconfig/ui/embossdialog.ui215
-rw-r--r--cui/uiconfig/ui/entrycontextmenu.ui57
-rw-r--r--cui/uiconfig/ui/eventassigndialog.ui84
-rw-r--r--cui/uiconfig/ui/eventassignpage.ui345
-rw-r--r--cui/uiconfig/ui/eventsconfigpage.ui250
-rw-r--r--cui/uiconfig/ui/fileextcheckdialog.ui109
-rw-r--r--cui/uiconfig/ui/fmsearchdialog.ui889
-rw-r--r--cui/uiconfig/ui/fontfeaturesdialog.ui199
-rw-r--r--cui/uiconfig/ui/fontfragment.ui51
-rw-r--r--cui/uiconfig/ui/formatcellsdialog.ui352
-rw-r--r--cui/uiconfig/ui/formatnumberdialog.ui90
-rw-r--r--cui/uiconfig/ui/galleryapplyprogress.ui97
-rw-r--r--cui/uiconfig/ui/galleryfilespage.ui276
-rw-r--r--cui/uiconfig/ui/gallerygeneralpage.ui202
-rw-r--r--cui/uiconfig/ui/gallerysearchprogress.ui133
-rw-r--r--cui/uiconfig/ui/gallerythemedialog.ui207
-rw-r--r--cui/uiconfig/ui/gallerythemeiddialog.ui111
-rw-r--r--cui/uiconfig/ui/gallerytitledialog.ui135
-rw-r--r--cui/uiconfig/ui/galleryupdateprogress.ui102
-rw-r--r--cui/uiconfig/ui/gradientpage.ui754
-rw-r--r--cui/uiconfig/ui/graphictestdlg.ui164
-rw-r--r--cui/uiconfig/ui/graphictestentry.ui43
-rw-r--r--cui/uiconfig/ui/hangulhanjaadddialog.ui155
-rw-r--r--cui/uiconfig/ui/hangulhanjaconversiondialog.ui791
-rw-r--r--cui/uiconfig/ui/hangulhanjaeditdictdialog.ui384
-rw-r--r--cui/uiconfig/ui/hangulhanjaoptdialog.ui367
-rw-r--r--cui/uiconfig/ui/hatchpage.ui458
-rw-r--r--cui/uiconfig/ui/hyperlinkdialog.ui446
-rw-r--r--cui/uiconfig/ui/hyperlinkdocpage.ui438
-rw-r--r--cui/uiconfig/ui/hyperlinkinternetpage.ui452
-rw-r--r--cui/uiconfig/ui/hyperlinkmailpage.ui362
-rw-r--r--cui/uiconfig/ui/hyperlinkmarkdialog.ui165
-rw-r--r--cui/uiconfig/ui/hyperlinknewdocpage.ui446
-rw-r--r--cui/uiconfig/ui/hyphenate.ui277
-rw-r--r--cui/uiconfig/ui/iconchangedialog.ui84
-rw-r--r--cui/uiconfig/ui/iconselectordialog.ui247
-rw-r--r--cui/uiconfig/ui/imagetabpage.ui608
-rw-r--r--cui/uiconfig/ui/imageviewer.ui44
-rw-r--r--cui/uiconfig/ui/insertfloatingframe.ui534
-rw-r--r--cui/uiconfig/ui/insertoleobject.ui315
-rw-r--r--cui/uiconfig/ui/insertrowcolumn.ui246
-rw-r--r--cui/uiconfig/ui/javaclasspathdialog.ui270
-rw-r--r--cui/uiconfig/ui/javastartparametersdialog.ui306
-rw-r--r--cui/uiconfig/ui/langtoolconfigpage.ui249
-rw-r--r--cui/uiconfig/ui/linedialog.ui305
-rw-r--r--cui/uiconfig/ui/lineendstabpage.ui310
-rw-r--r--cui/uiconfig/ui/linestyletabpage.ui477
-rw-r--r--cui/uiconfig/ui/linetabpage.ui953
-rw-r--r--cui/uiconfig/ui/macroassigndialog.ui94
-rw-r--r--cui/uiconfig/ui/macroassignpage.ui208
-rw-r--r--cui/uiconfig/ui/macroselectordialog.ui310
-rw-r--r--cui/uiconfig/ui/menuassignpage.ui1012
-rw-r--r--cui/uiconfig/ui/mosaicdialog.ui292
-rw-r--r--cui/uiconfig/ui/movemenu.ui305
-rw-r--r--cui/uiconfig/ui/multipathdialog.ui264
-rw-r--r--cui/uiconfig/ui/namedialog.ui129
-rw-r--r--cui/uiconfig/ui/newlibdialog.ui162
-rw-r--r--cui/uiconfig/ui/newtabledialog.ui175
-rw-r--r--cui/uiconfig/ui/newtoolbardialog.ui183
-rw-r--r--cui/uiconfig/ui/numberingformatpage.ui724
-rw-r--r--cui/uiconfig/ui/numberingoptionspage.ui760
-rw-r--r--cui/uiconfig/ui/numberingpositionpage.ui569
-rw-r--r--cui/uiconfig/ui/objectnamedialog.ui133
-rw-r--r--cui/uiconfig/ui/objecttitledescdialog.ui186
-rw-r--r--cui/uiconfig/ui/optaccessibilitypage.ui230
-rw-r--r--cui/uiconfig/ui/optadvancedpage.ui442
-rw-r--r--cui/uiconfig/ui/optappearancepage.ui261
-rw-r--r--cui/uiconfig/ui/optasianpage.ui371
-rw-r--r--cui/uiconfig/ui/optbasicidepage.ui224
-rw-r--r--cui/uiconfig/ui/optchartcolorspage.ui250
-rw-r--r--cui/uiconfig/ui/optctlpage.ui279
-rw-r--r--cui/uiconfig/ui/optemailpage.ui199
-rw-r--r--cui/uiconfig/ui/optfltrembedpage.ui359
-rw-r--r--cui/uiconfig/ui/optfltrpage.ui270
-rw-r--r--cui/uiconfig/ui/optfontspage.ui480
-rw-r--r--cui/uiconfig/ui/optgeneralpage.ui441
-rw-r--r--cui/uiconfig/ui/opthtmlpage.ui550
-rw-r--r--cui/uiconfig/ui/optionsdialog.ui215
-rw-r--r--cui/uiconfig/ui/optjsearchpage.ui448
-rw-r--r--cui/uiconfig/ui/optlanguagespage.ui557
-rw-r--r--cui/uiconfig/ui/optlingupage.ui623
-rw-r--r--cui/uiconfig/ui/optnewdictionarydialog.ui217
-rw-r--r--cui/uiconfig/ui/optonlineupdatepage.ui469
-rw-r--r--cui/uiconfig/ui/optopenclpage.ui75
-rw-r--r--cui/uiconfig/ui/optpathspage.ui214
-rw-r--r--cui/uiconfig/ui/optproxypage.ui327
-rw-r--r--cui/uiconfig/ui/optsavepage.ui475
-rw-r--r--cui/uiconfig/ui/optsecuritypage.ui506
-rw-r--r--cui/uiconfig/ui/optuserpage.ui1058
-rw-r--r--cui/uiconfig/ui/optviewpage.ui782
-rw-r--r--cui/uiconfig/ui/pageformatpage.ui830
-rw-r--r--cui/uiconfig/ui/paragalignpage.ui403
-rw-r--r--cui/uiconfig/ui/paraindentspacing.ui525
-rw-r--r--cui/uiconfig/ui/paratabspage.ui599
-rw-r--r--cui/uiconfig/ui/password.ui443
-rw-r--r--cui/uiconfig/ui/pastespecial.ui222
-rw-r--r--cui/uiconfig/ui/patterntabpage.ui401
-rw-r--r--cui/uiconfig/ui/percentdialog.ui121
-rw-r--r--cui/uiconfig/ui/personalization_tab.ui195
-rw-r--r--cui/uiconfig/ui/pickbulletpage.ui62
-rw-r--r--cui/uiconfig/ui/pickgraphicpage.ui109
-rw-r--r--cui/uiconfig/ui/picknumberingpage.ui62
-rw-r--r--cui/uiconfig/ui/pickoutlinepage.ui62
-rw-r--r--cui/uiconfig/ui/positionpage.ui546
-rw-r--r--cui/uiconfig/ui/positionsizedialog.ui305
-rw-r--r--cui/uiconfig/ui/possizetabpage.ui594
-rw-r--r--cui/uiconfig/ui/posterdialog.ui207
-rw-r--r--cui/uiconfig/ui/qrcodegen.ui402
-rw-r--r--cui/uiconfig/ui/querychangelineenddialog.ui35
-rw-r--r--cui/uiconfig/ui/querydeletebitmapdialog.ui34
-rw-r--r--cui/uiconfig/ui/querydeletechartcolordialog.ui35
-rw-r--r--cui/uiconfig/ui/querydeletecolordialog.ui33
-rw-r--r--cui/uiconfig/ui/querydeletedictionarydialog.ui35
-rw-r--r--cui/uiconfig/ui/querydeletegradientdialog.ui34
-rw-r--r--cui/uiconfig/ui/querydeletehatchdialog.ui34
-rw-r--r--cui/uiconfig/ui/querydeletelineenddialog.ui35
-rw-r--r--cui/uiconfig/ui/querydeletelinestyledialog.ui34
-rw-r--r--cui/uiconfig/ui/queryduplicatedialog.ui35
-rw-r--r--cui/uiconfig/ui/querynoloadedfiledialog.ui34
-rw-r--r--cui/uiconfig/ui/querynosavefiledialog.ui34
-rw-r--r--cui/uiconfig/ui/querysavelistdialog.ui35
-rw-r--r--cui/uiconfig/ui/queryupdategalleryfilelistdialog.ui34
-rw-r--r--cui/uiconfig/ui/recordnumberdialog.ui118
-rw-r--r--cui/uiconfig/ui/rotationtabpage.ui353
-rw-r--r--cui/uiconfig/ui/screenshotannotationdialog.ui138
-rw-r--r--cui/uiconfig/ui/scriptorganizer.ui270
-rw-r--r--cui/uiconfig/ui/searchattrdialog.ui159
-rw-r--r--cui/uiconfig/ui/searchformatdialog.ui544
-rw-r--r--cui/uiconfig/ui/securityoptionsdialog.ui457
-rw-r--r--cui/uiconfig/ui/selectpathdialog.ui237
-rw-r--r--cui/uiconfig/ui/shadowtabpage.ui344
-rw-r--r--cui/uiconfig/ui/showcoldialog.ui149
-rw-r--r--cui/uiconfig/ui/signatureline.ui354
-rw-r--r--cui/uiconfig/ui/signsignatureline.ui382
-rw-r--r--cui/uiconfig/ui/similaritysearchdialog.ui241
-rw-r--r--cui/uiconfig/ui/slantcornertabpage.ui459
-rw-r--r--cui/uiconfig/ui/smarttagoptionspage.ui177
-rw-r--r--cui/uiconfig/ui/smoothdialog.ui204
-rw-r--r--cui/uiconfig/ui/solarizedialog.ui225
-rw-r--r--cui/uiconfig/ui/specialcharacters.ui915
-rw-r--r--cui/uiconfig/ui/spellingdialog.ui669
-rw-r--r--cui/uiconfig/ui/spelloptionsdialog.ui88
-rw-r--r--cui/uiconfig/ui/spinbox.ui80
-rw-r--r--cui/uiconfig/ui/splitcellsdialog.ui272
-rw-r--r--cui/uiconfig/ui/storedwebconnectiondialog.ui214
-rw-r--r--cui/uiconfig/ui/swpossizepage.ui679
-rw-r--r--cui/uiconfig/ui/textanimtabpage.ui561
-rw-r--r--cui/uiconfig/ui/textattrtabpage.ui509
-rw-r--r--cui/uiconfig/ui/textcolumnstabpage.ui112
-rw-r--r--cui/uiconfig/ui/textdialog.ui257
-rw-r--r--cui/uiconfig/ui/textflowpage.ui728
-rw-r--r--cui/uiconfig/ui/themetabpage.ui557
-rw-r--r--cui/uiconfig/ui/thesaurus.ui328
-rw-r--r--cui/uiconfig/ui/tipofthedaydialog.ui180
-rw-r--r--cui/uiconfig/ui/toolbarmodedialog.ui391
-rw-r--r--cui/uiconfig/ui/transparencytabpage.ui582
-rw-r--r--cui/uiconfig/ui/tsaurldialog.ui250
-rw-r--r--cui/uiconfig/ui/twolinespage.ui239
-rw-r--r--cui/uiconfig/ui/wordcompletionpage.ui429
-rw-r--r--cui/uiconfig/ui/zoomdialog.ui450
-rw-r--r--cui/util/cui.component30
512 files changed, 172720 insertions, 0 deletions
diff --git a/cui/AllLangMoTarget_cui.mk b/cui/AllLangMoTarget_cui.mk
new file mode 100644
index 000000000..a21f043c4
--- /dev/null
+++ b/cui/AllLangMoTarget_cui.mk
@@ -0,0 +1,11 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+$(eval $(call gb_AllLangMoTarget_AllLangMoTarget,cui))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/CppunitTest_cui_dialogs_test.mk b/cui/CppunitTest_cui_dialogs_test.mk
new file mode 100644
index 000000000..2bafdb5fa
--- /dev/null
+++ b/cui/CppunitTest_cui_dialogs_test.mk
@@ -0,0 +1,71 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitScreenShot,cui_dialogs_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,cui_dialogs_test, \
+ cui/qa/unit/cui-dialogs-test \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test))
+
+$(eval $(call gb_CppunitTest_set_include,cui_dialogs_test,\
+ -I$(SRCDIR)/cui/source/inc \
+ -I$(SRCDIR)/cui/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,cui_dialogs_test, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ i18nlangtag \
+ i18nutil \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sfx \
+ sot \
+ svl \
+ svt \
+ cui \
+ svxcore \
+ test \
+ tl \
+ tk \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_use_external,cui_dialogs_test,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test))
+
+$(eval $(call gb_CppunitTest_use_ure,cui_dialogs_test))
+$(eval $(call gb_CppunitTest_use_vcl_non_headless_with_windows,cui_dialogs_test))
+
+$(eval $(call gb_CppunitTest_use_rdb,cui_dialogs_test,services))
+
+$(eval $(call gb_CppunitTest_use_configuration,cui_dialogs_test))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,cui_dialogs_test,\
+ cui \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/CppunitTest_cui_dialogs_test_2.mk b/cui/CppunitTest_cui_dialogs_test_2.mk
new file mode 100644
index 000000000..564c06c29
--- /dev/null
+++ b/cui/CppunitTest_cui_dialogs_test_2.mk
@@ -0,0 +1,71 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitScreenShot,cui_dialogs_test2))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,cui_dialogs_test2, \
+ cui/qa/unit/cui-dialogs-test_2 \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test2))
+
+$(eval $(call gb_CppunitTest_set_include,cui_dialogs_test2,\
+ -I$(SRCDIR)/cui/source/inc \
+ -I$(SRCDIR)/cui/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,cui_dialogs_test2, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ i18nlangtag \
+ i18nutil \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sfx \
+ sot \
+ svl \
+ svt \
+ cui \
+ test \
+ tl \
+ tk \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_use_external,cui_dialogs_test2,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test2))
+
+$(eval $(call gb_CppunitTest_use_ure,cui_dialogs_test2))
+$(eval $(call gb_CppunitTest_use_vcl_non_headless_with_windows,cui_dialogs_test2))
+
+$(eval $(call gb_CppunitTest_use_rdb,cui_dialogs_test2,services))
+
+# $(eval $(call gb_CppunitTest_use_configuration,cui_dialogs_test2))
+$(eval $(call gb_CppunitTest_use_instdir_configuration,cui_dialogs_test2))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,cui_dialogs_test2, \
+ cui \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/CppunitTest_cui_dialogs_test_3.mk b/cui/CppunitTest_cui_dialogs_test_3.mk
new file mode 100644
index 000000000..72e0bad2f
--- /dev/null
+++ b/cui/CppunitTest_cui_dialogs_test_3.mk
@@ -0,0 +1,71 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitScreenShot,cui_dialogs_test3))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,cui_dialogs_test3, \
+ cui/qa/unit/cui-dialogs-test_3 \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test3))
+
+$(eval $(call gb_CppunitTest_set_include,cui_dialogs_test3,\
+ -I$(SRCDIR)/cui/source/inc \
+ -I$(SRCDIR)/cui/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,cui_dialogs_test3, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ i18nlangtag \
+ i18nutil \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sfx \
+ sot \
+ svl \
+ svt \
+ cui \
+ test \
+ tl \
+ tk \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_use_external,cui_dialogs_test3,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test3))
+
+$(eval $(call gb_CppunitTest_use_ure,cui_dialogs_test3))
+$(eval $(call gb_CppunitTest_use_vcl_non_headless_with_windows,cui_dialogs_test3))
+
+$(eval $(call gb_CppunitTest_use_rdb,cui_dialogs_test3,services))
+
+# $(eval $(call gb_CppunitTest_use_configuration,cui_dialogs_test3))
+$(eval $(call gb_CppunitTest_use_instdir_configuration,cui_dialogs_test3))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,cui_dialogs_test3, \
+ cui \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/CppunitTest_cui_dialogs_test_4.mk b/cui/CppunitTest_cui_dialogs_test_4.mk
new file mode 100644
index 000000000..1a2382eb2
--- /dev/null
+++ b/cui/CppunitTest_cui_dialogs_test_4.mk
@@ -0,0 +1,71 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitScreenShot,cui_dialogs_test4))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,cui_dialogs_test4, \
+ cui/qa/unit/cui-dialogs-test_4 \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test4))
+
+$(eval $(call gb_CppunitTest_set_include,cui_dialogs_test4,\
+ -I$(SRCDIR)/cui/source/inc \
+ -I$(SRCDIR)/cui/inc \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,cui_dialogs_test4, \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ i18nlangtag \
+ i18nutil \
+ msfilter \
+ oox \
+ sal \
+ salhelper \
+ sax \
+ sfx \
+ sot \
+ svl \
+ svt \
+ cui \
+ test \
+ tl \
+ tk \
+ ucbhelper \
+ unotest \
+ utl \
+ vcl \
+ xo \
+))
+
+$(eval $(call gb_CppunitTest_use_external,cui_dialogs_test4,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,cui_dialogs_test4))
+
+$(eval $(call gb_CppunitTest_use_ure,cui_dialogs_test4))
+$(eval $(call gb_CppunitTest_use_vcl_non_headless_with_windows,cui_dialogs_test4))
+
+$(eval $(call gb_CppunitTest_use_rdb,cui_dialogs_test4,services))
+
+# $(eval $(call gb_CppunitTest_use_configuration,cui_dialogs_test4))
+$(eval $(call gb_CppunitTest_use_instdir_configuration,cui_dialogs_test4))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,cui_dialogs_test4, \
+ cui \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/IwyuFilter_cui.yaml b/cui/IwyuFilter_cui.yaml
new file mode 100644
index 000000000..739afefd4
--- /dev/null
+++ b/cui/IwyuFilter_cui.yaml
@@ -0,0 +1,44 @@
+---
+assumeFilename: cui/source/options/optgenrl.cxx
+excludelist:
+ cui/source/customize/macropg.cxx:
+ # Needed for TypedWhichId macro
+ - svl/macitem.hxx
+ cui/source/customize/CommandCategoryListBox.cxx:
+ # Actually used
+ - com/sun/star/script/browse/XBrowseNode.hpp
+ cui/source/customize/cfgutil.cxx:
+ # Actually used
+ - com/sun/star/script/browse/XBrowseNode.hpp
+ cui/source/dialogs/DiagramDialog.cxx:
+ # Needed for direct member access
+ - com/sun/star/beans/PropertyValue.hpp
+ cui/source/dialogs/pastedlg.cxx:
+ # Needed for direct member access
+ - com/sun/star/beans/PropertyValue.hpp
+ cui/source/dialogs/SignSignatureLineDialog.cxx:
+ # Actually used
+ - com/sun/star/graphic/XGraphic.hpp
+ - com/sun/star/security/XCertificate.hpp
+ cui/source/factory/dlgfact.cxx:
+ # Needed on WIN
+ - fileextcheckdlg.hxx
+ cui/source/dialogs/thesdlg.cxx:
+ # Actually used
+ - com/sun/star/linguistic2/XMeaning.hpp
+ - com/sun/star/linguistic2/XThesaurus.hpp
+ cui/source/dialogs/tipofthedaydlg.cxx:
+ # Needed for direct member access
+ - com/sun/star/beans/PropertyValue.hpp
+ cui/source/dialogs/toolbarmodedlg.cxx:
+ # Needed for direct member access
+ - com/sun/star/beans/PropertyValue.hpp
+ cui/source/tabpages/numfmt.cxx:
+ # Actually used
+ - com/sun/star/frame/XModel.hpp
+ cui/source/customize/cfg.cxx:
+ # Actually used
+ - com/sun/star/ui/dialogs/XFilePicker3.hpp
+ cui/source/dialogs/AdditionsDialog.cxx:
+ # Actually needed for orcus::json::parse_error
+ - orcus/json_parser.hpp
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
new file mode 100644
index 000000000..cb26653b3
--- /dev/null
+++ b/cui/Library_cui.mk
@@ -0,0 +1,245 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,cui))
+
+$(eval $(call gb_Library_set_plugin_for,cui,vcl))
+
+$(eval $(call gb_Library_set_componentfile,cui,cui/util/cui,services))
+
+$(eval $(call gb_Library_set_include,cui,\
+ $$(INCLUDE) \
+ -I$(SRCDIR)/cui/inc \
+ -I$(SRCDIR)/cui/source/inc \
+))
+
+$(eval $(call gb_Library_set_precompiled_header,cui,cui/inc/pch/precompiled_cui))
+
+$(eval $(call gb_Library_add_defs,cui,\
+ -DCUI_DLLIMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_use_custom_headers,cui,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_Library_use_sdk_api,cui))
+
+$(eval $(call gb_Library_use_libraries,cui,\
+ $(call gb_Helper_optional,AVMEDIA,avmedia) \
+ basegfx \
+ comphelper \
+ cppu \
+ cppuhelper \
+ drawinglayer \
+ editeng \
+ i18nlangtag \
+ i18nutil \
+ $(if $(ENABLE_JAVA), \
+ jvmfwk) \
+ lng \
+ $(call gb_Helper_optional,OPENCL, \
+ opencl) \
+ sal \
+ salhelper \
+ sax \
+ sb \
+ sfx \
+ sot \
+ svl \
+ svt \
+ svxcore \
+ svx \
+ tk \
+ tl \
+ ucbhelper \
+ utl \
+ $(if $(ENABLE_BREAKPAD), \
+ crashreport \
+ ) \
+))
+
+$(eval $(call gb_Library_use_externals,cui,\
+ boost_headers \
+ $(call gb_Helper_optional,OPENCL,\
+ clew) \
+ epoxy \
+ icuuc \
+ icu_headers \
+ libxml2 \
+ orcus-parser \
+ orcus \
+ zxing \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_Library_use_system_win32_libs,cui,\
+ advapi32 \
+ shlwapi \
+))
+
+$(eval $(call gb_Library_add_exception_objects,cui,\
+ cui/source/dialogs/fileextcheckdlg \
+))
+endif
+
+ifneq ($(ENABLE_WASM_STRIP_PINGUSER),TRUE)
+$(eval $(call gb_Library_add_exception_objects,cui,\
+ cui/source/dialogs/tipofthedaydlg \
+))
+endif
+
+ifneq ($(ENABLE_WASM_STRIP_HUNSPELL),TRUE)
+$(eval $(call gb_Library_add_exception_objects,cui,\
+ cui/source/dialogs/hyphen \
+))
+endif
+
+$(eval $(call gb_Library_add_exception_objects,cui,\
+ cui/source/customize/acccfg \
+ cui/source/customize/cfg \
+ cui/source/customize/cfgutil \
+ cui/source/customize/CommandCategoryListBox \
+ cui/source/customize/eventdlg \
+ cui/source/customize/macropg \
+ cui/source/customize/SvxConfigPageHelper \
+ cui/source/customize/SvxMenuConfigPage \
+ cui/source/customize/SvxToolbarConfigPage \
+ cui/source/customize/SvxNotebookbarConfigPage \
+ cui/source/customize/CustomNotebookbarGenerator \
+ cui/source/dialogs/about \
+ $(call gb_Helper_optional,EXTENSIONS, \
+ cui/source/dialogs/AdditionsDialog) \
+ cui/source/dialogs/colorpicker \
+ cui/source/dialogs/cuicharmap \
+ cui/source/dialogs/cuifmsearch \
+ cui/source/dialogs/cuigaldlg \
+ cui/source/dialogs/cuigrfflt \
+ cui/source/dialogs/cuihyperdlg \
+ cui/source/dialogs/cuiimapwnd \
+ cui/source/dialogs/cuitbxform \
+ cui/source/dialogs/dlgname \
+ cui/source/dialogs/DiagramDialog \
+ cui/source/dialogs/FontFeaturesDialog \
+ cui/source/dialogs/hangulhanjadlg \
+ cui/source/dialogs/hldocntp \
+ cui/source/dialogs/hldoctp \
+ cui/source/dialogs/hlinettp \
+ cui/source/dialogs/hlmailtp \
+ cui/source/dialogs/hlmarkwn \
+ cui/source/dialogs/hltpbase \
+ cui/source/dialogs/iconcdlg \
+ cui/source/dialogs/insdlg \
+ cui/source/dialogs/insrc \
+ cui/source/dialogs/linkdlg \
+ cui/source/dialogs/multipat \
+ cui/source/dialogs/newtabledlg \
+ cui/source/dialogs/passwdomdlg \
+ cui/source/dialogs/screenshotannotationdlg \
+ cui/source/dialogs/pastedlg \
+ cui/source/dialogs/postdlg \
+ cui/source/dialogs/QrCodeGenDialog \
+ cui/source/dialogs/GraphicTestsDialog \
+ cui/source/dialogs/ImageViewerDialog \
+ cui/source/dialogs/scriptdlg \
+ cui/source/dialogs/SignatureLineDialogBase \
+ cui/source/dialogs/SignatureLineDialog \
+ cui/source/dialogs/SignSignatureLineDialog \
+ cui/source/dialogs/sdrcelldlg \
+ cui/source/dialogs/showcols \
+ cui/source/dialogs/SpellDialog \
+ cui/source/dialogs/splitcelldlg \
+ cui/source/dialogs/srchxtra \
+ cui/source/dialogs/thesdlg \
+ cui/source/dialogs/toolbarmodedlg \
+ cui/source/dialogs/zoom \
+ cui/source/factory/cuiexp \
+ cui/source/factory/cuiresmgr \
+ cui/source/factory/dlgfact \
+ cui/source/factory/init \
+ cui/source/options/certpath \
+ cui/source/options/cfgchart \
+ cui/source/options/connpoolconfig \
+ cui/source/options/connpooloptions \
+ cui/source/options/connpoolsettings \
+ cui/source/options/cuisrchdlg \
+ cui/source/options/dbregister \
+ cui/source/options/dbregisterednamesconfig \
+ cui/source/options/dbregistersettings \
+ cui/source/options/doclinkdialog \
+ cui/source/options/fontsubs \
+ cui/source/options/optaboutconfig \
+ cui/source/options/optaccessibility \
+ cui/source/options/optasian \
+ $(call gb_Helper_optional,SCRIPTING, \
+ cui/source/options/optbasic) \
+ cui/source/options/optchart \
+ cui/source/options/optcolor \
+ cui/source/options/optctl \
+ cui/source/options/optdict \
+ cui/source/options/optfltr \
+ cui/source/options/optgdlg \
+ cui/source/options/optgenrl \
+ cui/source/options/opthtml \
+ cui/source/options/optlanguagetool \
+ cui/source/options/optinet2 \
+ cui/source/options/optjava \
+ cui/source/options/optjsearch \
+ cui/source/options/optlingu \
+ $(call gb_Helper_optional,OPENCL, \
+ cui/source/options/optopencl) \
+ cui/source/options/optpath \
+ cui/source/options/optsave \
+ cui/source/options/optupdt \
+ $(call gb_Helper_optional,DESKTOP,\
+ cui/source/options/personalization) \
+ cui/source/options/sdbcdriverenum \
+ cui/source/options/securityoptions \
+ cui/source/options/treeopt \
+ cui/source/options/tsaurls \
+ cui/source/options/webconninfo \
+ cui/source/tabpages/align \
+ cui/source/tabpages/autocdlg \
+ cui/source/tabpages/backgrnd \
+ cui/source/tabpages/bbdlg \
+ cui/source/tabpages/border \
+ cui/source/tabpages/chardlg \
+ cui/source/tabpages/connect \
+ cui/source/tabpages/grfpage \
+ cui/source/tabpages/labdlg \
+ cui/source/tabpages/macroass \
+ cui/source/tabpages/measure \
+ cui/source/tabpages/numfmt \
+ cui/source/tabpages/numpages \
+ cui/source/tabpages/page \
+ cui/source/tabpages/paragrph \
+ cui/source/tabpages/swpossizetabpage \
+ cui/source/tabpages/tabarea \
+ cui/source/tabpages/tabline \
+ cui/source/tabpages/tabstpge \
+ cui/source/tabpages/textanim \
+ cui/source/tabpages/textattr \
+ cui/source/tabpages/TextColumnsPage \
+ cui/source/tabpages/themepage \
+ cui/source/tabpages/tparea \
+ cui/source/tabpages/tpbitmap \
+ cui/source/tabpages/tpcolor \
+ cui/source/tabpages/tpgradnt \
+ cui/source/tabpages/tphatch \
+ cui/source/tabpages/tpline \
+ cui/source/tabpages/tplnedef \
+ cui/source/tabpages/tplneend \
+ cui/source/tabpages/tppattern \
+ cui/source/tabpages/tpshadow \
+ cui/source/tabpages/tptrans \
+ cui/source/tabpages/transfrm \
+ cui/source/util/FontFeatures \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/Makefile b/cui/Makefile
new file mode 100644
index 000000000..0997e6284
--- /dev/null
+++ b/cui/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/Module_cui.mk b/cui/Module_cui.mk
new file mode 100644
index 000000000..53492ef29
--- /dev/null
+++ b/cui/Module_cui.mk
@@ -0,0 +1,35 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,cui))
+
+$(eval $(call gb_Module_add_targets,cui,\
+ Library_cui \
+ Package_cui \
+ UIConfig_cui \
+))
+
+$(eval $(call gb_Module_add_l10n_targets,cui,\
+ AllLangMoTarget_cui \
+))
+
+# screenshots
+$(eval $(call gb_Module_add_screenshot_targets,cui,\
+ CppunitTest_cui_dialogs_test \
+ CppunitTest_cui_dialogs_test_2 \
+ CppunitTest_cui_dialogs_test_3 \
+ CppunitTest_cui_dialogs_test_4 \
+))
+
+$(eval $(call gb_Module_add_uicheck_targets,cui,\
+ UITest_cui_dialogs \
+ UITest_cui_tabpages \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/Package_cui.mk b/cui/Package_cui.mk
new file mode 100644
index 000000000..918e62f69
--- /dev/null
+++ b/cui/Package_cui.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Package_Package,cui,$(SRCDIR)/cui))
+
+$(eval $(call gb_Package_add_files,cui,$(LIBO_SHARE_FOLDER)/filter,\
+ source/dialogs/signature-line.svg \
+ source/dialogs/signature-line-draw.svg \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/README.md b/cui/README.md
new file mode 100644
index 000000000..34b30ebef
--- /dev/null
+++ b/cui/README.md
@@ -0,0 +1,8 @@
+# Common User Interface (cui)
+
+It was moved out from `svx` in DEV300m68:
+
+<http://www.mail-archive.com/dev@openoffice.org/msg12925.html>
+
+It contains dialogs used by more than one application, e.g. paragraph
+properties.
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk
new file mode 100644
index 000000000..cdedcc15a
--- /dev/null
+++ b/cui/UIConfig_cui.mk
@@ -0,0 +1,232 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UIConfig_UIConfig,cui))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_UIConfig_add_uifiles,cui,\
+ cui/uiconfig/ui/fileextcheckdialog \
+))
+endif
+
+ifneq ($(ENABLE_WASM_STRIP_PINGUSER),TRUE)
+$(eval $(call gb_UIConfig_add_uifiles,cui,\
+ cui/uiconfig/ui/tipofthedaydialog \
+))
+endif
+
+$(eval $(call gb_UIConfig_add_uifiles,cui,\
+ cui/uiconfig/ui/aboutdialog \
+ cui/uiconfig/ui/aboutconfigdialog\
+ cui/uiconfig/ui/aboutconfigvaluedialog \
+ cui/uiconfig/ui/accelconfigpage \
+ cui/uiconfig/ui/additionsdialog \
+ cui/uiconfig/ui/additionsfragment \
+ cui/uiconfig/ui/agingdialog \
+ cui/uiconfig/ui/acorexceptpage \
+ cui/uiconfig/ui/acoroptionspage \
+ cui/uiconfig/ui/acorreplacepage \
+ cui/uiconfig/ui/applyautofmtpage \
+ cui/uiconfig/ui/applylocalizedpage \
+ cui/uiconfig/ui/areadialog \
+ cui/uiconfig/ui/areatabpage \
+ cui/uiconfig/ui/asiantypography \
+ cui/uiconfig/ui/assigncomponentdialog \
+ cui/uiconfig/ui/autocorrectdialog \
+ cui/uiconfig/ui/baselinksdialog \
+ cui/uiconfig/ui/imagetabpage \
+ cui/uiconfig/ui/borderareatransparencydialog \
+ cui/uiconfig/ui/borderbackgrounddialog \
+ cui/uiconfig/ui/borderpage \
+ cui/uiconfig/ui/bulletandposition \
+ cui/uiconfig/ui/breaknumberoption \
+ cui/uiconfig/ui/calloutdialog \
+ cui/uiconfig/ui/calloutpage \
+ cui/uiconfig/ui/cellalignment \
+ cui/uiconfig/ui/certdialog \
+ cui/uiconfig/ui/chapterfragment \
+ cui/uiconfig/ui/charnamepage \
+ cui/uiconfig/ui/colorconfigwin \
+ cui/uiconfig/ui/colorfragment \
+ cui/uiconfig/ui/colorpage \
+ cui/uiconfig/ui/colorpickerdialog \
+ cui/uiconfig/ui/comment \
+ cui/uiconfig/ui/connectortabpage \
+ cui/uiconfig/ui/connpooloptions \
+ cui/uiconfig/ui/croppage \
+ cui/uiconfig/ui/cuiimapdlg \
+ cui/uiconfig/ui/databaselinkdialog \
+ cui/uiconfig/ui/diagramdialog \
+ cui/uiconfig/ui/dimensionlinestabpage \
+ cui/uiconfig/ui/editdictionarydialog \
+ cui/uiconfig/ui/editmodulesdialog \
+ cui/uiconfig/ui/embossdialog \
+ cui/uiconfig/ui/entrycontextmenu \
+ cui/uiconfig/ui/eventassigndialog \
+ cui/uiconfig/ui/eventassignpage \
+ cui/uiconfig/ui/fontfragment \
+ cui/uiconfig/ui/formatnumberdialog \
+ cui/uiconfig/ui/fmsearchdialog \
+ cui/uiconfig/ui/gradientpage \
+ cui/uiconfig/ui/customizedialog \
+ cui/uiconfig/ui/dbregisterpage \
+ cui/uiconfig/ui/effectspage \
+ cui/uiconfig/ui/eventsconfigpage \
+ cui/uiconfig/ui/formatcellsdialog \
+ cui/uiconfig/ui/fontfeaturesdialog \
+ cui/uiconfig/ui/galleryapplyprogress \
+ cui/uiconfig/ui/galleryfilespage \
+ cui/uiconfig/ui/gallerygeneralpage \
+ cui/uiconfig/ui/gallerysearchprogress \
+ cui/uiconfig/ui/gallerythemedialog \
+ cui/uiconfig/ui/gallerythemeiddialog \
+ cui/uiconfig/ui/gallerytitledialog \
+ cui/uiconfig/ui/galleryupdateprogress \
+ cui/uiconfig/ui/graphictestdlg \
+ cui/uiconfig/ui/graphictestentry \
+ cui/uiconfig/ui/imageviewer \
+ cui/uiconfig/ui/hangulhanjaadddialog \
+ cui/uiconfig/ui/hangulhanjaeditdictdialog \
+ cui/uiconfig/ui/hangulhanjaconversiondialog \
+ cui/uiconfig/ui/hangulhanjaoptdialog \
+ cui/uiconfig/ui/hatchpage \
+ cui/uiconfig/ui/hyperlinkdialog \
+ cui/uiconfig/ui/hyperlinkdocpage \
+ cui/uiconfig/ui/hyperlinkinternetpage \
+ cui/uiconfig/ui/hyperlinkmarkdialog \
+ cui/uiconfig/ui/hyperlinkmailpage \
+ cui/uiconfig/ui/hyperlinknewdocpage \
+ cui/uiconfig/ui/hyphenate \
+ cui/uiconfig/ui/iconchangedialog \
+ cui/uiconfig/ui/iconselectordialog \
+ cui/uiconfig/ui/insertfloatingframe \
+ cui/uiconfig/ui/insertoleobject \
+ cui/uiconfig/ui/insertrowcolumn \
+ cui/uiconfig/ui/javaclasspathdialog \
+ cui/uiconfig/ui/javastartparametersdialog \
+ cui/uiconfig/ui/linedialog \
+ cui/uiconfig/ui/linetabpage \
+ cui/uiconfig/ui/lineendstabpage \
+ cui/uiconfig/ui/linestyletabpage \
+ cui/uiconfig/ui/macroassigndialog \
+ cui/uiconfig/ui/macroassignpage \
+ cui/uiconfig/ui/macroselectordialog \
+ cui/uiconfig/ui/menuassignpage \
+ cui/uiconfig/ui/mosaicdialog \
+ cui/uiconfig/ui/movemenu \
+ cui/uiconfig/ui/multipathdialog \
+ cui/uiconfig/ui/namedialog \
+ cui/uiconfig/ui/newlibdialog \
+ cui/uiconfig/ui/newtabledialog \
+ cui/uiconfig/ui/newtoolbardialog \
+ cui/uiconfig/ui/numberingformatpage \
+ cui/uiconfig/ui/numberingoptionspage \
+ cui/uiconfig/ui/numberingpositionpage \
+ cui/uiconfig/ui/objectnamedialog \
+ cui/uiconfig/ui/objecttitledescdialog \
+ cui/uiconfig/ui/optaccessibilitypage \
+ cui/uiconfig/ui/optadvancedpage \
+ cui/uiconfig/ui/optappearancepage \
+ cui/uiconfig/ui/optasianpage \
+ cui/uiconfig/ui/optbasicidepage \
+ cui/uiconfig/ui/optctlpage \
+ cui/uiconfig/ui/optchartcolorspage \
+ cui/uiconfig/ui/optemailpage \
+ cui/uiconfig/ui/optfltrpage \
+ cui/uiconfig/ui/optfltrembedpage \
+ cui/uiconfig/ui/optfontspage \
+ cui/uiconfig/ui/optgeneralpage \
+ cui/uiconfig/ui/opthtmlpage \
+ cui/uiconfig/ui/langtoolconfigpage \
+ cui/uiconfig/ui/optionsdialog \
+ cui/uiconfig/ui/optjsearchpage \
+ cui/uiconfig/ui/optlanguagespage \
+ cui/uiconfig/ui/optlingupage \
+ cui/uiconfig/ui/optnewdictionarydialog \
+ cui/uiconfig/ui/optonlineupdatepage \
+ $(call gb_Helper_optional,OPENCL, \
+ cui/uiconfig/ui/optopenclpage) \
+ cui/uiconfig/ui/optpathspage \
+ cui/uiconfig/ui/optproxypage \
+ cui/uiconfig/ui/optsavepage \
+ cui/uiconfig/ui/optsecuritypage \
+ cui/uiconfig/ui/optuserpage \
+ cui/uiconfig/ui/optviewpage \
+ cui/uiconfig/ui/pageformatpage \
+ cui/uiconfig/ui/paragalignpage \
+ cui/uiconfig/ui/paraindentspacing \
+ cui/uiconfig/ui/paratabspage \
+ cui/uiconfig/ui/password \
+ cui/uiconfig/ui/screenshotannotationdialog \
+ cui/uiconfig/ui/pastespecial \
+ cui/uiconfig/ui/patterntabpage \
+ cui/uiconfig/ui/percentdialog \
+ cui/uiconfig/ui/personalization_tab \
+ cui/uiconfig/ui/pickbulletpage \
+ cui/uiconfig/ui/pickgraphicpage \
+ cui/uiconfig/ui/picknumberingpage \
+ cui/uiconfig/ui/pickoutlinepage \
+ cui/uiconfig/ui/positionpage \
+ cui/uiconfig/ui/positionsizedialog \
+ cui/uiconfig/ui/possizetabpage \
+ cui/uiconfig/ui/posterdialog \
+ cui/uiconfig/ui/qrcodegen \
+ cui/uiconfig/ui/querychangelineenddialog \
+ cui/uiconfig/ui/querydeletebitmapdialog \
+ cui/uiconfig/ui/querydeletechartcolordialog \
+ cui/uiconfig/ui/querydeletecolordialog \
+ cui/uiconfig/ui/querydeletedictionarydialog \
+ cui/uiconfig/ui/querydeletegradientdialog \
+ cui/uiconfig/ui/querydeletehatchdialog \
+ cui/uiconfig/ui/querydeletelineenddialog \
+ cui/uiconfig/ui/querydeletelinestyledialog \
+ cui/uiconfig/ui/queryduplicatedialog \
+ cui/uiconfig/ui/querynoloadedfiledialog \
+ cui/uiconfig/ui/querynosavefiledialog \
+ cui/uiconfig/ui/querysavelistdialog \
+ cui/uiconfig/ui/queryupdategalleryfilelistdialog \
+ cui/uiconfig/ui/recordnumberdialog \
+ cui/uiconfig/ui/rotationtabpage \
+ cui/uiconfig/ui/scriptorganizer \
+ cui/uiconfig/ui/searchattrdialog \
+ cui/uiconfig/ui/searchformatdialog \
+ cui/uiconfig/ui/securityoptionsdialog \
+ cui/uiconfig/ui/selectpathdialog \
+ cui/uiconfig/ui/shadowtabpage \
+ cui/uiconfig/ui/showcoldialog \
+ cui/uiconfig/ui/similaritysearchdialog \
+ cui/uiconfig/ui/signatureline \
+ cui/uiconfig/ui/signsignatureline \
+ cui/uiconfig/ui/slantcornertabpage \
+ cui/uiconfig/ui/smarttagoptionspage \
+ cui/uiconfig/ui/smoothdialog \
+ cui/uiconfig/ui/solarizedialog \
+ cui/uiconfig/ui/specialcharacters \
+ cui/uiconfig/ui/spellingdialog \
+ cui/uiconfig/ui/spelloptionsdialog \
+ cui/uiconfig/ui/splitcellsdialog \
+ cui/uiconfig/ui/storedwebconnectiondialog \
+ cui/uiconfig/ui/swpossizepage \
+ cui/uiconfig/ui/textattrtabpage \
+ cui/uiconfig/ui/textanimtabpage \
+ cui/uiconfig/ui/textcolumnstabpage \
+ cui/uiconfig/ui/textdialog \
+ cui/uiconfig/ui/textflowpage \
+ cui/uiconfig/ui/themetabpage \
+ cui/uiconfig/ui/thesaurus \
+ cui/uiconfig/ui/toolbarmodedialog \
+ cui/uiconfig/ui/transparencytabpage \
+ cui/uiconfig/ui/tsaurldialog \
+ cui/uiconfig/ui/twolinespage \
+ cui/uiconfig/ui/wordcompletionpage \
+ cui/uiconfig/ui/spinbox \
+ cui/uiconfig/ui/zoomdialog \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/UITest_cui_dialogs.mk b/cui/UITest_cui_dialogs.mk
new file mode 100644
index 000000000..d3ad2dc64
--- /dev/null
+++ b/cui/UITest_cui_dialogs.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UITest_UITest,cui_dialogs))
+
+$(eval $(call gb_UITest_add_modules,cui_dialogs,$(SRCDIR)/cui/qa/uitest,\
+ dialogs/ \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/UITest_cui_tabpages.mk b/cui/UITest_cui_tabpages.mk
new file mode 100644
index 000000000..4458e9859
--- /dev/null
+++ b/cui/UITest_cui_tabpages.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UITest_UITest,cui_tabpages))
+
+$(eval $(call gb_UITest_add_modules,cui_tabpages,$(SRCDIR)/cui/qa/uitest,\
+ tabpages/ \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/cui/inc/bitmaps.hlst b/cui/inc/bitmaps.hlst
new file mode 100644
index 000000000..733ce7b26
--- /dev/null
+++ b/cui/inc/bitmaps.hlst
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_NONE = u"svx/res/pr01.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_NONE_32 = u"svx/res/border_cell_none_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_ALL = u"svx/res/pr02.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_ALL_32 = u"svx/res/border_cell_all_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_LR = u"svx/res/pr03.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_LR_32 = u"svx/res/border_cell_lr_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_TB = u"svx/res/pr04.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_TB_32 = u"svx/res/border_cell_tb_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_L = u"svx/res/pr05.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_L_32 = u"svx/res/border_cell_l_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_DIAG = u"svx/res/pr06.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELL_DIAG_32 = u"svx/res/border_cell_diag_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_HOR_NONE = u"svx/res/pr07.png";
+inline constexpr OUStringLiteral RID_SVXBMP_HOR_OUTER = u"svx/res/pr08.png";
+inline constexpr OUStringLiteral RID_SVXBMP_HOR_HOR = u"svx/res/pr09.png";
+inline constexpr OUStringLiteral RID_SVXBMP_HOR_ALL = u"svx/res/pr010.png";
+inline constexpr OUStringLiteral RID_SVXBMP_HOR_OUTER2 = u"svx/res/pr011.png";
+inline constexpr OUStringLiteral RID_SVXBMP_VER_NONE = u"svx/res/pr012.png";
+inline constexpr OUStringLiteral RID_SVXBMP_VER_OUTER = u"svx/res/pr013.png";
+inline constexpr OUStringLiteral RID_SVXBMP_VER_VER = u"svx/res/pr014.png";
+inline constexpr OUStringLiteral RID_SVXBMP_VER_ALL = u"svx/res/pr015.png";
+inline constexpr OUStringLiteral RID_SVXBMP_VER_OUTER2 = u"svx/res/pr016.png";
+inline constexpr OUStringLiteral RID_SVXBMP_TABLE_NONE = u"svx/res/pr017.png";
+inline constexpr OUStringLiteral RID_SVXBMP_TABLE_OUTER = u"svx/res/pr018.png";
+inline constexpr OUStringLiteral RID_SVXBMP_TABLE_OUTERH = u"svx/res/pr019.png";
+inline constexpr OUStringLiteral RID_SVXBMP_TABLE_ALL = u"svx/res/pr020.png";
+inline constexpr OUStringLiteral RID_SVXBMP_TABLE_OUTER2 = u"svx/res/pr021.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOWNONE = u"svx/res/sh01.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOWNONE_32 = u"svx/res/shadow_none_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_BOT_RIGHT = u"svx/res/sh02.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_BOT_RIGHT_32 = u"svx/res/shadow_bottom_right_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_BOT_LEFT = u"svx/res/sh03.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_BOT_LEFT_32 = u"svx/res/shadow_bottom_left_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_TOP_RIGHT = u"svx/res/sh04.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_TOP_RIGHT_32 = u"svx/res/shadow_top_right_32.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_TOP_LEFT = u"svx/res/sh05.png";
+inline constexpr OUStringLiteral RID_SVXBMP_SHADOW_TOP_LEFT_32 = u"svx/res/shadow_top_left_32.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_BOTTOMLOCK = u"svx/res/lo01.png";
+inline constexpr OUStringLiteral RID_SVXBMP_TOPLOCK = u"svx/res/lo02.png";
+inline constexpr OUStringLiteral RID_SVXBMP_CELLLOCK = u"svx/res/lo03.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_LOCK = u"res/lock.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_THEME_NORMAL_BIG = u"svx/res/galnorl.png";
+inline constexpr OUStringLiteral RID_SVXBMP_THEME_READONLY_BIG = u"svx/res/galrdol.png";
+inline constexpr OUStringLiteral RID_SVXBMP_THEME_DEFAULT_BIG = u"svx/res/galdefl.png";
+
+inline constexpr OUStringLiteral RID_CUIBMP_HARDDISK = u"res/harddisk_16.png";
+inline constexpr OUStringLiteral RID_CUIBMP_LIB = u"res/im30820.png";
+inline constexpr OUStringLiteral RID_CUIBMP_MACRO = u"res/im30821.png";
+inline constexpr OUStringLiteral RID_CUIBMP_DOC = u"res/im30826.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_SCRIPT = u"res/script.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_LEGTYP1 = u"svx/res/legtyp1.png";
+inline constexpr OUStringLiteral RID_SVXBMP_LEGTYP2 = u"svx/res/legtyp2.png";
+inline constexpr OUStringLiteral RID_SVXBMP_LEGTYP3 = u"svx/res/legtyp3.png";
+
+inline constexpr OUStringLiteral RID_SVXBMP_COMPONENT = u"res/component_16.png";
+inline constexpr OUStringLiteral RID_SVXBMP_MACRO = u"svx/res/id018.png";
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/inc/numcategories.hrc b/cui/inc/numcategories.hrc
new file mode 100644
index 000000000..40370cc65
--- /dev/null
+++ b/cui/inc/numcategories.hrc
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <unotools/resmgr.hxx>
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+
+const TranslateId NUM_CATEGORIES[] =
+{
+ NC_("numberingformatpage|liststore1", "All"),
+ NC_("numberingformatpage|liststore1", "User-defined"),
+ NC_("numberingformatpage|liststore1", "Number"),
+ NC_("numberingformatpage|liststore1", "Percent"),
+ NC_("numberingformatpage|liststore1", "Currency"),
+ NC_("numberingformatpage|liststore1", "Date"),
+ NC_("numberingformatpage|liststore1", "Time"),
+ NC_("numberingformatpage|liststore1", "Scientific"),
+ NC_("numberingformatpage|liststore1", "Fraction"),
+ NC_("numberingformatpage|liststore1", "Boolean Value"),
+ NC_("numberingformatpage|liststore1", "Text")
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/inc/pch/precompiled_cui.cxx b/cui/inc/pch/precompiled_cui.cxx
new file mode 100644
index 000000000..4188841e2
--- /dev/null
+++ b/cui/inc/pch/precompiled_cui.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_cui.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/inc/pch/precompiled_cui.hxx b/cui/inc/pch/precompiled_cui.hxx
new file mode 100644
index 000000000..c784c49a2
--- /dev/null
+++ b/cui/inc/pch/precompiled_cui.hxx
@@ -0,0 +1,447 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2021-09-28 05:29:25 using:
+ ./bin/update_pch cui cui --cutoff=8 --exclude:system --include:module --exclude:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./cui/inc/pch/precompiled_cui.hxx "make cui.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <chrono>
+#include <cmath>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <deque>
+#include <float.h>
+#include <functional>
+#include <initializer_list>
+#include <iomanip>
+#include <iterator>
+#include <limits.h>
+#include <limits>
+#include <map>
+#include <math.h>
+#include <memory>
+#include <mutex>
+#include <new>
+#include <numeric>
+#include <optional>
+#include <ostream>
+#include <set>
+#include <stddef.h>
+#include <stdexcept>
+#include <string.h>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+#include <boost/property_tree/ptree_fwd.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#include <osl/diagnose.h>
+#include <osl/doublecheckedlocking.h>
+#include <osl/endian.h>
+#include <osl/file.hxx>
+#include <osl/getglobalmutex.hxx>
+#include <osl/interlck.h>
+#include <osl/mutex.h>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+#include <osl/security.hxx>
+#include <osl/thread.h>
+#include <osl/time.h>
+#include <rtl/alloc.h>
+#include <rtl/bootstrap.hxx>
+#include <rtl/character.hxx>
+#include <rtl/instance.hxx>
+#include <rtl/math.h>
+#include <rtl/ref.hxx>
+#include <rtl/strbuf.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.h>
+#include <rtl/string.hxx>
+#include <rtl/stringconcat.hxx>
+#include <rtl/stringutils.hxx>
+#include <rtl/textcvt.h>
+#include <rtl/textenc.h>
+#include <rtl/ustrbuf.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <sal/backtrace.hxx>
+#include <sal/log.hxx>
+#include <sal/macros.h>
+#include <sal/saldllapi.h>
+#include <sal/types.h>
+#include <sal/typesizes.h>
+#include <vcl/BinaryDataContainer.hxx>
+#include <vcl/BitmapFilter.hxx>
+#include <vcl/GraphicAttributes.hxx>
+#include <vcl/GraphicExternalLink.hxx>
+#include <vcl/GraphicObject.hxx>
+#include <vcl/IDialogRenderable.hxx>
+#include <vcl/Scanline.hxx>
+#include <vcl/alpha.hxx>
+#include <vcl/animate/Animation.hxx>
+#include <vcl/animate/AnimationBitmap.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmap/BitmapTypes.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/builderpage.hxx>
+#include <vcl/cairo.hxx>
+#include <vcl/checksum.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/devicecoordinate.hxx>
+#include <vcl/dllapi.h>
+#include <vcl/errcode.hxx>
+#include <vcl/event.hxx>
+#include <vcl/fntstyle.hxx>
+#include <vcl/font.hxx>
+#include <vcl/gfxlink.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/image.hxx>
+#include <vcl/imap.hxx>
+#include <vcl/imapobj.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/keycodes.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/metaactiontypes.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/region.hxx>
+#include <vcl/rendercontext/AddFontSubstituteFlags.hxx>
+#include <vcl/rendercontext/AntialiasingFlags.hxx>
+#include <vcl/rendercontext/DrawGridFlags.hxx>
+#include <vcl/rendercontext/DrawImageFlags.hxx>
+#include <vcl/rendercontext/DrawModeFlags.hxx>
+#include <vcl/rendercontext/DrawTextFlags.hxx>
+#include <vcl/rendercontext/GetDefaultFontFlags.hxx>
+#include <vcl/rendercontext/ImplMapRes.hxx>
+#include <vcl/rendercontext/InvertFlags.hxx>
+#include <vcl/rendercontext/RasterOp.hxx>
+#include <vcl/rendercontext/SalLayoutFlags.hxx>
+#include <vcl/rendercontext/State.hxx>
+#include <vcl/rendercontext/SystemTextColorFlags.hxx>
+#include <vcl/salctype.hxx>
+#include <vcl/salnativewidgets.hxx>
+#include <vcl/scopedbitmapaccess.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/task.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/transfer.hxx>
+#include <vcl/uitest/factory.hxx>
+#include <vcl/vclenum.hxx>
+#include <vcl/vclptr.hxx>
+#include <vcl/vclreferencebase.hxx>
+#include <vcl/vectorgraphicdata.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/window.hxx>
+#include <vcl/windowstate.hxx>
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <basegfx/basegfxdllapi.h>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/range/basicrange.hxx>
+#include <basegfx/tuple/Tuple2D.hxx>
+#include <basegfx/tuple/Tuple3D.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/tuple/b2ituple.hxx>
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/utils/common.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <basegfx/vector/b2ivector.hxx>
+#include <basic/basicdllapi.h>
+#include <basic/sbxdef.hxx>
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/awt/KeyGroup.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/datatransfer/DataFlavor.hpp>
+#include <com/sun/star/datatransfer/XTransferable2.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/datatransfer/dnd/DropTargetDragEvent.hpp>
+#include <com/sun/star/datatransfer/dnd/DropTargetDropEvent.hpp>
+#include <com/sun/star/datatransfer/dnd/XDragGestureListener.hpp>
+#include <com/sun/star/datatransfer/dnd/XDragSourceListener.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
+#include <com/sun/star/drawing/TextFitToSizeType.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/DispatchInformation.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <com/sun/star/graphic/XPrimitive2D.hpp>
+#include <com/sun/star/i18n/Calendar2.hpp>
+#include <com/sun/star/i18n/DirectionProperty.hpp>
+#include <com/sun/star/i18n/ForbiddenCharacters.hpp>
+#include <com/sun/star/i18n/KCharacterType.hpp>
+#include <com/sun/star/i18n/LanguageCountryInfo.hpp>
+#include <com/sun/star/i18n/LocaleDataItem2.hpp>
+#include <com/sun/star/i18n/LocaleItem.hpp>
+#include <com/sun/star/i18n/NativeNumberXmlAttributes.hpp>
+#include <com/sun/star/i18n/ParseResult.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/i18n/TransliterationModules.hpp>
+#include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
+#include <com/sun/star/i18n/UnicodeScript.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <com/sun/star/i18n/reservedWords.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/text/textfield/Type.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Type.h>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hdl>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/uno/XWeak.hpp>
+#include <com/sun/star/uno/genfunc.h>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <com/sun/star/util/Date.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/SearchAlgorithms.hpp>
+#include <com/sun/star/util/SearchOptions2.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <comphelper/comphelperdllapi.h>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/lok.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <comphelper/weak.hxx>
+#include <cppu/cppudllapi.h>
+#include <cppu/unotype.hxx>
+#include <cppuhelper/cppuhelperdllapi.h>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/implbase_ex.hxx>
+#include <cppuhelper/implbase_ex_post.hxx>
+#include <cppuhelper/implbase_ex_pre.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <drawinglayer/primitive2d/CommonTypes.hxx>
+#include <drawinglayer/primitive2d/Primitive2DContainer.hxx>
+#include <drawinglayer/primitive2d/Primitive2DVisitor.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editengdllapi.h>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/eedata.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/overflowingtxt.hxx>
+#include <editeng/paragraphdata.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/svxfont.hxx>
+#include <i18nlangtag/lang.h>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nutil/i18nutildllapi.h>
+#include <i18nutil/searchopt.hxx>
+#include <i18nutil/transliteration.hxx>
+#include <o3tl/cow_wrapper.hxx>
+#include <o3tl/deleter.hxx>
+#include <o3tl/enumarray.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/sorted_vector.hxx>
+#include <o3tl/strong_int.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <o3tl/underlyingenumvalue.hxx>
+#include <o3tl/unit_conversion.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <salhelper/salhelperdllapi.h>
+#include <salhelper/simplereferenceobject.hxx>
+#include <salhelper/thread.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dllapi.h>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <sot/sotdllapi.h>
+#include <svl/SfxBroadcaster.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/custritm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/hint.hxx>
+#include <svl/intitem.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/lstner.hxx>
+#include <svl/macitem.hxx>
+#include <svl/poolitem.hxx>
+#include <svl/setitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/style.hxx>
+#include <svl/stylesheetuser.hxx>
+#include <svl/svldllapi.h>
+#include <svl/typedwhich.hxx>
+#include <svl/undo.hxx>
+#include <svl/whichranges.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svtools/svtdllapi.h>
+#include <svtools/unitconv.hxx>
+#include <svtools/valueset.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/ipolypolygoneditorcontroller.hxx>
+#include <svx/itextprovider.hxx>
+#include <svx/langbox.hxx>
+#include <svx/rectenum.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/sdr/animation/scheduler.hxx>
+#include <svx/sdr/overlay/overlayobject.hxx>
+#include <svx/sdr/overlay/overlayobjectlist.hxx>
+#include <svx/sdr/properties/defaultproperties.hxx>
+#include <svx/sdr/properties/properties.hxx>
+#include <svx/sdrobjectuser.hxx>
+#include <svx/sdtaditm.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/sdtakitm.hxx>
+#include <svx/sdynitm.hxx>
+#include <svx/svddef.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdedtv.hxx>
+#include <svx/svdglue.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svdhlpln.hxx>
+#include <svx/svdlayer.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdoattr.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdobjkind.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdpntv.hxx>
+#include <svx/svdsnpv.hxx>
+#include <svx/svdsob.hxx>
+#include <svx/svdtext.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdtypes.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/svxdllapi.h>
+#include <svx/xdef.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xit.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/xtable.hxx>
+#include <tools/color.hxx>
+#include <tools/date.hxx>
+#include <tools/datetime.hxx>
+#include <tools/debug.hxx>
+#include <tools/degree.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/fldunit.hxx>
+#include <tools/fontenum.hxx>
+#include <tools/fract.hxx>
+#include <tools/gen.hxx>
+#include <tools/globname.hxx>
+#include <tools/helpers.hxx>
+#include <tools/lineend.hxx>
+#include <tools/link.hxx>
+#include <tools/long.hxx>
+#include <tools/mapunit.hxx>
+#include <tools/poly.hxx>
+#include <tools/ref.hxx>
+#include <tools/solar.h>
+#include <tools/stream.hxx>
+#include <tools/time.hxx>
+#include <tools/toolsdllapi.h>
+#include <tools/urlobj.hxx>
+#include <tools/weakbase.h>
+#include <tools/weakbase.hxx>
+#include <tools/wintypes.hxx>
+#include <typelib/typeclass.h>
+#include <typelib/typedescription.h>
+#include <typelib/uik.h>
+#include <uno/any2.h>
+#include <uno/data.h>
+#include <uno/sequence2.h>
+#include <unotools/charclass.hxx>
+#include <unotools/fontdefs.hxx>
+#include <unotools/options.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/resmgr.hxx>
+#include <unotools/syslocale.hxx>
+#include <unotools/unotoolsdllapi.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#include <cfgutil.hxx>
+#include <cuitabarea.hxx>
+#include <dialmgr.hxx>
+#include <helpids.h>
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc
new file mode 100644
index 000000000..cea0b183e
--- /dev/null
+++ b/cui/inc/strings.hrc
@@ -0,0 +1,406 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+
+#define RID_CUISTR_KEY_CONFIG_DIR NC_("RID_SVXSTR_KEY_CONFIG_DIR", "Configuration")
+#define RID_CUISTR_KEY_WORK_PATH NC_("RID_SVXSTR_KEY_WORK_PATH", "My Documents")
+#define RID_CUISTR_KEY_GRAPHICS_PATH NC_("RID_SVXSTR_KEY_GRAPHICS_PATH", "Images")
+#define RID_CUISTR_KEY_BITMAP_PATH NC_("RID_SVXSTR_KEY_BITMAP_PATH", "Icons")
+#define RID_CUISTR_KEY_PALETTE_PATH NC_("RID_SVXSTR_KEY_PALETTE_PATH", "Palettes")
+#define RID_CUISTR_KEY_BACKUP_PATH NC_("RID_SVXSTR_KEY_BACKUP_PATH", "Backups")
+#define RID_CUISTR_KEY_MODULES_PATH NC_("RID_SVXSTR_KEY_MODULES_PATH", "Modules")
+#define RID_CUISTR_KEY_TEMPLATE_PATH NC_("RID_SVXSTR_KEY_TEMPLATE_PATH", "Templates")
+#define RID_CUISTR_KEY_GLOSSARY_PATH NC_("RID_SVXSTR_KEY_GLOSSARY_PATH", "AutoText")
+#define RID_CUISTR_KEY_DICTIONARY_PATH NC_("RID_SVXSTR_KEY_DICTIONARY_PATH", "Dictionaries")
+#define RID_CUISTR_KEY_HELP_DIR NC_("RID_SVXSTR_KEY_HELP_DIR", "Help")
+#define RID_CUISTR_KEY_GALLERY_DIR NC_("RID_SVXSTR_KEY_GALLERY_DIR", "Gallery")
+#define RID_CUISTR_KEY_STORAGE_DIR NC_("RID_SVXSTR_KEY_STORAGE_DIR", "Message Storage")
+#define RID_CUISTR_KEY_TEMP_PATH NC_("RID_SVXSTR_KEY_TEMP_PATH", "Temporary files")
+#define RID_CUISTR_KEY_PLUGINS_PATH NC_("RID_SVXSTR_KEY_PLUGINS_PATH", "Plug-ins")
+#define RID_CUISTR_KEY_FAVORITES_DIR NC_("RID_SVXSTR_KEY_FAVORITES_DIR", "Folder Bookmarks")
+#define RID_CUISTR_KEY_FILTER_PATH NC_("RID_SVXSTR_KEY_FILTER_PATH", "Filters")
+#define RID_CUISTR_KEY_ADDINS_PATH NC_("RID_SVXSTR_KEY_ADDINS_PATH", "Add-ins")
+#define RID_CUISTR_KEY_USERCONFIG_PATH NC_("RID_SVXSTR_KEY_USERCONFIG_PATH", "User Configuration")
+#define RID_CUISTR_KEY_USERDICTIONARY_DIR NC_("RID_SVXSTR_KEY_USERDICTIONARY_DIR", "User-defined dictionaries")
+#define RID_CUISTR_KEY_CLASSIFICATION_PATH NC_("RID_SVXSTR_KEY_CLASSIFICATION_PATH", "Classification")
+#define RID_CUISTR_KEY_AUTOCORRECT_DIR NC_("RID_SVXSTR_KEY_AUTOCORRECT_DIR", "AutoCorrect")
+#define RID_CUISTR_KEY_LINGUISTIC_DIR NC_("RID_SVXSTR_KEY_LINGUISTIC_DIR", "Writing aids")
+/* %n will be replaced at runtime by a number starting with 1 and increasing as necessary */
+#define RID_CUISTR_NEW_MENU NC_("RID_SVXSTR_NEW_MENU", "New Menu %n")
+/* %n will be replaced at runtime by a number starting with 1 and increasing as necessary */
+#define RID_CUISTR_NEW_TOOLBAR NC_("RID_SVXSTR_NEW_TOOLBAR", "New Toolbar %n")
+#define RID_CUISTR_MOVE_MENU NC_("RID_SVXSTR_MOVE_MENU", "Move Menu")
+#define RID_CUISTR_ADD_SUBMENU NC_("RID_SVXSTR_ADD_SUBMENU", "Add Submenu")
+#define RID_CUISTR_SUBMENU_NAME NC_("RID_SVXSTR_SUBMENU_NAME", "Submenu name")
+#define RID_CUISTR_DELETE_ICON_CONFIRM NC_("RID_SVXSTR_DELETE_ICON_CONFIRM", "Are you sure to delete the image?")
+#define RID_CUISTR_REPLACE_ICON_WARNING NC_("RID_SVXSTR_REPLACE_ICON_WARNING", "The icon %ICONNAME is already contained in the image list.\nWould you like to replace the existing icon?")
+#define RID_CUISTR_REPLACE_ICON_CONFIRM NC_("RID_SVXSTR_REPLACE_ICON_CONFIRM", "Confirm Icon Replacement")
+#define RID_CUISTR_YESTOALL NC_("RID_SVXSTR_YESTOALL", "Yes to All")
+#define RID_SXVSTR_CONFIRM_DELETE_TOOLBAR NC_("RID_SXVSTR_CONFIRM_DELETE_TOOLBAR", "There are no more commands on the toolbar. Do you want to delete the toolbar?")
+/* Translators: Do not translate %SAVE IN SELECTION% It is a placeholder
+ and will be replaced at runtime by the name of the selected application
+ or document.
+*/
+#define RID_CUISTR_CONFIRM_MENU_RESET NC_("RID_SVXSTR_CONFIRM_MENU_RESET", "The menu configuration for %SAVE IN SELECTION% will be reset to the default settings. Do you want to continue?")
+#define RID_CUISTR_CONFIRM_TOOLBAR_RESET NC_("RID_SVXSTR_CONFIRM_TOOLBAR_RESET", "The toolbar configuration for %SAVE IN SELECTION% will be reset to the default settings. Do you want to continue?")
+#define RID_CUISTR_CONFIRM_RESTORE_DEFAULT NC_("RID_SVXSTR_CONFIRM_RESTORE_DEFAULT", "This will delete all changes previously made to this toolbar. Do you really want to reset the toolbar?")
+#define RID_CUISTR_CONFIRM_RESTORE_DEFAULT_MENU NC_("RID_SVXSTR_CONFIRM_RESTORE_DEFAULT_MENU", "This will delete all changes previously made to this context menu. Do you really want to reset?")
+#define RID_CUISTR_LABEL_NEW_NAME NC_("RID_SVXSTR_LABEL_NEW_NAME", "~New name")
+#define RID_CUISTR_RENAME_MENU NC_("RID_SVXSTR_RENAME_MENU", "Rename Menu")
+#define RID_CUISTR_RENAME_TOOLBAR NC_("RID_SVXSTR_RENAME_TOOLBAR", "Rename Toolbar")
+#define RID_CUISTR_ALL_COMMANDS NC_("RID_SVXSTR_ALL_COMMANDS", "All Commands")
+#define RID_CUISTR_TABBED NC_("RID_SVXSTR_TABBED", "Tabbed")
+#define RID_CUISTR_TABBED_COMPACT NC_("RID_SVXSTR_TABBED_COMPACT", "Tabbed Compact")
+#define RID_CUISTR_GROUPEDBAR NC_("RID_SVXSTR_GROUPEDBAR", "Groupedbar")
+#define RID_CUISTR_GROUPEDBAR_COMPACT NC_("RID_SVXSTR_GROUPEDBAR_COMPACT", "Groupedbar Compact")
+
+#define RID_CUISTR_HYPDLG_CLOSEBUT NC_("RID_SVXSTR_HYPDLG_CLOSEBUT", "Close")
+#define RID_CUISTR_HYPDLG_MACROACT1 NC_("RID_SVXSTR_HYPDLG_MACROACT1", "Mouse over object")
+#define RID_CUISTR_HYPDLG_MACROACT2 NC_("RID_SVXSTR_HYPDLG_MACROACT2", "Trigger hyperlink")
+#define RID_CUISTR_HYPDLG_MACROACT3 NC_("RID_SVXSTR_HYPDLG_MACROACT3", "Mouse leaves object")
+#define RID_CUISTR_HYPERDLG_FORM_BUTTON NC_("RID_SVXSTR_HYPERDLG_FORM_BUTTON", "Button")
+#define RID_CUISTR_HYPERDLG_FROM_TEXT NC_("RID_SVXSTR_HYPERDLG_FROM_TEXT", "Text")
+#define RID_CUISTR_HYPERDLG_QUERYOVERWRITE NC_("RID_SVXSTR_HYPERDLG_QUERYOVERWRITE", "The file already exists. Overwrite?")
+
+#define RID_CUISTR_SELECT_FILE_IFRAME NC_("RID_SVXSTR_SELECT_FILE_IFRAME", "Select File for Floating Frame")
+#define RID_CUISTR_ALLFUNCTIONS NC_("RID_SVXSTR_ALLFUNCTIONS", "All commands")
+#define RID_CUISTR_MACROS NC_("RID_SVXSTR_MACROS", "Macros")
+#define RID_CUISTR_MYMACROS NC_("RID_SVXSTR_MYMACROS", "My Macros")
+#define RID_CUISTR_PRODMACROS NC_("RID_SVXSTR_PRODMACROS", "Application Macros")
+#define RID_CUISTR_NOMACRODESC NC_("RID_SVXSTR_NOMACRODESC", "There is no description available for this macro.")
+#define RID_CUISTR_SELECTOR_RUN NC_("RID_SVXSTR_SELECTOR_RUN", "Run")
+#define RID_CUISTR_ROW NC_("RID_SVXSTR_ROW", "Insert Rows")
+// tdf#119293 Labels depending on row/col
+#define RID_CUISTR_INSERTROW_BEFORE NC_("RID_SVXSTR_INSERTROW_BEFORE", "Above selection")
+#define RID_CUISTR_INSERTROW_AFTER NC_("RID_SVXSTR_INSERTROW_AFTER", "Below selection")
+#define RID_CUISTR_REMOVE_FAVORITES NC_("RID_SVXSTR_REMOVE_FAVORITES", "Remove from Favorites")
+#define RID_CUISTR_MISSING_CHAR NC_("RID_SVXSTR_MISSING_CHAR", "Missing character")
+#define RID_CUISTR_ADD_FAVORITES NC_("RID_SVXSTR_ADD_FAVORITES", "Add to Favorites")
+// PPI is pixel per inch, %1 is a number
+#define RID_CUISTR_PPI NC_("RID_SVXSTR_PPI", "(%1 PPI)")
+#define RID_CUISTR_COL NC_("RID_SVXSTR_COL", "Insert Columns")
+// tdf#119293 Labels depending on row/col
+#define RID_CUISTR_INSERTCOL_BEFORE NC_("RID_SVXSTR_INSERTCOL_BEFORE", "Before selection")
+#define RID_CUISTR_INSERTCOL_AFTER NC_("RID_SVXSTR_INSERTCOL_AFTER", "After selection")
+#define RID_CUISTR_AUTO_ENTRY NC_("RID_SVXSTR_AUTO_ENTRY", "Automatic")
+#define RID_CUISTR_EDIT_GRAPHIC NC_("RID_SVXSTR_EDIT_GRAPHIC", "Link")
+#define RID_CUISTR_LOADACCELCONFIG NC_("RID_SVXSTR_LOADACCELCONFIG", "Load Keyboard Configuration")
+#define RID_CUISTR_SAVEACCELCONFIG NC_("RID_SVXSTR_SAVEACCELCONFIG", "Save Keyboard Configuration")
+#define RID_CUISTR_FILTERNAME_CFG NC_("RID_SVXSTR_FILTERNAME_CFG", "Configuration (*.cfg)")
+#define RID_CUISTR_HYPDLG_ERR_LERR_NOENTRIES NC_("RID_SVXSTR_HYPDLG_ERR_LERR_NOENTRIES", "Targets do not exist in the document.")
+#define RID_CUISTR_HYPDLG_ERR_LERR_DOCNOTOPEN NC_("RID_SVXSTR_HYPDLG_ERR_LERR_DOCNOTOPEN", "Couldn't open the document.")
+#define RID_CUISTR_EDITHINT NC_("RID_SVXSTR_EDITHINT", "[Enter text here]")
+#define RID_CUISTR_HANGUL NC_("RID_SVXSTR_HANGUL", "Hangul")
+#define RID_CUISTR_HANJA NC_("RID_SVXSTR_HANJA", "Hanja")
+#define RID_CUISTR_BASICMACROS NC_("RID_SVXSTR_BASICMACROS", "BASIC Macros")
+#define RID_CUISTR_GROUP_STYLES NC_("RID_SVXSTR_GROUP_STYLES", "Styles")
+#define RID_CUISTR_GROUP_SIDEBARDECKS NC_("RID_SVXSTR_GROUP_SIDEBARDECKS", "Sidebar Decks")
+
+#define RID_CUISTR_EVENT_STARTAPP NC_("RID_SVXSTR_EVENT_STARTAPP", "Start Application")
+#define RID_CUISTR_EVENT_CLOSEAPP NC_("RID_SVXSTR_EVENT_CLOSEAPP", "Close Application")
+#define RID_CUISTR_EVENT_NEWDOC NC_("RID_SVXSTR_EVENT_NEWDOC", "New Document")
+#define RID_CUISTR_EVENT_CLOSEDOC NC_("RID_SVXSTR_EVENT_CLOSEDOC", "Document closed")
+#define RID_CUISTR_EVENT_PREPARECLOSEDOC NC_("RID_SVXSTR_EVENT_PREPARECLOSEDOC", "Document is going to be closed")
+#define RID_CUISTR_EVENT_OPENDOC NC_("RID_SVXSTR_EVENT_OPENDOC", "Open Document")
+#define RID_CUISTR_EVENT_SAVEDOC NC_("RID_SVXSTR_EVENT_SAVEDOC", "Save Document")
+#define RID_CUISTR_EVENT_SAVEASDOC NC_("RID_SVXSTR_EVENT_SAVEASDOC", "Save Document As")
+#define RID_CUISTR_EVENT_SAVEDOCDONE NC_("RID_SVXSTR_EVENT_SAVEDOCDONE", "Document has been saved")
+#define RID_CUISTR_EVENT_SAVEASDOCDONE NC_("RID_SVXSTR_EVENT_SAVEASDOCDONE", "Document has been saved as")
+#define RID_CUISTR_EVENT_ACTIVATEDOC NC_("RID_SVXSTR_EVENT_ACTIVATEDOC", "Activate Document")
+#define RID_CUISTR_EVENT_DEACTIVATEDOC NC_("RID_SVXSTR_EVENT_DEACTIVATEDOC", "Deactivate Document")
+#define RID_CUISTR_EVENT_PRINTDOC NC_("RID_SVXSTR_EVENT_PRINTDOC", "Print Document")
+#define RID_CUISTR_EVENT_MODIFYCHANGED NC_("RID_SVXSTR_EVENT_MODIFYCHANGED", "'Modified' status was changed")
+#define RID_CUISTR_EVENT_MAILMERGE NC_("RID_SVXSTR_EVENT_MAILMERGE", "Printing of form letters started")
+#define RID_CUISTR_EVENT_MAILMERGE_END NC_("RID_SVXSTR_EVENT_MAILMERGE_END", "Printing of form letters finished")
+#define RID_CUISTR_EVENT_FIELDMERGE NC_("RID_SVXSTR_EVENT_FIELDMERGE", "Merging of form fields started")
+#define RID_CUISTR_EVENT_FIELDMERGE_FINISHED NC_("RID_SVXSTR_EVENT_FIELDMERGE_FINISHED", "Merging of form fields finished")
+#define RID_CUISTR_EVENT_PAGECOUNTCHANGE NC_("RID_SVXSTR_EVENT_PAGECOUNTCHANGE", "Changing the page count")
+#define RID_CUISTR_EVENT_SUBCOMPONENT_OPENED NC_("RID_SVXSTR_EVENT_SUBCOMPONENT_OPENED", "Loaded a sub component")
+#define RID_CUISTR_EVENT_SUBCOMPONENT_CLOSED NC_("RID_SVXSTR_EVENT_SUBCOMPONENT_CLOSED", "Closed a sub component")
+#define RID_CUISTR_EVENT_APPROVEPARAMETER NC_("RID_SVXSTR_EVENT_APPROVEPARAMETER", "Fill parameters")
+#define RID_CUISTR_EVENT_ACTIONPERFORMED NC_("RID_SVXSTR_EVENT_ACTIONPERFORMED", "Execute action")
+#define RID_CUISTR_EVENT_AFTERUPDATE NC_("RID_SVXSTR_EVENT_AFTERUPDATE", "After updating")
+#define RID_CUISTR_EVENT_BEFOREUPDATE NC_("RID_SVXSTR_EVENT_BEFOREUPDATE", "Before updating")
+#define RID_CUISTR_EVENT_APPROVEROWCHANGE NC_("RID_SVXSTR_EVENT_APPROVEROWCHANGE", "Before record action")
+#define RID_CUISTR_EVENT_ROWCHANGE NC_("RID_SVXSTR_EVENT_ROWCHANGE", "After record action")
+#define RID_CUISTR_EVENT_CONFIRMDELETE NC_("RID_SVXSTR_EVENT_CONFIRMDELETE", "Confirm deletion")
+#define RID_CUISTR_EVENT_ERROROCCURRED NC_("RID_SVXSTR_EVENT_ERROROCCURRED", "Error occurred")
+#define RID_CUISTR_EVENT_ADJUSTMENTVALUECHANGED NC_("RID_SVXSTR_EVENT_ADJUSTMENTVALUECHANGED", "While adjusting")
+#define RID_CUISTR_EVENT_FOCUSGAINED NC_("RID_SVXSTR_EVENT_FOCUSGAINED", "When receiving focus")
+#define RID_CUISTR_EVENT_FOCUSLOST NC_("RID_SVXSTR_EVENT_FOCUSLOST", "When losing focus")
+#define RID_CUISTR_EVENT_ITEMSTATECHANGED NC_("RID_SVXSTR_EVENT_ITEMSTATECHANGED", "Item status changed")
+#define RID_CUISTR_EVENT_KEYTYPED NC_("RID_SVXSTR_EVENT_KEYTYPED", "Key pressed")
+#define RID_CUISTR_EVENT_KEYUP NC_("RID_SVXSTR_EVENT_KEYUP", "Key released")
+#define RID_CUISTR_EVENT_LOADED NC_("RID_SVXSTR_EVENT_LOADED", "When loading")
+#define RID_CUISTR_EVENT_RELOADING NC_("RID_SVXSTR_EVENT_RELOADING", "Before reloading")
+#define RID_CUISTR_EVENT_RELOADED NC_("RID_SVXSTR_EVENT_RELOADED", "When reloading")
+#define RID_CUISTR_EVENT_MOUSEDRAGGED NC_("RID_SVXSTR_EVENT_MOUSEDRAGGED", "Mouse moved while key pressed")
+#define RID_CUISTR_EVENT_MOUSEENTERED NC_("RID_SVXSTR_EVENT_MOUSEENTERED", "Mouse inside")
+#define RID_CUISTR_EVENT_MOUSEEXITED NC_("RID_SVXSTR_EVENT_MOUSEEXITED", "Mouse outside")
+#define RID_CUISTR_EVENT_MOUSEMOVED NC_("RID_SVXSTR_EVENT_MOUSEMOVED", "Mouse moved")
+#define RID_CUISTR_EVENT_MOUSEPRESSED NC_("RID_SVXSTR_EVENT_MOUSEPRESSED", "Mouse button pressed")
+#define RID_CUISTR_EVENT_MOUSERELEASED NC_("RID_SVXSTR_EVENT_MOUSERELEASED", "Mouse button released")
+#define RID_CUISTR_EVENT_POSITIONING NC_("RID_SVXSTR_EVENT_POSITIONING", "Before record change")
+#define RID_CUISTR_EVENT_POSITIONED NC_("RID_SVXSTR_EVENT_POSITIONED", "After record change")
+#define RID_CUISTR_EVENT_RESETTED NC_("RID_SVXSTR_EVENT_RESETTED", "After resetting")
+#define RID_CUISTR_EVENT_APPROVERESETTED NC_("RID_SVXSTR_EVENT_APPROVERESETTED", "Prior to reset")
+#define RID_CUISTR_EVENT_APPROVEACTIONPERFORMED NC_("RID_SVXSTR_EVENT_APPROVEACTIONPERFORMED", "Approve action")
+#define RID_CUISTR_EVENT_SUBMITTED NC_("RID_SVXSTR_EVENT_SUBMITTED", "Before submitting")
+#define RID_CUISTR_EVENT_TEXTCHANGED NC_("RID_SVXSTR_EVENT_TEXTCHANGED", "Text modified")
+#define RID_CUISTR_EVENT_UNLOADING NC_("RID_SVXSTR_EVENT_UNLOADING", "Before unloading")
+#define RID_CUISTR_EVENT_UNLOADED NC_("RID_SVXSTR_EVENT_UNLOADED", "When unloading")
+#define RID_CUISTR_EVENT_CHANGED NC_("RID_SVXSTR_EVENT_CHANGED", "Changed")
+#define RID_CUISTR_EVENT_CREATEDOC NC_("RID_SVXSTR_EVENT_CREATEDOC", "Document created")
+#define RID_CUISTR_EVENT_LOADDOCFINISHED NC_("RID_SVXSTR_EVENT_LOADDOCFINISHED", "Document loading finished")
+#define RID_CUISTR_EVENT_SAVEDOCFAILED NC_("RID_SVXSTR_EVENT_SAVEDOCFAILED", "Saving of document failed")
+#define RID_CUISTR_EVENT_SAVEASDOCFAILED NC_("RID_SVXSTR_EVENT_SAVEASDOCFAILED", "'Save as' has failed")
+#define RID_CUISTR_EVENT_COPYTODOC NC_("RID_SVXSTR_EVENT_COPYTODOC", "Storing or exporting copy of document")
+#define RID_CUISTR_EVENT_COPYTODOCDONE NC_("RID_SVXSTR_EVENT_COPYTODOCDONE", "Document copy has been created")
+#define RID_CUISTR_EVENT_COPYTODOCFAILED NC_("RID_SVXSTR_EVENT_COPYTODOCFAILED", "Creating of document copy failed")
+#define RID_CUISTR_EVENT_VIEWCREATED NC_("RID_SVXSTR_EVENT_VIEWCREATED", "View created")
+#define RID_CUISTR_EVENT_PREPARECLOSEVIEW NC_("RID_SVXSTR_EVENT_PREPARECLOSEVIEW", "View is going to be closed")
+#define RID_CUISTR_EVENT_CLOSEVIEW NC_("RID_SVXSTR_EVENT_CLOSEVIEW", "View closed")
+#define RID_CUISTR_EVENT_TITLECHANGED NC_("RID_SVXSTR_EVENT_TITLECHANGED", "Document title changed")
+#define RID_CUISTR_EVENT_SELECTIONCHANGED NC_("RID_SVXSTR_EVENT_SELECTIONCHANGED", "Selection changed")
+#define RID_CUISTR_EVENT_DOUBLECLICK NC_("RID_SVXSTR_EVENT_DOUBLECLICK", "Double click")
+#define RID_CUISTR_EVENT_RIGHTCLICK NC_("RID_SVXSTR_EVENT_RIGHTCLICK", "Right click")
+#define RID_CUISTR_EVENT_CALCULATE NC_("RID_SVXSTR_EVENT_CALCULATE", "Formulas calculated")
+#define RID_CUISTR_EVENT_CONTENTCHANGED NC_("RID_SVXSTR_EVENT_CONTENTCHANGED", "Content changed")
+
+#define RID_STR_SEARCH_ANYWHERE NC_("RID_STR_SEARCH_ANYWHERE", "anywhere in the field")
+#define RID_STR_SEARCH_BEGINNING NC_("RID_STR_SEARCH_BEGINNING", "beginning of field")
+#define RID_STR_SEARCH_END NC_("RID_STR_SEARCH_END", "end of field")
+#define RID_STR_SEARCH_WHOLE NC_("RID_STR_SEARCH_WHOLE", "entire field")
+#define RID_STR_FROM_TOP NC_("RID_STR_FROM_TOP", "From top")
+#define RID_STR_FROM_BOTTOM NC_("RID_STR_FROM_BOTTOM", "From bottom")
+#define RID_STR_SEARCH_NORECORD NC_("RID_STR_SEARCH_NORECORD", "No records corresponding to your data found.")
+#define RID_STR_SEARCH_GENERAL_ERROR NC_("RID_STR_SEARCH_GENERAL_ERROR", "An unknown error occurred. The search could not be finished.")
+#define RID_STR_OVERFLOW_FORWARD NC_("RID_STR_OVERFLOW_FORWARD", "Overflow, search continued at the beginning")
+#define RID_STR_OVERFLOW_BACKWARD NC_("RID_STR_OVERFLOW_BACKWARD", "Overflow, search continued at the end")
+#define RID_STR_SEARCH_COUNTING NC_("RID_STR_SEARCH_COUNTING", "counting records")
+
+#define RID_CUISTR_GALLERY_NOFILES NC_("RID_SVXSTR_GALLERY_NOFILES", "<No Files>")
+#define RID_CUISTR_GALLERYPROPS_OBJECT NC_("RID_SVXSTR_GALLERYPROPS_OBJECT", "Object;Objects")
+#define RID_CUISTR_GALLERY_READONLY NC_("RID_SVXSTR_GALLERY_READONLY", "(read-only)")
+#define RID_CUISTR_GALLERY_ALLFILES NC_("RID_SVXSTR_GALLERY_ALLFILES", "<All Files>")
+#define RID_CUISTR_GALLERY_ID_EXISTS NC_("RID_SVXSTR_GALLERY_ID_EXISTS", "This ID already exists...")
+
+#define RID_MULTIPATH_DBL_ERR NC_("RID_MULTIPATH_DBL_ERR", "The path %1 already exists.")
+#define RID_CUISTR_ARCHIVE_TITLE NC_("RID_SVXSTR_ARCHIVE_TITLE", "Select Archives")
+#define RID_CUISTR_ARCHIVE_HEADLINE NC_("RID_SVXSTR_ARCHIVE_HEADLINE", "Archives")
+#define RID_CUISTR_MULTIFILE_DBL_ERR NC_("RID_SVXSTR_MULTIFILE_DBL_ERR", "The file %1 already exists.")
+#define RID_CUISTR_ADD_IMAGE NC_("RID_SVXSTR_ADD_IMAGE", "Add Image")
+
+#define RID_CUISTR_ONE_PASSWORD_MISMATCH NC_("RID_SVXSTR_ONE_PASSWORD_MISMATCH", "The confirmation password did not match the password. Set the password again by entering the same password in both boxes.")
+#define RID_CUISTR_TWO_PASSWORDS_MISMATCH NC_("RID_SVXSTR_TWO_PASSWORDS_MISMATCH", "The confirmation passwords did not match the original passwords. Set the passwords again.")
+#define RID_CUISTR_INVALID_STATE_FOR_OK_BUTTON NC_("RID_SVXSTR_INVALID_STATE_FOR_OK_BUTTON", "Please enter a password to open or to modify, or check the open read-only option to continue.")
+#define RID_CUISTR_INVALID_STATE_FOR_OK_BUTTON_V2 NC_("RID_SVXSTR_INVALID_STATE_FOR_OK_BUTTON_V2", "Set the password by entering the same password in both boxes.")
+#define RID_CUISTR_PASSWORD_LEN_INDICATOR NC_("RID_SVXSTR_PASSWORD_LEN_INDICATOR", "Password length limit of %1 reached")
+
+#define STR_AUTOLINK NC_("STR_AUTOLINK", "Automatic")
+#define STR_MANUALLINK NC_("STR_MANUALLINK", "Manual")
+#define STR_BROKENLINK NC_("STR_BROKENLINK", "Not available")
+#define STR_CLOSELINKMSG NC_("STR_CLOSELINKMSG", "Are you sure you want to remove the selected link?")
+#define STR_CLOSELINKMSG_MULTI NC_("STR_CLOSELINKMSG_MULTI", "Are you sure you want to remove the selected link?")
+#define STR_WAITINGLINK NC_("STR_WAITINGLINK", "Waiting")
+
+#define RID_CUISTR_SAVE_SCREENSHOT_AS NC_("RID_SVXSTR_SAVE_SCREENSHOT_AS", "Save Screenshot As...")
+
+// $(ROW) can be a number or the caption of the row in quotes
+#define RID_CUISTR_DIAGRAM_ROW NC_("RID_SVXSTR_DIAGRAM_ROW", "Data Series $(ROW)")
+
+#define RID_CUISTR_YES NC_("RID_SVXSTR_YES", "Yes")
+#define RID_CUISTR_NO NC_("RID_SVXSTR_NO", "No")
+
+#define STR_LINKEDDOC_DOESNOTEXIST NC_("STR_LINKEDDOC_DOESNOTEXIST", "The file\n$file$\ndoes not exist.")
+#define STR_LINKEDDOC_NO_SYSTEM_FILE NC_("STR_LINKEDDOC_NO_SYSTEM_FILE", "The file\n$file$\ndoes not exist in the local file system.")
+#define STR_NAME_CONFLICT NC_("STR_NAME_CONFLICT", "The name '$file$' is already used for another database.\nPlease choose a different name.")
+#define RID_CUISTR_QUERY_DELETE_CONFIRM NC_("RID_SVXSTR_QUERY_DELETE_CONFIRM", "Do you want to delete the entry?")
+
+#define RID_CUISTR_DELQUERY NC_("RID_SVXSTR_DELQUERY", "Do you want to delete the following object?")
+#define RID_CUISTR_DELQUERY_TITLE NC_("RID_SVXSTR_DELQUERY_TITLE", "Confirm Deletion")
+#define RID_CUISTR_DELFAILED NC_("RID_SVXSTR_DELFAILED", "The selected object could not be deleted.")
+#define RID_CUISTR_DELFAILED_TITLE NC_("RID_SVXSTR_DELFAILED_TITLE", "Error Deleting Object")
+#define RID_CUISTR_CREATEFAILED NC_("RID_SVXSTR_CREATEFAILED", "The object could not be created.")
+#define RID_CUISTR_CREATEFAILEDDUP NC_("RID_SVXSTR_CREATEFAILEDDUP", " Object with the same name already exists.")
+#define RID_CUISTR_CREATEFAILED_TITLE NC_("RID_SVXSTR_CREATEFAILED_TITLE", "Error Creating Object")
+#define RID_CUISTR_RENAMEFAILED NC_("RID_SVXSTR_RENAMEFAILED", "The object could not be renamed.")
+#define RID_CUISTR_RENAMEFAILED_TITLE NC_("RID_SVXSTR_RENAMEFAILED_TITLE", "Error Renaming Object")
+#define RID_CUISTR_ERROR_TITLE NC_("RID_SVXSTR_ERROR_TITLE", "%PRODUCTNAME Error")
+#define RID_CUISTR_ERROR_LANG_NOT_SUPPORTED NC_("RID_SVXSTR_ERROR_LANG_NOT_SUPPORTED", "The scripting language %LANGUAGENAME is not supported.")
+#define RID_CUISTR_ERROR_RUNNING NC_("RID_SVXSTR_ERROR_RUNNING", "An error occurred while running the %LANGUAGENAME script %SCRIPTNAME.")
+#define RID_CUISTR_EXCEPTION_RUNNING NC_("RID_SVXSTR_EXCEPTION_RUNNING", "An exception occurred while running the %LANGUAGENAME script %SCRIPTNAME.")
+#define RID_CUISTR_ERROR_AT_LINE NC_("RID_SVXSTR_ERROR_AT_LINE", "An error occurred while running the %LANGUAGENAME script %SCRIPTNAME at line: %LINENUMBER.")
+#define RID_CUISTR_EXCEPTION_AT_LINE NC_("RID_SVXSTR_EXCEPTION_AT_LINE", "An exception occurred while running the %LANGUAGENAME script %SCRIPTNAME at line: %LINENUMBER.")
+#define RID_CUISTR_FRAMEWORK_ERROR_RUNNING NC_("RID_SVXSTR_FRAMEWORK_ERROR_RUNNING", "A Scripting Framework error occurred while running the %LANGUAGENAME script %SCRIPTNAME.")
+#define RID_CUISTR_ERROR_TYPE_LABEL NC_("RID_SVXSTR_ERROR_TYPE_LABEL", "Type:")
+#define RID_CUISTR_ERROR_MESSAGE_LABEL NC_("RID_SVXSTR_ERROR_MESSAGE_LABEL", "Message:")
+
+#define RID_CUISTR_CHG_MATH NC_("RID_SVXSTR_CHG_MATH", "MathType to %PRODUCTNAME Math or reverse")
+#define RID_CUISTR_CHG_WRITER NC_("RID_SVXSTR_CHG_WRITER", "WinWord to %PRODUCTNAME Writer or reverse")
+#define RID_CUISTR_CHG_CALC NC_("RID_SVXSTR_CHG_CALC", "Excel to %PRODUCTNAME Calc or reverse")
+#define RID_CUISTR_CHG_IMPRESS NC_("RID_SVXSTR_CHG_IMPRESS", "PowerPoint to %PRODUCTNAME Impress or reverse")
+#define RID_CUISTR_CHG_SMARTART NC_("RID_SVXSTR_CHG_SMARTART", "SmartArt to %PRODUCTNAME shapes or reverse")
+#define RID_CUISTR_CHG_VISIO NC_("RID_SVXSTR_CHG_VISIO", "Visio to %PRODUCTNAME Draw or reverse")
+#define RID_CUISTR_CHG_PDF NC_("RID_SVXSTR_CHG_PDF", "PDF to %PRODUCTNAME Draw or reverse")
+
+#define RID_CUISTR_OPT_DOUBLE_DICTS NC_("RID_SVXSTR_OPT_DOUBLE_DICTS", "The specified name already exists.\nPlease enter a new name.")
+#define RID_CUISTR_OPT_INVALID_DICT_NAME NC_("RID_SVXSTR_OPT_INVALID_DICT_NAME", "The specified name is invalid.\nPlease enter a new name.")
+/* To translators:
+ Please, try to find a similar *short* translation to avoid
+ to get narrow "New" field in the "Edit custom dictionary" window,
+ for example, "Model word for optional affixation and compounding"
+ is too long, but "Grammar By" is a good name here (help page of
+ the window contains the details).
+
+ "Grammar By" text entry box of the "Edit custom dictionary" window
+ contains an optional model word associated to the new user word,
+ allowing its affixation or compounding during spell checking.
+ For example, adding "Grammar By" word "fund" to the new user
+ word "crowdfund", the spell checker will recognize "crowdfund"
+ with suffixes of "fund": "crowdfunding", "crowdfund's" etc.
+*/
+#define RID_CUISTR_OPT_GRAMMAR_BY NC_("RID_SVXSTR_OPT_GRAMMAR_BY", "~Grammar By")
+#define STR_MODIFY NC_("STR_MODIFY", "~Replace")
+#define RID_CUISTR_CONFIRM_SET_LANGUAGE NC_("RID_SVXSTR_CONFIRM_SET_LANGUAGE", "Do you want to change the '%1' dictionary language?")
+
+#define RID_CUISTR_COLOR_CONFIG_DELETE NC_("RID_SVXSTR_COLOR_CONFIG_DELETE", "Do you really want to delete the color scheme?")
+#define RID_CUISTR_COLOR_CONFIG_DELETE_TITLE NC_("RID_SVXSTR_COLOR_CONFIG_DELETE_TITLE", "Color Scheme Deletion")
+#define RID_CUISTR_COLOR_CONFIG_SAVE1 NC_("RID_SVXSTR_COLOR_CONFIG_SAVE1", "Save scheme")
+#define RID_CUISTR_COLOR_CONFIG_SAVE2 NC_("RID_SVXSTR_COLOR_CONFIG_SAVE2", "Name of color scheme")
+
+#define RID_CUISTR_SPELL NC_("RID_SVXSTR_SPELL", "Spelling")
+#define RID_CUISTR_HYPH NC_("RID_SVXSTR_HYPH", "Hyphenation")
+#define RID_CUISTR_THES NC_("RID_SVXSTR_THES", "Thesaurus")
+#define RID_CUISTR_GRAMMAR NC_("RID_SVXSTR_GRAMMAR", "Grammar")
+#define RID_CUISTR_CAPITAL_WORDS NC_("RID_SVXSTR_CAPITAL_WORDS", "Check uppercase words")
+#define RID_CUISTR_WORDS_WITH_DIGITS NC_("RID_SVXSTR_WORDS_WITH_DIGITS", "Check words with numbers ")
+#define RID_CUISTR_SPELL_SPECIAL NC_("RID_SVXSTR_SPELL_SPECIAL", "Check special regions")
+#define RID_CUISTR_SPELL_AUTO NC_("RID_SVXSTR_SPELL_AUTO", "Check spelling as you type")
+#define RID_CUISTR_GRAMMAR_AUTO NC_("RID_SVXSTR_GRAMMAR_AUTO", "Check grammar as you type")
+#define RID_CUISTR_NUM_MIN_WORDLEN NC_("RID_SVXSTR_NUM_MIN_WORDLEN", "Minimal number of characters for hyphenation: ")
+#define RID_CUISTR_NUM_PRE_BREAK NC_("RID_SVXSTR_NUM_PRE_BREAK", "Characters before line break: ")
+#define RID_CUISTR_NUM_POST_BREAK NC_("RID_SVXSTR_NUM_POST_BREAK", "Characters after line break: ")
+#define RID_CUISTR_HYPH_AUTO NC_("RID_SVXSTR_HYPH_AUTO", "Hyphenate without inquiry")
+#define RID_CUISTR_HYPH_SPECIAL NC_("RID_SVXSTR_HYPH_SPECIAL", "Hyphenate special regions")
+
+#define RID_CUISTR_JRE_NOT_RECOGNIZED NC_("RID_SVXSTR_JRE_NOT_RECOGNIZED", "The folder you selected does not contain a Java runtime environment.\nPlease select a different folder.")
+#define RID_CUISTR_JRE_FAILED_VERSION NC_("RID_SVXSTR_JRE_FAILED_VERSION", "The Java runtime environment you selected is not the required version.\nPlease select a different folder.")
+#define RID_CUISTR_JAVA_START_PARAM NC_("RID_SVXSTR_JAVA_START_PARAM", "Edit Parameter")
+
+#define RID_CUISTR_OPT_PROXYPORTS NC_("RID_SVXSTR_OPT_PROXYPORTS", "Invalid value!\n\nThe maximum value for a port number is 65535.")
+
+#define RID_CUISTR_DESC_GRADIENT NC_("RID_SVXSTR_DESC_GRADIENT", "Please enter a name for the gradient:")
+#define RID_CUISTR_DESC_NEW_BITMAP NC_("RID_SVXSTR_DESC_NEW_BITMAP", "Please enter a name for the bitmap:")
+#define RID_CUISTR_DESC_EXT_BITMAP NC_("RID_SVXSTR_DESC_EXT_BITMAP", "Please enter a name for the external bitmap:")
+#define RID_CUISTR_DESC_NEW_PATTERN NC_("RID_SVXSTR_DESC_NEW_PATTERN", "Please enter a name for the pattern:")
+#define RID_CUISTR_DESC_LINESTYLE NC_("RID_SVXSTR_DESC_LINESTYLE", "Please enter a name for the line style:")
+#define RID_CUISTR_ASK_CHANGE_LINESTYLE NC_("RID_SVXSTR_ASK_CHANGE_LINESTYLE", "The line style was modified without saving. \nModify the selected line style or add a new line style.")
+#define RID_CUISTR_DESC_HATCH NC_("RID_SVXSTR_DESC_HATCH", "Please enter a name for the hatching:")
+#define RID_CUISTR_CHANGE NC_("RID_SVXSTR_CHANGE", "Modify")
+#define RID_CUISTR_ADD NC_("RID_SVXSTR_ADD", "Add")
+#define RID_CUISTR_DESC_COLOR NC_("RID_SVXSTR_DESC_COLOR", "Please enter a name for the new color:")
+#define RID_CUISTR_TABLE NC_("RID_SVXSTR_TABLE", "Table")
+#define RID_CUISTR_DESC_LINEEND NC_("RID_SVXSTR_DESC_LINEEND", "Please enter a name for the new arrow style:")
+#define RID_CUISTR_CHARNAME_NOSTYLE NC_("RID_SVXSTR_CHARNAME_NOSTYLE", "No %1")
+#define RID_CUISTR_CHARNAME_FAMILY NC_("RID_SVXSTR_CHARNAME_FAMILY", "Family:")
+#define RID_CUISTR_CHARNAME_FONT NC_("RID_SVXSTR_CHARNAME_FONT", "Font:")
+#define RID_CUISTR_CHARNAME_STYLE NC_("RID_SVXSTR_CHARNAME_STYLE", "Style:")
+#define RID_CUISTR_CHARNAME_TYPEFACE NC_("RID_SVXSTR_CHARNAME_TYPEFACE", "Typeface:")
+#define RID_CUISTR_USE_REPLACE NC_("RID_SVXSTR_USE_REPLACE", "Use replacement table")
+#define RID_CUISTR_CPTL_STT_WORD NC_("RID_SVXSTR_CPTL_STT_WORD", "Correct TWo INitial CApitals")
+#define RID_CUISTR_CPTL_STT_SENT NC_("RID_SVXSTR_CPTL_STT_SENT", "Capitalize first letter of every sentence")
+#define RID_CUISTR_BOLD_UNDER NC_("RID_SVXSTR_BOLD_UNDER", "Automatic *bold*, /italic/, -strikeout- and _underline_")
+#define RID_CUISTR_NO_DBL_SPACES NC_("RID_SVXSTR_NO_DBL_SPACES", "Ignore double spaces")
+#define RID_CUISTR_DETECT_URL NC_("RID_SVXSTR_DETECT_URL", "URL Recognition")
+#define RID_CUISTR_DASH NC_("RID_SVXSTR_DASH", "Replace dashes")
+#define RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK NC_("RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK", "Correct accidental use of cAPS LOCK key")
+#define RID_CUISTR_NON_BREAK_SPACE NC_("RID_SVXSTR_NON_BREAK_SPACE", "Add non-breaking space before specific punctuation marks in French text")
+#define RID_CUISTR_ORDINAL NC_("RID_SVXSTR_ORDINAL", "Format ordinal numbers suffixes (1st -> 1^st)")
+#define RID_CUISTR_OLD_HUNGARIAN NC_("RID_SVXSTR_OLD_HUNGARIAN", "Transliterate to Old Hungarian if the text direction is from right to left")
+#define RID_CUISTR_ANGLE_QUOTES NC_("RID_SVXSTR_ANGLE_QUOTES", "Replace << and >> with angle quotes")
+#define RID_CUISTR_DEL_EMPTY_PARA NC_("RID_SVXSTR_DEL_EMPTY_PARA", "Remove blank paragraphs")
+#define RID_CUISTR_USER_STYLE NC_("RID_SVXSTR_USER_STYLE", "Replace Custom Styles")
+#define RID_CUISTR_BULLET NC_("RID_SVXSTR_BULLET", "Replace bullets with: %1")
+// To translators: %1 will be replaced with a percentage, e.g. "10%"
+#define RID_CUISTR_RIGHT_MARGIN NC_("RID_SVXSTR_RIGHT_MARGIN", "Combine single line paragraphs if length greater than %1")
+#define RID_CUISTR_NUM NC_("RID_SVXSTR_NUM", "Bulleted and numbered lists. Bullet symbol: %1")
+#define RID_CUISTR_BORDER NC_("RID_SVXSTR_BORDER", "Apply border")
+#define RID_CUISTR_CREATE_TABLE NC_("RID_SVXSTR_CREATE_TABLE", "Create table")
+#define RID_CUISTR_REPLACE_TEMPLATES NC_("RID_SVXSTR_REPLACE_TEMPLATES", "Apply Styles")
+#define RID_CUISTR_DEL_SPACES_AT_STT_END NC_("RID_SVXSTR_DEL_SPACES_AT_STT_END", "Delete spaces and tabs at beginning and end of paragraph")
+#define RID_CUISTR_DEL_SPACES_BETWEEN_LINES NC_("RID_SVXSTR_DEL_SPACES_BETWEEN_LINES", "Delete spaces and tabs at end and start of line")
+#define RID_CUISTR_CONNECTOR NC_("RID_SVXSTR_CONNECTOR", "Connector")
+#define RID_CUISTR_DIMENSION_LINE NC_("RID_SVXSTR_DIMENSION_LINE", "Dimension line")
+#define RID_CUISTR_STARTQUOTE NC_("RID_SVXSTR_STARTQUOTE", "Start Quote")
+#define RID_CUISTR_ENDQUOTE NC_("RID_SVXSTR_ENDQUOTE", "End Quote")
+
+#define RID_CUISTR_SHADOW_STYLE_NONE NC_("RID_SVXSTR_SHADOW_STYLE_NONE", "No Shadow")
+#define RID_CUISTR_SHADOW_STYLE_BOTTOMRIGHT NC_("RID_SVXSTR_SHADOW_STYLE_BOTTOMRIGHT", "Cast Shadow to Bottom Right")
+#define RID_CUISTR_SHADOW_STYLE_TOPRIGHT NC_("RID_SVXSTR_SHADOW_STYLE_TOPRIGHT", "Cast Shadow to Top Right")
+#define RID_CUISTR_SHADOW_STYLE_BOTTOMLEFT NC_("RID_SVXSTR_SHADOW_STYLE_BOTTOMLEFT", "Cast Shadow to Bottom Left")
+#define RID_CUISTR_SHADOW_STYLE_TOPLEFT NC_("RID_SVXSTR_SHADOW_STYLE_TOPLEFT", "Cast Shadow to Top Left")
+#define RID_CUISTR_SIGNATURELINE_SIGNED_BY NC_("RID_SVXSTR_SIGNATURELINE_SIGNED_BY", "Signed by: %1")
+
+#define RID_CUISTR_FILTER_ALL NC_("RID_SVXSTR_FILTER_ALL", "All files")
+
+#define RID_CUISTR_REGISTERED_DATABASES NC_("RID_SVXSTR_REGISTERED_DATABASES", "Registered Databases")
+
+#define RID_CUISTR_CANNOTCONVERTURL_ERR NC_("RID_SVXSTR_CANNOTCONVERTURL_ERR", "The URL <%1> cannot be converted to a filesystem path.")
+
+#define RID_CUISTR_ABOUT_COPYRIGHT NC_("aboutdialog|copyright", "Copyright © 2000–2022 LibreOffice contributors.")
+#define RID_CUISTR_ABOUT_VENDOR NC_("aboutdialog|vendor", "This release was supplied by %OOOVENDOR.")
+#define RID_CUISTR_ABOUT_BASED_ON NC_("aboutdialog|libreoffice", "LibreOffice was based on OpenOffice.org.")
+#define RID_CUISTR_ABOUT_DERIVED NC_("aboutdialog|derived", "%PRODUCTNAME is derived from LibreOffice which was based on OpenOffice.org")
+#define RID_CUISTR_ABOUT_UILOCALE NC_("aboutdialog|uilocale", "UI: $LOCALE")
+
+#define RID_CUISTR_EDIT_PATHS NC_("optpathspage|editpaths", "Edit Paths: %1")
+
+#define RID_CUISTR_COMMANDLABEL NC_("RID_SVXSTR_COMMANDLABEL", "Label")
+#define RID_CUISTR_COMMANDNAME NC_("RID_SVXSTR_COMMANDLABEL", "Command")
+#define RID_CUISTR_COMMANDTIP NC_("RID_SVXSTR_COMMANDLABEL", "Tooltip")
+#define RID_CUISTR_COMMANDEXPERIMENTAL NC_("RID_SVXSTR_COMMANDEXPERIMENTAL", "Experimental")
+
+#define RID_CUISTR_QRCODEDATALONG NC_("RID_SVXSTR_QRCODEDATALONG", "The URL or text is too long for the current error correction level. Either shorten the text or decrease the correction level.")
+#define RID_CUISTR_DELETEUSERCOLOR1 NC_("RID_SVXSTR_DELETEUSERCOLOR1", "You can only delete user-defined colors")
+#define RID_CUISTR_DELETEUSERCOLOR2 NC_("RID_SVXSTR_DELETEUSERCOLOR2", "Please select the color to delete")
+
+#define RID_CUISTR_ADDITIONS_INSTALLBUTTON NC_("RID_SVXSTR_ADDITIONS_INSTALLBUTTON", "Install")
+#define RID_CUISTR_ADDITIONS_INSTALLEDBUTTON NC_("RID_SVXSTR_ADDITIONS_INSTALLEDBUTTON", "Installed")
+#define RID_CUISTR_ADDITIONS_INSTALLING NC_("RID_SVXSTR_ADDITIONS_INSTALLING", "Installing")
+#define RID_CUISTR_ADDITIONS_SEARCHING NC_("RID_SVXSTR_ADDITIONS_SEARCHING", "Searching...")
+#define RID_CUISTR_ADDITIONS_LOADING NC_("RID_SVXSTR_ADDITIONS_LOADING", "Loading...")
+#define RID_CUISTR_ADDITIONS_DIALOG_TITLE_PREFIX NC_("RID_SVXSTR_ADDITIONS_DIALOG_TITLE_PREFIX", "Extensions")
+#define RID_CUISTR_ADDITIONS_DICTIONARY NC_("RID_SVXSTR_ADDITIONS_DICTIONARY", "Extensions: Dictionary")
+#define RID_CUISTR_ADDITIONS_GALLERY NC_("RID_SVXSTR_ADDITIONS_GALLERY", "Extensions: Gallery")
+#define RID_CUISTR_ADDITIONS_ICONS NC_("RID_SVXSTR_ADDITIONS_ICONS", "Extensions: Icons")
+#define RID_CUISTR_ADDITIONS_PALETTES NC_("RID_SVXSTR_ADDITIONS_PALETTES", "Extensions: Color Palette")
+#define RID_CUISTR_ADDITIONS_TEMPLATES NC_("RID_SVXSTR_ADDITIONS_TEMPLATES", "Extensions: Templates")
+
+#define RID_CUISTR_UI_APPLYALL NC_("RID_SVXSTR_UI_APPLYALL", "Apply to %MODULE")
+
+#define RID_CUISTR_OLE_INSERT NC_("RID_SVXSTR_OLE_INSERT", "Inserting OLE object...")
+
+#define RID_CUISTR_CLICK_RESULT NC_("RID_CUISTR_CLICK_RESULT", "(Click on any test to view its resultant bitmap image)")
+#define RID_CUISTR_ZIPFAIL NC_("RID_CUISTR_ZIPFAIL", "Creation of ZIP file failed.")
+#define RID_CUISTR_SAVED NC_("RID_CUISTR_SAVED", "The results have been successfully saved in the file 'GraphicTestResults.zip'!")
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/inc/strings.hxx b/cui/inc/strings.hxx
new file mode 100644
index 000000000..5b72f3873
--- /dev/null
+++ b/cui/inc/strings.hxx
@@ -0,0 +1,14 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#define RID_SVXSTR_KEY_BASIC_PATH "BASIC"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/inc/tipoftheday.hrc b/cui/inc/tipoftheday.hrc
new file mode 100644
index 000000000..171ae5290
--- /dev/null
+++ b/cui/inc/tipoftheday.hrc
@@ -0,0 +1,289 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+
+#include <rtl/ustring.hxx>
+#include <config_python.h>
+#include <tuple>
+#include <unotools/resmgr.hxx>
+
+/*
+ * std:tuple consists of <text, uri, image>
+ * text:
+ * escape backslash, ie. use \\ to show \
+ * Use %MOD1 for Ctrl/Cmd and %MOD2 for Alt/Option depending on OS (uppercase required)
+ * uri:
+ * if uri is empty, do not show any link
+ * if uri starts with "http", show the link directly in the browser
+ * if uri starts with ".uno:", run the command if available in the current module
+ * all other strings are converted to a link for the offline help
+ * to find the right uri, look in instdir/help/hid2file.js after building --with-help=html
+ * structure of hid2file.js 'uri' : 'rest of URL' (that starts: https://help.libreoffice.org/latest/en-US/)
+ * For example 'cui/ui/optsecuritypage/OptSecurityPage' is the uri for https://help.libreoffice.org/latest/en-US/text/shared/optionen/01030300.html#bm_id9049654
+ * image:
+ * leave the image string empty for the default tipoftheday.png
+ * place new images at extra/source/tipoftheday and do not forget to add the files to vcl/Package_tipoftheday.mk
+ * images are scaled to 150x150px; const ThumbSize() in tipoftheday.cxx
+*/
+
+const std::tuple<TranslateId, OUString, OUString> TIPOFTHEDAY_STRINGARRAY[] =
+{
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME offers a variety of user interface options to make you feel at home"), ".uno:ToolbarModeUI", "toolbarmode.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to allow changes to parts of a read-only document in Writer? Insert frames or sections that can authorize changes."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/section_edit.html", "tipoftheday_w.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "To print the notes of your slides go to File ▸ Print ▸ %PRODUCTNAME Impress tab and select Notes under Document ▸ Type."), "", "printnote.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To start temporarily with a fresh user profile, or to restore a non-working %PRODUCTNAME, use Help ▸ Restart in Safe Mode."), "svx/ui/safemodedialog/SafeModeDialog", ""}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/01/profile_safe_mode.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Writing a book? %PRODUCTNAME master document lets you manage large documents as a container for individual %PRODUCTNAME Writer files."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/globaldoc.html", "tipoftheday_w.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can create editable Hybrid PDFs with %PRODUCTNAME."), "https://wiki.documentfoundation.org/Documentation/HowTo/CreateAHybridPDF", "hybrid_pdf.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Explore the ten different functions in the status bar (at the bottom of the document window). Place the cursor over each field for an explanation. If not visible, use View ▸ Status Bar."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to sum a cell through several sheets? Refer to the range of sheets e.g. =SUM(Sheet1.A1:Sheet3.A1)."), "", "sum_sheets.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can create fillable form documents (even PDFs) with %PRODUCTNAME."), "https://www.techrepublic.com/article/how-to-create-interactive-pdfs-with-libreoffice", "formdocuments.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Cannot see all the text in a cell? Expand the input line in the formula bar and you can scroll."), "", "expand_formula_bar.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Optimize your table layout with Table ▸ Size ▸ Distribute Rows / Columns Evenly."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Find all expressions in brackets per Edit ▸ Find and Replace ▸ Find ▸ \\([^)]+\\) (check “Regular expressions”)"), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Select a different icon set from Tools ▸ Options ▸ %PRODUCTNAME ▸ View ▸ Icon Theme."), "", "icon_sets.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can display a number as a fraction (0.125 = 1/8): Format ▸ Cells, under Numbers tab in the Category select Fraction."), "", "fraction.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To remove a hyperlink but keep its text, right-click on the hyperlink, and use “Remove Hyperlink”."), "", "remove_hyperlink.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To remove several hyperlinks at once, select the text with the hyperlinks, then right-click and use “Remove Hyperlink”."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To zoom a selection to fit the entire window in Draw, use the / (divide key) on the number pad."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Click a column field (row) PivotTable and press F12 to group data. Choices adapt to content: Date (month, quarter, year), number (classes)"), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can restart the slide show after a pause specified at Slide Show ▸ Slide Show Settings ▸ Loop and repeat after."), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To distribute some text in multi-columns select the text and apply Format ▸ Columns."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use View ▸ Value Highlighting to display cell contents in colors: Text/black, Formulas/green, Numbers/blue, Protected cells/grey background."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/03080000.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can create different master pages in a presentation template: View ▸ Master Slide and Slide ▸ New Master (or per toolbar or right click in slide pane)."), "", "masterdocument.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to sort a pivot table? Click on drop-list’s arrow in the row/col header and select sort method: ascending, descending, or custom."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Display photos or images with different shapes in Writer. Insert and select shape, then Insert ▸ Image. To adjust image, right-click on selected shape and choose Area."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use Page/Slide ▸ Properties ▸ “Fit object to paper format” in Draw/Impress to resize the objects so that they fit on your chosen paper format."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Fit the entire page in a Draw window, use * on the number pad."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "In a Draw page, use “-” to zoom out; “+” to zoom in."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to show the contents of another document within your document? Use Insert ▸ Section and select Link."), "modules/swriter/ui/editsectiondialog/link", "tipoftheday_w.png"}, // https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/section_insert.html#par_id3153404
+ { NC_("RID_CUI_TIPOFTHEDAY", "To automatically number table rows in Writer, select the relevant column, then apply a List Style."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/01/05130004.html", "tipoftheday_w.png"}, // no local help URI
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME allows you to use assistive tools, such as external screen readers, Braille devices or speech recognition input devices."), "https://www.libreoffice.org/get-help/accessibility/", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to sort a series in %PRODUCTNAME Calc such as A1, A2, A3, A11, A15, not in alphabetical order but on the number? Enable natural sort in the Options tab."), "modules/scalc/ui/sortoptionspage/SortOptionsPage", "tipoftheday_c.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/12030200.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can change the default function in the status bar: right click on the area."), "", "statusbar.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to add many of the same shapes in Draw/Impress? Double-click a tool in the drawing toolbar to use it for repeated tasks."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%MOD1+Shift+F9 recalculates all formulas in all spreadsheets."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to keep a part of an editable document as read-only? Insert ▸ Section. Add text to the section, then right-click “Edit Section” and check “Protect”."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use the Backspace key instead of Delete in Calc. You can choose what to delete."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Best way to fix bad-looking MS Word table cells via Table ▸ Size ▸ Optimal Row Height / Column Width."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To repeat a table heading when a table spans over a page, use Table ▸ Table Properties ▸ Text Flow ▸ Repeat heading."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to quickly insert or delete rows? Select the desired number of rows (or columns) and press %MOD1+Plus sign (+) to add or %MOD1+Minus sign (-) to delete."), "modules/scalc/ui/insertcells/InsertCellsDialog", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To repeat rows/columns on every pages use Format ▸ Print Ranges ▸ Edit."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Insert images and photos into shapes in Draw and Impress. Right-click on a shape, choose Area ▸ Image ▸ Add / Import, and use Options to adjust appearance."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to insert the date in a spreadsheet cell? Type %MOD1+; or Shift+%MOD1+; to insert the time."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Insert your metadata in your document with Insert ▸ Fields ▸ More Fields… ▸ Document or DocInformation."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Get help from the community via the Ask portal."), "https://ask.libreoffice.org", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use Shift+Space to select the current row and %MOD1+Space to select the current column."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can move an object to another layer by holding it until its edges flash, then drag it to the tab of the layer you want to move it to."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Data ▸ Validity allows you to create drop-down lists where the user selects a value instead of typing."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/guide/validity.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Hold down %MOD1 and turn the mouse wheel to change the zoom factor."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME has great extensions to increase your productivity—check them out."), "https://extensions.libreoffice.org", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to count words for just one particular paragraph style? Use Edit ▸ Find and Replace, click Paragraph Styles, select the style in Find, and click Find All. Read the result in the status bar."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Generate fully customized PDF documents with the exact format, image compression, comments, access rights, password, etc., via File ▸ Export as PDF."), "", ""},
+#if ENABLE_LIBRELOGO
+ { NC_("RID_CUI_TIPOFTHEDAY", "Writer includes LibreLogo: simple Logo-like programming environment with turtle vector graphics, DTP and graphic design."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/librelogo/LibreLogo.html", "tipoftheday_w.png"}, //local help missing
+#endif
+ { NC_("RID_CUI_TIPOFTHEDAY", "Construct your own 2D shapes in Draw. Select two or more objects, and explore possibilities with Shape ▸ Combine, Shape ▸ Merge, Shape ▸ Subtract, and Shape ▸ Intersect."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/sdraw/guide/combine_etc.html", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Do you plan to change your computer and want to recover your customizations? See:"), "https://wiki.documentfoundation.org/UserProfile", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can toggle between the field names and the actual value with View ▸ Fields Names (or %MOD1+F9)."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Show or hide comments in Writer by clicking the comment toggle button in the ruler."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To enable macro recording, check Tools ▸ Options ▸ %PRODUCTNAME ▸ Advanced ▸ Enable macro recording."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to insert a placeholder for an image in a Writer template? Use Insert ▸ Fields ▸ More fields, click Functions tab, choose PlaceHolder for Type and Image for Format."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME supports four macro security levels (from low to very high) and trusted sources."), "cui/ui/optsecuritypage/OptSecurityPage", ""}, // https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/optionen/01030300.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Did you know that you can attach comments to portions of text? Just use the shortcut %MOD1+%MOD2+C."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to move one or more paragraphs? No need to cut and paste: Use the keyboard shortcut %MOD1+%MOD2+Arrow (Up/Down)"), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Change the basic fonts for the predefined template or current document per Tools ▸ Options ▸ %PRODUCTNAME Writer ▸ Basic Fonts."), "modules/swriter/ui/optfonttabpage/OptFontTabPage", "tipoftheday_w.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/optionen/01040300.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to find words containing more than 10 characters? Edit ▸ Find and Replace ▸ Search ▸ [a-z]{10,} ▸ Other Options ▸ check Regular expressions."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Open a CSV file as a new sheet in the current spreadsheet via Sheet ▸ Sheet from file."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Typing in bold, italics, or underlined in Writer you can continue with the default attributes using just the shortcut %MOD1+Shift+X (remove direct character formats)."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use %MOD1+%MOD2+Shift+V to paste the contents of the clipboard as unformatted text."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Customize footnote appearance with Tools ▸ Footnotes and Endnotes…"), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "With Slide Show ▸ Custom Slide Show, reorder and pick slides to fit a slideshow to the needs of your viewers."), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to change spell checking for some part of the text? Click in the language zone of the status bar or better, apply a style."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Writer can insert a blank page between two odd (even) pages that follow. Check “Print automatically inserted blank pages” in the print dialog’s %PRODUCTNAME Writer tab."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You do not want to print all columns? Hide or group the ones you do not need."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To modify an AutoPlay presentation, open it and after it starts, right click and select Edit in the context menu."), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to precisely position? %MOD2+arrow Keys move objects (shapes, pictures, formulas) by one pixel."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Embedded help is available by pressing F1, if you have installed it. Otherwise check online at:"), "https://help.libreoffice.org", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Right-click in the status bar in %PRODUCTNAME Calc and select “Selection count” to display the number of selected cells."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to have two or more columns for just a part of a %PRODUCTNAME Writer page? Insert ▸ Section, set with Columns tab, and place text in that section."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use Data ▸ Statistics for sampling, descriptive statistics, analysis of variance, correlation, and much more in %PRODUCTNAME Calc."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can copy from one sheet to another without the clipboard. Select the area to copy, %MOD1+click the target sheet’s tab and use Sheet ▸ Fill Cells ▸ Fill Sheets."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can change the look of %PRODUCTNAME via View ▸ User Interface."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "In %PRODUCTNAME Impress, use Insert ▸ Media ▸ Photo Album to create a slideshow from a series of pictures with the “Photo Album” feature."), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can show formulas instead of results with View ▸ Show Formula (or Tools ▸ Options ▸ %PRODUCTNAME Calc ▸ View ▸ Display ▸ Formulas)."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME is developed by a friendly community, made up of hundreds of contributors around the world. Join us with your skills beyond coding."), "https://www.libreoffice.org/community/get-involved/", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Left-handed? Enable Tools ▸ Options ▸ Language Settings ▸ Languages ▸ Asian and check Tools ▸ Options ▸ %PRODUCTNAME Writer ▸ View ▸ Ruler ▸ Right-aligned, which displays the scrollbar to the left."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want your chapter titles to always begin a page? Edit Heading1 (paragraph style) ▸ Text Flow ▸ Breaks and check Insert ▸ Page ▸ Before."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Date/time value is just a number of days since a chosen day zero; in the number, integer part represents date, and fractional part is time (elapsed part of a day), with 0.5 representing noon."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Shift+%MOD1+Del deletes from cursor to the end of the current sentence."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use column or row labels in formulas. For example, if you have two columns, “Time” and “KM”, use =Time/KM to get minutes per kilometer."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Annoyed by the “marching ants” around cells in Calc? Press escape to stop them; the copied content will remain available for pasting."), "", "marchingants.gif"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to become a %PRODUCTNAME Ambassador? There are certifications for developers, admins, and trainers."), "https://www.documentfoundation.org/certification/program/", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Mix portrait and landscape orientations in a Calc spreadsheet by applying different page styles on sheets."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Click on the special character icon in the toolbar to get quick access to favorite and recent characters to insert."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Choose “Hierarchical View” in the Styles sidebar to see the relation between styles."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can use styles to make the tables in your document consistent. Choose one from the predefined per Styles (F11) or via Table ▸ AutoFormat Styles..."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to open hyperlinks without pressing the %MOD1 key? Uncheck “%MOD1+click required to open hyperlinks” in Tools ▸ Options ▸ %PRODUCTNAME ▸ Security ▸ Options ▸ Security Options."), "cui/ui/securityoptionsdialog/ctrlclick", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You would like to view the calculation of individual elements of a formula, select the respective elements and press F9."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can protect cells with Format ▸ Cells ▸ Protection. To prevent insert, delete, rename, move/copy of sheets use Tools ▸ Protect Sheet."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/guide/cell_protect.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Write along a curve? Draw the line, double click, type the text, Format ▸ Text Box and Shape ▸ Fontwork."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to display only the highest values in a spreadsheet? Select menu Data ▸ AutoFilter, click the drop-down arrow, and choose “Top10”."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To remove the page number from your table of contents go to Insert ▸ Table of Contents and Index (or right-click and Edit Index to edit a previously inserted index). In the Entries tab delete the page number (#) from Structure line."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "With the Navigator you can select & move up/down headings and the text below the heading, in the Navigator and in the document."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to get a math object into Writer quickly? Type your formula, select it, and use Insert ▸ OLE Object ▸ Formula to convert the text."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "With %PRODUCTNAME it is very easy to install a new dictionary: they are supplied as extensions."), "https://extensions.libreoffice.org/?q=&Tags[]=50", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME has a portable version which gives you mobility. Even without administrator rights on your computer you can install %PRODUCTNAME Portable to your hard drive too."), "https://www.libreoffice.org/download/portable-versions/", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Writer lets you number your footnotes per page, chapter, document: Tools ▸ Footnotes and Endnotes ▸ Footnotes tab ▸ Counting."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Your Writer document does not reopen with the text cursor at the same editing position it was when you saved it? Add First or Last name in Tools ▸ Options ▸ %PRODUCTNAME ▸ User Data ▸ First/last name."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Citation management? Use a 3rd party extension."), "https://wiki.documentfoundation.org/Referencing_Systems_in_LibreOffice", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to insert a value in the same place on several sheets? Select the sheets: hold down %MOD1 key and click their tabs before entering."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to hide some text in a document? Select the text. Insert ▸ Section, and select “Hide”."), "modules/swriter/ui/editsectiondialog/hide", "tipoftheday_w.png"}, // online help is different https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/hidden_text.html#hd_id3148675
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can customize the middle mouse button by going to Tools ▸ Options ▸ %PRODUCTNAME ▸ View ▸ Mouse ▸ Middle button."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to print two portrait pages on a landscape one (reducing A4 to A5)? File ▸ Print and select 2 at “Pages per sheet”."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "For quick access to your document bookmarks, right-click on the page number of the status bar (lower-left corner of document window)."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Select an object in the document background via the Select tool in the Drawing toolbar to surround the object to select."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Define texts that you often use as AutoText. You will be able to insert them by their name, shortcut or toolbar in any Writer document."), "modules/swriter/ui/autotext/AutoTextDialog", "tipoftheday_w.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/autotext.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Play music throughout a slideshow by assigning the sound to the first slide transition without clicking the “Apply to All Slides” button."), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME Calc does not calculate from left to right but respects the order Parentheses – Exponents – Multiplication – Division – Addition – Subtraction."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Get %PRODUCTNAME documentation and free user guide books at:"), "https://documentation.libreoffice.org/", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to remove all <> at once and keep the text inside? Edit ▸ Find and Replace: Search = [<>], Replace = blank and check “Regular expressions” under Other options."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/01/02100001.html", ""}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to present a report written with Writer? File ▸ Send ▸ Outline to Presentation automatically creates a slideshow from the outline."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to manage the presentation of hyperlinks in a spreadsheet? Insert them with the HYPERLINK function."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/04060109.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Uncheck Tools ▸ Options ▸ %PRODUCTNAME Calc ▸ View ▸ Zoom: “Synchronize sheets” so that each sheet in Calc has its own zoom factor."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can set a color for each tab: right-click the tab or use Sheet ▸ Sheet Tab Color."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Trace cells used in a formula, precedents (Shift+F9) or dependents (Shift+F5) (or use Tools ▸ Detective). For each hit you go one more step in the chain."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/06030000.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Insert and number your formulas in one step: type fn then F3. An AutoText is inserted with formula and number aligned in a table."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can create an illustration index from object names, not only from captions."), "cui/ui/objectnamedialog/ObjectNameDialog", "tipoftheday_w.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/01/05190000.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use your Android or iPhone to remotely control your Impress presentation."), "https://help.libreoffice.org/%PRODUCTVERSION/he/text/simpress/guide/impress_remote.html", "tipoftheday_i.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to know how many days there are in the current month? Use the DAYSINMONTH(TODAY()) function."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Your numbers are displayed as ### in your spreadsheet? The column is too narrow to display all digits."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Enable massive parallel calculations of formula cells via Tools ▸ Options ▸ %PRODUCTNAME ▸ OpenCL."), "cui/ui/optopenclpage/OptOpenCLPage", "tipoftheday_c.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/optionen/opencl.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use the Connector tool from the Drawing toolbar in Draw/Impress to create nice flow charts and optionally copy/paste the object into Writer."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Your donations support our worldwide community."), "https://www.libreoffice.org/donate/", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You want to add x months to a date? Use =EDATE(date;months)."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/func_edate.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "To select a contiguous range of cells containing data and bounded by empty row and columns use %MOD1+* (numeric key pad)."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Your date acceptance pattern is inappropriate? Use Tools ▸ Options ▸ Language Settings ▸ Languages ▸ Date acceptance patterns to tweak the pattern."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to export formulas to CSV? File ▸ Save As ▸ Type:Text CSV, check “Edit filter settings”, and check “Save cell formulas” in the next dialog."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "The presenter console is a great feature when working with %PRODUCTNAME Impress. Have you checked it out?"), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/simpress/guide/presenter_console.html", "tipoftheday_i.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "To delete multiple comments, select cells with comments and use Sheet ▸ Cell Comments ▸ Delete Comment."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Easily convert your documents to PDF with one click by clicking on the PDF icon in the toolbar."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to select a large range of cells without scrolling? Type the range reference (e.g. A1:A1000) in the name box then Enter."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to know the valid command line parameters? Start soffice with --help or -h or -?"), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/guide/start_parameters.html", ""}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Fit your sheet or print ranges to a page with Format ▸ Page ▸ Sheet Tab ▸ Scaling Mode."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to include a list item without a bullet or number? Use “Insert Unnumbered Entry” in the Bullets and Numbering toolbar."), "HID_NUM_TOOLBOX", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can rotate cells table orientation with Table ▸ Properties… ▸ Text Flow ▸ Text orientation."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "In %PRODUCTNAME Draw to change the 0/0 point of the rulers, drag the intersection of the two rulers in the top left corner into the workspace."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Move a column in Calc between two others in one step? Click the header then a cell in the column, keep mouse button and move to the target with %MOD2 key."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Automatically mark alphabetical index entries using a concordance file."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/indices_index.html", "tipoftheday_w.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use Format ▸ Align Objects in Impress or Shape ▸ Align Objects in Draw (or the context menu) for precise positioning of objects: it centers on the page if one object is selected or works on the group respectively."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Do not use tabs to space items on a Writer document. Depending on what you are trying to do, a borderless table can be a better choice."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "No need to scroll through the list at Tools ▸ Customize ▸ Keyboard to find a shortcut: just type it."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME can automatically add a numbered caption when you insert objects. See Tools ▸ Options ▸ %PRODUCTNAME Writer ▸ AutoCaption."), "modules/swriter/ui/optcaptionpage/OptCaptionPage", "tipoftheday_w.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/optionen/01041100.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "With %PRODUCTNAME you can use your Google Mail account to do a mail merge. Fill in Tools ▸ Options ▸ %PRODUCTNAME Writer ▸ Mail Merge Email."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/form_letters_main.html", "tipoftheday_w.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Keep column headers of a sheet visible when scrolling lines via View ▸ Freeze Cells ▸ Freeze First Row."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You want to start working with Basic macros? Take a look at the examples under Tools ▸ Macros ▸ Edit Macros."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Apply Heading paragraph styles in Writer with shortcut keys: %MOD1+1 applies Heading 1, %MOD1+2 applies Heading 2, etc."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Do not get lost in large documents. Use the Navigator (F5) to find your way through the content."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Edit ▸ Find and Replace lets you insert special characters directly: right click in input fields or press Shift+%MOD1+S."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need custom contents for metadata properties? File ▸ Properties ▸ Custom Properties tab lets you create what you want."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to see, but not print, an object in Draw? Draw it on a layer for which the “Printable” flag is not set (right-click the layer’s tab and choose “Modify Layer”)."), "", "tipoftheday_d.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To insert the current date in your document, use Insert ▸ Field ▸ Date."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Got many images in your Writer document? Speed up the display by disabling View ▸ Images and charts."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use Sheet ▸ Fill Cells ▸ Random Number to generate a random series based on various distributions."), "modules/scalc/ui/randomnumbergenerator/RandomNumberGeneratorDialog", "tipoftheday_c.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/02140700.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Rename your slides in Impress to help you define “Go to page” interactions and to have a summary more explicit than Slide1, Slide2…"), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Chapter numbering dialog lets you set text to be displayed before the chapter number. For example, type “Chapter ” to display “Chapter 1”"), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Transpose a Writer table? Copy and paste in Calc, transpose with copy/paste special then copy/paste special ▸ Formatted text in Writer."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To get the “Vertical Text” tool in the Drawing toolbar, check Tools ▸ Options ▸ Language Settings ▸ Languages ▸ Default languages for Documents ▸ Asian (and make the button visible with right-click and then Visible Buttons ▸ Vertical Text)."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To quickly zoom in on range selection, right click on the zoom part of the status bar and choose Optimal."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can sign existing PDF files and also verify those signatures."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/guide/digital_signatures.html", ""}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Often create one document from another? Consider using a template."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use Format ▸ Conditional Formatting ▸ Manage in Calc to find out which cells have been defined with conditional formatting."), "modules/scalc/ui/conditionalformatdialog/ConditionalFormatDialog", "tipoftheday_c.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/05120000.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Tools ▸ Detective ▸ Mark Invalid Data highlights all cells in the sheet that contain values outside the validation rules."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/06030800.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Use font embedding for greater interoperability with other office suites at File ▸ Properties ▸ Font."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To convert a formula into static values you do not need to copy/paste; use Data ▸ Calculate ▸ Formula to Value."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can reformat all comments in a document by clicking the down arrow in a comment and choose “Format all Comments”."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want the same layout for the screen display and printing? Check Tools ▸ Options ▸ %PRODUCTNAME Calc ▸ General ▸ Use printer metrics for text formatting."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Writer helps you to make backups: with File ▸ Save a Copy you create a new document continuing to work on the original."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "When you have created a Style based on another, you can enter a percentage value or a point value (e.g. 110% or −2pt or +5pt)."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To copy a comment without losing the content of the target cell you should use Paste Special and uncheck everything except “Comments” in dialog. Use Operations “Add” to not override existing content."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Batch-convert your Microsoft Office documents to the OpenDocument format by using the Document Converter wizard in menu File ▸ Wizards ▸ Document Converter."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "When editing a cell in place, you can right click and Insert fields: Date, Sheet name, Document title, etc."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Need to move a Writer table? Table ▸ Select ▸ Table and Insert ▸ Frame ▸ Frame and move where you want."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "With Tools ▸ AutoText ▸ AutoText ▸ Import you can select a Word document or a template containing the AutoText entries that you want to import."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Do not insert manual breaks to separate two paragraphs. Rather change Indents & Spacing ▸ Spacing ▸ Below paragraph at the style/paragraph properties."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Keep the zeros before a number by using the “leading zeroes” cell format option or format the cell as text before entering the number."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to return to default after applying a list style? Click Bullets or Numbering On/Off tool on the Formatting toolbar."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Delete all of your printing areas in one step: select all sheets, then Format ▸ Print Ranges ▸ Clear."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Add background images to spreadsheets via Insert ▸ Image or drag a background from the Gallery, then Format ▸ Arrange ▸ To Background."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Having trouble pasting text from PDF files or webpages into documents? Try to paste as unformatted text (%MOD1+%MOD2+Shift+V)."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "In Calc use TRIMMEAN() to return the mean of a data set excluding the highest and lowest values."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/04060182.html?DbPAR=CALC#bm_id3152966", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "The 4th optional parameter of VLOOKUP Calc function indicates whether the first column of data is sorted. If not, enter FALSE or zero."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Toolbars are contextual—they open depending on the context. If you do not want that, uncheck them from View ▸ Toolbars."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can create a master document from the current Writer document by using File ▸ Send ▸ Create Master Document."), "SW_HID_SEND_MASTER_CTRL_PUSHBUTTON_CANCEL", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to center cells on a printed page in Calc? Format ▸ Page, Page ▸ Layout settings ▸ Table alignment."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Frames can be linked so that the text can flow from one to the other as in desktop publishing."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/text_frame.html", "tipoftheday_w.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can create a chart based on a Writer table by clicking in the table and choosing Insert ▸ Chart."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Select options in Tools ▸ Options ▸ %PRODUCTNAME Writer ▸ Formatting Aids ▸ Display Formatting to specify which non-printing characters are displayed."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to jump to a particular page by its number? Click the left-most statusbar entry or use Edit ▸ Go To Page… or press %MOD1+G."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME supports over 150 languages."), "https://wiki.documentfoundation.org/Language_support_of_LibreOffice", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Uncheck Slide Show ▸ Settings ▸ Presentation always on top if you need another program displays its window to the front of your presentation."), "", "tipoftheday_i.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to find the words in bold in a Writer document? Edit ▸ Find and Replace ▸ Other options ▸ Attributes ▸ Font weight."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/finding.html", "tipoftheday_w.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "You can sort paragraphs or table rows alphabetically or numerically per Tools ▸ Sort."), "modules/swriter/ui/sortdialog/SortDialog", "tipoftheday_w.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/01/06100000.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "To insert a paragraph before (after) a section, press %MOD2+Enter at the beginning (end) of the section."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME has a template center to create good looking documents—check it out."), "https://extensions.libreoffice.org/?q=&Tags[]=118", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Calculate loan repayments with Calc: eg. PMT(2%/12;36;2500) interest rate per payment period 2%/12, 36 months, loan amount 2500."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/04060119.html?DbPAR=CALC#bm_id3149577", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Cannot find what you want with the VLOOKUP function in Calc? With INDEX and MATCH you can do anything!"), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/01/04060109.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to show hidden column A? Click a cell in column B, press the left mouse button, move the mouse to the left, release. Then switch it on via Format ▸ Columns ▸ Show."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To change the number of a page in Writer, go to the properties of the first paragraph and at the Text Flow tab check Break ▸ Insert and enter the number."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Run %PRODUCTNAME in any browser via rollApp."), "https://www.rollapp.com/app/lowriter", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Strange error code in Calc, Err: followed by a number? This page gives the explanation:"), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/05/02140000.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Include a paragraph that is not a title in the table of contents by changing Outline & Numbering in the paragraph settings to an outline level."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Apart from table of contents, %PRODUCTNAME can create Alphabetical, Illustrations, Tables, Objects, Bibliography, User-Defined indexes."), "modules/swriter/ui/tocdialog/TocDialog", "tipoftheday_w.png"}, //https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/swriter/guide/indices_toc.html
+ { NC_("RID_CUI_TIPOFTHEDAY", "Unable to modify or delete a custom cell style? Check all sheets, none should be protected."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "You need to fill a series? Select the cell range and Sheet ▸ Fill Cells ▸ Fill Series and choose between Linear, Growth, Date and AutoFill."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/scalc/guide/calc_series.html", "tipoftheday_c.png"}, //local help missing
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to know if a cell is referred in formulas of other cells? Tools ▸ Detective ▸ Trace Dependents (Shift+F5)."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "In the replace input field of auto correct options you can use the wildcards .*"), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want to duplicate the above line? Press %MOD1+D or use Sheet ▸ Fill Cells ▸ Fill Down."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To search in several spreadsheets, select them before you start the search."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Drag & drop cells from Calc into the normal view of a slide creates a table; into the outline view, each cell creates a line in the outline."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "%PRODUCTNAME helps you not to enter two or more spaces in Writer. Check Tools ▸ AutoCorrect ▸ AutoCorrect Options ▸ Options ▸ Ignore double spaces."), "", "tipoftheday_w.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Want the cursor to go into the cell to the right, after entering a value in Calc? Use the Tab key instead of Enter."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "To display the scrollbar to the left, enable Tools ▸ Options ▸ Language Settings ▸ Languages ▸ Complex text and right click a sheet in Sheet tabs above Status bar ▸ Right-To-Left."), "", "tipoftheday_c.png"},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Drag a formatted object to the Styles and Formatting window. A dialog box opens, just enter the name of the new style."), "", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "New versions of %PRODUCTNAME provide new features, bug fixes, and security patches. Keep your software updated!"), "SFX2_HID_DLG_CHECKFORONLINEUPDATE", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Developing new XSLT and XML filters?"), "https://fridrich.blogspot.com/2013/08/extending-swiss-army-knife-overview.html", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Press Shift+F1 to see any available extended tooltips in dialog boxes, when \"Extended tips\" is not enabled in Tools ▸ Options ▸ %PRODUCTNAME ▸ General."), "https://help.libreoffice.org/%PRODUCTVERSION/%LANGUAGENAME/text/shared/05/00000120.html", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Never use certain arrow styles? Remove them by using the Delete button on the Format ▸ Text Box and Shape ▸ Line ▸ Arrow Styles tab."), "cui/ui/lineendstabpage/BTN_MODIFY", ""},
+ { NC_("RID_CUI_TIPOFTHEDAY", "Don’t like the position of some icons on your toolbar? Change it with Tools ▸ Customize ▸ Toolbars tab ▸ Target."), "CUI_HID_SVX_CONFIG_TOOLBAR", ""},
+};
+
+#define STR_HELP_LINK NC_("STR_HELP_LINK", "%PRODUCTNAME Help")
+#define STR_MORE_LINK NC_("STR_MORE_LINK", "More info")
+#define STR_UNO_LINK NC_("STR_UNO_LINK", "Run this action now...")
+#define STR_TITLE NC_("STR_TITLE", "Tip of the Day: %CURRENT/%TOTAL")
+#define STR_CMD NC_("STR_CMD", "⌘ Cmd") //use narrow no-break space U+202F here
+#define STR_CTRL NC_("STR_CTRL", "Ctrl")
+#define STR_Alt NC_("STR_CMD", "Alt")
+#define STR_Option NC_("STR_CTRL", "⌥ Opt") //use narrow no-break space U+202F here
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/inc/toolbarmode.hrc b/cui/inc/toolbarmode.hrc
new file mode 100644
index 000000000..d073eaaf9
--- /dev/null
+++ b/cui/inc/toolbarmode.hrc
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+
+#include <rtl/ustring.hxx>
+#include <tuple>
+#include <unotools/resmgr.hxx>
+
+/*
+ Description, ui file name, preview file name
+*/
+const std::tuple<TranslateId, OUString, OUString> TOOLBARMODES_ARRAY[] =
+{
+ { NC_("RID_CUI_TOOLBARMODES", "Standard user interface with menu, toolbar, and collapsed sidebar. Intended for users who are familiar with the classic interface."), "Default", "default.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "The Tabbed user interface is the most similar to the Ribbons used in Microsoft Office. It organizes functions in tabs and makes the main menu obsolete."), "notebookbar.ui", "notebookbar.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "Standard user interface but with single-line toolbar. Intended for use on small screens."), "Single", "single.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "Standard user interface with expanded sidebar. Expert users who want to quickly change many different properties are advised to use this UI."), "Sidebar", "sidebar.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "The Tabbed Compact variant aims to be familiar with the Microsoft Office interface, yet occupying less space for smaller screens."), "notebookbar_compact.ui", "notebookbar_compact.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "The Groupedbar interface provides access to functions in groups, with icons for most-frequently used features, and dropdown menus for others. This full variant favors functions and is slightly larger than others."), "notebookbar_groupedbar_full.ui", "notebookbar_groupedbar_full.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "The Groupedbar interface provides access to functions in groups, with icons for most-frequently used features, and dropdown menus for others. This compact variant favors vertical space."), "notebookbar_groupedbar_compact.ui", "notebookbar_groupedbar_compact.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "The Contextual Single interface shows functions in a single-line toolbar with context-dependent content."), "notebookbar_single.ui", "notebookbar_single.png" },
+ { NC_("RID_CUI_TOOLBARMODES", "The Contextual Groups interface focuses on beginners. It exposes the most frequently used functions on groups with the core action as large icon and a couple of small additional features. All functions have a label. Depending on the context, an additional section provides access to those functions."), "notebookbar_groups.ui", "notebookbar_groups.png" },
+};
+
+//hide experimental UIs
+constexpr int nGroupedbarFull = 5;
+constexpr int nContextualGroups = 8;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/inc/treeopt.hrc b/cui/inc/treeopt.hrc
new file mode 100644
index 000000000..f4fc28c57
--- /dev/null
+++ b/cui/inc/treeopt.hrc
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <sfx2/pageids.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+#include <unotools/resmgr.hxx>
+
+#include <utility>
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+
+const std::pair<TranslateId, sal_uInt16> SID_GENERAL_OPTIONS_RES[] =
+{
+ { NC_("SID_GENERAL_OPTIONS_RES", "%PRODUCTNAME"), 0 },
+ { NC_("SID_GENERAL_OPTIONS_RES", "User Data"), RID_SFXPAGE_GENERAL },
+ { NC_("SID_GENERAL_OPTIONS_RES", "General"), OFA_TP_MISC },
+ { NC_("SID_GENERAL_OPTIONS_RES", "View"), OFA_TP_VIEW },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Print"), RID_SFXPAGE_PRINTOPTIONS },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Paths"), RID_SFXPAGE_PATH },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Fonts"), RID_SVX_FONT_SUBSTITUTION },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Security"), RID_SVXPAGE_INET_SECURITY },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Personalization"), RID_SVXPAGE_PERSONALIZATION },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Application Colors"), RID_SVXPAGE_COLORCONFIG },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Accessibility"), RID_SVXPAGE_ACCESSIBILITYCONFIG },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Advanced"), RID_SVXPAGE_OPTIONS_JAVA },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Basic IDE"), RID_SVXPAGE_BASICIDE_OPTIONS },
+ { NC_("SID_GENERAL_OPTIONS_RES", "Online Update"), RID_SVXPAGE_ONLINEUPDATE },
+ { NC_("SID_GENERAL_OPTIONS_RES", "OpenCL"), RID_SVXPAGE_OPENCL }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_LANGUAGE_OPTIONS_RES[] =
+{
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "Language Settings"), 0 },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "Languages"), OFA_TP_LANGUAGES },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "Writing Aids"), RID_SFXPAGE_LINGU },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "Searching in Japanese"), RID_SVXPAGE_JSEARCH_OPTIONS },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "Asian Layout"), RID_SVXPAGE_ASIAN_LAYOUT },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "Complex Text Layout"), RID_SVXPAGE_OPTIONS_CTL },
+ { NC_("SID_LANGUAGE_OPTIONS_RES", "LanguageTool Server Settings"), RID_SVXPAGE_LANGTOOL_OPTIONS }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_INET_DLG_RES[] =
+{
+ { NC_("SID_INET_DLG_RES", "Internet"), 0 },
+ { NC_("SID_INET_DLG_RES", "Proxy"), RID_SVXPAGE_INET_PROXY },
+ { NC_("SID_INET_DLG_RES", "Email"), RID_SVXPAGE_INET_MAIL }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SW_EDITOPTIONS_RES[] =
+{
+ { NC_("SID_SW_EDITOPTIONS_RES", "%PRODUCTNAME Writer"), 0 },
+ { NC_("SID_SW_EDITOPTIONS_RES", "General"), RID_SW_TP_OPTLOAD_PAGE },
+ { NC_("SID_SW_EDITOPTIONS_RES", "View"), RID_SW_TP_CONTENT_OPT },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Formatting Aids"), RID_SW_TP_OPTSHDWCRSR },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Grid"), RID_SVXPAGE_GRID },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Basic Fonts (Western)"),RID_SW_TP_STD_FONT },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Basic Fonts (Asian)"),RID_SW_TP_STD_FONT_CJK },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Basic Fonts (CTL)"), RID_SW_TP_STD_FONT_CTL },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Print"), RID_SW_TP_OPTPRINT_PAGE },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Table"), RID_SW_TP_OPTTABLE_PAGE },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Changes"), RID_SW_TP_REDLINE_OPT },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Comparison"), RID_SW_TP_COMPARISON_OPT },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Compatibility"), RID_SW_TP_OPTCOMPATIBILITY_PAGE },
+ { NC_("SID_SW_EDITOPTIONS_RES", "AutoCaption"), RID_SW_TP_OPTCAPTION_PAGE },
+ { NC_("SID_SW_EDITOPTIONS_RES", "Mail Merge Email"), RID_SW_TP_MAILCONFIG }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SW_ONLINEOPTIONS_RES[] =
+{
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "%PRODUCTNAME Writer/Web"), 0 },
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "View"), RID_SW_TP_HTML_CONTENT_OPT },
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "Formatting Aids"), RID_SW_TP_HTML_OPTSHDWCRSR },
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "Grid"), RID_SW_TP_HTML_OPTGRID_PAGE },
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "Print"), RID_SW_TP_HTML_OPTPRINT_PAGE },
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "Table"), RID_SW_TP_HTML_OPTTABLE_PAGE },
+ { NC_("SID_SW_ONLINEOPTIONS_RES", "Background"), RID_SW_TP_BACKGROUND }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SM_EDITOPTIONS_RES[] =
+{
+ { NC_("SID_SM_EDITOPTIONS_RES", "%PRODUCTNAME Math"), 0 },
+ { NC_("SID_SM_EDITOPTIONS_RES", "Settings"), SID_SM_TP_PRINTOPTIONS },
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SC_EDITOPTIONS_RES[] =
+{
+ { NC_("SID_SC_EDITOPTIONS_RES", "%PRODUCTNAME Calc"), 0 },
+ { NC_("SID_SC_EDITOPTIONS_RES", "General"), SID_SC_TP_LAYOUT },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Defaults"), RID_SC_TP_DEFAULTS },
+ { NC_("SID_SC_EDITOPTIONS_RES", "View"), SID_SC_TP_CONTENT },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Calculate"), SID_SC_TP_CALC },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Formula"), SID_SC_TP_FORMULA },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Sort Lists"), SID_SC_TP_USERLISTS },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Changes"), SID_SC_TP_CHANGES },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Compatibility"), SID_SC_TP_COMPATIBILITY },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Grid"), SID_SC_TP_GRID },
+ { NC_("SID_SC_EDITOPTIONS_RES", "Print"), RID_SC_TP_PRINT }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SD_EDITOPTIONS_RES[] =
+{
+ { NC_("SID_SD_EDITOPTIONS_RES", "%PRODUCTNAME Impress"), 0 },
+ { NC_("SID_SD_EDITOPTIONS_RES", "General"), SID_SI_TP_MISC },
+ { NC_("SID_SD_EDITOPTIONS_RES", "View"), SID_SI_TP_CONTENTS },
+ { NC_("SID_SD_EDITOPTIONS_RES", "Grid"), SID_SI_TP_SNAP },
+ { NC_("SID_SD_EDITOPTIONS_RES", "Print"), SID_SI_TP_PRINT }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SD_GRAPHIC_OPTIONS_RES[] =
+{
+ { NC_("SID_SD_GRAPHIC_OPTIONS_RES", "%PRODUCTNAME Draw"), 0 },
+ { NC_("SID_SD_GRAPHIC_OPTIONS_RES", "General"), SID_SD_TP_MISC },
+ { NC_("SID_SD_GRAPHIC_OPTIONS_RES", "View"), SID_SD_TP_CONTENTS },
+ { NC_("SID_SD_GRAPHIC_OPTIONS_RES", "Grid"), SID_SD_TP_SNAP },
+ { NC_("SID_SD_GRAPHIC_OPTIONS_RES", "Print"), SID_SD_TP_PRINT }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SCH_EDITOPTIONS_RES[] =
+{
+ { NC_("SID_SCH_EDITOPTIONS_RES", "Charts"), 0 },
+ { NC_("SID_SCH_EDITOPTIONS_RES", "Default Colors"), RID_OPTPAGE_CHART_DEFCOLORS }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_FILTER_DLG_RES[] =
+{
+ { NC_("SID_FILTER_DLG_RES", "Load/Save"), 0 },
+ { NC_("SID_FILTER_DLG_RES", "General"), RID_SFXPAGE_SAVE },
+ { NC_("SID_FILTER_DLG_RES", "VBA Properties"), SID_OPTFILTER_MSOFFICE },
+ { NC_("SID_FILTER_DLG_RES", "Microsoft Office"), RID_OFAPAGE_MSFILTEROPT2 },
+ { NC_("SID_FILTER_DLG_RES", "HTML Compatibility"), RID_OFAPAGE_HTMLOPT }
+};
+
+const std::pair<TranslateId, sal_uInt16> SID_SB_STARBASEOPTIONS_RES[] =
+{
+ { NC_("SID_SB_STARBASEOPTIONS_RES", "%PRODUCTNAME Base"), 0 },
+ { NC_("SID_SB_STARBASEOPTIONS_RES", "Connections"), SID_SB_CONNECTIONPOOLING },
+ { NC_("SID_SB_STARBASEOPTIONS_RES", "Databases"), SID_SB_DBREGISTEROPTIONS }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/inc/twolines.hrc b/cui/inc/twolines.hrc
new file mode 100644
index 000000000..659efa838
--- /dev/null
+++ b/cui/inc/twolines.hrc
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <unotools/resmgr.hxx>
+
+#include <utility>
+
+#define NC_(Context, String) TranslateId(Context, reinterpret_cast<char const *>(u8##String))
+
+#define CHRDLG_ENCLOSE_NONE 0
+#define CHRDLG_ENCLOSE_ROUND 1
+#define CHRDLG_ENCLOSE_SQUARE 2
+#define CHRDLG_ENCLOSE_POINTED 3
+#define CHRDLG_ENCLOSE_CURVED 4
+#define CHRDLG_ENCLOSE_SPECIAL_CHAR 5
+
+const std::pair<TranslateId, sal_uInt16> TWOLINE_OPEN[] =
+{
+ { NC_("twolinespage|liststore1", "(None)"), CHRDLG_ENCLOSE_NONE },
+ { NC_("twolinespage|liststore1", "("), CHRDLG_ENCLOSE_ROUND },
+ { NC_("twolinespage|liststore1", "["), CHRDLG_ENCLOSE_SQUARE },
+ { NC_("twolinespage|liststore1", "<"), CHRDLG_ENCLOSE_POINTED },
+ { NC_("twolinespage|liststore1", "{"), CHRDLG_ENCLOSE_CURVED },
+ { NC_("twolinespage|liststore1", "Other Characters..."), CHRDLG_ENCLOSE_SPECIAL_CHAR }
+};
+
+const std::pair<TranslateId, sal_uInt16> TWOLINE_CLOSE[] =
+{
+ { NC_("twolinespage|liststore2", "(None)"), CHRDLG_ENCLOSE_NONE },
+ { NC_("twolinespage|liststore2", ")"), CHRDLG_ENCLOSE_ROUND },
+ { NC_("twolinespage|liststore2", "]"), CHRDLG_ENCLOSE_SQUARE },
+ { NC_("twolinespage|liststore2", ">"), CHRDLG_ENCLOSE_POINTED },
+ { NC_("twolinespage|liststore2", "}"), CHRDLG_ENCLOSE_CURVED },
+ { NC_("twolinespage|liststore2", "Other Characters..."), CHRDLG_ENCLOSE_SPECIAL_CHAR }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/qa/uitest/dialogs/chardlg.py b/cui/qa/uitest/dialogs/chardlg.py
new file mode 100644
index 000000000..c52664f36
--- /dev/null
+++ b/cui/qa/uitest/dialogs/chardlg.py
@@ -0,0 +1,167 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+from uitest.uihelper.common import get_state_as_dict
+from uitest.uihelper.common import select_by_text
+
+# Test for cui/source/tabpages/chardlg.cxx.
+class Test(UITestCase):
+
+ def testSvxCharEffectsPage(self):
+ # Start Impress.
+ with self.ui_test.create_doc_in_start_center("impress") as component:
+ template = self.xUITest.getTopFocusWindow()
+ self.ui_test.close_dialog_through_button(template.getChild("close"))
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("impress_win")
+ # Select the title shape.
+ editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
+ editWin.executeAction("TYPE", mkPropertyValues({"TEXT": "t"}))
+ self.xUITest.executeCommand(".uno:SelectAll")
+
+ # Now use Format -> Character.
+ with self.ui_test.execute_dialog_through_command(".uno:FontDialog") as xDialog:
+ xTabs = xDialog.getChild("tabcontrol")
+ # Select RID_SVXPAGE_CHAR_EFFECTS.
+ select_pos(xTabs, "1")
+ xFontTransparency = xDialog.getChild("fonttransparencymtr")
+ for _ in range(5):
+ xFontTransparency.executeAction("UP", tuple())
+
+ # Verify the result.
+ drawPage = component.getDrawPages()[0]
+ shape = drawPage[0]
+
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 100 != 5
+ # i.e. the dialog did not set transparency to 5%, instead it left the character color at
+ # COL_AUTO.
+ self.assertEqual(shape.CharTransparence, 5)
+
+ def testSvxCharEffectsPageTheme(self):
+ # Given a document with a document theme:
+ # Start Impress.
+ with self.ui_test.create_doc_in_start_center("impress") as component:
+ template = self.xUITest.getTopFocusWindow()
+ self.ui_test.close_dialog_through_button(template.getChild("close"))
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("impress_win")
+
+ # Set theme colors.
+ drawPage = component.getDrawPages().getByIndex(0)
+ master = drawPage.MasterPage
+ theme = mkPropertyValues({
+ "Name": "nameA",
+ "ColorSchemeName": "colorSetA",
+ "ColorScheme": tuple([
+ 0x000000, # dk1
+ 0x000000, # lt1
+ 0x000000, # dk2
+ 0x000000, # lt2
+ 0x000000, # accent1
+ 0x000000, # accent2
+ 0x000000, # accent3
+ 0x000000, # accent4
+ 0x000000, # accent5
+ 0x000000, # accent6
+ 0x000000, # hlink
+ 0x000000, # folHlink
+ ])
+ })
+ master.Theme = theme
+
+ # Select the title shape.
+ editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
+ editWin.executeAction("TYPE", mkPropertyValues({"TEXT": "t"}))
+ self.xUITest.executeCommand(".uno:SelectAll")
+
+ # Now use Format -> Character.
+ with self.ui_test.execute_dialog_through_command(".uno:FontDialog") as xDialog:
+ xTabs = xDialog.getChild("tabcontrol")
+ # Select RID_SVXPAGE_CHAR_EFFECTS.
+ select_pos(xTabs, "1")
+
+ # When setting the shape text color to accent 1:
+ accent1 = xDialog.getChild("fontcolorlb")
+ accent1.executeAction("OPENLIST", tuple())
+ floatWindow = self.xUITest.getFloatWindow()
+ paletteSelector = floatWindow.getChild("palette_listbox")
+ select_by_text(paletteSelector, "Theme colors")
+ colorSet = floatWindow.getChild("colorset")
+ # 4 would be accent1, +12 is the first from the effect variants.
+ colorSet.executeAction("CHOOSE", mkPropertyValues({"POS": "16"}))
+
+ # Then make sure the doc model has the correct color theme index:
+ drawPage = component.getDrawPages().getByIndex(0)
+ shape = drawPage.getByIndex(0)
+ paragraphs = shape.createEnumeration()
+ paragraph = paragraphs.nextElement()
+ portions = paragraph.createEnumeration()
+ portion = portions.nextElement()
+
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: -1 != 4
+ # i.e. no theme index was set, instead of accent1 (index into the above color scheme).
+ self.assertEqual(portion.CharColorTheme, 4)
+
+ # Then make sure that '80% lighter' is lum-mod=2000 and lum-off=8000:
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 10000 != 2000
+ # i.e. the effects where not applied, luminance modulation was the default instead of a
+ # custom value.
+ self.assertEqual(portion.CharColorLumMod, 2000)
+ self.assertEqual(portion.CharColorLumOff, 8000)
+
+ def testSvxCharEffectsPageWriter(self):
+ # Start Writer.
+ with self.ui_test.create_doc_in_start_center("writer") as component:
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("writer_edit")
+ # Type a character and select it.
+ editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
+ editWin.executeAction("TYPE", mkPropertyValues({"TEXT": "t"}))
+ self.xUITest.executeCommand(".uno:SelectAll")
+
+ # Now use Format -> Character.
+ with self.ui_test.execute_dialog_through_command(".uno:FontDialog") as xDialog:
+ xTabs = xDialog.getChild("tabcontrol")
+ # Select RID_SVXPAGE_CHAR_EFFECTS.
+ select_pos(xTabs, "1")
+ xFontTransparency = xDialog.getChild("fonttransparencymtr")
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 'false' != 'true'
+ # i.e. the transparency widget was hidden.
+ self.assertEqual(get_state_as_dict(xFontTransparency)["Visible"], "true")
+ for _ in range(5):
+ xFontTransparency.executeAction("UP", tuple())
+
+ # Verify the result.
+ paragraph = component.Text.createEnumeration().nextElement()
+
+ self.assertEqual(paragraph.CharTransparence, 5)
+
+ def testSvxCharEffectsPageWriterAutomatic(self):
+ # Start Writer.
+ with self.ui_test.create_doc_in_start_center("writer"):
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("writer_edit")
+
+ # Use Format -> Character.
+ with self.ui_test.execute_dialog_through_command(".uno:FontDialog") as xDialog:
+ xTabs = xDialog.getChild("tabcontrol")
+ # Select RID_SVXPAGE_CHAR_EFFECTS.
+ select_pos(xTabs, "1")
+ xFontColorLB = xDialog.getChild("fontcolorlb")
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 'White' != 'Automatic'
+ # i.e. the auto color lost its alpha component and appeared as white.
+ self.assertEqual(get_state_as_dict(xFontColorLB)["Text"], "Automatic")
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/qa/uitest/dialogs/pastedlg.py b/cui/qa/uitest/dialogs/pastedlg.py
new file mode 100644
index 000000000..50a39d232
--- /dev/null
+++ b/cui/qa/uitest/dialogs/pastedlg.py
@@ -0,0 +1,43 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+
+
+# Test for SvPasteObjectDialog.
+class Test(UITestCase):
+
+ def testGetFormat(self):
+ # Copy a string in Impress.
+ with self.ui_test.create_doc_in_start_center("impress"):
+ template = self.xUITest.getTopFocusWindow()
+ self.ui_test.close_dialog_through_button(template.getChild("close"))
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("impress_win")
+ # Select the title shape.
+ editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
+ editWin.executeAction("TYPE", mkPropertyValues({"TEXT": "t"}))
+ self.xUITest.executeCommand(".uno:SelectAll")
+ self.xUITest.executeCommand(".uno:Copy")
+
+ # Now use paste special to see what formats are offered.
+ with self.ui_test.execute_dialog_through_command(".uno:PasteSpecial", close_button="cancel") as pasteSpecial:
+ formats = pasteSpecial.getChild("list")
+ entryCount = int(get_state_as_dict(formats)["Children"])
+ items = []
+ for index in range(entryCount):
+ entry = formats.getChild(str(index))
+ entry.executeAction("SELECT", tuple())
+ items.append(get_state_as_dict(formats)["SelectEntryText"])
+
+ # Make sure there is no RTF vs Richtext duplication.
+ self.assertTrue("Rich text formatting (RTF)" in items)
+ self.assertFalse("Rich text formatting (Richtext)" in items)
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/qa/uitest/dialogs/shortcuts.py b/cui/qa/uitest/dialogs/shortcuts.py
new file mode 100644
index 000000000..99d2bd1cc
--- /dev/null
+++ b/cui/qa/uitest/dialogs/shortcuts.py
@@ -0,0 +1,39 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.uihelper.common import get_state_as_dict
+
+class Test(UITestCase):
+
+ def test_tab_navigation(self):
+ with self.ui_test.create_doc_in_start_center("writer"):
+ xWriterDoc = self.xUITest.getTopFocusWindow()
+ xWriterEdit = xWriterDoc.getChild("writer_edit")
+
+ with self.ui_test.execute_dialog_through_command(".uno:EditStyle") as xDialog:
+
+ xTabs = xDialog.getChild("tabcontrol")
+ select_pos(xTabs, "0")
+
+ for i in range(16):
+ self.assertEqual(get_state_as_dict(xTabs)["CurrPagePos"], str(i))
+
+ xTabs.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+PAGEDOWN"}))
+
+ self.assertEqual(get_state_as_dict(xTabs)["CurrPagePos"], "0")
+
+ for i in reversed(range(16)):
+ xTabs.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+PAGEUP"}))
+
+ self.assertEqual(get_state_as_dict(xTabs)["CurrPagePos"], str(i))
+
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/qa/uitest/tabpages/themepage.py b/cui/qa/uitest/tabpages/themepage.py
new file mode 100644
index 000000000..f85af965f
--- /dev/null
+++ b/cui/qa/uitest/tabpages/themepage.py
@@ -0,0 +1,87 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from libreoffice.uno.propertyvalue import convert_property_values_to_dict
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+from uitest.uihelper.common import select_pos
+from uitest.uihelper.common import select_by_text
+
+# Test for cui/source/tabpages/themepage.cxx.
+class Test(UITestCase):
+
+ def testThemePage(self):
+ # Given an Impress document with a master page that has a theme:
+ with self.ui_test.create_doc_in_start_center("impress") as component:
+ template = self.xUITest.getTopFocusWindow()
+ self.ui_test.close_dialog_through_button(template.getChild("close"))
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("impress_win")
+ drawPage = component.getDrawPages().getByIndex(0)
+ master = drawPage.MasterPage
+ theme = mkPropertyValues({
+ "Name": "nameA",
+ "ColorSchemeName": "colorSetA",
+ "ColorScheme": tuple([
+ 0x000000, # dk1
+ 0x000000, # lt1
+ 0x000000, # dk2
+ 0x000000, # lt2
+ 0x0000ff, # accent1
+ 0x000000, # accent2
+ 0x000000, # accent3
+ 0x000000, # accent4
+ 0x000000, # accent5
+ 0x000000, # accent6
+ 0x000000, # hlink
+ 0x000000, # folHlink
+ ])
+ })
+ master.Theme = theme
+
+ # When changing the name of the theme:
+ self.xUITest.executeCommand(".uno:SlideMasterPage")
+ with self.ui_test.execute_dialog_through_command(".uno:PageSetup") as xDialog:
+ xTabs = xDialog.getChild("tabcontrol")
+ # Select RID_SVXPAGE_THEME.
+ select_pos(xTabs, "3")
+ themeName = xDialog.getChild("themeName")
+ themeName.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
+ themeName.executeAction("TYPE", mkPropertyValues({"KEYCODE":"BACKSPACE"}))
+ themeName.executeAction("TYPE", mkPropertyValues({"TEXT": "nameB"}))
+ colorSetName = xDialog.getChild("colorSetName")
+ colorSetName.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
+ colorSetName.executeAction("TYPE", mkPropertyValues({"KEYCODE":"BACKSPACE"}))
+ colorSetName.executeAction("TYPE", mkPropertyValues({"TEXT": "colorSetB"}))
+
+ # Select a custom accent1 color.
+ accent1 = xDialog.getChild("btnAccent1")
+ accent1.executeAction("OPENLIST", tuple())
+ floatWindow = self.xUITest.getFloatWindow()
+ paletteSelector = floatWindow.getChild("palette_listbox")
+ select_by_text(paletteSelector, "chart-palettes")
+ colorSet = floatWindow.getChild("colorset")
+ colorSet.executeAction("CHOOSE", mkPropertyValues({"POS": "2"}))
+
+ # Then make sure the doc model is updated accordingly:
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 'nameA' != 'nameB'
+ # i.e. the UI didn't update the theme name.
+ theme = convert_property_values_to_dict(master.Theme)
+ self.assertEqual(theme["Name"], "nameB")
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 'colorSetA' != 'colorSetB'
+ # i.e. the UI didn't update the color scheme name.
+ self.assertEqual(theme["ColorSchemeName"], "colorSetB")
+ colorSet = theme["ColorScheme"]
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: 0 != 16728590 (#ff420e)
+ # i.e. the UI didn't update the accent1 color from black to a custom value.
+ self.assertEqual(colorSet[4], 0xff420e)
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/qa/uitest/tabpages/tpcolor.py b/cui/qa/uitest/tabpages/tpcolor.py
new file mode 100644
index 000000000..e6ae91ada
--- /dev/null
+++ b/cui/qa/uitest/tabpages/tpcolor.py
@@ -0,0 +1,69 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import select_pos
+from uitest.uihelper.common import select_by_text
+
+
+# Test for cui/source/tabpages/tpcolor.cxx.
+class Test(UITestCase):
+
+ def testSvxColorTabPageTheme(self):
+ # Given an Impress document with a theme:
+ with self.ui_test.create_doc_in_start_center("impress") as component:
+ template = self.xUITest.getTopFocusWindow()
+ self.ui_test.close_dialog_through_button(template.getChild("close"))
+ doc = self.xUITest.getTopFocusWindow()
+ editWin = doc.getChild("impress_win")
+ # Set theme colors.
+ drawPage = component.getDrawPages().getByIndex(0)
+ master = drawPage.MasterPage
+ theme = mkPropertyValues({
+ "Name": "nameA",
+ "ColorSchemeName": "colorSetA",
+ "ColorScheme": tuple([
+ 0x000000, # dk1
+ 0x000000, # lt1
+ 0x000000, # dk2
+ 0x000000, # lt2
+ 0x0000ff, # accent1
+ 0x000000, # accent2
+ 0x000000, # accent3
+ 0x000000, # accent4
+ 0x000000, # accent5
+ 0x000000, # accent6
+ 0x000000, # hlink
+ 0x000000, # folHlink
+ ])
+ })
+ master.Theme = theme
+ # Select the title shape.
+ editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
+
+ # When using right click -> Area to refer to a theme for shape fill:
+ with self.ui_test.execute_dialog_through_command(".uno:FormatArea") as xDialog:
+ tabControl = xDialog.getChild("tabcontrol")
+ # Area
+ select_pos(tabControl, "0")
+ # Color
+ btnColor = xDialog.getChild("btncolor")
+ btnColor.executeAction("CLICK", tuple())
+ paletteSelector = xDialog.getChild("paletteselector")
+ select_by_text(paletteSelector, "Theme colors")
+ colorSelector = xDialog.getChild("colorset")
+ colorSelector.executeAction("CHOOSE", mkPropertyValues({"POS": "4"}))
+
+ # Then make sure the doc model is updated accordingly:
+ shape = drawPage.getByIndex(0)
+ # Without the accompanying fix in place, this test would have failed with:
+ # AssertionError: -1 != 4
+ # i.e. the theme metadata of the selected fill color was lost.
+ self.assertEqual(shape.FillColorTheme, 4)
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/cui/qa/unit/cui-dialogs-test.cxx b/cui/qa/unit/cui-dialogs-test.cxx
new file mode 100644
index 000000000..f4f73facb
--- /dev/null
+++ b/cui/qa/unit/cui-dialogs-test.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <test/screenshot_test.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svxdlg.hxx>
+#include <vcl/abstdlg.hxx>
+
+using namespace ::com::sun::star;
+
+/// Test opening a dialog in cui
+class CuiDialogsTest : public ScreenshotTest
+{
+private:
+ std::unique_ptr<SdrModel> mxModel;
+ std::unique_ptr<SfxItemSet> mxAttr;
+ SvxAbstractDialogFactory* mpFact;
+
+ void initialize();
+
+ /// helper method to populate KnownDialogs, called in setUp(). Needs to be
+ /// written and has to add entries to KnownDialogs
+ virtual void registerKnownDialogsByID(mapType& rKnownDialogs) override;
+
+ /// dialog creation for known dialogs by ID. Has to be implemented for
+ /// each registered known dialog
+ virtual VclPtr<VclAbstractDialog> createDialogByID(sal_uInt32 nID) override;
+
+public:
+ CuiDialogsTest();
+
+ // try to open a dialog
+ void openAnyDialog();
+
+ CPPUNIT_TEST_SUITE(CuiDialogsTest);
+ CPPUNIT_TEST(openAnyDialog);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CuiDialogsTest::CuiDialogsTest() {}
+
+void CuiDialogsTest::initialize()
+{
+ mpFact = SvxAbstractDialogFactory::Create();
+ mxModel.reset(new SdrModel(nullptr, nullptr, true));
+ mxModel->GetItemPool().FreezeIdRanges();
+ mxAttr.reset(new SfxItemSet(mxModel->GetItemPool()));
+}
+
+void CuiDialogsTest::registerKnownDialogsByID(mapType& rKnownDialogs)
+{
+ // fill map of known dialogs
+ rKnownDialogs["cui/ui/formatcellsdialog.ui"] = 0;
+ rKnownDialogs["cui/ui/textdialog.ui"] = 1;
+}
+
+VclPtr<VclAbstractDialog> CuiDialogsTest::createDialogByID(sal_uInt32 nID)
+{
+ VclPtr<VclAbstractDialog> pReturnDialog;
+
+ switch (nID)
+ {
+ case 0: // "cui/ui/formatcellsdialog.ui"
+ {
+ pReturnDialog = mpFact->CreateSvxFormatCellsDialog(nullptr, mxAttr.get(), *mxModel);
+ break;
+ }
+
+ case 1: // "cui/ui/textdialog.ui"
+ {
+ pReturnDialog = mpFact->CreateTextTabDialog(nullptr, mxAttr.get(), nullptr);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return pReturnDialog;
+}
+
+void CuiDialogsTest::openAnyDialog()
+{
+ initialize();
+
+ /// process input file containing the UXMLDescriptions of the dialogs to dump
+ processDialogBatchFile(u"cui/qa/unit/data/cui-dialogs-test.txt");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CuiDialogsTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/qa/unit/cui-dialogs-test_2.cxx b/cui/qa/unit/cui-dialogs-test_2.cxx
new file mode 100644
index 000000000..5d98650fd
--- /dev/null
+++ b/cui/qa/unit/cui-dialogs-test_2.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <test/screenshot_test.hxx>
+#include <vcl/abstdlg.hxx>
+
+using namespace ::com::sun::star;
+
+/// Test opening a dialog in cui
+class CuiDialogsTest2 : public ScreenshotTest
+{
+private:
+ /// helper method to populate KnownDialogs, called in setUp(). Needs to be
+ /// written and has to add entries to KnownDialogs
+ virtual void registerKnownDialogsByID(mapType& rKnownDialogs) override;
+
+ /// dialog creation for known dialogs by ID. Has to be implemented for
+ /// each registered known dialog
+ virtual VclPtr<VclAbstractDialog> createDialogByID(sal_uInt32 nID) override;
+
+public:
+ CuiDialogsTest2();
+
+ // try to open a dialog
+ void openAnyDialog();
+
+ CPPUNIT_TEST_SUITE(CuiDialogsTest2);
+ CPPUNIT_TEST(openAnyDialog);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CuiDialogsTest2::CuiDialogsTest2() {}
+
+void CuiDialogsTest2::registerKnownDialogsByID(mapType& /*rKnownDialogs*/)
+{
+ // leave empty should be in CuiDialogTest if any
+}
+
+VclPtr<VclAbstractDialog> CuiDialogsTest2::createDialogByID(sal_uInt32 /*nID*/) { return nullptr; }
+
+void CuiDialogsTest2::openAnyDialog()
+{
+ /// process input file containing the UXMLDescriptions of the dialogs to dump
+ processDialogBatchFile(u"cui/qa/unit/data/cui-dialogs-test_2.txt");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CuiDialogsTest2);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/qa/unit/cui-dialogs-test_3.cxx b/cui/qa/unit/cui-dialogs-test_3.cxx
new file mode 100644
index 000000000..ebd194885
--- /dev/null
+++ b/cui/qa/unit/cui-dialogs-test_3.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <test/screenshot_test.hxx>
+#include <vcl/abstdlg.hxx>
+
+using namespace ::com::sun::star;
+
+/// Test opening a dialog in cui
+class CuiDialogsTest3 : public ScreenshotTest
+{
+private:
+ /// helper method to populate KnownDialogs, called in setUp(). Needs to be
+ /// written and has to add entries to KnownDialogs
+ virtual void registerKnownDialogsByID(mapType& rKnownDialogs) override;
+
+ /// dialog creation for known dialogs by ID. Has to be implemented for
+ /// each registered known dialog
+ virtual VclPtr<VclAbstractDialog> createDialogByID(sal_uInt32 nID) override;
+
+public:
+ CuiDialogsTest3();
+
+ // try to open a dialog
+ void openAnyDialog();
+
+ CPPUNIT_TEST_SUITE(CuiDialogsTest3);
+ CPPUNIT_TEST(openAnyDialog);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CuiDialogsTest3::CuiDialogsTest3() {}
+
+void CuiDialogsTest3::registerKnownDialogsByID(mapType& /*rKnownDialogs*/)
+{
+ // leave empty should be in CuiDialogTest if any
+}
+
+VclPtr<VclAbstractDialog> CuiDialogsTest3::createDialogByID(sal_uInt32 /*nID*/) { return nullptr; }
+
+void CuiDialogsTest3::openAnyDialog()
+{
+ /// process input file containing the UXMLDescriptions of the dialogs to dump
+ processDialogBatchFile(u"cui/qa/unit/data/cui-dialogs-test_3.txt");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CuiDialogsTest3);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/qa/unit/cui-dialogs-test_4.cxx b/cui/qa/unit/cui-dialogs-test_4.cxx
new file mode 100644
index 000000000..157ffa8b3
--- /dev/null
+++ b/cui/qa/unit/cui-dialogs-test_4.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <test/screenshot_test.hxx>
+#include <vcl/abstdlg.hxx>
+
+using namespace ::com::sun::star;
+
+/// Test opening a dialog in cui
+class CuiDialogsTest4 : public ScreenshotTest
+{
+private:
+ /// helper method to populate KnownDialogs, called in setUp(). Needs to be
+ /// written and has to add entries to KnownDialogs
+ virtual void registerKnownDialogsByID(mapType& rKnownDialogs) override;
+
+ /// dialog creation for known dialogs by ID. Has to be implemented for
+ /// each registered known dialog
+ virtual VclPtr<VclAbstractDialog> createDialogByID(sal_uInt32 nID) override;
+
+public:
+ CuiDialogsTest4();
+
+ // try to open a dialog
+ void openAnyDialog();
+
+ CPPUNIT_TEST_SUITE(CuiDialogsTest4);
+ CPPUNIT_TEST(openAnyDialog);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+CuiDialogsTest4::CuiDialogsTest4() {}
+
+void CuiDialogsTest4::registerKnownDialogsByID(mapType& /*rKnownDialogs*/)
+{
+ // leave empty should be in CuiDialogTest if any
+}
+
+VclPtr<VclAbstractDialog> CuiDialogsTest4::createDialogByID(sal_uInt32 /*nID*/) { return nullptr; }
+
+void CuiDialogsTest4::openAnyDialog()
+{
+ /// process input file containing the UXMLDescriptions of the dialogs to dump
+ processDialogBatchFile(u"cui/qa/unit/data/cui-dialogs-test_4.txt");
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CuiDialogsTest4);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/qa/unit/data/cui-dialogs-test.txt b/cui/qa/unit/data/cui-dialogs-test.txt
new file mode 100644
index 000000000..cb1760884
--- /dev/null
+++ b/cui/qa/unit/data/cui-dialogs-test.txt
@@ -0,0 +1,96 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# This file contains all dialogs that the unit tests in the module
+# will work on if it is in script mode. It will read one-by-one,
+# try to open it and create a screenshot that will be saved in
+# workdir/screenshots using the pattern of the ui-file name.
+#
+# Syntax:
+# - empty lines are allowed
+# - lines starting with '#' are treated as comment
+# - all other lines should contain a *.ui filename in the same
+# notation as in the dialog constructors (see code)
+
+#
+# The 'known' dialogs which have a hard-coded representation
+# in registerKnownDialogsByID/createDialogByID
+#
+
+cui/ui/formatcellsdialog.ui
+cui/ui/textdialog.ui
+
+#
+# Dialogs without a hard-coded representation. These will
+# be visualized using a fallback based on weld::Builder
+#
+
+# currently deactivated, leads to problems and the test to not work
+# This is typically a hint that these should be hard-coded in the
+# test case since they need some document and model data to work
+#
+# cui/ui/imagetabpage.ui
+# cui/ui/connpooloptions.ui <- not calling DriverListControl::Init for
+# ConnectionPoolOptionsPage::m_pDriverList leaves its BrowseBox::mvCols empty, causing "implicit
+# conversion from type 'int' of value -1 (32-bit, signed) to type 'sal_uInt16' (aka 'unsigned
+# short') changed the value to 65535 (16-bit, unsigned)" when calling
+# GetColumnId( static_cast<sal_uInt16>(mvCols.size()) - 1 );
+# in BrowseBox::AutoSizeLastColumn (svtools/source/brwbox/brwbox1.cxx) with Clang
+# -fsanitize=implicit-signed-integer-truncation
+# cui/ui/thesaurus.ui <- problems under Linux
+
+# this is part 1. in order to help the build time when building all
+# lang, the list of ui is split in multiple parts to balance the run time
+# or all the tests, which improve the overall elapsed time
+# of make screenshot on big machines
+# covering a to e
+
+
+cui/ui/aboutconfigdialog.ui
+cui/ui/aboutconfigvaluedialog.ui
+cui/ui/aboutdialog.ui
+cui/ui/accelconfigpage.ui
+cui/ui/acorexceptpage.ui
+cui/ui/acoroptionspage.ui
+cui/ui/acorreplacepage.ui
+cui/ui/agingdialog.ui
+cui/ui/applyautofmtpage.ui
+cui/ui/applylocalizedpage.ui
+cui/ui/areadialog.ui
+cui/ui/areatabpage.ui
+cui/ui/asiantypography.ui
+cui/ui/assigncomponentdialog.ui
+cui/ui/autocorrectdialog.ui
+cui/ui/baselinksdialog.ui
+cui/ui/borderareatransparencydialog.ui
+cui/ui/borderbackgrounddialog.ui
+cui/ui/borderpage.ui
+cui/ui/breaknumberoption.ui
+cui/ui/calloutdialog.ui
+cui/ui/calloutpage.ui
+cui/ui/cellalignment.ui
+cui/ui/certdialog.ui
+cui/ui/charnamepage.ui
+cui/ui/colorconfigwin.ui
+cui/ui/colorpage.ui
+cui/ui/colorpickerdialog.ui
+cui/ui/comment.ui
+cui/ui/connectortabpage.ui
+cui/ui/croppage.ui
+cui/ui/cuiimapdlg.ui
+cui/ui/customizedialog.ui
+cui/ui/databaselinkdialog.ui
+cui/ui/dbregisterpage.ui
+cui/ui/dimensionlinestabpage.ui
+cui/ui/editdictionarydialog.ui
+cui/ui/editmodulesdialog.ui
+cui/ui/effectspage.ui
+cui/ui/embossdialog.ui
+cui/ui/eventassigndialog.ui
+cui/ui/eventassignpage.ui
diff --git a/cui/qa/unit/data/cui-dialogs-test_2.txt b/cui/qa/unit/data/cui-dialogs-test_2.txt
new file mode 100644
index 000000000..bccb00563
--- /dev/null
+++ b/cui/qa/unit/data/cui-dialogs-test_2.txt
@@ -0,0 +1,61 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# See cui-dialogs-test.txt for explanations
+
+# covering f to n
+
+cui/ui/eventsconfigpage.ui
+cui/ui/fmsearchdialog.ui
+cui/ui/galleryapplyprogress.ui
+cui/ui/galleryfilespage.ui
+cui/ui/gallerygeneralpage.ui
+cui/ui/gallerysearchprogress.ui
+cui/ui/gallerythemedialog.ui
+cui/ui/gallerythemeiddialog.ui
+cui/ui/gallerytitledialog.ui
+cui/ui/galleryupdateprogress.ui
+cui/ui/gradientpage.ui
+cui/ui/hangulhanjaadddialog.ui
+cui/ui/hangulhanjaconversiondialog.ui
+cui/ui/hangulhanjaeditdictdialog.ui
+cui/ui/hangulhanjaoptdialog.ui
+cui/ui/hatchpage.ui
+cui/ui/hyperlinkdialog.ui
+cui/ui/hyperlinkdocpage.ui
+cui/ui/hyperlinkinternetpage.ui
+cui/ui/hyperlinkmailpage.ui
+cui/ui/hyperlinkmarkdialog.ui
+cui/ui/hyperlinknewdocpage.ui
+cui/ui/hyphenate.ui
+cui/ui/iconchangedialog.ui
+cui/ui/iconselectordialog.ui
+cui/ui/insertfloatingframe.ui
+cui/ui/insertoleobject.ui
+cui/ui/insertrowcolumn.ui
+cui/ui/javaclasspathdialog.ui
+cui/ui/javastartparametersdialog.ui
+cui/ui/linedialog.ui
+cui/ui/lineendstabpage.ui
+cui/ui/linestyletabpage.ui
+cui/ui/linetabpage.ui
+cui/ui/macroassigndialog.ui
+cui/ui/macroassignpage.ui
+cui/ui/macroselectordialog.ui
+cui/ui/menuassignpage.ui
+cui/ui/mosaicdialog.ui
+cui/ui/movemenu.ui
+cui/ui/multipathdialog.ui
+cui/ui/namedialog.ui
+cui/ui/newlibdialog.ui
+cui/ui/newtabledialog.ui
+cui/ui/newtoolbardialog.ui
+cui/ui/numberingformatpage.ui
+cui/ui/numberingoptionspage.ui
+cui/ui/numberingpositionpage.ui
diff --git a/cui/qa/unit/data/cui-dialogs-test_3.txt b/cui/qa/unit/data/cui-dialogs-test_3.txt
new file mode 100644
index 000000000..f2f0491ff
--- /dev/null
+++ b/cui/qa/unit/data/cui-dialogs-test_3.txt
@@ -0,0 +1,43 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# See cui-dialogs-test.txt for explanations
+
+# covering o
+
+cui/ui/objectnamedialog.ui
+cui/ui/objecttitledescdialog.ui
+cui/ui/optaccessibilitypage.ui
+cui/ui/optadvancedpage.ui
+cui/ui/optappearancepage.ui
+cui/ui/optasianpage.ui
+cui/ui/optbasicidepage.ui
+cui/ui/optchartcolorspage.ui
+cui/ui/optctlpage.ui
+cui/ui/optemailpage.ui
+cui/ui/optfltrembedpage.ui
+cui/ui/optfltrpage.ui
+cui/ui/optfontspage.ui
+cui/ui/optgeneralpage.ui
+cui/ui/opthtmlpage.ui
+cui/ui/optionsdialog.ui
+cui/ui/optionsdialog.ui
+cui/ui/optjsearchpage.ui
+cui/ui/optlanguagespage.ui
+cui/ui/optlingupage.ui
+cui/ui/optnewdictionarydialog.ui
+cui/ui/optonlineupdatepage.ui
+cui/ui/optopenclpage.ui
+cui/ui/optpathspage.ui
+cui/ui/optproxypage.ui
+cui/ui/optsavepage.ui
+cui/ui/optsecuritypage.ui
+cui/ui/optuserpage.ui
+cui/ui/optviewpage.ui
+
diff --git a/cui/qa/unit/data/cui-dialogs-test_4.txt b/cui/qa/unit/data/cui-dialogs-test_4.txt
new file mode 100644
index 000000000..a537b2b09
--- /dev/null
+++ b/cui/qa/unit/data/cui-dialogs-test_4.txt
@@ -0,0 +1,72 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+# See cui-dialogs-test.txt for explanations
+
+# covering p to z
+
+cui/ui/pageformatpage.ui
+cui/ui/paragalignpage.ui
+cui/ui/paraindentspacing.ui
+cui/ui/paratabspage.ui
+cui/ui/password.ui
+cui/ui/pastespecial.ui
+cui/ui/percentdialog.ui
+cui/ui/personalization_tab.ui
+cui/ui/pickbulletpage.ui
+cui/ui/pickgraphicpage.ui
+cui/ui/picknumberingpage.ui
+cui/ui/pickoutlinepage.ui
+cui/ui/positionpage.ui
+cui/ui/positionsizedialog.ui
+cui/ui/possizetabpage.ui
+cui/ui/posterdialog.ui
+cui/ui/querychangelineenddialog.ui
+cui/ui/querydeletebitmapdialog.ui
+cui/ui/querydeletechartcolordialog.ui
+cui/ui/querydeletecolordialog.ui
+cui/ui/querydeletedictionarydialog.ui
+cui/ui/querydeletegradientdialog.ui
+cui/ui/querydeletehatchdialog.ui
+cui/ui/querydeletelineenddialog.ui
+cui/ui/querydeletelinestyledialog.ui
+cui/ui/queryduplicatedialog.ui
+cui/ui/querynoloadedfiledialog.ui
+cui/ui/querynosavefiledialog.ui
+cui/ui/querysavelistdialog.ui
+cui/ui/queryupdategalleryfilelistdialog.ui
+cui/ui/recordnumberdialog.ui
+cui/ui/rotationtabpage.ui
+cui/ui/scriptorganizer.ui
+cui/ui/searchattrdialog.ui
+cui/ui/searchformatdialog.ui
+cui/ui/securityoptionsdialog.ui
+cui/ui/selectpathdialog.ui
+cui/ui/shadowtabpage.ui
+cui/ui/showcoldialog.ui
+cui/ui/similaritysearchdialog.ui
+cui/ui/slantcornertabpage.ui
+cui/ui/smarttagoptionspage.ui
+cui/ui/smoothdialog.ui
+cui/ui/solarizedialog.ui
+cui/ui/specialcharacters.ui
+cui/ui/spellingdialog.ui
+cui/ui/spelloptionsdialog.ui
+cui/ui/splitcellsdialog.ui
+cui/ui/storedwebconnectiondialog.ui
+cui/ui/swpossizepage.ui
+cui/ui/textanimtabpage.ui
+cui/ui/textattrtabpage.ui
+cui/ui/textflowpage.ui
+cui/ui/transparencytabpage.ui
+cui/ui/tsaurldialog.ui
+cui/ui/twolinespage.ui
+cui/ui/wordcompletionpage.ui
+cui/ui/zoomdialog.ui
+
diff --git a/cui/source/customize/CommandCategoryListBox.cxx b/cui/source/customize/CommandCategoryListBox.cxx
new file mode 100644
index 000000000..f6b34076f
--- /dev/null
+++ b/cui/source/customize/CommandCategoryListBox.cxx
@@ -0,0 +1,607 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <CommandCategoryListBox.hxx>
+
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/ui/theUICategoryDescription.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+// include search util
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <tools/diagnose_ex.h>
+#include <unotools/textsearch.hxx>
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <comphelper/string.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nutil/searchopt.hxx>
+#include <sal/log.hxx>
+
+#include <cfg.hxx> //for SaveInData
+
+CommandCategoryListBox::CommandCategoryListBox(std::unique_ptr<weld::ComboBox> xControl)
+ : pStylesInfo(nullptr)
+ , m_xControl(std::move(xControl))
+{
+ //Initialize search util
+ m_searchOptions.AlgorithmType2 = css::util::SearchAlgorithms2::ABSOLUTE;
+ m_searchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_searchOptions.searchFlag |= (css::util::SearchFlags::REG_NOT_BEGINOFLINE
+ | css::util::SearchFlags::REG_NOT_ENDOFLINE);
+}
+
+CommandCategoryListBox::~CommandCategoryListBox() { ClearAll(); }
+
+void CommandCategoryListBox::ClearAll()
+{
+ // Clear objects from m_aGroupInfo vector to avoid memory leak
+ for (const auto& It : m_aGroupInfo)
+ {
+ if (It->nKind == SfxCfgKind::GROUP_STYLES && It->pObject)
+ {
+ SfxStyleInfo_Impl* pStyle = static_cast<SfxStyleInfo_Impl*>(It->pObject);
+ delete pStyle;
+ }
+ else if (It->nKind == SfxCfgKind::FUNCTION_SCRIPT && It->pObject)
+ {
+ OUString* pScriptURI = static_cast<OUString*>(It->pObject);
+ delete pScriptURI;
+ }
+ else if (It->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER && It->pObject)
+ {
+ css::uno::XInterface* xi = static_cast<css::uno::XInterface*>(It->pObject);
+ if (xi != nullptr)
+ {
+ xi->release();
+ }
+ }
+ }
+
+ m_aGroupInfo.clear();
+ m_xControl->clear();
+}
+
+void CommandCategoryListBox::Init(const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::frame::XFrame>& xFrame,
+ const OUString& sModuleLongName)
+{
+ // User will not see incomplete UI
+ m_xControl->freeze();
+ ClearAll();
+
+ m_xContext = xContext;
+ m_xFrame = xFrame;
+
+ m_sModuleLongName = sModuleLongName;
+ m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get(m_xContext);
+ m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName),
+ css::uno::UNO_QUERY_THROW);
+ m_xUICmdDescription = css::frame::theUICommandDescription::get(m_xContext);
+
+ // Support style commands
+ css::uno::Reference<css::frame::XController> xController;
+ css::uno::Reference<css::frame::XModel> xModel;
+ if (xFrame.is())
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+
+ m_aStylesInfo.init(sModuleLongName, xModel);
+ SetStylesInfo(&m_aStylesInfo);
+
+ try
+ {
+ css::uno::Reference<css::frame::XDispatchInformationProvider> xProvider(
+ m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence<sal_Int16> lGroups = xProvider->getSupportedCommandGroups();
+
+ sal_Int32 nGroupsLength = lGroups.getLength();
+
+ if (nGroupsLength > 0)
+ {
+ // Add the category of "All commands"
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_ALLFUNCTIONS, 0));
+ m_xControl->append(weld::toId(m_aGroupInfo.back().get()),
+ CuiResId(RID_CUISTR_ALLFUNCTIONS));
+ }
+
+ // Separate the "All commands"category from the actual categories
+ m_xControl->append_separator("");
+
+ typedef std::pair<OUString, sal_Int16> str_id;
+ std::vector<str_id> aCategories;
+
+ // Add the actual categories
+ for (sal_Int32 i = 0; i < nGroupsLength; ++i)
+ {
+ sal_Int16 nGroupID = lGroups[i];
+ OUString sGroupID = OUString::number(nGroupID);
+ OUString sGroupName;
+
+ try
+ {
+ m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
+ if (sGroupName.isEmpty())
+ continue;
+ }
+ catch (const css::container::NoSuchElementException&)
+ {
+ continue;
+ }
+ aCategories.emplace_back(std::make_pair(sGroupName, nGroupID));
+ }
+
+ auto const sort = comphelper::string::NaturalStringSorter(
+ comphelper::getProcessComponentContext(),
+ Application::GetSettings().GetUILanguageTag().getLocale());
+
+ std::sort(aCategories.begin(), aCategories.end(),
+ [&sort](const str_id& a, const str_id& b) {
+ return sort.compare(a.first, b.first) < 0;
+ });
+
+ // Add the actual categories
+ for (const auto& a : aCategories)
+ {
+ const OUString& rGroupName = a.first;
+ sal_Int16 nGroupID = a.second;
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_FUNCTION, nGroupID));
+ m_xControl->append(weld::toId(m_aGroupInfo.back().get()), rGroupName);
+ }
+
+ // Separate regular commands from styles and macros
+ m_xControl->append_separator("");
+
+ // Add macros category
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, nullptr));
+ m_xControl->append(weld::toId(m_aGroupInfo.back().get()), CuiResId(RID_CUISTR_MACROS));
+
+ // Add styles category
+ //TODO: last param should contain user data?
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0, nullptr));
+ m_xControl->append(weld::toId(m_aGroupInfo.back().get()),
+ CuiResId(RID_CUISTR_GROUP_STYLES));
+ }
+ catch (const css::uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const css::uno::Exception&)
+ {
+ }
+
+ // Reveal the updated UI to user
+ m_xControl->thaw();
+ m_xControl->set_active(0);
+}
+
+void CommandCategoryListBox::FillFunctionsList(
+ const css::uno::Sequence<css::frame::DispatchInformation>& xCommands,
+ CuiConfigFunctionListBox* pFunctionListBox, const OUString& filterTerm,
+ SaveInData* pCurrentSaveInData)
+{
+ // Setup search filter parameters
+ m_searchOptions.searchString = filterTerm;
+ utl::TextSearch textSearch(m_searchOptions);
+ const bool bInExperimentalMode = officecfg::Office::Common::Misc::ExperimentalMode::get();
+
+ for (const auto& rInfo : xCommands)
+ {
+ auto aProperties
+ = vcl::CommandInfoProvider::GetCommandProperties(rInfo.Command, m_sModuleLongName);
+
+ OUString sUIName = getCommandName(rInfo.Command);
+ OUString sLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+ OUString sTooltipLabel
+ = vcl::CommandInfoProvider::GetTooltipForCommand(rInfo.Command, aProperties, m_xFrame);
+ OUString sPopupLabel = (vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties))
+ .replaceFirst("~", "");
+ bool bIsExperimental
+ = vcl::CommandInfoProvider::IsExperimental(rInfo.Command, m_sModuleLongName);
+
+ // Hide experimental commands when not in experimental mode
+ bool bHideExperimental = bIsExperimental && !bInExperimentalMode;
+
+ // Apply the search filter
+ if (bHideExperimental
+ || (!filterTerm.isEmpty() && !textSearch.searchForward(sUIName)
+ && !textSearch.searchForward(sLabel) && !textSearch.searchForward(sTooltipLabel)
+ && !textSearch.searchForward(sPopupLabel)))
+ {
+ continue;
+ }
+
+ css::uno::Reference<css::graphic::XGraphic> xImage;
+ if (pCurrentSaveInData)
+ xImage = pCurrentSaveInData->GetImage(rInfo.Command);
+
+ m_aGroupInfo.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::FUNCTION_SLOT, 0));
+ SfxGroupInfo_Impl* pGrpInfo = m_aGroupInfo.back().get();
+ pGrpInfo->sCommand = rInfo.Command;
+ pGrpInfo->sLabel = sUIName;
+ pGrpInfo->sTooltip = sTooltipLabel;
+ pFunctionListBox->append(weld::toId(m_aGroupInfo.back().get()), sUIName, xImage);
+ }
+}
+
+OUString CommandCategoryListBox::getCommandName(const OUString& sCommand)
+{
+ OUString sUIName;
+ try
+ {
+ css::uno::Reference<css::container::XNameAccess> xModuleConf;
+ m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
+ if (xModuleConf.is())
+ {
+ ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
+ sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
+ }
+ }
+ catch (const css::uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (css::uno::Exception&)
+ {
+ sUIName.clear();
+ }
+
+ // fallback for missing UINames !?
+ if (sUIName.isEmpty())
+ {
+ sUIName = sCommand;
+ }
+
+ return sUIName;
+}
+
+void CommandCategoryListBox::categorySelected(CuiConfigFunctionListBox* pFunctionListBox,
+ const OUString& filterTerm,
+ SaveInData* pCurrentSaveInData)
+{
+ SfxGroupInfo_Impl* pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xControl->get_active_id());
+ std::vector<std::unique_ptr<weld::TreeIter>> aNodesToExpand;
+ pFunctionListBox->freeze();
+ pFunctionListBox->ClearAll();
+
+ switch (pInfo->nKind)
+ {
+ case SfxCfgKind::GROUP_ALLFUNCTIONS:
+ {
+ css::uno::Reference<css::frame::XDispatchInformationProvider> xProvider(
+ m_xFrame, css::uno::UNO_QUERY);
+ sal_Int32 nEntryCount = m_xControl->get_count();
+
+ for (sal_Int32 nCurPos = 0; nCurPos < nEntryCount; ++nCurPos)
+ {
+ SfxGroupInfo_Impl* pCurrentInfo
+ = weld::fromId<SfxGroupInfo_Impl*>(m_xControl->get_id(nCurPos));
+
+ if (!pCurrentInfo) //separator
+ continue;
+
+ if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
+ {
+ css::uno::Sequence<css::frame::DispatchInformation> lCommands;
+ try
+ {
+ lCommands = xProvider->getConfigurableDispatchInformation(
+ pCurrentInfo->nUniqueID);
+ FillFunctionsList(lCommands, pFunctionListBox, filterTerm,
+ pCurrentSaveInData);
+ }
+ catch (css::container::NoSuchElementException&)
+ {
+ }
+ }
+ }
+
+ break;
+ }
+ case SfxCfgKind::GROUP_FUNCTION:
+ {
+ sal_uInt16 nGroup = pInfo->nUniqueID;
+ css::uno::Reference<css::frame::XDispatchInformationProvider> xProvider(
+ m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence<css::frame::DispatchInformation> lCommands
+ = xProvider->getConfigurableDispatchInformation(nGroup);
+ FillFunctionsList(lCommands, pFunctionListBox, filterTerm, pCurrentSaveInData);
+ break;
+ }
+ case SfxCfgKind::GROUP_SCRIPTCONTAINER: //Macros
+ {
+ SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
+ // Add Scripting Framework entries
+ css::uno::Reference<css::script::browse::XBrowseNode> rootNode;
+ try
+ {
+ css::uno::Reference<css::script::browse::XBrowseNodeFactory> xFac
+ = css::script::browse::theBrowseNodeFactory::get(m_xContext);
+ rootNode.set(xFac->createView(
+ css::script::browse::BrowseNodeFactoryViewTypes::MACROSELECTOR));
+ }
+ catch (css::uno::Exception const&)
+ {
+ TOOLS_WARN_EXCEPTION(
+ "cui.customize",
+ "Caught some exception whilst retrieving browse nodes from factory");
+ // TODO exception handling
+ }
+
+ if (rootNode.is() && rootNode->hasChildNodes())
+ {
+ //We call acquire on the XBrowseNode so that it does not
+ //get autodestructed and become invalid when accessed later.
+ rootNode->acquire();
+
+ m_aGroupInfo.push_back(std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, static_cast<void*>(rootNode.get())));
+
+ // Add main macro groups
+ const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
+ aChildNodes = rootNode->getChildNodes();
+ for (auto const& childGroup : aChildNodes)
+ {
+ childGroup->acquire();
+
+ if (childGroup->hasChildNodes())
+ {
+ OUString sUIName;
+ if (childGroup->getName() == "user")
+ {
+ sUIName = CuiResId(RID_CUISTR_MYMACROS);
+ }
+ else if (childGroup->getName() == "share")
+ {
+ sUIName = CuiResId(RID_CUISTR_PRODMACROS);
+ }
+ else
+ {
+ sUIName = childGroup->getName();
+ }
+
+ if (sUIName.isEmpty())
+ {
+ continue;
+ }
+
+ m_aGroupInfo.push_back(std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_SCRIPTCONTAINER, 0));
+ std::unique_ptr<weld::TreeIter> xMacroGroup(pFunctionListBox->tree_append(
+ weld::toId(m_aGroupInfo.back().get()), sUIName));
+
+ {
+ // tdf#128010: Do not nag user asking to enable JRE: if it's disabled,
+ // simply don't show relevant entries (user chose to not use JRE)
+ css::uno::ContextLayer layer(
+ comphelper::NoEnableJavaInteractionContext());
+ //Add the children and the grand children
+ addChildren(xMacroGroup.get(), childGroup, pFunctionListBox, filterTerm,
+ pCurrentSaveInData, aNodesToExpand);
+ }
+
+ // Remove the main group if empty
+ if (!pFunctionListBox->iter_has_child(*xMacroGroup))
+ {
+ pFunctionListBox->remove(*xMacroGroup);
+ }
+ else if (!filterTerm.isEmpty())
+ {
+ aNodesToExpand.emplace_back(std::move(xMacroGroup));
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case SfxCfgKind::GROUP_STYLES:
+ {
+ const std::vector<SfxStyleInfo_Impl> lStyleFamilies = pStylesInfo->getStyleFamilies();
+
+ for (const auto& pIt : lStyleFamilies)
+ {
+ if (pIt.sLabel.isEmpty())
+ {
+ continue;
+ }
+
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0));
+ // pIt.sLabel is Name of the style family
+ std::unique_ptr<weld::TreeIter> xFuncEntry(pFunctionListBox->tree_append(
+ weld::toId(m_aGroupInfo.back().get()), pIt.sLabel));
+
+ const std::vector<SfxStyleInfo_Impl> lStyles = pStylesInfo->getStyles(pIt.sFamily);
+
+ // Setup search filter parameters
+ m_searchOptions.searchString = filterTerm;
+ utl::TextSearch textSearch(m_searchOptions);
+
+ // Insert children (styles)
+ for (const auto& pStyleIt : lStyles)
+ {
+ OUString sUIName = pStyleIt.sLabel;
+ sal_Int32 aStartPos = 0;
+ sal_Int32 aEndPos = sUIName.getLength();
+
+ // Apply the search filter
+ if (!filterTerm.isEmpty()
+ && !textSearch.SearchForward(sUIName, &aStartPos, &aEndPos))
+ {
+ continue;
+ }
+
+ SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(pStyleIt);
+
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0, pStyle));
+
+ m_aGroupInfo.back()->sCommand = pStyle->sCommand;
+ m_aGroupInfo.back()->sLabel = pStyle->sLabel;
+
+ pFunctionListBox->append(weld::toId(m_aGroupInfo.back().get()), sUIName,
+ xFuncEntry.get());
+ }
+
+ // Remove the style group from the list if no children
+ if (!pFunctionListBox->iter_has_child(*xFuncEntry))
+ {
+ pFunctionListBox->remove(*xFuncEntry);
+ }
+ else if (!filterTerm.isEmpty())
+ {
+ aNodesToExpand.emplace_back(std::move(xFuncEntry));
+ }
+ }
+
+ break;
+ }
+ default:
+ // Do nothing, the list box will stay empty
+ SAL_INFO("cui.customize",
+ "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind));
+ break;
+ }
+
+ pFunctionListBox->thaw();
+
+ if (pFunctionListBox->n_children())
+ pFunctionListBox->select(0);
+
+ //post freeze
+ for (const auto& it : aNodesToExpand)
+ pFunctionListBox->expand_row(*it);
+}
+
+void CommandCategoryListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles) { pStylesInfo = pStyles; }
+
+void CommandCategoryListBox::addChildren(
+ const weld::TreeIter* parentEntry,
+ const css::uno::Reference<css::script::browse::XBrowseNode>& parentNode,
+ CuiConfigFunctionListBox* pFunctionListBox, const OUString& filterTerm,
+ SaveInData* pCurrentSaveInData, std::vector<std::unique_ptr<weld::TreeIter>>& rNodesToExpand)
+{
+ // Setup search filter parameters
+ m_searchOptions.searchString = filterTerm;
+ utl::TextSearch textSearch(m_searchOptions);
+
+ const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> aChildNodes
+ = parentNode->getChildNodes();
+ for (auto const& child : aChildNodes)
+ {
+ // Acquire to prevent auto-destruction
+ child->acquire();
+
+ if (child->hasChildNodes())
+ {
+ OUString sUIName = child->getName();
+
+ m_aGroupInfo.push_back(std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, static_cast<void*>(child.get())));
+ std::unique_ptr<weld::TreeIter> xNewEntry(pFunctionListBox->tree_append(
+ weld::toId(m_aGroupInfo.back().get()), sUIName, parentEntry));
+
+ addChildren(xNewEntry.get(), child, pFunctionListBox, filterTerm, pCurrentSaveInData,
+ rNodesToExpand);
+
+ // Remove the group if empty
+ if (!pFunctionListBox->iter_has_child(*xNewEntry))
+ pFunctionListBox->remove(*xNewEntry);
+ else
+ rNodesToExpand.emplace_back(std::move(xNewEntry));
+ }
+ else if (child->getType() == css::script::browse::BrowseNodeTypes::SCRIPT)
+ {
+ // Prepare for filtering
+ OUString sUIName = child->getName();
+ sal_Int32 aStartPos = 0;
+ sal_Int32 aEndPos = sUIName.getLength();
+
+ // Apply the search filter
+ if (!filterTerm.isEmpty() && !textSearch.SearchForward(sUIName, &aStartPos, &aEndPos))
+ {
+ continue;
+ }
+
+ OUString uri, description;
+
+ css::uno::Reference<css::beans::XPropertySet> xPropSet(child, css::uno::UNO_QUERY);
+
+ if (!xPropSet.is())
+ {
+ continue;
+ }
+
+ css::uno::Any value = xPropSet->getPropertyValue("URI");
+ value >>= uri;
+
+ try
+ {
+ value = xPropSet->getPropertyValue("Description");
+ value >>= description;
+ }
+ catch (css::uno::Exception&)
+ {
+ // do nothing, the description will be empty
+ }
+
+ if (description.isEmpty())
+ {
+ description = CuiResId(RID_CUISTR_NOMACRODESC);
+ }
+
+ OUString* pScriptURI = new OUString(uri);
+
+ css::uno::Reference<css::graphic::XGraphic> xImage;
+ if (pCurrentSaveInData)
+ xImage = pCurrentSaveInData->GetImage(uri);
+
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI));
+ m_aGroupInfo.back()->sCommand = uri;
+ m_aGroupInfo.back()->sLabel = sUIName;
+ m_aGroupInfo.back()->sHelpText = description;
+ pFunctionListBox->append(weld::toId(m_aGroupInfo.back().get()), sUIName, xImage,
+ parentEntry);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/customize/CustomNotebookbarGenerator.cxx b/cui/source/customize/CustomNotebookbarGenerator.cxx
new file mode 100644
index 000000000..bae85525e
--- /dev/null
+++ b/cui/source/customize/CustomNotebookbarGenerator.cxx
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/processfactory.hxx>
+#include <rtl/bootstrap.hxx>
+#include <config_folders.h>
+#include <CustomNotebookbarGenerator.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <vcl/EnumContext.hxx>
+#include <vcl/settings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <unotools/confignode.hxx>
+#include <libxml/parser.h>
+#include <o3tl/string_view.hxx>
+
+#define aUIPropertiesCount 3
+
+using namespace css;
+
+CustomNotebookbarGenerator::CustomNotebookbarGenerator() {}
+
+static OUString lcl_activeAppName(vcl::EnumContext::Application eApp)
+{
+ switch (eApp)
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "ActiveWriter";
+ case vcl::EnumContext::Application::Calc:
+ return "ActiveCalc";
+ case vcl::EnumContext::Application::Impress:
+ return "ActiveImpress";
+ case vcl::EnumContext::Application::Draw:
+ return "ActiveDraw";
+ default:
+ return OUString();
+ }
+}
+
+static OUString lcl_getAppName(vcl::EnumContext::Application eApp)
+{
+ switch (eApp)
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "Writer";
+ case vcl::EnumContext::Application::Calc:
+ return "Calc";
+ case vcl::EnumContext::Application::Impress:
+ return "Impress";
+ case vcl::EnumContext::Application::Draw:
+ return "Draw";
+ default:
+ return OUString();
+ }
+}
+
+static OUString getAppNameRegistryPath()
+{
+ vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any;
+
+ if (SfxViewFrame* pViewFrame = SfxViewFrame::Current())
+ {
+ const Reference<frame::XFrame>& xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager
+ = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
+ eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ }
+
+ OUString sAppName(lcl_getAppName(eApp));
+ return "org.openoffice.Office.UI.ToolbarMode/Applications/" + sAppName;
+}
+
+static OUString customizedUIPathBuffer()
+{
+ OUString sDirPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE(
+ "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
+ rtl::Bootstrap::expandMacros(sDirPath);
+ return sDirPath;
+}
+
+OUString CustomNotebookbarGenerator::getCustomizedUIPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ return customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
+ + sNotebookbarUIFileName;
+}
+
+OUString CustomNotebookbarGenerator::getOriginalUIPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ return AllSettings::GetUIRootDir() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
+ + sNotebookbarUIFileName;
+}
+
+static OUString getUIDirPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ OUString sUIDirPath
+ = customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/";
+ return sUIDirPath;
+}
+
+OString CustomNotebookbarGenerator::getSystemPath(OUString const& sURL)
+{
+ if (sURL.isEmpty())
+ return OString();
+ OUString sSystemPathSettings;
+ if (osl_getSystemPathFromFileURL(sURL.pData, &sSystemPathSettings.pData) != osl_File_E_None)
+ {
+ SAL_WARN("cui.customnotebookbar", "Cannot get system path for :" << sURL);
+ return OString();
+ }
+ OString osSystemPathSettings
+ = OUStringToOString(sSystemPathSettings, osl_getThreadTextEncoding());
+ return osSystemPathSettings;
+}
+
+static void changeNodeValue(xmlNode* pNodePtr, const char* pProperty, const char* pValue)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pProperty))))
+ xmlNodeSetContent(pNodePtr, reinterpret_cast<const xmlChar*>(pValue));
+ xmlFree(UriValue);
+ break;
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+static void searchNodeAndAttribute(xmlNode* pNodePtr, const char* pUIItemID, const char* pProperty,
+ const char* pValue)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (pNodePtr->type == XML_ELEMENT_NODE)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("object"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pUIItemID))))
+ changeNodeValue(pNodePtr, pProperty, pValue);
+ xmlFree(UriValue);
+ }
+ searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+static xmlDocPtr notebookbarXMLParser(const OString& rDocName, const OString& rUIItemID,
+ const OString& rProperty, const OString& rValue)
+{
+ xmlDocPtr pDocPtr = xmlParseFile(rDocName.getStr());
+ xmlNodePtr pNodePtr = xmlDocGetRootElement(pDocPtr);
+ searchNodeAndAttribute(pNodePtr, rUIItemID.getStr(), rProperty.getStr(), rValue.getStr());
+ return pDocPtr;
+}
+
+void CustomNotebookbarGenerator::modifyCustomizedUIFile(const Sequence<OUString>& sUIItemProperties)
+{
+ OString sCustomizedUIPath = getSystemPath(getCustomizedUIPath());
+ for (auto const& aValue : sUIItemProperties)
+ {
+ std::vector<OString> aProperties(aUIPropertiesCount);
+ for (sal_Int32 aIndex = 0; aIndex < aUIPropertiesCount; aIndex++)
+ {
+ sal_Int32 nPos = aIndex;
+ std::u16string_view sToken = o3tl::getToken(aValue, nPos, ',', nPos);
+ aProperties[aIndex] = OUStringToOString(sToken, RTL_TEXTENCODING_UTF8);
+ }
+ xmlDocPtr doc = notebookbarXMLParser(sCustomizedUIPath, aProperties[0], aProperties[1],
+ aProperties[2]);
+
+ if (doc != nullptr)
+ {
+ xmlSaveFormatFile(sCustomizedUIPath.getStr(), doc, 1);
+ xmlFreeDoc(doc);
+ }
+ }
+}
+
+void CustomNotebookbarGenerator::getFileNameAndAppName(OUString& sAppName,
+ OUString& sNotebookbarUIFileName)
+{
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ if (!pFrame)
+ return;
+
+ const auto xContext = comphelper::getProcessComponentContext();
+ utl::OConfigurationTreeRoot aRoot(xContext, "org.openoffice.Office.UI.ToolbarMode/", false);
+ const Reference<frame::XFrame>& xFrame = pFrame->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create(xContext);
+
+ vcl::EnumContext::Application eApp
+ = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ OUString sActiveAppName(lcl_activeAppName(eApp));
+ sAppName = lcl_getAppName(eApp);
+ const Any aValue = aRoot.getNodeValue(sActiveAppName);
+ aValue >>= sNotebookbarUIFileName;
+}
+
+void CustomNotebookbarGenerator::createCustomizedUIFile()
+{
+ OUString sUserUIDir = getUIDirPath();
+ OUString sOriginalUIPath = getOriginalUIPath();
+ OUString sCustomizedUIPath = getCustomizedUIPath();
+
+ sal_uInt32 nflag = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
+ osl::Directory aDirectory(sUserUIDir);
+ if (aDirectory.open() != osl::FileBase::E_None)
+ osl::Directory::create(sUserUIDir, nflag);
+ else
+ SAL_WARN("cui.customnotebookbar",
+ "Cannot create the directory or directory was present :" << sUserUIDir);
+
+ osl::File aFile(sCustomizedUIPath);
+ if (aFile.open(nflag) != osl::FileBase::E_None)
+ osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
+ else
+ SAL_WARN("cui.customnotebookbar",
+ "Cannot copy the file or file was present :" << sCustomizedUIPath);
+}
+
+Sequence<OUString> CustomNotebookbarGenerator::getCustomizedUIItem(OUString sNotebookbarConfigType)
+{
+ OUString aPath = getAppNameRegistryPath();
+ const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), aPath,
+ false);
+
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
+ const Any aValue = aModeNode.getNodeValue("UIItemProperties");
+ Sequence<OUString> aValues;
+ aValue >>= aValues;
+ return aValues;
+}
+
+void CustomNotebookbarGenerator::setCustomizedUIItem(Sequence<OUString> sUIItemProperties,
+ OUString sNotebookbarConfigType)
+{
+ OUString aPath = getAppNameRegistryPath();
+ const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), aPath,
+ true);
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
+
+ css::uno::Any aUIItemProperties(sUIItemProperties);
+ aModeNode.setNodeValue("UIItemProperties", aUIItemProperties);
+ aAppNode.commit();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxConfigPageHelper.cxx b/cui/source/customize/SvxConfigPageHelper.cxx
new file mode 100644
index 000000000..52265ef09
--- /dev/null
+++ b/cui/source/customize/SvxConfigPageHelper.cxx
@@ -0,0 +1,424 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <SvxConfigPageHelper.hxx>
+
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/random.hxx>
+#include <svtools/imgdef.hxx>
+#include <svtools/miscopt.hxx>
+
+static sal_Int16 theImageType = css::ui::ImageType::COLOR_NORMAL | css::ui::ImageType::SIZE_DEFAULT;
+
+void SvxConfigPageHelper::RemoveEntry(SvxEntries* pEntries, SvxConfigEntry const* pChildEntry)
+{
+ SvxEntries::iterator iter = pEntries->begin();
+
+ while (iter != pEntries->end())
+ {
+ if (pChildEntry == *iter)
+ {
+ pEntries->erase(iter);
+ break;
+ }
+ ++iter;
+ }
+}
+
+OUString SvxConfigPageHelper::replaceSaveInName(const OUString& rMessage,
+ std::u16string_view rSaveInName)
+{
+ OUString name = rMessage.replaceFirst("%SAVE IN SELECTION%", rSaveInName);
+
+ return name;
+}
+
+OUString SvxConfigPageHelper::stripHotKey(const OUString& str) { return str.replaceFirst("~", ""); }
+
+OUString SvxConfigPageHelper::replaceSixteen(const OUString& str, sal_Int32 nReplacement)
+{
+ return str.replaceAll(OUString::number(16), OUString::number(nReplacement));
+}
+
+sal_Int16 SvxConfigPageHelper::GetImageType() { return theImageType; }
+
+void SvxConfigPageHelper::InitImageType()
+{
+ theImageType = css::ui::ImageType::COLOR_NORMAL | css::ui::ImageType::SIZE_DEFAULT;
+
+ if (SvtMiscOptions().GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE)
+ {
+ theImageType |= css::ui::ImageType::SIZE_LARGE;
+ }
+ else if (SvtMiscOptions().GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_32)
+ {
+ theImageType |= css::ui::ImageType::SIZE_32;
+ }
+}
+
+css::uno::Reference<css::graphic::XGraphic>
+SvxConfigPageHelper::GetGraphic(const css::uno::Reference<css::ui::XImageManager>& xImageManager,
+ const OUString& rCommandURL)
+{
+ css::uno::Reference<css::graphic::XGraphic> result;
+
+ if (xImageManager.is())
+ {
+ // TODO handle large graphics
+ css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq;
+
+ css::uno::Sequence<OUString> aImageCmdSeq{ rCommandURL };
+
+ try
+ {
+ aGraphicSeq = xImageManager->getImages(GetImageType(), aImageCmdSeq);
+
+ if (aGraphicSeq.hasElements())
+ {
+ result = aGraphicSeq[0];
+ }
+ }
+ catch (css::uno::Exception&)
+ {
+ // will return empty XGraphic
+ }
+ }
+
+ return result;
+}
+
+OUString SvxConfigPageHelper::generateCustomName(const OUString& prefix, SvxEntries* entries,
+ sal_Int32 suffix /*= 1*/)
+{
+ OUString name;
+ sal_Int32 pos = 0;
+
+ // find and replace the %n placeholder in the prefix string
+ name = prefix.replaceFirst("%n", OUString::number(suffix), &pos);
+
+ if (pos == -1)
+ {
+ // no placeholder found so just append the suffix
+ name += OUString::number(suffix);
+ }
+
+ if (!entries)
+ return name;
+
+ // now check if there is an already existing entry with this name
+ bool bFoundEntry = false;
+ for (auto const& entry : *entries)
+ {
+ if (name.equals(entry->GetName()))
+ {
+ bFoundEntry = true;
+ break;
+ }
+ }
+
+ if (bFoundEntry)
+ {
+ // name already exists so try the next number up
+ return generateCustomName(prefix, entries, ++suffix);
+ }
+
+ return name;
+}
+
+OUString SvxConfigPageHelper::generateCustomMenuURL(SvxEntries* entries, sal_Int32 suffix /*= 1*/)
+{
+ OUString url = "vnd.openoffice.org:CustomMenu" + OUString::number(suffix);
+ if (!entries)
+ return url;
+
+ // now check is there is an already existing entry with this url
+ bool bFoundEntry = false;
+ for (auto const& entry : *entries)
+ {
+ if (url.equals(entry->GetCommand()))
+ {
+ bFoundEntry = true;
+ break;
+ }
+ }
+
+ if (bFoundEntry)
+ {
+ // url already exists so try the next number up
+ return generateCustomMenuURL(entries, ++suffix);
+ }
+
+ return url;
+}
+
+sal_uInt32 SvxConfigPageHelper::generateRandomValue()
+{
+ return comphelper::rng::uniform_uint_distribution(0, std::numeric_limits<unsigned int>::max());
+}
+
+OUString SvxConfigPageHelper::generateCustomURL(SvxEntries* entries)
+{
+ OUString url = OUString::Concat(ITEM_TOOLBAR_URL) + CUSTOM_TOOLBAR_STR +
+ // use a random number to minimize possible clash with existing custom toolbars
+ OUString::number(generateRandomValue(), 16);
+
+ // now check is there is an already existing entry with this url
+ bool bFoundEntry = false;
+ for (auto const& entry : *entries)
+ {
+ if (url.equals(entry->GetCommand()))
+ {
+ bFoundEntry = true;
+ break;
+ }
+ }
+
+ if (bFoundEntry)
+ {
+ // url already exists so try the next number up
+ return generateCustomURL(entries);
+ }
+
+ return url;
+}
+
+OUString SvxConfigPageHelper::GetModuleName(std::u16string_view aModuleId)
+{
+ if (aModuleId == u"com.sun.star.text.TextDocument"
+ || aModuleId == u"com.sun.star.text.GlobalDocument")
+ return "Writer";
+ else if (aModuleId == u"com.sun.star.text.WebDocument")
+ return "Writer/Web";
+ else if (aModuleId == u"com.sun.star.drawing.DrawingDocument")
+ return "Draw";
+ else if (aModuleId == u"com.sun.star.presentation.PresentationDocument")
+ return "Impress";
+ else if (aModuleId == u"com.sun.star.sheet.SpreadsheetDocument")
+ return "Calc";
+ else if (aModuleId == u"com.sun.star.script.BasicIDE")
+ return "Basic";
+ else if (aModuleId == u"com.sun.star.formula.FormulaProperties")
+ return "Math";
+ else if (aModuleId == u"com.sun.star.sdb.RelationDesign")
+ return "Relation Design";
+ else if (aModuleId == u"com.sun.star.sdb.QueryDesign")
+ return "Query Design";
+ else if (aModuleId == u"com.sun.star.sdb.TableDesign")
+ return "Table Design";
+ else if (aModuleId == u"com.sun.star.sdb.DataSourceBrowser")
+ return "Data Source Browser";
+ else if (aModuleId == u"com.sun.star.sdb.DatabaseDocument")
+ return "Database";
+
+ return OUString();
+}
+
+OUString SvxConfigPageHelper::GetUIModuleName(
+ const OUString& aModuleId,
+ const css::uno::Reference<css::frame::XModuleManager2>& rModuleManager)
+{
+ assert(rModuleManager.is());
+
+ OUString aModuleUIName;
+
+ try
+ {
+ css::uno::Any a = rModuleManager->getByName(aModuleId);
+ css::uno::Sequence<css::beans::PropertyValue> aSeq;
+
+ if (a >>= aSeq)
+ {
+ for (css::beans::PropertyValue const& rProp : std::as_const(aSeq))
+ {
+ if (rProp.Name == "ooSetupFactoryUIName")
+ {
+ rProp.Value >>= aModuleUIName;
+ break;
+ }
+ }
+ }
+ }
+ catch (css::uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (css::uno::Exception&)
+ {
+ }
+
+ if (aModuleUIName.isEmpty())
+ aModuleUIName = GetModuleName(aModuleId);
+
+ return aModuleUIName;
+}
+
+bool SvxConfigPageHelper::GetMenuItemData(
+ const css::uno::Reference<css::container::XIndexAccess>& rItemContainer, sal_Int32 nIndex,
+ OUString& rCommandURL, OUString& rLabel, sal_uInt16& rType, sal_Int32& rStyle,
+ css::uno::Reference<css::container::XIndexAccess>& rSubMenu)
+{
+ try
+ {
+ css::uno::Sequence<css::beans::PropertyValue> aProps;
+ if (rItemContainer->getByIndex(nIndex) >>= aProps)
+ {
+ for (css::beans::PropertyValue const& rProp : std::as_const(aProps))
+ {
+ if (rProp.Name == ITEM_DESCRIPTOR_COMMANDURL)
+ {
+ rProp.Value >>= rCommandURL;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_CONTAINER)
+ {
+ rProp.Value >>= rSubMenu;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_STYLE)
+ {
+ rProp.Value >>= rStyle;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_LABEL)
+ {
+ rProp.Value >>= rLabel;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_TYPE)
+ {
+ rProp.Value >>= rType;
+ }
+ }
+
+ return true;
+ }
+ }
+ catch (css::lang::IndexOutOfBoundsException&)
+ {
+ }
+
+ return false;
+}
+
+bool SvxConfigPageHelper::GetToolbarItemData(
+ const css::uno::Reference<css::container::XIndexAccess>& rItemContainer, sal_Int32 nIndex,
+ OUString& rCommandURL, OUString& rLabel, sal_uInt16& rType, bool& rIsVisible, sal_Int32& rStyle)
+{
+ try
+ {
+ css::uno::Sequence<css::beans::PropertyValue> aProps;
+ if (rItemContainer->getByIndex(nIndex) >>= aProps)
+ {
+ for (css::beans::PropertyValue const& rProp : std::as_const(aProps))
+ {
+ if (rProp.Name == ITEM_DESCRIPTOR_COMMANDURL)
+ {
+ rProp.Value >>= rCommandURL;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_STYLE)
+ {
+ rProp.Value >>= rStyle;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_LABEL)
+ {
+ rProp.Value >>= rLabel;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_TYPE)
+ {
+ rProp.Value >>= rType;
+ }
+ else if (rProp.Name == ITEM_DESCRIPTOR_ISVISIBLE)
+ {
+ rProp.Value >>= rIsVisible;
+ }
+ }
+
+ return true;
+ }
+ }
+ catch (css::lang::IndexOutOfBoundsException&)
+ {
+ }
+
+ return false;
+}
+
+css::uno::Sequence<css::beans::PropertyValue>
+SvxConfigPageHelper::ConvertSvxConfigEntry(const SvxConfigEntry* pEntry)
+{
+ // If the name has not been changed, then the label can be stored
+ // as an empty string.
+ // It will be initialised again later using the command to label map.
+ OUString sLabel;
+ if (pEntry->HasChangedName() || pEntry->GetCommand().isEmpty())
+ sLabel = pEntry->GetName();
+
+ css::uno::Sequence<css::beans::PropertyValue> aPropSeq{
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_COMMANDURL, pEntry->GetCommand()),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_TYPE, css::ui::ItemType::DEFAULT),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_LABEL, sLabel),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_STYLE,
+ static_cast<sal_Int16>(pEntry->GetStyle()))
+ };
+
+ return aPropSeq;
+}
+
+css::uno::Sequence<css::beans::PropertyValue>
+SvxConfigPageHelper::ConvertToolbarEntry(const SvxConfigEntry* pEntry)
+{
+ // If the name has not been changed, then the label can be stored
+ // as an empty string.
+ // It will be initialised again later using the command to label map.
+ OUString sLabel;
+ if (pEntry->HasChangedName() || pEntry->GetCommand().isEmpty())
+ sLabel = pEntry->GetName();
+
+ css::uno::Sequence<css::beans::PropertyValue> aPropSeq{
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_COMMANDURL, pEntry->GetCommand()),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_TYPE, css::ui::ItemType::DEFAULT),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_LABEL, sLabel),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_ISVISIBLE, pEntry->IsVisible()),
+ comphelper::makePropertyValue(ITEM_DESCRIPTOR_STYLE,
+ static_cast<sal_Int16>(pEntry->GetStyle()))
+ };
+
+ return aPropSeq;
+}
+
+bool SvxConfigPageHelper::EntrySort(SvxConfigEntry const* a, SvxConfigEntry const* b)
+{
+ return a->GetName().compareTo(b->GetName()) < 0;
+}
+
+bool SvxConfigPageHelper::SvxConfigEntryModified(SvxConfigEntry const* pEntry)
+{
+ SvxEntries* pEntries = pEntry->GetEntries();
+ if (!pEntries)
+ return false;
+
+ for (const auto& entry : *pEntries)
+ {
+ if (entry->IsModified() || SvxConfigEntryModified(entry))
+ return true;
+ }
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxMenuConfigPage.cxx b/cui/source/customize/SvxMenuConfigPage.cxx
new file mode 100644
index 000000000..5793825b5
--- /dev/null
+++ b/cui/source/customize/SvxMenuConfigPage.cxx
@@ -0,0 +1,595 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/commandevent.hxx>
+
+#include <strings.hrc>
+#include <helpids.h>
+
+#include <cfg.hxx>
+#include <SvxMenuConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include <dialmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+#include <dlgname.hxx>
+
+SvxMenuConfigPage::SvxMenuConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet, bool bIsMenuBar)
+ : SvxConfigPage(pPage, pController, rSet)
+ , m_bIsMenuBar(bIsMenuBar)
+{
+ m_xGearBtn = m_xBuilder->weld_menu_button("menugearbtn");
+ m_xGearBtn->show();
+ m_xContentsListBox.reset(
+ new SvxMenuEntriesListBox(m_xBuilder->weld_tree_view("menucontents"), this));
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(*this, rTreeView));
+ rTreeView.connect_size_allocate(LINK(this, SvxMenuConfigPage, MenuEntriesSizeAllocHdl));
+ Size aSize(m_xFunctions->get_size_request());
+ rTreeView.set_size_request(aSize.Width(), aSize.Height());
+ MenuEntriesSizeAllocHdl(aSize);
+ rTreeView.set_hexpand(true);
+ rTreeView.set_vexpand(true);
+ rTreeView.show();
+
+ rTreeView.connect_changed(LINK(this, SvxMenuConfigPage, SelectMenuEntry));
+ rTreeView.connect_popup_menu(LINK(this, SvxMenuConfigPage, ContentContextMenuHdl));
+
+ m_xFunctions->get_widget().connect_popup_menu(
+ LINK(this, SvxMenuConfigPage, FunctionContextMenuHdl));
+
+ m_xGearBtn->connect_selected(LINK(this, SvxMenuConfigPage, GearHdl));
+
+ m_xCommandCategoryListBox->connect_changed(LINK(this, SvxMenuConfigPage, SelectCategory));
+
+ m_xMoveUpButton->connect_clicked(LINK(this, SvxConfigPage, MoveHdl));
+ m_xMoveDownButton->connect_clicked(LINK(this, SvxConfigPage, MoveHdl));
+
+ m_xAddCommandButton->connect_clicked(LINK(this, SvxMenuConfigPage, AddCommandHdl));
+ m_xRemoveCommandButton->connect_clicked(LINK(this, SvxMenuConfigPage, RemoveCommandHdl));
+
+ m_xInsertBtn->connect_selected(LINK(this, SvxMenuConfigPage, InsertHdl));
+ m_xModifyBtn->connect_selected(LINK(this, SvxMenuConfigPage, ModifyItemHdl));
+ m_xResetBtn->connect_clicked(LINK(this, SvxMenuConfigPage, ResetMenuHdl));
+
+ // These operations are not possible on menus/context menus yet
+ m_xModifyBtn->remove_item("changeIcon");
+ m_xModifyBtn->remove_item("resetIcon");
+ m_xModifyBtn->remove_item("restoreItem");
+
+ if (!bIsMenuBar)
+ {
+ //TODO: Remove this when the gear button is implemented for context menus
+ m_xGearBtn->set_sensitive(false);
+ m_xGearBtn->hide();
+ }
+ else
+ {
+ // TODO: Remove this when it is possible to reset menubar menus individually
+ m_xResetBtn->set_sensitive(false);
+ }
+}
+
+void SvxMenuConfigPage::ListModified()
+{
+ // regenerate with the current ordering within the list
+ SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
+ pEntries->clear();
+
+ for (int i = 0; i < m_xContentsListBox->n_children(); ++i)
+ pEntries->push_back(weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(i)));
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+ UpdateButtonStates();
+}
+
+IMPL_LINK(SvxMenuConfigPage, MenuEntriesSizeAllocHdl, const Size&, rSize, void)
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ std::vector<int> aWidths;
+
+ int nStandardImageColWidth = rTreeView.get_checkbox_column_width();
+ int nMargin = 16;
+
+ aWidths.push_back(rSize.Width() - (nMargin + nStandardImageColWidth));
+ rTreeView.set_column_fixed_widths(aWidths);
+}
+
+SvxMenuConfigPage::~SvxMenuConfigPage()
+{
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ delete weld::fromId<SaveInData*>(m_xSaveInListBox->get_id(i));
+ m_xSaveInListBox->clear();
+}
+
+// Populates the Menu combo box
+void SvxMenuConfigPage::Init()
+{
+ // ensure that the UI is cleared before populating it
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+
+ ReloadTopLevelListBox();
+
+ m_xTopLevelListBox->set_active(m_xTopLevelListBox->get_count() ? 0 : -1);
+ SelectElement();
+
+ m_xCommandCategoryListBox->Init(comphelper::getProcessComponentContext(), m_xFrame,
+ m_aModuleId);
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), OUString(), GetSaveInData());
+ SelectFunctionHdl(m_xFunctions->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, SelectMenuEntry, weld::TreeView&, void) { UpdateButtonStates(); }
+
+void SvxMenuConfigPage::UpdateButtonStates()
+{
+ // Disable Up and Down buttons depending on current selection
+ int selection = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator
+ = selection != -1
+ && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(selection))->IsSeparator();
+ bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && selection != -1);
+
+ m_xMoveUpButton->set_sensitive(bIsValidSelection && selection != 0);
+ m_xMoveDownButton->set_sensitive(bIsValidSelection
+ && selection != m_xContentsListBox->n_children() - 1);
+
+ m_xRemoveCommandButton->set_sensitive(bIsValidSelection);
+
+ m_xModifyBtn->set_sensitive(bIsValidSelection && !bIsSeparator);
+
+ // If there is no top level selection (menu), then everything working on the right box
+ // which contains the functions of the selected menu/toolbar needs to be disabled
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ m_xInsertBtn->set_sensitive(pMenuData != nullptr);
+
+ SvxConfigEntry* selectedCmd = CreateCommandFromSelection(GetScriptURL());
+
+ m_xAddCommandButton->set_sensitive(
+ pMenuData != nullptr && !IsCommandInMenuList(selectedCmd, pMenuData->GetEntries()));
+
+ delete selectedCmd;
+
+ if (bIsValidSelection)
+ {
+ m_xRemoveCommandButton->set_sensitive(pMenuData != nullptr);
+ }
+
+ //Handle the gear button
+ if (pMenuData && m_bIsMenuBar)
+ {
+ // Add option (gear_add) will always be enabled
+ m_xGearBtn->set_item_sensitive("menu_gear_delete", pMenuData->IsDeletable());
+ m_xGearBtn->set_item_sensitive("menu_gear_rename", pMenuData->IsRenamable());
+ m_xGearBtn->set_item_sensitive("menu_gear_move", pMenuData->IsMovable());
+ }
+}
+
+void SvxMenuConfigPage::DeleteSelectedTopLevel()
+{
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ SvxEntries* pParentEntries = FindParentForChild(GetSaveInData()->GetEntries(), pMenuData);
+
+ SvxConfigPageHelper::RemoveEntry(pParentEntries, pMenuData);
+ delete pMenuData;
+
+ ReloadTopLevelListBox();
+
+ GetSaveInData()->SetModified();
+}
+
+void SvxMenuConfigPage::DeleteSelectedContent()
+{
+ int nActEntry = m_xContentsListBox->get_selected_index();
+
+ if (nActEntry == -1)
+ return;
+
+ // get currently selected menu entry
+ SvxConfigEntry* pMenuEntry
+ = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ // get currently selected menu
+ SvxConfigEntry* pMenu = GetTopLevelSelection();
+
+ // remove menu entry from the list for this menu
+ SvxConfigPageHelper::RemoveEntry(pMenu->GetEntries(), pMenuEntry);
+
+ // remove menu entry from UI
+ m_xContentsListBox->remove(nActEntry);
+
+ // if this is a submenu entry, redraw the menus list box
+ if (pMenuEntry->IsPopup())
+ {
+ ReloadTopLevelListBox();
+ }
+
+ // delete data for menu entry
+ delete pMenuEntry;
+
+ GetSaveInData()->SetModified();
+ pMenu->SetModified();
+}
+
+short SvxMenuConfigPage::QueryReset()
+{
+ OUString msg = CuiResId(RID_CUISTR_CONFIRM_MENU_RESET);
+
+ OUString saveInName = m_xSaveInListBox->get_active_text();
+
+ OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
+ return xQueryBox->run();
+}
+
+void SvxMenuConfigPage::SelectElement()
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+ if (!pMenuData)
+ rTreeView.clear();
+ else
+ {
+ SvxEntries* pEntries = pMenuData->GetEntries();
+
+ rTreeView.bulk_insert_for_each(
+ pEntries->size(), [this, &rTreeView, pEntries](weld::TreeIter& rIter, int nIdx) {
+ auto const& entry = (*pEntries)[nIdx];
+ OUString sId(weld::toId(entry));
+ rTreeView.set_id(rIter, sId);
+ InsertEntryIntoUI(entry, rTreeView, rIter, true);
+ });
+ }
+
+ UpdateButtonStates();
+}
+
+IMPL_LINK(SvxMenuConfigPage, GearHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "menu_gear_add")
+ {
+ SvxMainMenuOrganizerDialog aDialog(GetFrameWeld(), GetSaveInData()->GetEntries(), nullptr,
+ true);
+
+ if (aDialog.run() == RET_OK)
+ {
+ GetSaveInData()->SetEntries(aDialog.ReleaseEntries());
+ ReloadTopLevelListBox(aDialog.GetSelectedEntry());
+ GetSaveInData()->SetModified();
+ }
+ }
+ else if (rIdent == "menu_gear_delete")
+ {
+ DeleteSelectedTopLevel();
+ }
+ else if (rIdent == "menu_gear_rename")
+ {
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ OUString sCurrentName(SvxConfigPageHelper::stripHotKey(pMenuData->GetName()));
+ OUString sDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), sCurrentName, sDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_MENU);
+ aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_MENU));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ OUString sNewName = aNameDialog.GetName();
+
+ if (sCurrentName == sNewName)
+ return;
+
+ pMenuData->SetName(sNewName);
+
+ ReloadTopLevelListBox();
+
+ GetSaveInData()->SetModified();
+ }
+ }
+ else if (rIdent == "menu_gear_move")
+ {
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ SvxMainMenuOrganizerDialog aDialog(GetFrameWeld(), GetSaveInData()->GetEntries(), pMenuData,
+ false);
+ if (aDialog.run() == RET_OK)
+ {
+ GetSaveInData()->SetEntries(aDialog.ReleaseEntries());
+
+ ReloadTopLevelListBox();
+
+ GetSaveInData()->SetModified();
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown gear menu option: " << rIdent);
+ return;
+ }
+
+ UpdateButtonStates();
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, SelectCategory, weld::ComboBox&, void)
+{
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
+
+ SelectFunctionHdl(m_xFunctions->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, AddCommandHdl, weld::Button&, void)
+{
+ int nPos = AddFunction(-1, /*bAllowDuplicates*/ false);
+ if (nPos == -1)
+ return;
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(rTreeView.get_id(nPos));
+ InsertEntryIntoUI(pEntry, rTreeView, nPos, true);
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, RemoveCommandHdl, weld::Button&, void)
+{
+ DeleteSelectedContent();
+ if (GetSaveInData()->IsModified())
+ {
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK(SvxMenuConfigPage, InsertHdl, const OString&, rIdent, void)
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ if (rIdent == "insertseparator")
+ {
+ SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
+ pNewEntryData->SetUserDefined();
+ int nPos = AppendEntry(pNewEntryData, -1);
+ InsertEntryIntoUI(pNewEntryData, rTreeView, nPos, true);
+ }
+ else if (rIdent == "insertsubmenu")
+ {
+ OUString aNewName;
+ OUString aDesc = CuiResId(RID_CUISTR_SUBMENU_NAME);
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_NAME_SUBMENU);
+ aNameDialog.set_title(CuiResId(RID_CUISTR_ADD_SUBMENU));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ SvxConfigEntry* pNewEntryData
+ = new SvxConfigEntry(aNewName, aNewName, true, /*bParentData*/ false);
+ pNewEntryData->SetName(aNewName);
+ pNewEntryData->SetUserDefined();
+
+ int nPos = AppendEntry(pNewEntryData, -1);
+ InsertEntryIntoUI(pNewEntryData, rTreeView, nPos, true);
+
+ ReloadTopLevelListBox();
+
+ m_xContentsListBox->scroll_to_row(nPos);
+ m_xContentsListBox->select(nPos);
+
+ GetSaveInData()->SetModified();
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+
+ if (GetSaveInData()->IsModified())
+ {
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK(SvxMenuConfigPage, ModifyItemHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "renameItem")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry
+ = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ OUString aNewName(SvxConfigPageHelper::stripHotKey(pEntry->GetName()));
+ OUString aDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_MENU_ITEM);
+ aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_MENU));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ pEntry->SetName(aNewName);
+ m_xContentsListBox->set_text(nActEntry, aNewName, 0);
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+
+ if (GetSaveInData()->IsModified())
+ {
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, ResetMenuHdl, weld::Button&, void)
+{
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ if (pMenuData == nullptr)
+ {
+ SAL_WARN("cui.customize",
+ "RHB top level selection is null. A menu must be selected to reset!");
+ return;
+ }
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_CONFIRM_RESTORE_DEFAULT_MENU)));
+
+ // Resetting individual top-level menus is not possible at the moment.
+ // So we are resetting only if it is a context menu
+ if (m_bIsMenuBar || xQueryBox->run() != RET_YES)
+ return;
+
+ sal_Int32 nPos = m_xTopLevelListBox->get_active();
+ ContextMenuSaveInData* pSaveInData = static_cast<ContextMenuSaveInData*>(GetSaveInData());
+
+ pSaveInData->ResetContextMenu(pMenuData);
+
+ // ensure that the UI is cleared before populating it
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+
+ ReloadTopLevelListBox();
+
+ // Reselect the reset menu
+ m_xTopLevelListBox->set_active(nPos);
+ SelectElement();
+}
+
+SaveInData* SvxMenuConfigPage::CreateSaveInData(
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
+ const OUString& aModuleId, bool bDocConfig)
+{
+ if (!m_bIsMenuBar)
+ return static_cast<SaveInData*>(
+ new ContextMenuSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
+
+ return static_cast<SaveInData*>(
+ new MenuSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
+}
+
+IMPL_LINK(SvxMenuConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
+ if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
+ return false;
+ rTreeView.select(*xIter);
+ SelectMenuEntry(rTreeView);
+
+ int nSelectIndex = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator
+ = nSelectIndex != -1
+ && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex))->IsSeparator();
+ bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && nSelectIndex != -1);
+
+ std::unique_ptr<weld::Builder> xBuilder(
+ Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", false);
+ xContextMenu->set_visible("remove", bIsValidSelection);
+ xContextMenu->set_visible("rename", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("changeIcon", false);
+ xContextMenu->set_visible("resetIcon", false);
+ xContextMenu->set_visible("restoreDefault", false);
+ OString sCommand(xContextMenu->popup_at_rect(
+ &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
+
+ if (sCommand == "remove")
+ {
+ RemoveCommandHdl(*m_xRemoveCommandButton);
+ }
+ else if (sCommand == "rename")
+ {
+ ModifyItemHdl("renameItem");
+ }
+ else if (!sCommand.isEmpty())
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
+ return true;
+}
+
+IMPL_LINK(SvxMenuConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xFunctions->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
+ if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
+ return false;
+ rTreeView.select(*xIter);
+ SelectFunctionHdl(rTreeView);
+
+ std::unique_ptr<weld::Builder> xBuilder(
+ Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", true);
+ xContextMenu->set_visible("remove", false);
+ xContextMenu->set_visible("rename", false);
+ xContextMenu->set_visible("changeIcon", false);
+ xContextMenu->set_visible("resetIcon", false);
+ xContextMenu->set_visible("restoreDefault", false);
+ OString sCommand(xContextMenu->popup_at_rect(
+ &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
+
+ if (sCommand == "add")
+ {
+ AddCommandHdl(*m_xAddCommandButton);
+ }
+ else if (!sCommand.isEmpty())
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxNotebookbarConfigPage.cxx b/cui/source/customize/SvxNotebookbarConfigPage.cxx
new file mode 100644
index 000000000..99c15b8f3
--- /dev/null
+++ b/cui/source/customize/SvxNotebookbarConfigPage.cxx
@@ -0,0 +1,543 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/event.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+
+#include <algorithm>
+#include <cstddef>
+
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <cfg.hxx>
+#include <SvxNotebookbarConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include <dialmgr.hxx>
+#include <libxml/parser.h>
+#include <osl/file.hxx>
+#include <CustomNotebookbarGenerator.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <unotools/configmgr.hxx>
+#include <comphelper/processfactory.hxx>
+#include <o3tl/string_view.hxx>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+
+namespace uno = com::sun::star::uno;
+namespace frame = com::sun::star::frame;
+namespace lang = com::sun::star::lang;
+namespace container = com::sun::star::container;
+namespace beans = com::sun::star::beans;
+namespace graphic = com::sun::star::graphic;
+
+static bool isCategoryAvailable(std::u16string_view sClassId, std::u16string_view sUIItemId,
+ std::u16string_view sActiveCategory, bool& isCategory)
+{
+ if (sUIItemId == sActiveCategory)
+ return true;
+ else if ((sClassId == u"GtkMenu" || sClassId == u"GtkGrid") && sUIItemId != sActiveCategory)
+ {
+ isCategory = false;
+ return false;
+ }
+ return false;
+}
+
+static OUString charToString(const char* cString)
+{
+ return OUString(cString, strlen(cString), RTL_TEXTENCODING_UTF8);
+}
+
+static OUString getFileName(std::u16string_view aFileName)
+{
+ if (aFileName == u"notebookbar.ui")
+ return CuiResId(RID_CUISTR_TABBED);
+ else if (aFileName == u"notebookbar_compact.ui")
+ return CuiResId(RID_CUISTR_TABBED_COMPACT);
+ else if (aFileName == u"notebookbar_groupedbar_full.ui")
+ return CuiResId(RID_CUISTR_GROUPEDBAR);
+ else if (aFileName == u"notebookbar_groupedbar_compact.ui")
+ return CuiResId(RID_CUISTR_GROUPEDBAR_COMPACT);
+ else
+ return "None";
+}
+
+static OUString getModuleId(std::u16string_view sModuleName)
+{
+ if (sModuleName == u"Writer")
+ return "com.sun.star.text.TextDocument";
+ else if (sModuleName == u"Draw")
+ return "com.sun.star.drawing.DrawingDocument";
+ else if (sModuleName == u"Impress")
+ return "com.sun.star.presentation.PresentationDocument";
+ else if (sModuleName == u"Calc")
+ return "com.sun.star.sheet.SpreadsheetDocument";
+ else
+ return "None";
+}
+
+SvxNotebookbarConfigPage::SvxNotebookbarConfigPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SvxConfigPage(pPage, pController, rSet)
+{
+ m_xCommandCategoryListBox->set_visible(false);
+ m_xDescriptionFieldLb->set_visible(false);
+ m_xSearchEdit->set_visible(false);
+ m_xDescriptionField->set_visible(false);
+ m_xMoveUpButton->set_visible(false);
+ m_xMoveDownButton->set_visible(false);
+ m_xAddCommandButton->set_visible(false);
+ m_xRemoveCommandButton->set_visible(false);
+ m_xLeftFunctionLabel->set_visible(false);
+ m_xSearchLabel->set_visible(false);
+ m_xCategoryLabel->set_visible(false);
+ m_xInsertBtn->set_visible(false);
+ m_xModifyBtn->set_visible(false);
+ m_xResetBtn->set_visible(false);
+ m_xCustomizeLabel->set_visible(false);
+
+ weld::TreeView& rCommandCategoryBox = m_xFunctions->get_widget();
+ rCommandCategoryBox.hide();
+
+ m_xContentsListBox.reset(
+ new SvxNotebookbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
+ m_xDropTargetHelper.reset(
+ new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ Size aSize(m_xFunctions->get_size_request());
+ rTreeView.set_size_request(aSize.Width(), aSize.Height());
+
+ rTreeView.set_hexpand(true);
+ rTreeView.set_vexpand(true);
+ rTreeView.set_help_id(HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS);
+ rTreeView.show();
+}
+
+SvxNotebookbarConfigPage::~SvxNotebookbarConfigPage() {}
+
+void SvxNotebookbarConfigPage::DeleteSelectedTopLevel() {}
+
+void SvxNotebookbarConfigPage::DeleteSelectedContent() {}
+
+void SvxNotebookbarConfigPage::Init()
+{
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+ m_xSaveInListBox->clear();
+ CustomNotebookbarGenerator::createCustomizedUIFile();
+ OUString sNotebookbarInterface = getFileName(m_sFileName);
+
+ OUString sScopeName
+ = utl::ConfigManager::getProductName() + " " + m_sAppName + " - " + sNotebookbarInterface;
+ OUString sSaveInListBoxID = notebookbarTabScope;
+
+ m_xSaveInListBox->append(sSaveInListBoxID, sScopeName);
+ m_xSaveInListBox->set_active_id(sSaveInListBoxID);
+
+ m_xTopLevelListBox->append("NotebookBar", CuiResId(RID_CUISTR_ALL_COMMANDS));
+ m_xTopLevelListBox->set_active_id("NotebookBar");
+ SelectElement();
+}
+
+SaveInData* SvxNotebookbarConfigPage::CreateSaveInData(
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
+ const OUString& aModuleId, bool bDocConfig)
+{
+ return static_cast<SaveInData*>(
+ new ToolbarSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
+}
+
+void SvxNotebookbarConfigPage::UpdateButtonStates() {}
+
+short SvxNotebookbarConfigPage::QueryReset()
+{
+ OUString msg = CuiResId(RID_CUISTR_CONFIRM_TOOLBAR_RESET);
+
+ OUString saveInName = m_xSaveInListBox->get_active_text();
+
+ OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
+ int nValue = xQueryBox->run();
+ if (nValue == RET_YES)
+ {
+ OUString sOriginalUIPath = CustomNotebookbarGenerator::getOriginalUIPath();
+ OUString sCustomizedUIPath = CustomNotebookbarGenerator::getCustomizedUIPath();
+ osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
+ OUString sNotebookbarInterface = getFileName(m_sFileName);
+ Sequence<OUString> sSequenceEntries;
+ CustomNotebookbarGenerator::setCustomizedUIItem(sSequenceEntries, sNotebookbarInterface);
+ OUString sUIPath = "modules/s" + m_sAppName.toAsciiLowerCase() + "/ui/";
+ sfx2::SfxNotebookBar::ReloadNotebookBar(sUIPath);
+ }
+ return nValue;
+}
+
+void SvxConfigPage::InsertEntryIntoNotebookbarTabUI(std::u16string_view sClassId,
+ const OUString& sUIItemId,
+ const OUString& sUIItemCommand,
+ weld::TreeView& rTreeView,
+ const weld::TreeIter& rIter)
+{
+ css::uno::Reference<css::container::XNameAccess> m_xCommandToLabelMap;
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference<container::XNameAccess> xNameAccess(
+ css::frame::theUICommandDescription::get(xContext));
+
+ uno::Sequence<beans::PropertyValue> aPropSeq;
+
+ xNameAccess->getByName(getModuleId(m_sAppName)) >>= m_xCommandToLabelMap;
+
+ try
+ {
+ uno::Any aModuleVal = m_xCommandToLabelMap->getByName(sUIItemCommand);
+
+ aModuleVal >>= aPropSeq;
+ }
+ catch (container::NoSuchElementException&)
+ {
+ }
+
+ OUString aLabel;
+ for (auto const& prop : std::as_const(aPropSeq))
+ if (prop.Name == "Name")
+ prop.Value >>= aLabel;
+
+ OUString aName = SvxConfigPageHelper::stripHotKey(aLabel);
+
+ if (sClassId == u"GtkSeparatorMenuItem" || sClassId == u"GtkSeparator")
+ {
+ rTreeView.set_text(rIter, "--------------------------------------------", 0);
+ }
+ else
+ {
+ if (aName.isEmpty())
+ aName = sUIItemId;
+ auto xImage = GetSaveInData()->GetImage(sUIItemCommand);
+ if (xImage.is())
+ rTreeView.set_image(rIter, xImage, -1);
+ rTreeView.set_text(rIter, aName, 0);
+ rTreeView.set_id(rIter, sUIItemId);
+ }
+}
+
+void SvxNotebookbarConfigPage::getNodeValue(xmlNode* pNodePtr, NotebookbarEntries& aNodeEntries)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>("visible"))))
+ {
+ xmlChar* aValue = xmlNodeGetContent(pNodePtr);
+ const char* cVisibleValue = reinterpret_cast<const char*>(aValue);
+ aNodeEntries.sVisibleValue = charToString(cVisibleValue);
+ xmlFree(aValue);
+ }
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>("action_name"))))
+ {
+ xmlChar* aValue = xmlNodeGetContent(pNodePtr);
+ const char* cActionName = reinterpret_cast<const char*>(aValue);
+ aNodeEntries.sActionName = charToString(cActionName);
+ xmlFree(aValue);
+ }
+ xmlFree(UriValue);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+void SvxNotebookbarConfigPage::searchNodeandAttribute(std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory,
+ CategoriesEntries& aCurItemEntry,
+ xmlNode* pNodePtr, bool isCategory)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (pNodePtr->type == XML_ELEMENT_NODE)
+ {
+ const char* cNodeName = reinterpret_cast<const char*>(pNodePtr->name);
+ if (strcmp(cNodeName, "object") == 0)
+ {
+ OUString sSecondVal;
+
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
+ const char* cUIItemID = reinterpret_cast<const char*>(UriValue);
+ OUString sUIItemId = charToString(cUIItemID);
+ xmlFree(UriValue);
+
+ UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("class"));
+ const char* cClassId = reinterpret_cast<const char*>(UriValue);
+ OUString sClassId = charToString(cClassId);
+ xmlFree(UriValue);
+
+ CategoriesEntries aCategoryEntry;
+ if (sClassId == "sfxlo-PriorityHBox")
+ {
+ aCategoryEntry.sDisplayName = sUIItemId;
+ aCategoryEntry.sUIItemId = sUIItemId;
+ aCategoryEntry.sClassType = sClassId;
+ aCategoryList.push_back(aCategoryEntry);
+
+ aCurItemEntry = aCategoryEntry;
+ }
+ else if (sClassId == "sfxlo-PriorityMergedHBox")
+ {
+ aCategoryEntry.sDisplayName = aCurItemEntry.sDisplayName + " | " + sUIItemId;
+ aCategoryEntry.sUIItemId = sUIItemId;
+ aCategoryEntry.sClassType = sClassId;
+
+ if (aCurItemEntry.sClassType == sClassId)
+ {
+ sal_Int32 rPos = 0;
+ aCategoryEntry.sDisplayName
+ = OUString::Concat(
+ o3tl::getToken(aCurItemEntry.sDisplayName, rPos, ' ', rPos))
+ + " | " + sUIItemId;
+ }
+ aCategoryList.push_back(aCategoryEntry);
+ aCurItemEntry = aCategoryEntry;
+ }
+ else if (sClassId == "svtlo-ManagedMenuButton")
+ {
+ sal_Int32 rPos = 1;
+ sSecondVal = sUIItemId.getToken(rPos, ':', rPos);
+ if (!sSecondVal.isEmpty())
+ {
+ aCategoryEntry.sDisplayName
+ = aCurItemEntry.sDisplayName + " | " + sSecondVal;
+ aCategoryEntry.sUIItemId = sSecondVal;
+ aCategoryList.push_back(aCategoryEntry);
+ }
+ }
+
+ NotebookbarEntries nodeEntries;
+ if (isCategoryAvailable(sClassId, sUIItemId, sActiveCategory, isCategory)
+ || isCategory)
+ {
+ isCategory = true;
+ if (sClassId == "GtkMenuItem" || sClassId == "GtkToolButton"
+ || sClassId == "GtkMenuToolButton"
+ || (sClassId == "svtlo-ManagedMenuButton" && sSecondVal.isEmpty()))
+ {
+ nodeEntries.sClassId = sClassId;
+ nodeEntries.sUIItemId = sUIItemId;
+ nodeEntries.sDisplayName = sUIItemId;
+
+ getNodeValue(pNodePtr, nodeEntries);
+ aEntries.push_back(nodeEntries);
+ }
+ else if (sClassId == "GtkSeparatorMenuItem" || sClassId == "GtkSeparator")
+ {
+ nodeEntries.sClassId = sClassId;
+ nodeEntries.sUIItemId = sUIItemId;
+ nodeEntries.sDisplayName = "Null";
+ nodeEntries.sVisibleValue = "Null";
+ nodeEntries.sActionName = "Null";
+ aEntries.push_back(nodeEntries);
+ }
+ else if (sClassId == "sfxlo-PriorityHBox"
+ || sClassId == "sfxlo-PriorityMergedHBox"
+ || sClassId == "svtlo-ManagedMenuButton")
+ {
+ nodeEntries.sClassId = sClassId;
+ nodeEntries.sUIItemId = sUIItemId;
+ nodeEntries.sDisplayName
+ = aCategoryList[aCategoryList.size() - 1].sDisplayName;
+ nodeEntries.sVisibleValue = "Null";
+ nodeEntries.sActionName = "Null";
+ aEntries.push_back(nodeEntries);
+ }
+ }
+ }
+ searchNodeandAttribute(aEntries, aCategoryList, sActiveCategory, aCurItemEntry,
+ pNodePtr, isCategory);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+void SvxNotebookbarConfigPage::FillFunctionsList(xmlNodePtr pRootNodePtr,
+ std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory)
+{
+ CategoriesEntries aCurItemEntry;
+ searchNodeandAttribute(aEntries, aCategoryList, sActiveCategory, aCurItemEntry, pRootNodePtr,
+ false);
+}
+
+void SvxNotebookbarConfigPage::SelectElement()
+{
+ OString sUIFileUIPath = CustomNotebookbarGenerator::getSystemPath(
+ CustomNotebookbarGenerator::getCustomizedUIPath());
+ xmlDocPtr pDoc = xmlParseFile(sUIFileUIPath.getStr());
+ if (!pDoc)
+ return;
+ xmlNodePtr pNodePtr = xmlDocGetRootElement(pDoc);
+
+ std::vector<NotebookbarEntries> aEntries;
+ std::vector<CategoriesEntries> aCategoryList;
+ OUString sActiveCategory = m_xTopLevelListBox->get_active_id();
+ FillFunctionsList(pNodePtr, aEntries, aCategoryList, sActiveCategory);
+
+ if (m_xTopLevelListBox->get_count() == 1)
+ {
+ for (std::size_t nIdx = 0; nIdx < aCategoryList.size(); nIdx++)
+ m_xTopLevelListBox->append(aCategoryList[nIdx].sUIItemId,
+ aCategoryList[nIdx].sDisplayName);
+ }
+ tools::ULong nStart = 0;
+ if (aEntries[nStart].sClassId == "sfxlo-PriorityHBox"
+ || aEntries[nStart].sClassId == "sfxlo-PriorityMergedHBox")
+ nStart = 1;
+
+ std::vector<NotebookbarEntries> aTempEntries;
+ for (std::size_t nIdx = nStart; nIdx < aEntries.size(); nIdx++)
+ {
+ if (aEntries[nIdx].sClassId == "svtlo-ManagedMenuButton")
+ {
+ aTempEntries.push_back(aEntries[nIdx]);
+ sal_Int32 rPos = 1;
+ sActiveCategory = aEntries[nIdx].sUIItemId.getToken(rPos, ':', rPos);
+ FillFunctionsList(pNodePtr, aTempEntries, aCategoryList, sActiveCategory);
+ }
+ else
+ aTempEntries.push_back(aEntries[nIdx]);
+ }
+
+ aEntries = std::move(aTempEntries);
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ rTreeView.bulk_insert_for_each(
+ aEntries.size(), [this, &rTreeView, &aEntries](weld::TreeIter& rIter, int nIdx) {
+ OUString sId(OUString::number(nIdx));
+ rTreeView.set_id(rIter, sId);
+ if (aEntries[nIdx].sActionName != "Null")
+ {
+ if (aEntries[nIdx].sVisibleValue == "True")
+ {
+ rTreeView.set_toggle(rIter, TRISTATE_TRUE);
+ }
+ else
+ {
+ rTreeView.set_toggle(rIter, TRISTATE_FALSE);
+ }
+ }
+ InsertEntryIntoNotebookbarTabUI(aEntries[nIdx].sClassId, aEntries[nIdx].sDisplayName,
+ aEntries[nIdx].sActionName, rTreeView, rIter);
+ });
+
+ aEntries.clear();
+
+ xmlFreeDoc(pDoc);
+}
+
+SvxNotebookbarEntriesListBox::SvxNotebookbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
+ SvxConfigPage* pPg)
+ : SvxMenuEntriesListBox(std::move(xParent), pPg)
+{
+ m_xControl->connect_toggled(LINK(this, SvxNotebookbarEntriesListBox, CheckButtonHdl));
+ m_xControl->connect_key_press(Link<const KeyEvent&, bool>());
+ m_xControl->connect_key_press(LINK(this, SvxNotebookbarEntriesListBox, KeyInputHdl));
+}
+
+SvxNotebookbarEntriesListBox::~SvxNotebookbarEntriesListBox() {}
+
+static void EditRegistryFile(std::u16string_view sUIItemId, const OUString& sSetEntry,
+ const OUString& sNotebookbarInterface)
+{
+ int nFlag = 0;
+ Sequence<OUString> aOldEntries
+ = CustomNotebookbarGenerator::getCustomizedUIItem(sNotebookbarInterface);
+ Sequence<OUString> aNewEntries(aOldEntries.getLength() + 1);
+ auto pNewEntries = aNewEntries.getArray();
+ for (int nIdx = 0; nIdx < aOldEntries.getLength(); nIdx++)
+ {
+ sal_Int32 rPos = 0;
+ std::u16string_view sFirstValue = o3tl::getToken(aOldEntries[nIdx], rPos, ',', rPos);
+ if (sFirstValue == sUIItemId)
+ {
+ aOldEntries.getArray()[nIdx] = sSetEntry;
+ nFlag = 1;
+ break;
+ }
+ pNewEntries[nIdx] = aOldEntries[nIdx];
+ }
+
+ if (nFlag == 0)
+ {
+ pNewEntries[aOldEntries.getLength()] = sSetEntry;
+ CustomNotebookbarGenerator::setCustomizedUIItem(aNewEntries, sNotebookbarInterface);
+ }
+ else
+ {
+ CustomNotebookbarGenerator::setCustomizedUIItem(aOldEntries, sNotebookbarInterface);
+ }
+}
+
+void SvxNotebookbarEntriesListBox::ChangedVisibility(int nRow)
+{
+ OUString sUIItemId = m_xControl->get_selected_id();
+ OUString sNotebookbarInterface = getFileName(m_pPage->GetFileName());
+
+ OUString sVisible;
+ if (m_xControl->get_toggle(nRow) == TRISTATE_TRUE)
+ sVisible = "True";
+ else
+ sVisible = "False";
+ OUString sSetEntries = sUIItemId + ",visible," + sVisible;
+ Sequence<OUString> sSeqOfEntries{ sSetEntries };
+ EditRegistryFile(sUIItemId, sSetEntries, sNotebookbarInterface);
+ CustomNotebookbarGenerator::modifyCustomizedUIFile(sSeqOfEntries);
+ OUString sUIPath = "modules/s" + m_pPage->GetAppName().toAsciiLowerCase() + "/ui/";
+ sfx2::SfxNotebookBar::ReloadNotebookBar(sUIPath);
+}
+
+IMPL_LINK(SvxNotebookbarEntriesListBox, CheckButtonHdl, const weld::TreeView::iter_col&, rRowCol,
+ void)
+{
+ ChangedVisibility(m_xControl->get_iter_index_in_parent(rRowCol.first));
+}
+
+IMPL_LINK(SvxNotebookbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ if (rKeyEvent.GetKeyCode() == KEY_SPACE)
+ {
+ int nRow = m_xControl->get_selected_index();
+ m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow) == TRISTATE_TRUE ? TRISTATE_FALSE
+ : TRISTATE_TRUE);
+ ChangedVisibility(nRow);
+ return true;
+ }
+ return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxToolbarConfigPage.cxx b/cui/source/customize/SvxToolbarConfigPage.cxx
new file mode 100644
index 000000000..bc8346922
--- /dev/null
+++ b/cui/source/customize/SvxToolbarConfigPage.cxx
@@ -0,0 +1,929 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <vcl/event.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/commandevent.hxx>
+
+#include <sfx2/sfxsids.hrc>
+#include <svl/stritem.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <cfg.hxx>
+#include <SvxToolbarConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include <dialmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+#include <dlgname.hxx>
+
+SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SvxConfigPage(pPage, pController, rSet)
+{
+ m_xGearBtn = m_xBuilder->weld_menu_button("toolbargearbtn");
+ m_xGearBtn->show();
+ m_xContainer->set_help_id(HID_SVX_CONFIG_TOOLBAR);
+
+ m_xContentsListBox.reset(
+ new SvxToolbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
+ m_xDropTargetHelper.reset(
+ new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ Size aSize(m_xFunctions->get_size_request());
+ rTreeView.set_size_request(aSize.Width(), aSize.Height());
+
+ rTreeView.set_hexpand(true);
+ rTreeView.set_vexpand(true);
+ rTreeView.set_help_id(HID_SVX_CONFIG_TOOLBAR_CONTENTS);
+ rTreeView.show();
+
+ rTreeView.connect_changed(LINK(this, SvxToolbarConfigPage, SelectToolbarEntry));
+ rTreeView.connect_popup_menu(LINK(this, SvxToolbarConfigPage, ContentContextMenuHdl));
+
+ m_xFunctions->get_widget().connect_popup_menu(
+ LINK(this, SvxToolbarConfigPage, FunctionContextMenuHdl));
+
+ m_xTopLevelListBox->set_help_id(HID_SVX_TOPLEVELLISTBOX);
+ m_xSaveInListBox->set_help_id(HID_SVX_SAVE_IN);
+ m_xMoveUpButton->set_help_id(HID_SVX_UP_TOOLBAR_ITEM);
+ m_xMoveDownButton->set_help_id(HID_SVX_DOWN_TOOLBAR_ITEM);
+ m_xDescriptionField->set_help_id(HID_SVX_DESCFIELD);
+
+ m_xCommandCategoryListBox->connect_changed(LINK(this, SvxToolbarConfigPage, SelectCategory));
+
+ m_xGearBtn->connect_selected(LINK(this, SvxToolbarConfigPage, GearHdl));
+
+ m_xMoveUpButton->connect_clicked(LINK(this, SvxToolbarConfigPage, MoveHdl));
+ m_xMoveDownButton->connect_clicked(LINK(this, SvxToolbarConfigPage, MoveHdl));
+ // Always enable Up and Down buttons
+ // added for issue i53677 by shizhoubo
+ m_xMoveDownButton->set_sensitive(true);
+ m_xMoveUpButton->set_sensitive(true);
+
+ m_xAddCommandButton->connect_clicked(LINK(this, SvxToolbarConfigPage, AddCommandHdl));
+ m_xRemoveCommandButton->connect_clicked(LINK(this, SvxToolbarConfigPage, RemoveCommandHdl));
+
+ m_xInsertBtn->connect_selected(LINK(this, SvxToolbarConfigPage, InsertHdl));
+ m_xModifyBtn->connect_selected(LINK(this, SvxToolbarConfigPage, ModifyItemHdl));
+ m_xResetBtn->connect_clicked(LINK(this, SvxToolbarConfigPage, ResetToolbarHdl));
+
+ // "Insert Submenu" is irrelevant to the toolbars
+ m_xInsertBtn->remove_item("insertsubmenu");
+
+ // Gear menu's "Move" action is irrelevant to the toolbars
+ m_xGearBtn->set_item_sensitive("toolbar_gear_move", false);
+
+ // default toolbar to select is standardbar unless a different one
+ // has been passed in
+ m_aURLToSelect = ITEM_TOOLBAR_URL;
+ m_aURLToSelect += "standardbar";
+
+ const SfxPoolItem* pItem = rSet.GetItem(SID_CONFIG);
+
+ if (pItem)
+ {
+ OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if (text.startsWith(ITEM_TOOLBAR_URL))
+ {
+ m_aURLToSelect = text.copy(0);
+ }
+ }
+}
+
+void SvxToolbarConfigPage::ListModified()
+{
+ // regenerate with the current ordering within the list
+ SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
+ pEntries->clear();
+
+ for (int i = 0; i < m_xContentsListBox->n_children(); ++i)
+ pEntries->push_back(weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(i)));
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ if (pToolbar)
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
+}
+
+SvxToolbarConfigPage::~SvxToolbarConfigPage()
+{
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ {
+ ToolbarSaveInData* pData = weld::fromId<ToolbarSaveInData*>(m_xSaveInListBox->get_id(i));
+ delete pData;
+ }
+ m_xSaveInListBox->clear();
+}
+
+void SvxToolbarConfigPage::DeleteSelectedTopLevel()
+{
+ const sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
+ pSaveInData->RemoveToolbar(GetTopLevelSelection());
+
+ int nCount = m_xTopLevelListBox->get_count();
+ if (nCount > 1)
+ {
+ // select next entry after the one being deleted
+ // selection position is indexed from 0 so need to
+ // subtract one from the entry count
+ if (nSelectionPos != nCount - 1)
+ {
+ m_xTopLevelListBox->set_active(nSelectionPos + 1);
+ }
+ else
+ {
+ m_xTopLevelListBox->set_active(nSelectionPos - 1);
+ }
+ SelectElement();
+
+ // and now remove the entry
+ m_xTopLevelListBox->remove(nSelectionPos);
+ }
+ else
+ {
+ ReloadTopLevelListBox();
+ }
+}
+
+void SvxToolbarConfigPage::DeleteSelectedContent()
+{
+ int nActEntry = m_xContentsListBox->get_selected_index();
+
+ if (nActEntry == -1)
+ return;
+
+ // get currently selected entry
+ SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ // remove entry from the list for this toolbar
+ SvxConfigPageHelper::RemoveEntry(pToolbar->GetEntries(), pEntry);
+
+ // remove toolbar entry from UI
+ m_xContentsListBox->remove(nActEntry);
+
+ // delete data for toolbar entry
+ delete pEntry;
+
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
+ UpdateButtonStates();
+
+ // if this is the last entry in the toolbar and it is a user
+ // defined toolbar pop up a dialog asking the user if they
+ // want to delete the toolbar
+ if (m_xContentsListBox->n_children() == 0 && GetTopLevelSelection()->IsDeletable())
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_SXVSTR_CONFIRM_DELETE_TOOLBAR)));
+ if (xQueryBox->run() == RET_YES)
+ {
+ DeleteSelectedTopLevel();
+ }
+ }
+}
+
+IMPL_LINK(SvxToolbarConfigPage, MoveHdl, weld::Button&, rButton, void)
+{
+ MoveEntry(&rButton == m_xMoveUpButton.get());
+}
+
+void SvxToolbarConfigPage::MoveEntry(bool bMoveUp)
+{
+ SvxConfigPage::MoveEntry(bMoveUp);
+
+ // Apply change to currently selected toolbar
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ if (pToolbar)
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
+ else
+ {
+ SAL_WARN("cui.customize", "SvxToolbarConfigPage::MoveEntry(): no entry");
+ UpdateButtonStates();
+ }
+}
+
+void SvxToolbarConfigPage::Init()
+{
+ // ensure that the UI is cleared before populating it
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+
+ ReloadTopLevelListBox();
+
+ sal_Int32 nCount = m_xTopLevelListBox->get_count();
+ sal_Int32 nPos = nCount > 0 ? 0 : -1;
+
+ if (!m_aURLToSelect.isEmpty())
+ {
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ SvxConfigEntry* pData = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(i));
+
+ if (pData->GetCommand().equals(m_aURLToSelect))
+ {
+ nPos = i;
+ break;
+ }
+ }
+
+ // in future select the default toolbar: Standard
+ m_aURLToSelect = ITEM_TOOLBAR_URL;
+ m_aURLToSelect += "standardbar";
+ }
+
+ m_xTopLevelListBox->set_active(nPos);
+ SelectElement();
+
+ m_xCommandCategoryListBox->Init(comphelper::getProcessComponentContext(), m_xFrame,
+ m_aModuleId);
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), OUString(), GetSaveInData());
+ SelectFunctionHdl(m_xFunctions->get_widget());
+}
+
+SaveInData* SvxToolbarConfigPage::CreateSaveInData(
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
+ const OUString& aModuleId, bool bDocConfig)
+{
+ return static_cast<SaveInData*>(
+ new ToolbarSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
+}
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectToolbarEntry, weld::TreeView&, void)
+{
+ UpdateButtonStates();
+}
+
+IMPL_LINK(SvxToolbarConfigPage, GearHdl, const OString&, rIdent, void)
+{
+ SvxConfigEntry* pCurrentToolbar = GetTopLevelSelection();
+
+ if (rIdent == "toolbar_gear_add")
+ {
+ OUString prefix = CuiResId(RID_CUISTR_NEW_TOOLBAR);
+
+ OUString aNewName
+ = SvxConfigPageHelper::generateCustomName(prefix, GetSaveInData()->GetEntries());
+
+ OUString aNewURL = SvxConfigPageHelper::generateCustomURL(GetSaveInData()->GetEntries());
+
+ SvxNewToolbarDialog aNameDialog(GetFrameWeld(), aNewName);
+
+ // Reflect the actual m_xSaveInListBox into the new toolbar dialog
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ aNameDialog.m_xSaveInListBox->append_text(m_xSaveInListBox->get_text(i));
+
+ aNameDialog.m_xSaveInListBox->set_active(m_xSaveInListBox->get_active());
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ // Where to save the new toolbar? (i.e. Modulewise or documentwise)
+ int nInsertPos = aNameDialog.m_xSaveInListBox->get_active();
+
+ ToolbarSaveInData* pData
+ = weld::fromId<ToolbarSaveInData*>(m_xSaveInListBox->get_id(nInsertPos));
+
+ if (GetSaveInData() != pData)
+ {
+ m_xSaveInListBox->set_active(nInsertPos);
+ SelectSaveInLocation(*m_xSaveInListBox);
+ }
+
+ SvxConfigEntry* pToolbar = new SvxConfigEntry(aNewName, aNewURL, true, false);
+
+ pToolbar->SetUserDefined();
+ pToolbar->SetMain();
+
+ pData->CreateToolbar(pToolbar);
+
+ OUString sId(weld::toId(pToolbar));
+ m_xTopLevelListBox->append(sId, pToolbar->GetName());
+ m_xTopLevelListBox->set_active_id(sId);
+ SelectElement();
+
+ pData->SetModified();
+ }
+ }
+ else if (rIdent == "toolbar_gear_delete")
+ {
+ if (pCurrentToolbar && pCurrentToolbar->IsDeletable())
+ {
+ DeleteSelectedTopLevel();
+ UpdateButtonStates();
+ }
+ }
+ else if (rIdent == "toolbar_gear_rename")
+ {
+ sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
+ SvxConfigEntry* pToolbar
+ = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos));
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
+
+ //Rename the toolbar
+ OUString sCurrentName(SvxConfigPageHelper::stripHotKey(pToolbar->GetName()));
+ OUString sDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), sCurrentName, sDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_TOOLBAR);
+ aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_TOOLBAR));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ OUString sNewName = aNameDialog.GetName();
+
+ if (sCurrentName == sNewName)
+ return;
+
+ pToolbar->SetName(sNewName);
+ pSaveInData->ApplyToolbar(pToolbar);
+
+ // have to use remove and insert to change the name
+ m_xTopLevelListBox->remove(nSelectionPos);
+ OUString sId(weld::toId(pToolbar));
+ m_xTopLevelListBox->insert(nSelectionPos, sNewName, &sId, nullptr, nullptr);
+ m_xTopLevelListBox->set_active_id(sId);
+ }
+ }
+ else if (rIdent == "toolbar_gear_iconOnly" || rIdent == "toolbar_gear_textOnly"
+ || rIdent == "toolbar_gear_iconAndText")
+ {
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
+
+ if (pCurrentToolbar == nullptr || pSaveInData == nullptr)
+ {
+ SAL_WARN("cui.customize", "NULL toolbar or savein data");
+ return;
+ }
+
+ sal_Int32 nStyle = 0;
+ if (rIdent == "toolbar_gear_iconOnly")
+ nStyle = 0;
+ else if (rIdent == "toolbar_gear_textOnly")
+ nStyle = 1;
+ else if (rIdent == "toolbar_gear_iconAndText")
+ nStyle = 2;
+
+ pCurrentToolbar->SetStyle(nStyle);
+ pSaveInData->SetSystemStyle(m_xFrame, pCurrentToolbar->GetCommand(), nStyle);
+
+ SelectElement();
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown gear menu option: " << rIdent);
+ return;
+ }
+}
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectCategory, weld::ComboBox&, void)
+{
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
+
+ SelectFunctionHdl(m_xFunctions->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, AddCommandHdl, weld::Button&, void) { AddFunction(); }
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, RemoveCommandHdl, weld::Button&, void)
+{
+ DeleteSelectedContent();
+}
+
+IMPL_LINK(SvxToolbarConfigPage, InsertHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "insertseparator")
+ {
+ // Get the currently selected toolbar
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
+ pNewEntryData->SetUserDefined();
+
+ int nPos = AppendEntry(pNewEntryData, -1);
+ InsertEntryIntoUI(pNewEntryData, m_xContentsListBox->get_widget(), nPos);
+
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
+
+ UpdateButtonStates();
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+}
+
+IMPL_LINK(SvxToolbarConfigPage, ModifyItemHdl, const OString&, rIdent, void)
+{
+ bool bNeedsApply = false;
+
+ // get currently selected toolbar
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ if (rIdent.isEmpty() || pToolbar == nullptr)
+ {
+ SAL_WARN("cui.customize", "No toolbar selected, or empty rIdent!");
+ return;
+ }
+
+ if (rIdent == "renameItem")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry
+ = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ OUString aNewName(SvxConfigPageHelper::stripHotKey(pEntry->GetName()));
+ OUString aDesc = CuiResId(RID_CUISTR_LABEL_NEW_NAME);
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM);
+ aNameDialog.set_title(CuiResId(RID_CUISTR_RENAME_TOOLBAR));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ if (aNewName.isEmpty()) // tdf#80758 - Accelerator character ("~") is passed as
+ pEntry->SetName("~"); // the button name in case of empty values.
+ else
+ pEntry->SetName(aNewName);
+
+ m_xContentsListBox->set_text(nActEntry, aNewName, 0);
+ bNeedsApply = true;
+ }
+ }
+ else if (rIdent == "changeIcon")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry
+ = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ SvxIconSelectorDialog aIconDialog(GetFrameWeld(), GetSaveInData()->GetImageManager(),
+ GetSaveInData()->GetParentImageManager());
+
+ if (aIconDialog.run() == RET_OK)
+ {
+ css::uno::Reference<css::graphic::XGraphic> newgraphic = aIconDialog.GetSelectedIcon();
+
+ if (newgraphic.is())
+ {
+ css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
+
+ if (!pEntry->GetBackupGraphic().is())
+ {
+ css::uno::Reference<css::graphic::XGraphic> backup
+ = SvxConfigPageHelper::GetGraphic(GetSaveInData()->GetImageManager(),
+ aURLSeq[0]);
+
+ if (backup.is())
+ {
+ pEntry->SetBackupGraphic(backup);
+ }
+ }
+
+ css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{
+ newgraphic
+ };
+ try
+ {
+ GetSaveInData()->GetImageManager()->replaceImages(
+ SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq);
+
+ m_xContentsListBox->remove(nActEntry);
+
+ OUString sId(weld::toId(pEntry));
+ m_xContentsListBox->insert(nActEntry, sId);
+ m_xContentsListBox->set_toggle(nActEntry, pEntry->IsVisible() ? TRISTATE_TRUE
+ : TRISTATE_FALSE);
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
+
+ m_xContentsListBox->select(nActEntry);
+ m_xContentsListBox->scroll_to_row(nActEntry);
+
+ GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
+ }
+ catch (const css::uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Error replacing image");
+ }
+ }
+ }
+ }
+ else if (rIdent == "resetIcon")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry
+ = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ css::uno::Reference<css::graphic::XGraphic> backup = pEntry->GetBackupGraphic();
+
+ css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq{ backup };
+
+ css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
+
+ try
+ {
+ GetSaveInData()->GetImageManager()->replaceImages(SvxConfigPageHelper::GetImageType(),
+ aURLSeq, aGraphicSeq);
+
+ m_xContentsListBox->remove(nActEntry);
+
+ OUString sId(weld::toId(pEntry));
+ m_xContentsListBox->insert(nActEntry, sId);
+ m_xContentsListBox->set_toggle(nActEntry,
+ pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
+
+ m_xContentsListBox->select(nActEntry);
+ m_xContentsListBox->scroll_to_row(nActEntry);
+
+ // reset backup in entry
+ pEntry->SetBackupGraphic(css::uno::Reference<css::graphic::XGraphic>());
+
+ GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
+ }
+ catch (const css::uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Error resetting image");
+ }
+ }
+ else if (rIdent == "restoreItem")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry
+ = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry));
+
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
+
+ OUString aSystemName = pSaveInData->GetSystemUIName(pEntry->GetCommand());
+
+ if (!pEntry->GetName().equals(aSystemName))
+ {
+ pEntry->SetName(aSystemName);
+ m_xContentsListBox->set_text(nActEntry, SvxConfigPageHelper::stripHotKey(aSystemName),
+ 0);
+ bNeedsApply = true;
+ }
+
+ css::uno::Sequence<OUString> aURLSeq{ pEntry->GetCommand() };
+
+ try
+ {
+ GetSaveInData()->GetImageManager()->removeImages(SvxConfigPageHelper::GetImageType(),
+ aURLSeq);
+
+ // reset backup in entry
+ pEntry->SetBackupGraphic(css::uno::Reference<css::graphic::XGraphic>());
+
+ GetSaveInData()->PersistChanges(GetSaveInData()->GetImageManager());
+
+ m_xContentsListBox->remove(nActEntry);
+
+ OUString sId(weld::toId(pEntry));
+ m_xContentsListBox->insert(nActEntry, sId);
+ m_xContentsListBox->set_toggle(nActEntry,
+ pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry);
+
+ m_xContentsListBox->select(nActEntry);
+ m_xContentsListBox->scroll_to_row(nActEntry);
+
+ bNeedsApply = true;
+ }
+ catch (const css::uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Error restoring image");
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+
+ if (bNeedsApply)
+ {
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, ResetToolbarHdl, weld::Button&, void)
+{
+ sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
+
+ SvxConfigEntry* pToolbar
+ = weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos));
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_CONFIRM_RESTORE_DEFAULT)));
+ if (xQueryBox->run() == RET_YES)
+ {
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>(GetSaveInData());
+
+ pSaveInData->RestoreToolbar(pToolbar);
+
+ SelectElement();
+ }
+}
+
+void SvxToolbarConfigPage::UpdateButtonStates()
+{
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ int selection = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator
+ = selection != -1
+ && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(selection))->IsSeparator();
+ bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && selection != -1);
+
+ m_xMoveUpButton->set_sensitive(bIsValidSelection);
+ m_xMoveDownButton->set_sensitive(bIsValidSelection);
+
+ m_xRemoveCommandButton->set_sensitive(bIsValidSelection);
+
+ m_xModifyBtn->set_sensitive(bIsValidSelection && !bIsSeparator);
+
+ // Handle the gear button
+ // "toolbar_gear_add" option is always enabled
+ m_xGearBtn->set_item_sensitive("toolbar_gear_delete", pToolbar && pToolbar->IsDeletable());
+ m_xGearBtn->set_item_sensitive("toolbar_gear_rename", pToolbar && pToolbar->IsRenamable());
+}
+
+short SvxToolbarConfigPage::QueryReset()
+{
+ OUString msg = CuiResId(RID_CUISTR_CONFIRM_TOOLBAR_RESET);
+
+ OUString saveInName = m_xSaveInListBox->get_active_text();
+
+ OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
+ return xQueryBox->run();
+}
+
+void SvxToolbarConfigPage::SelectElement()
+{
+ m_xContentsListBox->clear();
+
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ if (pToolbar == nullptr)
+ {
+ //TODO: Disable related buttons
+ m_xInsertBtn->set_sensitive(false);
+ m_xResetBtn->set_sensitive(false);
+ m_xGearBtn->set_sensitive(false);
+
+ return;
+ }
+ else
+ {
+ m_xInsertBtn->set_sensitive(true);
+ m_xResetBtn->set_sensitive(true);
+ m_xGearBtn->set_sensitive(true);
+ }
+
+ switch (pToolbar->GetStyle())
+ {
+ case 0:
+ {
+ m_xGearBtn->set_item_active("toolbar_gear_iconOnly", true);
+ break;
+ }
+ case 1:
+ {
+ m_xGearBtn->set_item_active("toolbar_gear_textOnly", true);
+ break;
+ }
+ case 2:
+ {
+ m_xGearBtn->set_item_active("toolbar_gear_iconAndText", true);
+ break;
+ }
+ }
+
+ int i = 0;
+ SvxEntries* pEntries = pToolbar->GetEntries();
+ for (auto const& entry : *pEntries)
+ {
+ OUString sId(weld::toId(entry));
+ m_xContentsListBox->insert(i, sId);
+ if (entry->IsBinding() && !entry->IsSeparator())
+ m_xContentsListBox->set_toggle(i, entry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ InsertEntryIntoUI(entry, m_xContentsListBox->get_widget(), i);
+ ++i;
+ }
+
+ UpdateButtonStates();
+}
+
+void SvxToolbarConfigPage::AddFunction(int nTarget)
+{
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ if (pToolbar == nullptr)
+ return;
+
+ // Add the command to the contents listbox of the selected toolbar
+ int nNewLBEntry = SvxConfigPage::AddFunction(nTarget, true /*bAllowDuplicates*/);
+
+ if (nNewLBEntry == -1)
+ return;
+
+ SvxConfigEntry* pEntry = weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nNewLBEntry));
+
+ if (pEntry->IsBinding()) //TODO sep ?
+ {
+ pEntry->SetVisible(true);
+ m_xContentsListBox->set_toggle(nNewLBEntry, TRISTATE_TRUE);
+ }
+
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nNewLBEntry);
+
+ // Changes are not visible on the toolbar until this point
+ // TODO: Figure out a way to show the changes on the toolbar, but revert if
+ // the dialog is closed by pressing "Cancel"
+ // get currently selected toolbar and apply change
+ if (pToolbar != nullptr)
+ {
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar(pToolbar);
+ }
+}
+
+SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
+ SvxToolbarConfigPage* pPg)
+ : SvxMenuEntriesListBox(std::move(xParent), pPg)
+{
+ m_xControl->connect_toggled(LINK(this, SvxToolbarEntriesListBox, CheckButtonHdl));
+ m_xControl->connect_key_press(
+ Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
+ m_xControl->connect_key_press(
+ LINK(this, SvxToolbarEntriesListBox, KeyInputHdl)); // then add the new one
+}
+
+SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox() {}
+
+void SvxToolbarEntriesListBox::ChangedVisibility(int nRow)
+{
+ SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
+
+ if (pEntryData->IsBinding())
+ {
+ pEntryData->SetVisible(m_xControl->get_toggle(nRow) == TRISTATE_TRUE);
+
+ SvxConfigEntry* pToolbar = m_pPage->GetTopLevelSelection();
+
+ ToolbarSaveInData* pToolbarSaveInData
+ = static_cast<ToolbarSaveInData*>(m_pPage->GetSaveInData());
+
+ pToolbarSaveInData->ApplyToolbar(pToolbar);
+ }
+}
+
+IMPL_LINK(SvxToolbarEntriesListBox, CheckButtonHdl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ ChangedVisibility(m_xControl->get_iter_index_in_parent(rRowCol.first));
+}
+
+IMPL_LINK(SvxToolbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ // space key will change visibility of toolbar items
+ if (rKeyEvent.GetKeyCode() == KEY_SPACE)
+ {
+ int nRow = m_xControl->get_selected_index();
+ SvxConfigEntry* pEntryData = weld::fromId<SvxConfigEntry*>(m_xControl->get_id(nRow));
+ if (pEntryData->IsBinding() && !pEntryData->IsSeparator())
+ {
+ m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow) == TRISTATE_TRUE
+ ? TRISTATE_FALSE
+ : TRISTATE_TRUE);
+ ChangedVisibility(nRow);
+ }
+ return true;
+ }
+ return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
+}
+
+IMPL_LINK(SvxToolbarConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
+ if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
+ return false;
+ rTreeView.select(*xIter);
+ SelectToolbarEntry(rTreeView);
+
+ int nSelectIndex = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator
+ = nSelectIndex != -1
+ && weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex))->IsSeparator();
+ bool bIsValidSelection = (m_xContentsListBox->n_children() != 0 && nSelectIndex != -1);
+
+ std::unique_ptr<weld::Builder> xBuilder(
+ Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", false);
+ xContextMenu->set_visible("remove", bIsValidSelection);
+ xContextMenu->set_visible("rename", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("changeIcon", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("resetIcon", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("restoreDefault", bIsValidSelection && !bIsSeparator);
+ OString sCommand(xContextMenu->popup_at_rect(
+ &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
+
+ if (sCommand == "remove")
+ RemoveCommandHdl(*m_xRemoveCommandButton);
+ else if (sCommand == "rename")
+ ModifyItemHdl("renameItem");
+ else if (sCommand == "changeIcon")
+ ModifyItemHdl("changeIcon");
+ else if (sCommand == "resetIcon")
+ ModifyItemHdl("resetIcon");
+ else if (sCommand == "restoreDefault")
+ ModifyItemHdl("restoreItem");
+ else if (!sCommand.isEmpty())
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
+ return true;
+}
+
+IMPL_LINK(SvxToolbarConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xFunctions->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
+ if (!rTreeView.get_dest_row_at_pos(rCEvt.GetMousePosPixel(), xIter.get(), false))
+ return false;
+ rTreeView.select(*xIter);
+ SelectFunctionHdl(rTreeView);
+ std::unique_ptr<weld::Builder> xBuilder(
+ Application::CreateBuilder(&rTreeView, "cui/ui/entrycontextmenu.ui"));
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", true);
+ xContextMenu->set_visible("remove", false);
+ xContextMenu->set_visible("rename", false);
+ xContextMenu->set_visible("changeIcon", false);
+ xContextMenu->set_visible("resetIcon", false);
+ xContextMenu->set_visible("restoreDefault", false);
+ OString sCommand(xContextMenu->popup_at_rect(
+ &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1))));
+
+ if (sCommand == "add")
+ AddCommandHdl(*m_xAddCommandButton);
+ else if (!sCommand.isEmpty())
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/acccfg.cxx b/cui/source/customize/acccfg.cxx
new file mode 100644
index 000000000..080cab981
--- /dev/null
+++ b/cui/source/customize/acccfg.cxx
@@ -0,0 +1,1600 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// include own files
+
+#include <acccfg.hxx>
+#include <cfgutil.hxx>
+#include <dialmgr.hxx>
+
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/minfitem.hxx>
+#include <sfx2/sfxresid.hxx>
+
+#include <sal/macros.h>
+#include <vcl/event.hxx>
+
+#include <strings.hrc>
+#include <sfx2/strings.hrc>
+#include <svx/svxids.hrc>
+
+// include interface declarations
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/StorageFactory.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/form/XReset.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/UIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+// include search util
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <unotools/textsearch.hxx>
+
+// include other projects
+#include <comphelper/processfactory.hxx>
+#include <svtools/acceleratorexecute.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <config_features.h>
+
+// namespaces
+
+using namespace css;
+
+constexpr OUStringLiteral FOLDERNAME_UICONFIG = u"Configurations2";
+
+constexpr OUStringLiteral MEDIATYPE_PROPNAME = u"MediaType";
+
+const sal_uInt16 KEYCODE_ARRAY[] = { KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ KEY_F7,
+ KEY_F8,
+ KEY_F9,
+ KEY_F10,
+ KEY_F11,
+ KEY_F12,
+ KEY_F13,
+ KEY_F14,
+ KEY_F15,
+ KEY_F16,
+
+ KEY_DOWN,
+ KEY_UP,
+ KEY_LEFT,
+ KEY_RIGHT,
+ KEY_HOME,
+ KEY_END,
+ KEY_PAGEUP,
+ KEY_PAGEDOWN,
+ KEY_RETURN,
+ KEY_ESCAPE,
+ KEY_BACKSPACE,
+ KEY_INSERT,
+ KEY_DELETE,
+
+ KEY_OPEN,
+ KEY_CUT,
+ KEY_COPY,
+ KEY_PASTE,
+ KEY_UNDO,
+ KEY_REPEAT,
+ KEY_FIND,
+ KEY_PROPERTIES,
+ KEY_FRONT,
+ KEY_CONTEXTMENU,
+ KEY_MENU,
+ KEY_HELP,
+
+ KEY_SHIFT | KEY_F1,
+ KEY_SHIFT | KEY_F2,
+ KEY_SHIFT | KEY_F3,
+ KEY_SHIFT | KEY_F4,
+ KEY_SHIFT | KEY_F5,
+ KEY_SHIFT | KEY_F6,
+ KEY_SHIFT | KEY_F7,
+ KEY_SHIFT | KEY_F8,
+ KEY_SHIFT | KEY_F9,
+ KEY_SHIFT | KEY_F10,
+ KEY_SHIFT | KEY_F11,
+ KEY_SHIFT | KEY_F12,
+ KEY_SHIFT | KEY_F13,
+ KEY_SHIFT | KEY_F14,
+ KEY_SHIFT | KEY_F15,
+ KEY_SHIFT | KEY_F16,
+
+ KEY_SHIFT | KEY_DOWN,
+ KEY_SHIFT | KEY_UP,
+ KEY_SHIFT | KEY_LEFT,
+ KEY_SHIFT | KEY_RIGHT,
+ KEY_SHIFT | KEY_HOME,
+ KEY_SHIFT | KEY_END,
+ KEY_SHIFT | KEY_PAGEUP,
+ KEY_SHIFT | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_RETURN,
+ KEY_SHIFT | KEY_SPACE,
+ KEY_SHIFT | KEY_ESCAPE,
+ KEY_SHIFT | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_INSERT,
+ KEY_SHIFT | KEY_DELETE,
+ KEY_SHIFT | KEY_EQUAL,
+
+ KEY_MOD1 | KEY_0,
+ KEY_MOD1 | KEY_1,
+ KEY_MOD1 | KEY_2,
+ KEY_MOD1 | KEY_3,
+ KEY_MOD1 | KEY_4,
+ KEY_MOD1 | KEY_5,
+ KEY_MOD1 | KEY_6,
+ KEY_MOD1 | KEY_7,
+ KEY_MOD1 | KEY_8,
+ KEY_MOD1 | KEY_9,
+ KEY_MOD1 | KEY_A,
+ KEY_MOD1 | KEY_B,
+ KEY_MOD1 | KEY_C,
+ KEY_MOD1 | KEY_D,
+ KEY_MOD1 | KEY_E,
+ KEY_MOD1 | KEY_F,
+ KEY_MOD1 | KEY_G,
+ KEY_MOD1 | KEY_H,
+ KEY_MOD1 | KEY_I,
+ KEY_MOD1 | KEY_J,
+ KEY_MOD1 | KEY_K,
+ KEY_MOD1 | KEY_L,
+ KEY_MOD1 | KEY_M,
+ KEY_MOD1 | KEY_N,
+ KEY_MOD1 | KEY_O,
+ KEY_MOD1 | KEY_P,
+ KEY_MOD1 | KEY_Q,
+ KEY_MOD1 | KEY_R,
+ KEY_MOD1 | KEY_S,
+ KEY_MOD1 | KEY_T,
+ KEY_MOD1 | KEY_U,
+ KEY_MOD1 | KEY_V,
+ KEY_MOD1 | KEY_W,
+ KEY_MOD1 | KEY_X,
+ KEY_MOD1 | KEY_Y,
+ KEY_MOD1 | KEY_Z,
+ KEY_MOD1 | KEY_SEMICOLON,
+ KEY_MOD1 | KEY_QUOTELEFT,
+ KEY_MOD1 | KEY_QUOTERIGHT,
+ KEY_MOD1 | KEY_BRACKETLEFT,
+ KEY_MOD1 | KEY_BRACKETRIGHT,
+ KEY_MOD1 | KEY_POINT,
+ KEY_MOD1 | KEY_COMMA,
+ KEY_MOD1 | KEY_TILDE,
+ KEY_MOD1 | KEY_TAB,
+
+ KEY_MOD1 | KEY_F1,
+ KEY_MOD1 | KEY_F2,
+ KEY_MOD1 | KEY_F3,
+ KEY_MOD1 | KEY_F4,
+ KEY_MOD1 | KEY_F5,
+ KEY_MOD1 | KEY_F6,
+ KEY_MOD1 | KEY_F7,
+ KEY_MOD1 | KEY_F8,
+ KEY_MOD1 | KEY_F9,
+ KEY_MOD1 | KEY_F10,
+ KEY_MOD1 | KEY_F11,
+ KEY_MOD1 | KEY_F12,
+ KEY_MOD1 | KEY_F13,
+ KEY_MOD1 | KEY_F14,
+ KEY_MOD1 | KEY_F15,
+ KEY_MOD1 | KEY_F16,
+
+ KEY_MOD1 | KEY_DOWN,
+ KEY_MOD1 | KEY_UP,
+ KEY_MOD1 | KEY_LEFT,
+ KEY_MOD1 | KEY_RIGHT,
+ KEY_MOD1 | KEY_HOME,
+ KEY_MOD1 | KEY_END,
+ KEY_MOD1 | KEY_PAGEUP,
+ KEY_MOD1 | KEY_PAGEDOWN,
+ KEY_MOD1 | KEY_RETURN,
+ KEY_MOD1 | KEY_SPACE,
+ KEY_MOD1 | KEY_BACKSPACE,
+ KEY_MOD1 | KEY_INSERT,
+ KEY_MOD1 | KEY_DELETE,
+
+ KEY_MOD1 | KEY_ADD,
+ KEY_MOD1 | KEY_SUBTRACT,
+ KEY_MOD1 | KEY_MULTIPLY,
+ KEY_MOD1 | KEY_DIVIDE,
+ KEY_MOD1 | KEY_EQUAL,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_0,
+ KEY_SHIFT | KEY_MOD1 | KEY_1,
+ KEY_SHIFT | KEY_MOD1 | KEY_2,
+ KEY_SHIFT | KEY_MOD1 | KEY_3,
+ KEY_SHIFT | KEY_MOD1 | KEY_4,
+ KEY_SHIFT | KEY_MOD1 | KEY_5,
+ KEY_SHIFT | KEY_MOD1 | KEY_6,
+ KEY_SHIFT | KEY_MOD1 | KEY_7,
+ KEY_SHIFT | KEY_MOD1 | KEY_8,
+ KEY_SHIFT | KEY_MOD1 | KEY_9,
+ KEY_SHIFT | KEY_MOD1 | KEY_A,
+ KEY_SHIFT | KEY_MOD1 | KEY_B,
+ KEY_SHIFT | KEY_MOD1 | KEY_C,
+ KEY_SHIFT | KEY_MOD1 | KEY_D,
+ KEY_SHIFT | KEY_MOD1 | KEY_E,
+ KEY_SHIFT | KEY_MOD1 | KEY_F,
+ KEY_SHIFT | KEY_MOD1 | KEY_G,
+ KEY_SHIFT | KEY_MOD1 | KEY_H,
+ KEY_SHIFT | KEY_MOD1 | KEY_I,
+ KEY_SHIFT | KEY_MOD1 | KEY_J,
+ KEY_SHIFT | KEY_MOD1 | KEY_K,
+ KEY_SHIFT | KEY_MOD1 | KEY_L,
+ KEY_SHIFT | KEY_MOD1 | KEY_M,
+ KEY_SHIFT | KEY_MOD1 | KEY_N,
+ KEY_SHIFT | KEY_MOD1 | KEY_O,
+ KEY_SHIFT | KEY_MOD1 | KEY_P,
+ KEY_SHIFT | KEY_MOD1 | KEY_Q,
+ KEY_SHIFT | KEY_MOD1 | KEY_R,
+ KEY_SHIFT | KEY_MOD1 | KEY_S,
+ KEY_SHIFT | KEY_MOD1 | KEY_T,
+ KEY_SHIFT | KEY_MOD1 | KEY_U,
+ KEY_SHIFT | KEY_MOD1 | KEY_V,
+ KEY_SHIFT | KEY_MOD1 | KEY_W,
+ KEY_SHIFT | KEY_MOD1 | KEY_X,
+ KEY_SHIFT | KEY_MOD1 | KEY_Y,
+ KEY_SHIFT | KEY_MOD1 | KEY_Z,
+ KEY_SHIFT | KEY_MOD1 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD1 | KEY_QUOTELEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD1 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD1 | KEY_TILDE,
+ KEY_SHIFT | KEY_MOD1 | KEY_TAB,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_F1,
+ KEY_SHIFT | KEY_MOD1 | KEY_F2,
+ KEY_SHIFT | KEY_MOD1 | KEY_F3,
+ KEY_SHIFT | KEY_MOD1 | KEY_F4,
+ KEY_SHIFT | KEY_MOD1 | KEY_F5,
+ KEY_SHIFT | KEY_MOD1 | KEY_F6,
+ KEY_SHIFT | KEY_MOD1 | KEY_F7,
+ KEY_SHIFT | KEY_MOD1 | KEY_F8,
+ KEY_SHIFT | KEY_MOD1 | KEY_F9,
+ KEY_SHIFT | KEY_MOD1 | KEY_F10,
+ KEY_SHIFT | KEY_MOD1 | KEY_F11,
+ KEY_SHIFT | KEY_MOD1 | KEY_F12,
+ KEY_SHIFT | KEY_MOD1 | KEY_F13,
+ KEY_SHIFT | KEY_MOD1 | KEY_F14,
+ KEY_SHIFT | KEY_MOD1 | KEY_F15,
+ KEY_SHIFT | KEY_MOD1 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_UP,
+ KEY_SHIFT | KEY_MOD1 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD1 | KEY_END,
+ KEY_SHIFT | KEY_MOD1 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD1 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD1 | KEY_ESCAPE,
+ KEY_SHIFT | KEY_MOD1 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD1 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD1 | KEY_EQUAL,
+
+ KEY_MOD2 | KEY_0,
+ KEY_MOD2 | KEY_1,
+ KEY_MOD2 | KEY_2,
+ KEY_MOD2 | KEY_3,
+ KEY_MOD2 | KEY_4,
+ KEY_MOD2 | KEY_5,
+ KEY_MOD2 | KEY_6,
+ KEY_MOD2 | KEY_7,
+ KEY_MOD2 | KEY_8,
+ KEY_MOD2 | KEY_9,
+ KEY_MOD2 | KEY_A,
+ KEY_MOD2 | KEY_B,
+ KEY_MOD2 | KEY_C,
+ KEY_MOD2 | KEY_D,
+ KEY_MOD2 | KEY_E,
+ KEY_MOD2 | KEY_F,
+ KEY_MOD2 | KEY_G,
+ KEY_MOD2 | KEY_H,
+ KEY_MOD2 | KEY_I,
+ KEY_MOD2 | KEY_J,
+ KEY_MOD2 | KEY_K,
+ KEY_MOD2 | KEY_L,
+ KEY_MOD2 | KEY_M,
+ KEY_MOD2 | KEY_N,
+ KEY_MOD2 | KEY_O,
+ KEY_MOD2 | KEY_P,
+ KEY_MOD2 | KEY_Q,
+ KEY_MOD2 | KEY_R,
+ KEY_MOD2 | KEY_S,
+ KEY_MOD2 | KEY_T,
+ KEY_MOD2 | KEY_U,
+ KEY_MOD2 | KEY_V,
+ KEY_MOD2 | KEY_W,
+ KEY_MOD2 | KEY_X,
+ KEY_MOD2 | KEY_Y,
+ KEY_MOD2 | KEY_Z,
+ KEY_MOD2 | KEY_SEMICOLON,
+ KEY_MOD2 | KEY_QUOTELEFT,
+ KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_MOD2 | KEY_POINT,
+ KEY_MOD2 | KEY_COMMA,
+ KEY_MOD2 | KEY_TILDE,
+
+ KEY_MOD2 | KEY_F1,
+ KEY_MOD2 | KEY_F2,
+ KEY_MOD2 | KEY_F3,
+ KEY_MOD2 | KEY_F4,
+ KEY_MOD2 | KEY_F5,
+ KEY_MOD2 | KEY_F6,
+ KEY_MOD2 | KEY_F7,
+ KEY_MOD2 | KEY_F8,
+ KEY_MOD2 | KEY_F9,
+ KEY_MOD2 | KEY_F10,
+ KEY_MOD2 | KEY_F11,
+ KEY_MOD2 | KEY_F12,
+ KEY_MOD2 | KEY_F13,
+ KEY_MOD2 | KEY_F14,
+ KEY_MOD2 | KEY_F15,
+ KEY_MOD2 | KEY_F16,
+
+ KEY_MOD2 | KEY_DOWN,
+ KEY_MOD2 | KEY_UP,
+ KEY_MOD2 | KEY_LEFT,
+ KEY_MOD2 | KEY_RIGHT,
+ KEY_MOD2 | KEY_HOME,
+ KEY_MOD2 | KEY_END,
+ KEY_MOD2 | KEY_PAGEUP,
+ KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_MOD2 | KEY_RETURN,
+ KEY_MOD2 | KEY_SPACE,
+ KEY_MOD2 | KEY_BACKSPACE,
+ KEY_MOD2 | KEY_INSERT,
+ KEY_MOD2 | KEY_DELETE,
+ KEY_MOD2 | KEY_EQUAL,
+
+ KEY_SHIFT | KEY_MOD2 | KEY_0,
+ KEY_SHIFT | KEY_MOD2 | KEY_1,
+ KEY_SHIFT | KEY_MOD2 | KEY_2,
+ KEY_SHIFT | KEY_MOD2 | KEY_3,
+ KEY_SHIFT | KEY_MOD2 | KEY_4,
+ KEY_SHIFT | KEY_MOD2 | KEY_5,
+ KEY_SHIFT | KEY_MOD2 | KEY_6,
+ KEY_SHIFT | KEY_MOD2 | KEY_7,
+ KEY_SHIFT | KEY_MOD2 | KEY_8,
+ KEY_SHIFT | KEY_MOD2 | KEY_9,
+ KEY_SHIFT | KEY_MOD2 | KEY_A,
+ KEY_SHIFT | KEY_MOD2 | KEY_B,
+ KEY_SHIFT | KEY_MOD2 | KEY_C,
+ KEY_SHIFT | KEY_MOD2 | KEY_D,
+ KEY_SHIFT | KEY_MOD2 | KEY_E,
+ KEY_SHIFT | KEY_MOD2 | KEY_F,
+ KEY_SHIFT | KEY_MOD2 | KEY_G,
+ KEY_SHIFT | KEY_MOD2 | KEY_H,
+ KEY_SHIFT | KEY_MOD2 | KEY_I,
+ KEY_SHIFT | KEY_MOD2 | KEY_J,
+ KEY_SHIFT | KEY_MOD2 | KEY_K,
+ KEY_SHIFT | KEY_MOD2 | KEY_L,
+ KEY_SHIFT | KEY_MOD2 | KEY_M,
+ KEY_SHIFT | KEY_MOD2 | KEY_N,
+ KEY_SHIFT | KEY_MOD2 | KEY_O,
+ KEY_SHIFT | KEY_MOD2 | KEY_P,
+ KEY_SHIFT | KEY_MOD2 | KEY_Q,
+ KEY_SHIFT | KEY_MOD2 | KEY_R,
+ KEY_SHIFT | KEY_MOD2 | KEY_S,
+ KEY_SHIFT | KEY_MOD2 | KEY_T,
+ KEY_SHIFT | KEY_MOD2 | KEY_U,
+ KEY_SHIFT | KEY_MOD2 | KEY_V,
+ KEY_SHIFT | KEY_MOD2 | KEY_W,
+ KEY_SHIFT | KEY_MOD2 | KEY_X,
+ KEY_SHIFT | KEY_MOD2 | KEY_Y,
+ KEY_SHIFT | KEY_MOD2 | KEY_Z,
+ KEY_SHIFT | KEY_MOD2 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD2 | KEY_QUOTELEFT,
+ KEY_SHIFT | KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD2 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD2 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD2 | KEY_TILDE,
+
+ KEY_SHIFT | KEY_MOD2 | KEY_F1,
+ KEY_SHIFT | KEY_MOD2 | KEY_F2,
+ KEY_SHIFT | KEY_MOD2 | KEY_F3,
+ KEY_SHIFT | KEY_MOD2 | KEY_F4,
+ KEY_SHIFT | KEY_MOD2 | KEY_F5,
+ KEY_SHIFT | KEY_MOD2 | KEY_F6,
+ KEY_SHIFT | KEY_MOD2 | KEY_F7,
+ KEY_SHIFT | KEY_MOD2 | KEY_F8,
+ KEY_SHIFT | KEY_MOD2 | KEY_F9,
+ KEY_SHIFT | KEY_MOD2 | KEY_F10,
+ KEY_SHIFT | KEY_MOD2 | KEY_F11,
+ KEY_SHIFT | KEY_MOD2 | KEY_F12,
+ KEY_SHIFT | KEY_MOD2 | KEY_F13,
+ KEY_SHIFT | KEY_MOD2 | KEY_F14,
+ KEY_SHIFT | KEY_MOD2 | KEY_F15,
+ KEY_SHIFT | KEY_MOD2 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD2 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD2 | KEY_UP,
+ KEY_SHIFT | KEY_MOD2 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD2 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD2 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD2 | KEY_END,
+ KEY_SHIFT | KEY_MOD2 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD2 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD2 | KEY_ESCAPE,
+ KEY_SHIFT | KEY_MOD2 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD2 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD2 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD2 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD2 | KEY_EQUAL,
+
+ KEY_MOD1 | KEY_MOD2 | KEY_0,
+ KEY_MOD1 | KEY_MOD2 | KEY_1,
+ KEY_MOD1 | KEY_MOD2 | KEY_2,
+ KEY_MOD1 | KEY_MOD2 | KEY_3,
+ KEY_MOD1 | KEY_MOD2 | KEY_4,
+ KEY_MOD1 | KEY_MOD2 | KEY_5,
+ KEY_MOD1 | KEY_MOD2 | KEY_6,
+ KEY_MOD1 | KEY_MOD2 | KEY_7,
+ KEY_MOD1 | KEY_MOD2 | KEY_8,
+ KEY_MOD1 | KEY_MOD2 | KEY_9,
+ KEY_MOD1 | KEY_MOD2 | KEY_A,
+ KEY_MOD1 | KEY_MOD2 | KEY_B,
+ KEY_MOD1 | KEY_MOD2 | KEY_C,
+ KEY_MOD1 | KEY_MOD2 | KEY_D,
+ KEY_MOD1 | KEY_MOD2 | KEY_E,
+ KEY_MOD1 | KEY_MOD2 | KEY_F,
+ KEY_MOD1 | KEY_MOD2 | KEY_G,
+ KEY_MOD1 | KEY_MOD2 | KEY_H,
+ KEY_MOD1 | KEY_MOD2 | KEY_I,
+ KEY_MOD1 | KEY_MOD2 | KEY_J,
+ KEY_MOD1 | KEY_MOD2 | KEY_K,
+ KEY_MOD1 | KEY_MOD2 | KEY_L,
+ KEY_MOD1 | KEY_MOD2 | KEY_M,
+ KEY_MOD1 | KEY_MOD2 | KEY_N,
+ KEY_MOD1 | KEY_MOD2 | KEY_O,
+ KEY_MOD1 | KEY_MOD2 | KEY_P,
+ KEY_MOD1 | KEY_MOD2 | KEY_Q,
+ KEY_MOD1 | KEY_MOD2 | KEY_R,
+ KEY_MOD1 | KEY_MOD2 | KEY_S,
+ KEY_MOD1 | KEY_MOD2 | KEY_T,
+ KEY_MOD1 | KEY_MOD2 | KEY_U,
+ KEY_MOD1 | KEY_MOD2 | KEY_V,
+ KEY_MOD1 | KEY_MOD2 | KEY_W,
+ KEY_MOD1 | KEY_MOD2 | KEY_X,
+ KEY_MOD1 | KEY_MOD2 | KEY_Y,
+ KEY_MOD1 | KEY_MOD2 | KEY_Z,
+ KEY_MOD1 | KEY_MOD2 | KEY_SEMICOLON,
+ KEY_MOD1 | KEY_MOD2 | KEY_QUOTELEFT,
+ KEY_MOD1 | KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_MOD1 | KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_MOD1 | KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_MOD1 | KEY_MOD2 | KEY_POINT,
+ KEY_MOD1 | KEY_MOD2 | KEY_COMMA,
+ KEY_MOD1 | KEY_MOD2 | KEY_TILDE,
+ KEY_MOD1 | KEY_MOD2 | KEY_EQUAL,
+
+ KEY_MOD1 | KEY_MOD2 | KEY_F1,
+ KEY_MOD1 | KEY_MOD2 | KEY_F2,
+ KEY_MOD1 | KEY_MOD2 | KEY_F3,
+ KEY_MOD1 | KEY_MOD2 | KEY_F4,
+ KEY_MOD1 | KEY_MOD2 | KEY_F5,
+ KEY_MOD1 | KEY_MOD2 | KEY_F6,
+ KEY_MOD1 | KEY_MOD2 | KEY_F7,
+ KEY_MOD1 | KEY_MOD2 | KEY_F8,
+ KEY_MOD1 | KEY_MOD2 | KEY_F9,
+ KEY_MOD1 | KEY_MOD2 | KEY_F10,
+ KEY_MOD1 | KEY_MOD2 | KEY_F11,
+ KEY_MOD1 | KEY_MOD2 | KEY_F12,
+ KEY_MOD1 | KEY_MOD2 | KEY_F13,
+ KEY_MOD1 | KEY_MOD2 | KEY_F14,
+ KEY_MOD1 | KEY_MOD2 | KEY_F15,
+ KEY_MOD1 | KEY_MOD2 | KEY_F16,
+
+ KEY_MOD1 | KEY_MOD2 | KEY_DOWN,
+ KEY_MOD1 | KEY_MOD2 | KEY_UP,
+ KEY_MOD1 | KEY_MOD2 | KEY_LEFT,
+ KEY_MOD1 | KEY_MOD2 | KEY_RIGHT,
+ KEY_MOD1 | KEY_MOD2 | KEY_HOME,
+ KEY_MOD1 | KEY_MOD2 | KEY_END,
+ KEY_MOD1 | KEY_MOD2 | KEY_PAGEUP,
+ KEY_MOD1 | KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_MOD1 | KEY_MOD2 | KEY_RETURN,
+ KEY_MOD1 | KEY_MOD2 | KEY_SPACE,
+ KEY_MOD1 | KEY_MOD2 | KEY_BACKSPACE,
+ KEY_MOD1 | KEY_MOD2 | KEY_INSERT,
+ KEY_MOD1 | KEY_MOD2 | KEY_DELETE,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_0,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_1,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_2,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_3,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_4,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_5,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_6,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_7,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_8,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_9,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_A,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_B,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_C,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_D,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_E,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_G,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_H,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_I,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_J,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_K,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_L,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_M,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_N,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_O,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_P,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_Q,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_R,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_S,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_T,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_U,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_V,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_W,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_X,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_Y,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_Z,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_QUOTELEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_TILDE,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F1,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F2,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F3,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F4,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F5,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F6,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F7,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F8,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F9,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F10,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F11,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F12,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F13,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F14,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F15,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_UP,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_END,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_EQUAL
+
+#ifdef __APPLE__
+ ,
+ KEY_MOD3 | KEY_0,
+ KEY_MOD3 | KEY_1,
+ KEY_MOD3 | KEY_2,
+ KEY_MOD3 | KEY_3,
+ KEY_MOD3 | KEY_4,
+ KEY_MOD3 | KEY_5,
+ KEY_MOD3 | KEY_6,
+ KEY_MOD3 | KEY_7,
+ KEY_MOD3 | KEY_8,
+ KEY_MOD3 | KEY_9,
+ KEY_MOD3 | KEY_A,
+ KEY_MOD3 | KEY_B,
+ KEY_MOD3 | KEY_C,
+ KEY_MOD3 | KEY_D,
+ KEY_MOD3 | KEY_E,
+ KEY_MOD3 | KEY_F,
+ KEY_MOD3 | KEY_G,
+ KEY_MOD3 | KEY_H,
+ KEY_MOD3 | KEY_I,
+ KEY_MOD3 | KEY_J,
+ KEY_MOD3 | KEY_K,
+ KEY_MOD3 | KEY_L,
+ KEY_MOD3 | KEY_M,
+ KEY_MOD3 | KEY_N,
+ KEY_MOD3 | KEY_O,
+ KEY_MOD3 | KEY_P,
+ KEY_MOD3 | KEY_Q,
+ KEY_MOD3 | KEY_R,
+ KEY_MOD3 | KEY_S,
+ KEY_MOD3 | KEY_T,
+ KEY_MOD3 | KEY_U,
+ KEY_MOD3 | KEY_V,
+ KEY_MOD3 | KEY_W,
+ KEY_MOD3 | KEY_X,
+ KEY_MOD3 | KEY_Y,
+ KEY_MOD3 | KEY_Z,
+ KEY_MOD3 | KEY_SEMICOLON,
+ KEY_MOD3 | KEY_QUOTELEFT,
+ KEY_MOD3 | KEY_QUOTERIGHT,
+ KEY_MOD3 | KEY_BRACKETLEFT,
+ KEY_MOD3 | KEY_BRACKETRIGHT,
+ KEY_MOD3 | KEY_POINT,
+ KEY_MOD3 | KEY_COMMA,
+ KEY_MOD3 | KEY_TILDE,
+ KEY_MOD3 | KEY_TAB,
+
+ KEY_MOD3 | KEY_F1,
+ KEY_MOD3 | KEY_F2,
+ KEY_MOD3 | KEY_F3,
+ KEY_MOD3 | KEY_F4,
+ KEY_MOD3 | KEY_F5,
+ KEY_MOD3 | KEY_F6,
+ KEY_MOD3 | KEY_F7,
+ KEY_MOD3 | KEY_F8,
+ KEY_MOD3 | KEY_F9,
+ KEY_MOD3 | KEY_F10,
+ KEY_MOD3 | KEY_F11,
+ KEY_MOD3 | KEY_F12,
+ KEY_MOD3 | KEY_F13,
+ KEY_MOD3 | KEY_F14,
+ KEY_MOD3 | KEY_F15,
+ KEY_MOD3 | KEY_F16,
+
+ KEY_MOD3 | KEY_DOWN,
+ KEY_MOD3 | KEY_UP,
+ KEY_MOD3 | KEY_LEFT,
+ KEY_MOD3 | KEY_RIGHT,
+ KEY_MOD3 | KEY_HOME,
+ KEY_MOD3 | KEY_END,
+ KEY_MOD3 | KEY_PAGEUP,
+ KEY_MOD3 | KEY_PAGEDOWN,
+ KEY_MOD3 | KEY_RETURN,
+ KEY_MOD3 | KEY_SPACE,
+ KEY_MOD3 | KEY_BACKSPACE,
+ KEY_MOD3 | KEY_INSERT,
+ KEY_MOD3 | KEY_DELETE,
+
+ KEY_MOD3 | KEY_ADD,
+ KEY_MOD3 | KEY_SUBTRACT,
+ KEY_MOD3 | KEY_MULTIPLY,
+ KEY_MOD3 | KEY_DIVIDE,
+ KEY_MOD3 | KEY_EQUAL,
+
+ KEY_SHIFT | KEY_MOD3 | KEY_0,
+ KEY_SHIFT | KEY_MOD3 | KEY_1,
+ KEY_SHIFT | KEY_MOD3 | KEY_2,
+ KEY_SHIFT | KEY_MOD3 | KEY_3,
+ KEY_SHIFT | KEY_MOD3 | KEY_4,
+ KEY_SHIFT | KEY_MOD3 | KEY_5,
+ KEY_SHIFT | KEY_MOD3 | KEY_6,
+ KEY_SHIFT | KEY_MOD3 | KEY_7,
+ KEY_SHIFT | KEY_MOD3 | KEY_8,
+ KEY_SHIFT | KEY_MOD3 | KEY_9,
+ KEY_SHIFT | KEY_MOD3 | KEY_A,
+ KEY_SHIFT | KEY_MOD3 | KEY_B,
+ KEY_SHIFT | KEY_MOD3 | KEY_C,
+ KEY_SHIFT | KEY_MOD3 | KEY_D,
+ KEY_SHIFT | KEY_MOD3 | KEY_E,
+ KEY_SHIFT | KEY_MOD3 | KEY_F,
+ KEY_SHIFT | KEY_MOD3 | KEY_G,
+ KEY_SHIFT | KEY_MOD3 | KEY_H,
+ KEY_SHIFT | KEY_MOD3 | KEY_I,
+ KEY_SHIFT | KEY_MOD3 | KEY_J,
+ KEY_SHIFT | KEY_MOD3 | KEY_K,
+ KEY_SHIFT | KEY_MOD3 | KEY_L,
+ KEY_SHIFT | KEY_MOD3 | KEY_M,
+ KEY_SHIFT | KEY_MOD3 | KEY_N,
+ KEY_SHIFT | KEY_MOD3 | KEY_O,
+ KEY_SHIFT | KEY_MOD3 | KEY_P,
+ KEY_SHIFT | KEY_MOD3 | KEY_Q,
+ KEY_SHIFT | KEY_MOD3 | KEY_R,
+ KEY_SHIFT | KEY_MOD3 | KEY_S,
+ KEY_SHIFT | KEY_MOD3 | KEY_T,
+ KEY_SHIFT | KEY_MOD3 | KEY_U,
+ KEY_SHIFT | KEY_MOD3 | KEY_V,
+ KEY_SHIFT | KEY_MOD3 | KEY_W,
+ KEY_SHIFT | KEY_MOD3 | KEY_X,
+ KEY_SHIFT | KEY_MOD3 | KEY_Y,
+ KEY_SHIFT | KEY_MOD3 | KEY_Z,
+ KEY_SHIFT | KEY_MOD3 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD3 | KEY_QUOTELEFT,
+ KEY_SHIFT | KEY_MOD3 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD3 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD3 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD3 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD3 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD3 | KEY_TILDE,
+ KEY_SHIFT | KEY_MOD3 | KEY_TAB,
+
+ KEY_SHIFT | KEY_MOD3 | KEY_F1,
+ KEY_SHIFT | KEY_MOD3 | KEY_F2,
+ KEY_SHIFT | KEY_MOD3 | KEY_F3,
+ KEY_SHIFT | KEY_MOD3 | KEY_F4,
+ KEY_SHIFT | KEY_MOD3 | KEY_F5,
+ KEY_SHIFT | KEY_MOD3 | KEY_F6,
+ KEY_SHIFT | KEY_MOD3 | KEY_F7,
+ KEY_SHIFT | KEY_MOD3 | KEY_F8,
+ KEY_SHIFT | KEY_MOD3 | KEY_F9,
+ KEY_SHIFT | KEY_MOD3 | KEY_F10,
+ KEY_SHIFT | KEY_MOD3 | KEY_F11,
+ KEY_SHIFT | KEY_MOD3 | KEY_F12,
+ KEY_SHIFT | KEY_MOD3 | KEY_F13,
+ KEY_SHIFT | KEY_MOD3 | KEY_F14,
+ KEY_SHIFT | KEY_MOD3 | KEY_F15,
+ KEY_SHIFT | KEY_MOD3 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD3 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD3 | KEY_UP,
+ KEY_SHIFT | KEY_MOD3 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD3 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD3 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD3 | KEY_END,
+ KEY_SHIFT | KEY_MOD3 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD3 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD3 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD3 | KEY_ESCAPE,
+ KEY_SHIFT | KEY_MOD3 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD3 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD3 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD3 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD3 | KEY_EQUAL
+#endif
+};
+
+const sal_uInt16 KEYCODE_ARRAY_SIZE = std::size(KEYCODE_ARRAY);
+
+/** select the entry, which match the current key input ... excepting
+ keys, which are used for the dialog itself.
+ */
+IMPL_LINK(SfxAcceleratorConfigPage, KeyInputHdl, const KeyEvent&, rKey, bool)
+{
+ vcl::KeyCode aCode1 = rKey.GetKeyCode();
+ sal_uInt16 nCode1 = aCode1.GetCode();
+ sal_uInt16 nMod1 = aCode1.GetModifier();
+
+ // is it related to our list box ?
+ if ((nCode1 == KEY_DOWN) || (nCode1 == KEY_UP) || (nCode1 == KEY_LEFT) || (nCode1 == KEY_RIGHT)
+ || (nCode1 == KEY_PAGEUP) || (nCode1 == KEY_PAGEDOWN))
+ // no - handle it as normal dialog input
+ return false;
+
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(i));
+ if (pUserData)
+ {
+ sal_uInt16 nCode2 = pUserData->m_aKey.GetCode();
+ sal_uInt16 nMod2 = pUserData->m_aKey.GetModifier();
+
+ if (nCode1 == nCode2 && nMod1 == nMod2)
+ {
+ m_xEntriesBox->select(i);
+ m_xEntriesBox->scroll_to_row(i);
+ return true;
+ }
+ }
+ }
+
+ // no - handle it as normal dialog input
+ return false;
+}
+
+SfxAcceleratorConfigPage::SfxAcceleratorConfigPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& aSet)
+ : SfxTabPage(pPage, pController, "cui/ui/accelconfigpage.ui", "AccelConfigPage", &aSet)
+#if HAVE_FEATURE_SCRIPTING
+ , m_pMacroInfoItem()
+#endif
+ , aLoadAccelConfigStr(CuiResId(RID_CUISTR_LOADACCELCONFIG))
+ , aSaveAccelConfigStr(CuiResId(RID_CUISTR_SAVEACCELCONFIG))
+ , aFilterAllStr(SfxResId(STR_SFX_FILTERNAME_ALL))
+ , aFilterCfgStr(CuiResId(RID_CUISTR_FILTERNAME_CFG))
+ , m_bStylesInfoInitialized(false)
+ , m_aUpdateDataTimer("SfxAcceleratorConfigPage UpdateDataTimer")
+ , m_aFillGroupIdle("SfxAcceleratorConfigPage m_aFillGroupIdle")
+ , m_xEntriesBox(m_xBuilder->weld_tree_view("shortcuts"))
+ , m_xOfficeButton(m_xBuilder->weld_radio_button("office"))
+ , m_xModuleButton(m_xBuilder->weld_radio_button("module"))
+ , m_xChangeButton(m_xBuilder->weld_button("change"))
+ , m_xRemoveButton(m_xBuilder->weld_button("delete"))
+ , m_xGroupLBox(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("category")))
+ , m_xFunctionBox(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("function")))
+ , m_xKeyBox(m_xBuilder->weld_tree_view("keys"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xLoadButton(m_xBuilder->weld_button("load"))
+ , m_xSaveButton(m_xBuilder->weld_button("save"))
+ , m_xResetButton(m_xBuilder->weld_button("reset"))
+{
+ Size aSize(m_xEntriesBox->get_approximate_digit_width() * 40,
+ m_xEntriesBox->get_height_rows(10));
+ m_xEntriesBox->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xEntriesBox->get_approximate_digit_width() * 19,
+ m_xEntriesBox->get_height_rows(9));
+ m_xGroupLBox->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xEntriesBox->get_approximate_digit_width() * 21,
+ m_xEntriesBox->get_height_rows(9));
+ m_xFunctionBox->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xEntriesBox->get_approximate_digit_width() * 20,
+ m_xEntriesBox->get_height_rows(9));
+ m_xKeyBox->set_size_request(aSize.Width(), aSize.Height());
+
+ // install handler functions
+ m_xChangeButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, ChangeHdl));
+ m_xRemoveButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, RemoveHdl));
+ m_xEntriesBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xEntriesBox->connect_key_press(LINK(this, SfxAcceleratorConfigPage, KeyInputHdl));
+ m_xGroupLBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xFunctionBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xKeyBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xLoadButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, Load));
+ m_xSaveButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, Save));
+ m_xResetButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, Default));
+ m_xOfficeButton->connect_toggled(LINK(this, SfxAcceleratorConfigPage, RadioHdl));
+ m_xSearchEdit->connect_changed(LINK(this, SfxAcceleratorConfigPage, SearchUpdateHdl));
+ m_xSearchEdit->connect_focus_out(LINK(this, SfxAcceleratorConfigPage, FocusOut_Impl));
+
+ // detect max keyname width
+ int nMaxWidth = 0;
+ for (unsigned short i : KEYCODE_ARRAY)
+ {
+ int nTmp = m_xEntriesBox->get_pixel_size(vcl::KeyCode(i).GetName()).Width();
+ if (nTmp > nMaxWidth)
+ nMaxWidth = nTmp;
+ }
+ // recalc second tab
+ auto nNewTab = nMaxWidth + 5; // additional space
+
+ // initialize Entriesbox
+ std::vector<int> aWidths{ nNewTab };
+ m_xEntriesBox->set_column_fixed_widths(aWidths);
+
+ //Initialize search util
+ m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+ m_options.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_options.searchFlag
+ |= (util::SearchFlags::REG_NOT_BEGINOFLINE | util::SearchFlags::REG_NOT_ENDOFLINE);
+ // initialize GroupBox
+ m_xGroupLBox->SetFunctionListBox(m_xFunctionBox.get());
+
+ // initialize KeyBox
+ m_xKeyBox->make_sorted();
+
+ m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SfxAcceleratorConfigPage, ImplUpdateDataHdl));
+ m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+
+ m_aFillGroupIdle.SetInvokeHandler(LINK(this, SfxAcceleratorConfigPage, TimeOut_Impl));
+ m_aFillGroupIdle.SetPriority(TaskPriority::HIGHEST);
+}
+
+SfxAcceleratorConfigPage::~SfxAcceleratorConfigPage()
+{
+ m_aFillGroupIdle.Stop();
+
+ // free memory - remove all dynamic user data
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(i));
+ delete pUserData;
+ }
+}
+
+void SfxAcceleratorConfigPage::InitAccCfg()
+{
+ // already initialized ?
+ if (m_xContext.is())
+ return; // yes -> do nothing
+
+ try
+ {
+ // no - initialize this instance
+ m_xContext = comphelper::getProcessComponentContext();
+
+ m_xUICmdDescription = frame::theUICommandDescription::get(m_xContext);
+
+ // get the current active frame, which should be our "parent"
+ // for this session
+ m_xFrame = GetFrame();
+ if (!m_xFrame.is())
+ {
+ uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(m_xContext);
+ m_xFrame = xDesktop->getActiveFrame();
+ }
+
+ // identify module
+ uno::Reference<frame::XModuleManager2> xModuleManager
+ = frame::ModuleManager::create(m_xContext);
+ m_sModuleLongName = xModuleManager->identify(m_xFrame);
+ comphelper::SequenceAsHashMap lModuleProps(xModuleManager->getByName(m_sModuleLongName));
+ m_sModuleUIName
+ = lModuleProps.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
+
+ // get global accelerator configuration
+ m_xGlobal = css::ui::GlobalAcceleratorConfiguration::create(m_xContext);
+
+ // get module accelerator configuration
+
+ uno::Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgSupplier(
+ ui::theModuleUIConfigurationManagerSupplier::get(m_xContext));
+ uno::Reference<ui::XUIConfigurationManager> xUICfgManager
+ = xModuleCfgSupplier->getUIConfigurationManager(m_sModuleLongName);
+ m_xModule = xUICfgManager->getShortCutManager();
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ m_xContext.clear();
+ }
+}
+
+void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfiguration>& xAccMgr)
+{
+ if (!xAccMgr.is())
+ return;
+
+ if (!m_bStylesInfoInitialized)
+ {
+ uno::Reference<frame::XController> xController;
+ uno::Reference<frame::XModel> xModel;
+ if (m_xFrame.is())
+ xController = m_xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+
+ m_aStylesInfo.init(m_sModuleLongName, xModel);
+ m_xGroupLBox->SetStylesInfo(&m_aStylesInfo);
+ m_bStylesInfoInitialized = true;
+ }
+
+ // Insert all editable accelerators into list box. It is possible
+ // that some accelerators are not mapped on the current system/keyboard
+ // but we don't want to lose these mappings.
+ for (sal_Int32 i1 = 0; i1 < KEYCODE_ARRAY_SIZE; ++i1)
+ {
+ vcl::KeyCode aKey = KEYCODE_ARRAY[i1];
+ OUString sKey = aKey.GetName();
+ if (sKey.isEmpty())
+ continue;
+ TAccInfo* pEntry = new TAccInfo(i1, 0 /*nListPos*/, aKey);
+ m_xEntriesBox->append(weld::toId(pEntry), sKey);
+ int nPos = m_xEntriesBox->n_children() - 1;
+ m_xEntriesBox->set_text(nPos, OUString(), 1);
+ m_xEntriesBox->set_sensitive(nPos, true);
+ }
+
+ // Assign all commands to its shortcuts - reading the accelerator config.
+ uno::Sequence<awt::KeyEvent> lKeys = xAccMgr->getAllKeyEvents();
+ sal_Int32 c2 = lKeys.getLength();
+ sal_Int32 i2 = 0;
+
+ for (i2 = 0; i2 < c2; ++i2)
+ {
+ const awt::KeyEvent& aAWTKey = lKeys[i2];
+ OUString sCommand = xAccMgr->getCommandByKeyEvent(aAWTKey);
+ OUString sLabel = GetLabel4Command(sCommand);
+ vcl::KeyCode aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey(aAWTKey);
+ sal_Int32 nPos = MapKeyCodeToPos(aKeyCode);
+
+ if (nPos == -1)
+ continue;
+
+ m_xEntriesBox->set_text(nPos, sLabel, 1);
+
+ TAccInfo* pEntry = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(nPos));
+ pEntry->m_bIsConfigurable = true;
+
+ pEntry->m_sCommand = sCommand;
+ }
+
+ // Map the VCL hardcoded key codes and mark them as not changeable
+ size_t c3 = Application::GetReservedKeyCodeCount();
+ size_t i3 = 0;
+ for (i3 = 0; i3 < c3; ++i3)
+ {
+ const vcl::KeyCode* pKeyCode = Application::GetReservedKeyCode(i3);
+ sal_Int32 nPos = MapKeyCodeToPos(*pKeyCode);
+
+ if (nPos == -1)
+ continue;
+
+ // Hardcoded function mapped so no ID possible and mark entry as not changeable
+ TAccInfo* pEntry = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(nPos));
+ pEntry->m_bIsConfigurable = false;
+
+ m_xEntriesBox->set_sensitive(nPos, false);
+ }
+}
+
+void SfxAcceleratorConfigPage::Apply(const uno::Reference<ui::XAcceleratorConfiguration>& xAccMgr)
+{
+ if (!xAccMgr.is())
+ return;
+
+ // Go through the list from the bottom to the top ...
+ // because logical accelerator must be preferred instead of
+ // physical ones!
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(i));
+ OUString sCommand;
+ awt::KeyEvent aAWTKey;
+
+ if (pUserData)
+ {
+ sCommand = pUserData->m_sCommand;
+ aAWTKey = svt::AcceleratorExecute::st_VCLKey2AWTKey(pUserData->m_aKey);
+ }
+
+ try
+ {
+ if (!sCommand.isEmpty())
+ xAccMgr->setKeyEvent(aAWTKey, sCommand);
+ else
+ xAccMgr->removeKeyEvent(aAWTKey);
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+}
+
+void SfxAcceleratorConfigPage::ResetConfig() { m_xEntriesBox->clear(); }
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ImplUpdateDataHdl, Timer*, void)
+{
+ SelectHdl(m_xGroupLBox->get_widget());
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, SearchUpdateHdl, weld::Entry&, void)
+{
+ m_aUpdateDataTimer.Start();
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, FocusOut_Impl, weld::Widget&, void)
+{
+ if (m_aUpdateDataTimer.IsActive())
+ {
+ m_aUpdateDataTimer.Stop();
+ m_aUpdateDataTimer.Invoke();
+ }
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Load, weld::Button&, void)
+{
+ // ask for filename, where we should load the new config data from
+ StartFileDialog(StartFileDialogType::Open, aLoadAccelConfigStr);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Save, weld::Button&, void)
+{
+ StartFileDialog(StartFileDialogType::SaveAs, aSaveAccelConfigStr);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Default, weld::Button&, void)
+{
+ uno::Reference<form::XReset> xReset(m_xAct, uno::UNO_QUERY);
+ if (xReset.is())
+ xReset->reset();
+
+ m_xEntriesBox->freeze();
+ ResetConfig();
+ Init(m_xAct);
+ m_xEntriesBox->thaw();
+ m_xEntriesBox->select(0);
+ SelectHdl(*m_xEntriesBox);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ChangeHdl, weld::Button&, void)
+{
+ int nPos = m_xEntriesBox->get_selected_index();
+ if (nPos == -1)
+ return;
+
+ TAccInfo* pEntry = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(nPos));
+ OUString sNewCommand = m_xFunctionBox->GetCurCommand();
+ OUString sLabel = m_xFunctionBox->GetCurLabel();
+ if (sLabel.isEmpty())
+ sLabel = GetLabel4Command(sNewCommand);
+
+ pEntry->m_sCommand = sNewCommand;
+ m_xEntriesBox->set_text(nPos, sLabel, 1);
+
+ SelectHdl(m_xFunctionBox->get_widget());
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RemoveHdl, weld::Button&, void)
+{
+ // get selected entry
+ int nPos = m_xEntriesBox->get_selected_index();
+ if (nPos == -1)
+ return;
+
+ TAccInfo* pEntry = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(nPos));
+
+ // remove function name from selected entry
+ m_xEntriesBox->set_text(nPos, OUString(), 1);
+ pEntry->m_sCommand.clear();
+
+ SelectHdl(m_xFunctionBox->get_widget());
+}
+
+IMPL_LINK(SfxAcceleratorConfigPage, SelectHdl, weld::TreeView&, rListBox, void)
+{
+ if (&rListBox == m_xEntriesBox.get())
+ {
+ TAccInfo* pEntry = weld::fromId<TAccInfo*>(m_xEntriesBox->get_selected_id());
+
+ OUString sPossibleNewCommand = m_xFunctionBox->GetCurCommand();
+
+ m_xRemoveButton->set_sensitive(false);
+ m_xChangeButton->set_sensitive(false);
+
+ if (pEntry && pEntry->m_bIsConfigurable)
+ {
+ if (pEntry->isConfigured())
+ m_xRemoveButton->set_sensitive(true);
+ m_xChangeButton->set_sensitive(pEntry->m_sCommand != sPossibleNewCommand);
+ }
+ }
+ else if (&rListBox == &m_xGroupLBox->get_widget())
+ {
+ m_xGroupLBox->GroupSelected();
+
+ // Pause redraw (Do not redraw at each removal)
+ m_xFunctionBox->freeze();
+ // Apply the search filter to the functions list
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+ int nMatchFound = applySearchFilter(aSearchTerm);
+ // Resume redraw
+ m_xFunctionBox->thaw();
+ if (nMatchFound != -1)
+ {
+ m_xFunctionBox->select(nMatchFound);
+ SelectHdl(m_xFunctionBox->get_widget());
+ }
+ else
+ {
+ m_xKeyBox->clear();
+ m_xChangeButton->set_sensitive(false);
+ }
+ }
+ else if (&rListBox == &m_xFunctionBox->get_widget())
+ {
+ m_xRemoveButton->set_sensitive(false);
+ m_xChangeButton->set_sensitive(false);
+
+ // #i36994 First selected can return null!
+ TAccInfo* pEntry = weld::fromId<TAccInfo*>(m_xEntriesBox->get_selected_id());
+ if (pEntry)
+ {
+ OUString sPossibleNewCommand = m_xFunctionBox->GetCurCommand();
+
+ if (pEntry->m_bIsConfigurable)
+ {
+ if (pEntry->isConfigured())
+ m_xRemoveButton->set_sensitive(true);
+ m_xChangeButton->set_sensitive(pEntry->m_sCommand != sPossibleNewCommand
+ && !sPossibleNewCommand.isEmpty());
+ }
+
+ // update key box
+ m_xKeyBox->clear();
+ if (!sPossibleNewCommand.isEmpty())
+ {
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(i));
+ if (pUserData && pUserData->m_sCommand == sPossibleNewCommand)
+ {
+ m_xKeyBox->append(weld::toId(pUserData), pUserData->m_aKey.GetName());
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // goto selected "key" entry of the key box
+ int nP2 = -1;
+ TAccInfo* pU2 = weld::fromId<TAccInfo*>(m_xKeyBox->get_selected_id());
+ if (pU2)
+ nP2 = MapKeyCodeToPos(pU2->m_aKey);
+ if (nP2 != -1)
+ {
+ m_xEntriesBox->select(nP2);
+ m_xEntriesBox->scroll_to_row(nP2);
+ SelectHdl(*m_xEntriesBox);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RadioHdl, weld::Toggleable&, void)
+{
+ uno::Reference<ui::XAcceleratorConfiguration> xOld = m_xAct;
+
+ if (m_xOfficeButton->get_active())
+ m_xAct = m_xGlobal;
+ else if (m_xModuleButton->get_active())
+ m_xAct = m_xModule;
+
+ // nothing changed? => do nothing!
+ if (m_xAct.is() && (xOld == m_xAct))
+ return;
+
+ m_xEntriesBox->freeze();
+ ResetConfig();
+ Init(m_xAct);
+ m_xEntriesBox->thaw();
+
+ m_xGroupLBox->Init(m_xContext, m_xFrame, m_sModuleLongName, true);
+
+ // pb: #133213# do not select NULL entries
+ if (m_xEntriesBox->n_children())
+ m_xEntriesBox->select(0);
+
+ m_aFillGroupIdle.Start();
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, TimeOut_Impl, Timer*, void)
+{
+ // activating the selection, typically "all commands", can take a long time
+ // -> show wait cursor and disable input
+ weld::WaitObject aWaitObject(GetFrameWeld());
+
+ weld::TreeView& rTreeView = m_xGroupLBox->get_widget();
+ SelectHdl(rTreeView);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, LoadHdl, sfx2::FileDialogHelper*, void)
+{
+ assert(m_pFileDlg);
+
+ OUString sCfgName;
+ if (ERRCODE_NONE == m_pFileDlg->GetError())
+ sCfgName = m_pFileDlg->GetPath();
+
+ if (sCfgName.isEmpty())
+ return;
+
+ weld::WaitObject aWaitObject(GetFrameWeld());
+
+ uno::Reference<ui::XUIConfigurationManager> xCfgMgr;
+ uno::Reference<embed::XStorage>
+ xRootStorage; // we must hold the root storage alive, if xCfgMgr is used!
+
+ try
+ {
+ // don't forget to release the storage afterwards!
+ uno::Reference<lang::XSingleServiceFactory> xStorageFactory(
+ embed::StorageFactory::create(m_xContext));
+ uno::Sequence<uno::Any> lArgs{ uno::Any(sCfgName),
+ uno::Any(css::embed::ElementModes::READ) };
+
+ xRootStorage.set(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> xUIConfig
+ = xRootStorage->openStorageElement(FOLDERNAME_UICONFIG, embed::ElementModes::READ);
+ if (xUIConfig.is())
+ {
+ uno::Reference<ui::XUIConfigurationManager2> xCfgMgr2
+ = ui::UIConfigurationManager::create(m_xContext);
+ xCfgMgr2->setStorage(xUIConfig);
+ xCfgMgr.set(xCfgMgr2, uno::UNO_QUERY_THROW);
+ }
+
+ if (xCfgMgr.is())
+ {
+ // open the configuration and update our UI
+ uno::Reference<ui::XAcceleratorConfiguration> xTempAccMgr(xCfgMgr->getShortCutManager(),
+ uno::UNO_SET_THROW);
+
+ m_xEntriesBox->freeze();
+ ResetConfig();
+ Init(xTempAccMgr);
+ m_xEntriesBox->thaw();
+ if (m_xEntriesBox->n_children())
+ {
+ m_xEntriesBox->select(0);
+ SelectHdl(m_xFunctionBox->get_widget());
+ }
+ }
+
+ // don't forget to close the new opened storage!
+ // We are the owner of it.
+ if (xRootStorage.is())
+ {
+ uno::Reference<lang::XComponent> xComponent;
+ xComponent.set(xCfgMgr, uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ xRootStorage->dispose();
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, SaveHdl, sfx2::FileDialogHelper*, void)
+{
+ assert(m_pFileDlg);
+
+ OUString sCfgName;
+ if (ERRCODE_NONE == m_pFileDlg->GetError())
+ sCfgName = m_pFileDlg->GetPath();
+
+ if (sCfgName.isEmpty())
+ return;
+
+ weld::WaitObject aWaitObject(GetFrameWeld());
+
+ uno::Reference<embed::XStorage> xRootStorage;
+
+ try
+ {
+ uno::Reference<lang::XSingleServiceFactory> xStorageFactory(
+ embed::StorageFactory::create(m_xContext));
+ uno::Sequence<uno::Any> lArgs{ uno::Any(sCfgName), uno::Any(embed::ElementModes::WRITE) };
+
+ xRootStorage.set(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY_THROW);
+
+ uno::Reference<embed::XStorage> xUIConfig(
+ xRootStorage->openStorageElement(FOLDERNAME_UICONFIG, embed::ElementModes::WRITE),
+ uno::UNO_SET_THROW);
+ uno::Reference<beans::XPropertySet> xUIConfigProps(xUIConfig, uno::UNO_QUERY_THROW);
+
+ // set the correct media type if the storage was new created
+ OUString sMediaType;
+ xUIConfigProps->getPropertyValue(MEDIATYPE_PROPNAME) >>= sMediaType;
+ if (sMediaType.isEmpty())
+ xUIConfigProps->setPropertyValue(
+ MEDIATYPE_PROPNAME, uno::Any(OUString("application/vnd.sun.xml.ui.configuration")));
+
+ uno::Reference<ui::XUIConfigurationManager2> xCfgMgr
+ = ui::UIConfigurationManager::create(m_xContext);
+ xCfgMgr->setStorage(xUIConfig);
+
+ // get the target configuration access and update with all shortcuts
+ // which are set currently at the UI!
+ // Don't copy the m_xAct content to it... because m_xAct will be updated
+ // from the UI on pressing the button "OK" only. And inbetween it's not up to date!
+ uno::Reference<ui::XAcceleratorConfiguration> xTargetAccMgr(xCfgMgr->getShortCutManager(),
+ uno::UNO_SET_THROW);
+ Apply(xTargetAccMgr);
+
+ // commit (order is important!)
+ uno::Reference<ui::XUIConfigurationPersistence> xCommit1(xTargetAccMgr,
+ uno::UNO_QUERY_THROW);
+ uno::Reference<ui::XUIConfigurationPersistence> xCommit2(xCfgMgr, uno::UNO_QUERY_THROW);
+ xCommit1->store();
+ xCommit2->store();
+
+ if (xRootStorage.is())
+ {
+ // Commit root storage
+ uno::Reference<embed::XTransactedObject> xCommit3(xRootStorage, uno::UNO_QUERY_THROW);
+ xCommit3->commit();
+ }
+
+ if (xRootStorage.is())
+ {
+ if (xCfgMgr.is())
+ xCfgMgr->dispose();
+ xRootStorage->dispose();
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+void SfxAcceleratorConfigPage::StartFileDialog(StartFileDialogType nType, const OUString& rTitle)
+{
+ bool bSave = nType == StartFileDialogType::SaveAs;
+ short nDialogType = bSave ? ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
+ : ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
+ m_pFileDlg.reset(
+ new sfx2::FileDialogHelper(nDialogType, FileDialogFlags::NONE, GetFrameWeld()));
+
+ m_pFileDlg->SetTitle(rTitle);
+ m_pFileDlg->AddFilter(aFilterAllStr, FILEDIALOG_FILTER_ALL);
+ m_pFileDlg->AddFilter(aFilterCfgStr, "*.cfg");
+ m_pFileDlg->SetCurrentFilter(aFilterCfgStr);
+ m_pFileDlg->SetContext(sfx2::FileDialogHelper::AcceleratorConfig);
+
+ Link<sfx2::FileDialogHelper*, void> aDlgClosedLink
+ = bSave ? LINK(this, SfxAcceleratorConfigPage, SaveHdl)
+ : LINK(this, SfxAcceleratorConfigPage, LoadHdl);
+ m_pFileDlg->StartExecuteModal(aDlgClosedLink);
+}
+
+bool SfxAcceleratorConfigPage::FillItemSet(SfxItemSet*)
+{
+ Apply(m_xAct);
+ try
+ {
+ m_xAct->store();
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void SfxAcceleratorConfigPage::Reset(const SfxItemSet* rSet)
+{
+ // open accelerator configs
+ // Note: It initialize some other members too, which are needed here ...
+ // e.g. m_sModuleUIName!
+ InitAccCfg();
+
+ // change the description of the radio button, which switch to the module
+ // dependent accelerator configuration
+ OUString sButtonText = m_xModuleButton->get_label();
+ sButtonText
+ = m_xModuleButton->strip_mnemonic(sButtonText).replaceFirst("$(MODULE)", m_sModuleUIName);
+ m_xModuleButton->set_label(sButtonText);
+
+ if (m_xModule.is())
+ m_xModuleButton->set_active(true);
+ else
+ {
+ m_xModuleButton->hide();
+ m_xOfficeButton->set_active(true);
+ }
+
+ RadioHdl(*m_xOfficeButton);
+
+#if HAVE_FEATURE_SCRIPTING
+ if (const SfxMacroInfoItem* pMacroItem = rSet->GetItemIfSet(SID_MACROINFO))
+ {
+ m_pMacroInfoItem = pMacroItem;
+ m_xGroupLBox->SelectMacro(m_pMacroInfoItem);
+ }
+#else
+ (void)rSet;
+#endif
+}
+
+sal_Int32 SfxAcceleratorConfigPage::MapKeyCodeToPos(const vcl::KeyCode& aKey) const
+{
+ sal_uInt16 nCode1 = aKey.GetCode() + aKey.GetModifier();
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = weld::fromId<TAccInfo*>(m_xEntriesBox->get_id(i));
+ if (pUserData)
+ {
+ sal_uInt16 nCode2 = pUserData->m_aKey.GetCode() + pUserData->m_aKey.GetModifier();
+ if (nCode1 == nCode2)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+OUString SfxAcceleratorConfigPage::GetLabel4Command(const OUString& sCommand)
+{
+ try
+ {
+ // check global command configuration first
+ uno::Reference<container::XNameAccess> xModuleConf;
+ m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
+ if (xModuleConf.is())
+ {
+ ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
+ OUString sLabel = lProps.getUnpackedValueOrDefault("Name", OUString());
+ if (!sLabel.isEmpty())
+ return sLabel;
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ // may be it's a style URL .. they must be handled special
+ SfxStyleInfo_Impl aStyle;
+ aStyle.sCommand = sCommand;
+ if (SfxStylesInfo_Impl::parseStyleCommand(aStyle))
+ {
+ m_aStylesInfo.getLabel4Style(aStyle);
+ return aStyle.sLabel;
+ }
+
+ return sCommand;
+}
+
+/*
+ * Remove entries which doesn't contain the search term
+ */
+int SfxAcceleratorConfigPage::applySearchFilter(OUString const& rSearchTerm)
+{
+ if (rSearchTerm.isEmpty())
+ return -1;
+
+ m_options.searchString = rSearchTerm;
+ utl::TextSearch textSearch(m_options);
+
+ for (int i = m_xFunctionBox->n_children(); i > 0; --i)
+ {
+ int nEntry = i - 1;
+ OUString aStr = m_xFunctionBox->get_text(nEntry);
+ sal_Int32 aStartPos = 0;
+ sal_Int32 aEndPos = aStr.getLength();
+
+ if (!textSearch.SearchForward(aStr, &aStartPos, &aEndPos))
+ m_xFunctionBox->remove(nEntry);
+ }
+
+ return m_xFunctionBox->n_children() ? 0 : -1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
new file mode 100644
index 000000000..4c8192b61
--- /dev/null
+++ b/cui/source/customize/cfg.cxx
@@ -0,0 +1,3221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <cassert>
+#include <stdlib.h>
+#include <typeinfo>
+
+#include <utility>
+#include <vcl/stdtext.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/event.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/virdev.hxx>
+
+#include <sfx2/sfxhelp.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/stritem.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <algorithm>
+#include <strings.hrc>
+
+#include <acccfg.hxx>
+#include <cfg.hxx>
+#include <CustomNotebookbarGenerator.hxx>
+#include <SvxMenuConfigPage.hxx>
+#include <SvxToolbarConfigPage.hxx>
+#include <SvxNotebookbarConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include "eventdlg.hxx"
+#include <dialmgr.hxx>
+
+#include <unotools/configmgr.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/FileSystemStorageFactory.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/XFrames.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/ui/ImageManager.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/ui/theWindowStateConfiguration.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/processfactory.hxx>
+
+namespace uno = com::sun::star::uno;
+namespace frame = com::sun::star::frame;
+namespace lang = com::sun::star::lang;
+namespace container = com::sun::star::container;
+namespace beans = com::sun::star::beans;
+namespace graphic = com::sun::star::graphic;
+
+#if OSL_DEBUG_LEVEL > 1
+
+void printPropertySet(
+ const OUString& prefix,
+ const uno::Reference< beans::XPropertySet >& xPropSet )
+{
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
+ xPropSet->getPropertySetInfo();
+
+ const uno::Sequence< beans::Property >& aPropDetails =
+ xPropSetInfo->getProperties();
+
+ SAL_WARN("cui", "printPropertySet: " << aPropDetails.getLength() << " properties" );
+
+ for ( beans::Property const & aPropDetail : aPropDetails )
+ {
+ OUString tmp;
+ sal_Int32 ival;
+
+ uno::Any a = xPropSet->getPropertyValue( aPropDetail.Name );
+
+ if ( a >>= tmp )
+ {
+ SAL_WARN("cui", prefix << ": Got property: " << aPropDetail.Name << tmp);
+ }
+ else if ( ( a >>= ival ) )
+ {
+ SAL_WARN("cui", prefix << ": Got property: " << aPropDetail.Name << " = " << ival);
+ }
+ else
+ {
+ SAL_WARN("cui", prefix << ": Got property: " << aPropDetail.Name << " of type " << a.getValueTypeName());
+ }
+ }
+}
+
+void printProperties(
+ const OUString& prefix,
+ const uno::Sequence< beans::PropertyValue >& aProp )
+{
+ for (beans::PropertyValue const & aPropVal : aProp)
+ {
+ OUString tmp;
+
+ aPropVal.Value >>= tmp;
+
+ SAL_WARN("cui", prefix << ": Got property: " << aPropVal.Name << " = " << tmp);
+ }
+}
+
+void printEntries(SvxEntries* entries)
+{
+ for (auto const& entry : *entries)
+ {
+ SAL_WARN("cui", "printEntries: " << entry->GetName());
+ }
+}
+
+#endif
+
+bool
+SvxConfigPage::CanConfig( std::u16string_view aModuleId )
+{
+ return aModuleId != u"com.sun.star.script.BasicIDE" && aModuleId != u"com.sun.star.frame.Bibliography";
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxMenuConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxMenuConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxContextMenuConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxMenuConfigPage>(pPage, pController, *rSet, false);
+}
+
+static std::unique_ptr<SfxTabPage> CreateKeyboardConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SfxAcceleratorConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxNotebookbarConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxNotebookbarConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxToolbarConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxToolbarConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxEventConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxEventConfigPage>(pPage, pController, *rSet, SvxEventConfigPage::EarlyInit());
+}
+
+/******************************************************************************
+ *
+ * SvxConfigDialog is the configuration dialog which is brought up from the
+ * Tools menu. It includes tabs for customizing menus, toolbars, events and
+ * key bindings.
+ *
+ *****************************************************************************/
+SvxConfigDialog::SvxConfigDialog(weld::Window * pParent, const SfxItemSet* pInSet)
+ : SfxTabDialogController(pParent, "cui/ui/customizedialog.ui", "CustomizeDialog", pInSet)
+{
+ SvxConfigPageHelper::InitImageType();
+
+ AddTabPage("menus", CreateSvxMenuConfigPage, nullptr);
+ AddTabPage("toolbars", CreateSvxToolbarConfigPage, nullptr);
+ AddTabPage("notebookbar", CreateSvxNotebookbarConfigPage, nullptr);
+ AddTabPage("contextmenus", CreateSvxContextMenuConfigPage, nullptr);
+ AddTabPage("keyboard", CreateKeyboardConfigPage, nullptr);
+ AddTabPage("events", CreateSvxEventConfigPage, nullptr);
+ m_xTabCtrl->connect_enter_page(LINK(this, SvxConfigDialog, ActivatePageHdl));
+
+ const SfxPoolItem* pItem = pInSet->GetItem( SID_CONFIG );
+
+ if ( pItem )
+ {
+ OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
+
+ if (text.startsWith( ITEM_TOOLBAR_URL ) )
+ {
+ SetCurPageId("toolbars");
+ }
+ }
+}
+
+IMPL_LINK(SvxConfigDialog, ActivatePageHdl, const OString&, rPage, void)
+{
+ GetResetButton()->set_visible(rPage != "keyboard");
+}
+
+void SvxConfigDialog::SetFrame(const css::uno::Reference<css::frame::XFrame>& xFrame)
+{
+ m_xFrame = xFrame;
+ OUString aModuleId = SvxConfigPage::GetFrameWithDefaultAndIdentify(m_xFrame);
+
+ if (aModuleId != "com.sun.star.text.TextDocument" &&
+ aModuleId != "com.sun.star.sheet.SpreadsheetDocument" &&
+ aModuleId != "com.sun.star.presentation.PresentationDocument" &&
+ aModuleId != "com.sun.star.drawing.DrawingDocument")
+ RemoveTabPage("notebookbar");
+
+ if (aModuleId == "com.sun.star.frame.StartModule")
+ RemoveTabPage("keyboard");
+}
+
+void SvxConfigDialog::PageCreated(const OString &rId, SfxTabPage& rPage)
+{
+ if (rId == "menus" || rId == "keyboard" || rId == "notebookbar"
+ || rId == "toolbars" || rId == "contextmenus")
+ {
+ rPage.SetFrame(m_xFrame);
+ }
+ else if (rId == "events")
+ {
+ dynamic_cast< SvxEventConfigPage& >( rPage ).LateInit( m_xFrame );
+ }
+}
+
+/******************************************************************************
+ *
+ * The SaveInData class is used to hold data for entries in the Save In
+ * ListBox controls in the menu and toolbar tabs
+ *
+ ******************************************************************************/
+
+// Initialize static variable which holds default XImageManager
+uno::Reference< css::ui::XImageManager>* SaveInData::xDefaultImgMgr = nullptr;
+
+SaveInData::SaveInData(
+ uno::Reference< css::ui::XUIConfigurationManager > xCfgMgr,
+ uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr,
+ const OUString& aModuleId,
+ bool isDocConfig )
+ :
+ bModified( false ),
+ bDocConfig( isDocConfig ),
+ bReadOnly( false ),
+ m_xCfgMgr(std::move( xCfgMgr )),
+ m_xParentCfgMgr(std::move( xParentCfgMgr )),
+ m_aSeparatorSeq{ comphelper::makePropertyValue(ITEM_DESCRIPTOR_TYPE,
+ css::ui::ItemType::SEPARATOR_LINE) }
+{
+ if ( bDocConfig )
+ {
+ uno::Reference< css::ui::XUIConfigurationPersistence >
+ xDocPersistence( GetConfigManager(), uno::UNO_QUERY );
+
+ bReadOnly = xDocPersistence->isReadOnly();
+ }
+
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ css::frame::theUICommandDescription::get(xContext) );
+
+ xNameAccess->getByName( aModuleId ) >>= m_xCommandToLabelMap;
+
+ if ( !m_xImgMgr.is() )
+ {
+ m_xImgMgr.set( GetConfigManager()->getImageManager(), uno::UNO_QUERY );
+ }
+
+ if ( !IsDocConfig() )
+ {
+ // If this is not a document configuration then it is the settings
+ // for the module (writer, calc, impress etc.) Use this as the default
+ // XImageManager instance
+ xDefaultImgMgr = &m_xImgMgr;
+ }
+ else
+ {
+ // If this is a document configuration then use the module image manager
+ // as default.
+ if ( m_xParentCfgMgr.is() )
+ {
+ m_xParentImgMgr.set( m_xParentCfgMgr->getImageManager(), uno::UNO_QUERY );
+ xDefaultImgMgr = &m_xParentImgMgr;
+ }
+ }
+}
+
+uno::Reference<graphic::XGraphic> SaveInData::GetImage(const OUString& rCommandURL)
+{
+ uno::Reference< graphic::XGraphic > xGraphic =
+ SvxConfigPageHelper::GetGraphic( m_xImgMgr, rCommandURL );
+
+ if (!xGraphic.is() && xDefaultImgMgr != nullptr && (*xDefaultImgMgr).is())
+ {
+ xGraphic = SvxConfigPageHelper::GetGraphic( (*xDefaultImgMgr), rCommandURL );
+ }
+
+ return xGraphic;
+}
+
+bool SaveInData::PersistChanges(
+ const uno::Reference< uno::XInterface >& xManager )
+{
+ bool result = true;
+
+ try
+ {
+ if ( xManager.is() && !IsReadOnly() )
+ {
+ uno::Reference< css::ui::XUIConfigurationPersistence >
+ xConfigPersistence( xManager, uno::UNO_QUERY );
+
+ if ( xConfigPersistence->isModified() )
+ {
+ xConfigPersistence->store();
+ }
+ }
+ }
+ catch ( css::io::IOException& )
+ {
+ result = false;
+ }
+
+ return result;
+}
+
+/******************************************************************************
+ *
+ * The MenuSaveInData class extends SaveInData and provides menu specific
+ * load and store functionality.
+ *
+ ******************************************************************************/
+
+// Initialize static variable which holds default Menu data
+MenuSaveInData* MenuSaveInData::pDefaultData = nullptr;
+
+MenuSaveInData::MenuSaveInData(
+ const uno::Reference< css::ui::XUIConfigurationManager >& cfgmgr,
+ const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool isDocConfig )
+ :
+ SaveInData( cfgmgr, xParentCfgMgr, aModuleId, isDocConfig ),
+ m_aMenuResourceURL(
+ ITEM_MENUBAR_URL ),
+ m_aDescriptorContainer(
+ ITEM_DESCRIPTOR_CONTAINER )
+{
+ try
+ {
+ m_xMenuSettings = GetConfigManager()->getSettings( ITEM_MENUBAR_URL, false );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // will use menu settings for the module
+ }
+
+ // If this is not a document configuration then it is the settings
+ // for the module (writer, calc, impress etc.). These settings should
+ // be set as the default to be used for SaveIn locations that do not
+ // have custom settings
+ if ( !IsDocConfig() )
+ {
+ SetDefaultData( this );
+ }
+}
+
+MenuSaveInData::~MenuSaveInData()
+{
+}
+
+SvxEntries*
+MenuSaveInData::GetEntries()
+{
+ if ( pRootEntry == nullptr )
+ {
+ pRootEntry.reset( new SvxConfigEntry( "MainMenus", OUString(), true, /*bParentData*/false) );
+
+ if ( m_xMenuSettings.is() )
+ {
+ LoadSubMenus( m_xMenuSettings, OUString(), pRootEntry.get(), false );
+ }
+ else if ( GetDefaultData() != nullptr )
+ {
+ // If the doc has no config settings use module config settings
+ LoadSubMenus( GetDefaultData()->m_xMenuSettings, OUString(), pRootEntry.get(), false );
+ }
+ }
+
+ return pRootEntry->GetEntries();
+}
+
+void
+MenuSaveInData::SetEntries( std::unique_ptr<SvxEntries> pNewEntries )
+{
+ pRootEntry->SetEntries( std::move(pNewEntries) );
+}
+
+void SaveInData::LoadSubMenus( const uno::Reference< container::XIndexAccess >& xMenuSettings,
+ const OUString& rBaseTitle, SvxConfigEntry const * pParentData, bool bContextMenu )
+{
+ SvxEntries* pEntries = pParentData->GetEntries();
+
+ // Don't access non existing menu configuration!
+ if ( !xMenuSettings.is() )
+ return;
+
+ for ( sal_Int32 nIndex = 0; nIndex < xMenuSettings->getCount(); ++nIndex )
+ {
+ uno::Reference< container::XIndexAccess > xSubMenu;
+ OUString aCommandURL;
+ OUString aLabel;
+
+ sal_uInt16 nType( css::ui::ItemType::DEFAULT );
+ sal_Int32 nStyle(0);
+
+ bool bItem = SvxConfigPageHelper::GetMenuItemData( xMenuSettings, nIndex,
+ aCommandURL, aLabel, nType, nStyle, xSubMenu );
+
+ if ( bItem )
+ {
+ bool bIsUserDefined = true;
+
+ if ( nType == css::ui::ItemType::DEFAULT )
+ {
+ uno::Any a;
+ try
+ {
+ a = m_xCommandToLabelMap->getByName( aCommandURL );
+ bIsUserDefined = false;
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ bIsUserDefined = true;
+ }
+
+ bool bUseDefaultLabel = false;
+ // If custom label not set retrieve it from the command
+ // to info service
+ if ( aLabel.isEmpty() )
+ {
+ bUseDefaultLabel = true;
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ if ( a >>= aPropSeq )
+ {
+ OUString aMenuLabel;
+ for ( const beans::PropertyValue& prop : std::as_const(aPropSeq) )
+ {
+ if ( bContextMenu )
+ {
+ if ( prop.Name == "PopupLabel" )
+ {
+ prop.Value >>= aLabel;
+ break;
+ }
+ else if ( prop.Name == "Label" )
+ {
+ prop.Value >>= aMenuLabel;
+ }
+ }
+ else if ( prop.Name == "Label" )
+ {
+ prop.Value >>= aLabel;
+ break;
+ }
+ }
+ if ( aLabel.isEmpty() )
+ aLabel = aMenuLabel;
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ aLabel, aCommandURL, xSubMenu.is(), /*bParentData*/false );
+
+ pEntry->SetStyle( nStyle );
+ pEntry->SetUserDefined( bIsUserDefined );
+ if ( !bUseDefaultLabel )
+ pEntry->SetName( aLabel );
+
+ pEntries->push_back( pEntry );
+
+ if ( xSubMenu.is() )
+ {
+ // popup menu
+ OUString subMenuTitle( rBaseTitle );
+
+ if ( !subMenuTitle.isEmpty() )
+ {
+ subMenuTitle += aMenuSeparatorStr;
+ }
+ else
+ {
+ pEntry->SetMain();
+ }
+
+ subMenuTitle += SvxConfigPageHelper::stripHotKey( aLabel );
+
+ LoadSubMenus( xSubMenu, subMenuTitle, pEntry, bContextMenu );
+ }
+ }
+ else
+ {
+ SvxConfigEntry* pEntry = new SvxConfigEntry;
+ pEntry->SetUserDefined( bIsUserDefined );
+ pEntries->push_back( pEntry );
+ }
+ }
+ }
+}
+
+bool MenuSaveInData::Apply()
+{
+ bool result = false;
+
+ if ( IsModified() )
+ {
+ // Apply new menu bar structure to our settings container
+ m_xMenuSettings = GetConfigManager()->createSettings();
+
+ uno::Reference< container::XIndexContainer > xIndexContainer (
+ m_xMenuSettings, uno::UNO_QUERY );
+
+ uno::Reference< lang::XSingleComponentFactory > xFactory (
+ m_xMenuSettings, uno::UNO_QUERY );
+
+ Apply( xIndexContainer, xFactory );
+
+ try
+ {
+ if ( GetConfigManager()->hasSettings( m_aMenuResourceURL ) )
+ {
+ GetConfigManager()->replaceSettings(
+ m_aMenuResourceURL, m_xMenuSettings );
+ }
+ else
+ {
+ GetConfigManager()->insertSettings(
+ m_aMenuResourceURL, m_xMenuSettings );
+ }
+ }
+ catch ( css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "caught some other exception saving settings");
+ }
+
+ SetModified( false );
+
+ result = PersistChanges( GetConfigManager() );
+ }
+
+ return result;
+}
+
+void MenuSaveInData::Apply(
+ uno::Reference< container::XIndexContainer > const & rMenuBar,
+ uno::Reference< lang::XSingleComponentFactory >& rFactory )
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ for (auto const& entryData : *GetEntries())
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertSvxConfigEntry(entryData);
+
+ uno::Reference< container::XIndexContainer > xSubMenuBar(
+ rFactory->createInstanceWithContext( xContext ),
+ uno::UNO_QUERY );
+
+ sal_Int32 nIndex = aPropValueSeq.getLength();
+ aPropValueSeq.realloc( nIndex + 1 );
+ auto pPropValueSeq = aPropValueSeq.getArray();
+ pPropValueSeq[nIndex].Name = m_aDescriptorContainer;
+ pPropValueSeq[nIndex].Value <<= xSubMenuBar;
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( aPropValueSeq ));
+ ApplyMenu( xSubMenuBar, rFactory, entryData );
+ }
+}
+
+void SaveInData::ApplyMenu(
+ uno::Reference< container::XIndexContainer > const & rMenuBar,
+ uno::Reference< lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry* pMenuData )
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ for (auto const& entry : *pMenuData->GetEntries())
+ {
+ if (entry->IsPopup())
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertSvxConfigEntry(entry);
+
+ uno::Reference< container::XIndexContainer > xSubMenuBar(
+ rFactory->createInstanceWithContext( xContext ),
+ uno::UNO_QUERY );
+
+ sal_Int32 nIndex = aPropValueSeq.getLength();
+ aPropValueSeq.realloc( nIndex + 1 );
+ auto pPropValueSeq = aPropValueSeq.getArray();
+ pPropValueSeq[nIndex].Name = ITEM_DESCRIPTOR_CONTAINER;
+ pPropValueSeq[nIndex].Value <<= xSubMenuBar;
+
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( aPropValueSeq ));
+
+ ApplyMenu( xSubMenuBar, rFactory, entry );
+ entry->SetModified( false );
+ }
+ else if (entry->IsSeparator())
+ {
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( m_aSeparatorSeq ));
+ }
+ else
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertSvxConfigEntry(entry);
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( aPropValueSeq ));
+ }
+ }
+ pMenuData->SetModified( false );
+}
+
+void
+MenuSaveInData::Reset()
+{
+ try
+ {
+ GetConfigManager()->removeSettings( m_aMenuResourceURL );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ PersistChanges( GetConfigManager() );
+
+ pRootEntry.reset();
+
+ try
+ {
+ m_xMenuSettings = GetConfigManager()->getSettings(
+ m_aMenuResourceURL, false );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // will use default settings
+ }
+}
+
+ContextMenuSaveInData::ContextMenuSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId, bool bIsDocConfig )
+ : SaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bIsDocConfig )
+{
+ css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
+ css::uno::Reference< css::container::XNameAccess > xConfig( css::ui::theWindowStateConfiguration::get( xContext ) );
+ xConfig->getByName( aModuleId ) >>= m_xPersistentWindowState;
+}
+
+ContextMenuSaveInData::~ContextMenuSaveInData()
+{
+}
+
+OUString ContextMenuSaveInData::GetUIName( const OUString& rResourceURL )
+{
+ if ( m_xPersistentWindowState.is() )
+ {
+ css::uno::Sequence< css::beans::PropertyValue > aProps;
+ try
+ {
+ m_xPersistentWindowState->getByName( rResourceURL ) >>= aProps;
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ for ( const auto& aProp : std::as_const(aProps) )
+ {
+ if ( aProp.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ OUString aResult;
+ aProp.Value >>= aResult;
+ return aResult;
+ }
+ }
+ }
+ return OUString();
+}
+
+SvxEntries* ContextMenuSaveInData::GetEntries()
+{
+ if ( !m_pRootEntry )
+ {
+ std::unordered_map< OUString, bool > aMenuInfo;
+
+ m_pRootEntry.reset( new SvxConfigEntry( "ContextMenus", OUString(), true, /*bParentData*/false ) );
+ css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aElementsInfo;
+ try
+ {
+ aElementsInfo = GetConfigManager()->getUIElementsInfo( css::ui::UIElementType::POPUPMENU );
+ }
+ catch ( const css::lang::IllegalArgumentException& )
+ {}
+
+ for ( const auto& aElement : std::as_const(aElementsInfo) )
+ {
+ OUString aUrl;
+ for ( const auto& aElementProp : aElement )
+ {
+ if ( aElementProp.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ aElementProp.Value >>= aUrl;
+ break;
+ }
+ }
+
+ css::uno::Reference< css::container::XIndexAccess > xPopupMenu;
+ try
+ {
+ xPopupMenu = GetConfigManager()->getSettings( aUrl, false );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ if ( xPopupMenu.is() )
+ {
+ // insert into std::unordered_map to filter duplicates from the parent
+ aMenuInfo.emplace( aUrl, true );
+
+ OUString aUIMenuName = GetUIName( aUrl );
+ if ( aUIMenuName.isEmpty() )
+ // Menus without UI name aren't supposed to be customized.
+ continue;
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry( aUIMenuName, aUrl, true, /*bParentData*/false );
+ pEntry->SetMain();
+ m_pRootEntry->GetEntries()->push_back( pEntry );
+ LoadSubMenus( xPopupMenu, aUIMenuName, pEntry, true );
+ }
+ }
+
+ // Retrieve also the parent menus, to make it possible to configure module menus and save them into the document.
+ css::uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
+ css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aParentElementsInfo;
+ try
+ {
+ if ( xParentCfgMgr.is() )
+ aParentElementsInfo = xParentCfgMgr->getUIElementsInfo( css::ui::UIElementType::POPUPMENU );
+ }
+ catch ( const css::lang::IllegalArgumentException& )
+ {}
+
+ for ( const auto& aElement : std::as_const(aParentElementsInfo) )
+ {
+ OUString aUrl;
+ for ( const auto& aElementProp : aElement )
+ {
+ if ( aElementProp.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ aElementProp.Value >>= aUrl;
+ break;
+ }
+ }
+
+ css::uno::Reference< css::container::XIndexAccess > xPopupMenu;
+ try
+ {
+ if ( aMenuInfo.find( aUrl ) == aMenuInfo.end() )
+ xPopupMenu = xParentCfgMgr->getSettings( aUrl, false );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ if ( xPopupMenu.is() )
+ {
+ OUString aUIMenuName = GetUIName( aUrl );
+ if ( aUIMenuName.isEmpty() )
+ continue;
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry( aUIMenuName, aUrl, true, true );
+ pEntry->SetMain();
+ m_pRootEntry->GetEntries()->push_back( pEntry );
+ LoadSubMenus( xPopupMenu, aUIMenuName, pEntry, true );
+ }
+ }
+ std::sort( m_pRootEntry->GetEntries()->begin(), m_pRootEntry->GetEntries()->end(), SvxConfigPageHelper::EntrySort );
+ }
+ return m_pRootEntry->GetEntries();
+}
+
+void ContextMenuSaveInData::SetEntries( std::unique_ptr<SvxEntries> pNewEntries )
+{
+ m_pRootEntry->SetEntries( std::move(pNewEntries) );
+}
+
+bool ContextMenuSaveInData::HasURL( const OUString& rURL )
+{
+ SvxEntries* pEntries = GetEntries();
+ for ( const auto& pEntry : *pEntries )
+ if ( pEntry->GetCommand() == rURL )
+ return true;
+
+ return false;
+}
+
+bool ContextMenuSaveInData::HasSettings()
+{
+ return m_pRootEntry && !m_pRootEntry->GetEntries()->empty();
+}
+
+bool ContextMenuSaveInData::Apply()
+{
+ if ( !IsModified() )
+ return false;
+
+ SvxEntries* pEntries = GetEntries();
+ for ( const auto& pEntry : *pEntries )
+ {
+ if ( pEntry->IsModified() || SvxConfigPageHelper::SvxConfigEntryModified( pEntry ) )
+ {
+ css::uno::Reference< css::container::XIndexContainer > xIndexContainer = GetConfigManager()->createSettings();
+ css::uno::Reference< css::lang::XSingleComponentFactory > xFactory( xIndexContainer, css::uno::UNO_QUERY );
+ ApplyMenu( xIndexContainer, xFactory, pEntry );
+
+ const OUString& aUrl = pEntry->GetCommand();
+ try
+ {
+ if ( GetConfigManager()->hasSettings( aUrl ) )
+ GetConfigManager()->replaceSettings( aUrl, xIndexContainer );
+ else
+ GetConfigManager()->insertSettings( aUrl, xIndexContainer );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+ }
+ }
+ SetModified( false );
+ return PersistChanges( GetConfigManager() );
+}
+
+void ContextMenuSaveInData::Reset()
+{
+ SvxEntries* pEntries = GetEntries();
+ for ( const auto& pEntry : *pEntries )
+ {
+ try
+ {
+ GetConfigManager()->removeSettings( pEntry->GetCommand() );
+ }
+ catch ( const css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menus");
+ }
+ }
+ PersistChanges( GetConfigManager() );
+ m_pRootEntry.reset();
+}
+
+void ContextMenuSaveInData::ResetContextMenu( const SvxConfigEntry* pEntry )
+{
+ try
+ {
+ GetConfigManager()->removeSettings( pEntry->GetCommand() );
+ }
+ catch ( const css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menu");
+ }
+ PersistChanges( GetConfigManager() );
+ m_pRootEntry.reset();
+}
+
+void SvxMenuEntriesListBox::CreateDropDown()
+{
+ int nWidth = (m_xControl->get_text_height() * 3) / 4;
+ m_xDropDown->SetOutputSizePixel(Size(nWidth, nWidth));
+ DecorationView aDecoView(m_xDropDown.get());
+ aDecoView.DrawSymbol(tools::Rectangle(Point(0, 0), Size(nWidth, nWidth)),
+ SymbolType::SPIN_RIGHT, m_xDropDown->GetTextColor(),
+ DrawSymbolFlags::NONE);
+}
+
+/******************************************************************************
+ *
+ * SvxMenuEntriesListBox is the listbox in which the menu items for a
+ * particular menu are shown. We have a custom listbox because we need
+ * to add drag'n'drop support from the Macro Selector and within the
+ * listbox
+ *
+ *****************************************************************************/
+SvxMenuEntriesListBox::SvxMenuEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxConfigPage* pPg)
+ : m_xControl(std::move(xControl))
+ , m_xDropDown(m_xControl->create_virtual_device())
+ , m_pPage(pPg)
+{
+ m_xControl->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ CreateDropDown();
+ m_xControl->connect_key_press(LINK(this, SvxMenuEntriesListBox, KeyInputHdl));
+}
+
+SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
+{
+}
+
+IMPL_LINK(SvxMenuEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ vcl::KeyCode keycode = rKeyEvent.GetKeyCode();
+
+ // support DELETE for removing the current entry
+ if ( keycode == KEY_DELETE )
+ {
+ m_pPage->DeleteSelectedContent();
+ }
+ // support CTRL+UP and CTRL+DOWN for moving selected entries
+ else if ( keycode.GetCode() == KEY_UP && keycode.IsMod1() )
+ {
+ m_pPage->MoveEntry( true );
+ }
+ else if ( keycode.GetCode() == KEY_DOWN && keycode.IsMod1() )
+ {
+ m_pPage->MoveEntry( false );
+ }
+ else
+ {
+ return false; // pass on to default handler
+ }
+ return true;
+}
+
+/******************************************************************************
+ *
+ * SvxConfigPage is the abstract base class on which the Menu and Toolbar
+ * configuration tabpages are based. It includes methods which are common to
+ * both tabpages to add, delete, move and rename items etc.
+ *
+ *****************************************************************************/
+SvxConfigPage::SvxConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/menuassignpage.ui", "MenuAssignPage", &rSet)
+ , m_aUpdateDataTimer( "SvxConfigPage UpdateDataTimer" )
+ , bInitialised(false)
+ , pCurrentSaveInData(nullptr)
+ , m_xCommandCategoryListBox(new CommandCategoryListBox(m_xBuilder->weld_combo_box("commandcategorylist")))
+ , m_xFunctions(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("functions")))
+ , m_xCategoryLabel(m_xBuilder->weld_label("categorylabel"))
+ , m_xDescriptionFieldLb(m_xBuilder->weld_label("descriptionlabel"))
+ , m_xDescriptionField(m_xBuilder->weld_text_view("desc"))
+ , m_xLeftFunctionLabel(m_xBuilder->weld_label("leftfunctionlabel"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xSearchLabel(m_xBuilder->weld_label("searchlabel"))
+ , m_xCustomizeLabel(m_xBuilder->weld_label("customizelabel"))
+ , m_xTopLevelListBox(m_xBuilder->weld_combo_box("toplevellist"))
+ , m_xMoveUpButton(m_xBuilder->weld_button("up"))
+ , m_xMoveDownButton(m_xBuilder->weld_button("down"))
+ , m_xSaveInListBox(m_xBuilder->weld_combo_box("savein"))
+ , m_xInsertBtn(m_xBuilder->weld_menu_button("insert"))
+ , m_xModifyBtn(m_xBuilder->weld_menu_button("modify"))
+ , m_xResetBtn(m_xBuilder->weld_button("defaultsbtn"))
+ , m_xAddCommandButton(m_xBuilder->weld_button("add"))
+ , m_xRemoveCommandButton(m_xBuilder->weld_button("remove"))
+{
+ CustomNotebookbarGenerator::getFileNameAndAppName(m_sAppName, m_sFileName);
+
+ m_xTopLevelListBox->connect_changed(LINK(this, SvxConfigPage, SelectElementHdl));
+
+ weld::TreeView& rTreeView = m_xFunctions->get_widget();
+ Size aSize(rTreeView.get_approximate_digit_width() * 40, rTreeView.get_height_rows(8));
+ m_xFunctions->set_size_request(aSize.Width(), aSize.Height());
+ m_xDescriptionField->set_size_request(aSize.Width(), m_xDescriptionField->get_height_rows(3));
+
+ m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SvxConfigPage, ImplUpdateDataHdl));
+ m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+
+ m_xSearchEdit->connect_changed(LINK(this, SvxConfigPage, SearchUpdateHdl));
+ m_xSearchEdit->connect_focus_out(LINK(this, SvxConfigPage, FocusOut_Impl));
+
+ rTreeView.connect_row_activated(LINK(this, SvxConfigPage, FunctionDoubleClickHdl));
+ rTreeView.connect_changed(LINK(this, SvxConfigPage, SelectFunctionHdl));
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SelectElementHdl, weld::ComboBox&, void)
+{
+ SelectElement();
+}
+
+SvxConfigPage::~SvxConfigPage()
+{
+ int cnt = m_xSaveInListBox->get_count();
+ for(int i=0; i < cnt; ++i)
+ {
+ SaveInData *pData = weld::fromId<SaveInData*>(m_xSaveInListBox->get_id(i));
+ delete pData;
+ }
+}
+
+void SvxConfigPage::Reset( const SfxItemSet* )
+{
+ // If we haven't initialised our XMultiServiceFactory reference
+ // then Reset is being called at the opening of the dialog.
+
+ // Load menu configuration data for the module of the currently
+ // selected document, for the currently selected document, and for
+ // all other open documents of the same module type
+ if ( !bInitialised )
+ {
+ sal_Int32 nPos = 0;
+ uno::Reference < css::ui::XUIConfigurationManager > xCfgMgr;
+ uno::Reference < css::ui::XUIConfigurationManager > xDocCfgMgr;
+
+ uno::Reference< uno::XComponentContext > xContext(
+ ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW );
+
+ m_xFrame = GetFrame();
+ m_aModuleId = GetFrameWithDefaultAndIdentify( m_xFrame );
+
+ // replace %MODULENAME in the label with the correct module name
+ uno::Reference< css::frame::XModuleManager2 > xModuleManager(
+ css::frame::ModuleManager::create( xContext ));
+ OUString aModuleName = SvxConfigPageHelper::GetUIModuleName( m_aModuleId, xModuleManager );
+
+ uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier >
+ xModuleCfgSupplier( css::ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
+
+ // Set up data for module specific menus
+ SaveInData* pModuleData = nullptr;
+
+ try
+ {
+ xCfgMgr =
+ xModuleCfgSupplier->getUIConfigurationManager( m_aModuleId );
+
+ pModuleData = CreateSaveInData( xCfgMgr,
+ uno::Reference< css::ui::XUIConfigurationManager >(),
+ m_aModuleId,
+ false );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ }
+
+ if ( pModuleData != nullptr )
+ {
+ OUString sId(weld::toId(pModuleData));
+ m_xSaveInListBox->append(sId, utl::ConfigManager::getProductName() + " " + aModuleName);
+ }
+
+ // try to retrieve the document based ui configuration manager
+ OUString aTitle;
+ uno::Reference< frame::XController > xController =
+ m_xFrame->getController();
+ if ( CanConfig( m_aModuleId ) && xController.is() )
+ {
+ uno::Reference< frame::XModel > xModel( xController->getModel() );
+ if ( xModel.is() )
+ {
+ uno::Reference< css::ui::XUIConfigurationManagerSupplier >
+ xCfgSupplier( xModel, uno::UNO_QUERY );
+
+ if ( xCfgSupplier.is() )
+ {
+ xDocCfgMgr = xCfgSupplier->getUIConfigurationManager();
+ }
+ aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
+ }
+ }
+
+ SaveInData* pDocData = nullptr;
+ if ( xDocCfgMgr.is() )
+ {
+ pDocData = CreateSaveInData( xDocCfgMgr, xCfgMgr, m_aModuleId, true );
+
+ if ( !pDocData->IsReadOnly() )
+ {
+ OUString sId(weld::toId(pDocData));
+ m_xSaveInListBox->append(sId, aTitle);
+ }
+ }
+
+ // if an item to select has been passed in (eg. the ResourceURL for a
+ // toolbar) then try to select the SaveInData entry that has that item
+ bool bURLToSelectFound = false;
+ if ( !m_aURLToSelect.isEmpty() )
+ {
+ if ( pDocData && pDocData->HasURL( m_aURLToSelect ) )
+ {
+ m_xSaveInListBox->set_active(nPos);
+ pCurrentSaveInData = pDocData;
+ bURLToSelectFound = true;
+ }
+ else if ( pModuleData && pModuleData->HasURL( m_aURLToSelect ) )
+ {
+ m_xSaveInListBox->set_active(0);
+ pCurrentSaveInData = pModuleData;
+ bURLToSelectFound = true;
+ }
+ }
+
+ if ( !bURLToSelectFound )
+ {
+ // if the document has menu configuration settings select it
+ // it the SaveIn listbox, otherwise select the module data
+ if ( pDocData != nullptr && pDocData->HasSettings() )
+ {
+ m_xSaveInListBox->set_active(nPos);
+ pCurrentSaveInData = pDocData;
+ }
+ else
+ {
+ m_xSaveInListBox->set_active(0);
+ pCurrentSaveInData = pModuleData;
+ }
+ }
+
+#ifdef DBG_UTIL
+ DBG_ASSERT( pCurrentSaveInData, "SvxConfigPage::Reset(): no SaveInData" );
+#endif
+
+ if ( CanConfig( m_aModuleId ) )
+ {
+ // Load configuration for other open documents which have
+ // same module type
+ uno::Sequence< uno::Reference< frame::XFrame > > aFrameList;
+ try
+ {
+ uno::Reference< frame::XDesktop2 > xFramesSupplier = frame::Desktop::create(
+ xContext );
+
+ uno::Reference< frame::XFrames > xFrames =
+ xFramesSupplier->getFrames();
+
+ aFrameList = xFrames->queryFrames(
+ frame::FrameSearchFlag::ALL & ~frame::FrameSearchFlag::SELF );
+
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+
+ for ( uno::Reference < frame::XFrame > const & xf : std::as_const(aFrameList) )
+ {
+ if ( xf.is() && xf != m_xFrame )
+ {
+ OUString aCheckId;
+ try{
+ aCheckId = xModuleManager->identify( xf );
+ } catch(const uno::Exception&)
+ { aCheckId.clear(); }
+
+ if ( m_aModuleId == aCheckId )
+ {
+ // try to get the document based ui configuration manager
+ OUString aTitle2;
+ uno::Reference< frame::XController > xController_ =
+ xf->getController();
+
+ if ( xController_.is() )
+ {
+ uno::Reference< frame::XModel > xModel(
+ xController_->getModel() );
+
+ if ( xModel.is() )
+ {
+ uno::Reference<
+ css::ui::XUIConfigurationManagerSupplier >
+ xCfgSupplier( xModel, uno::UNO_QUERY );
+
+ if ( xCfgSupplier.is() )
+ {
+ xDocCfgMgr =
+ xCfgSupplier->getUIConfigurationManager();
+ }
+ aTitle2 = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
+ }
+ }
+
+ if ( xDocCfgMgr.is() )
+ {
+ SaveInData* pData = CreateSaveInData( xDocCfgMgr, xCfgMgr, m_aModuleId, true );
+
+ if ( pData && !pData->IsReadOnly() )
+ {
+ OUString sId(weld::toId(pData));
+ m_xSaveInListBox->append(sId, aTitle2);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ m_xSaveInListBox->connect_changed(
+ LINK( this, SvxConfigPage, SelectSaveInLocation ) );
+
+ bInitialised = true;
+
+ Init();
+ }
+ else
+ {
+ if ( QueryReset() == RET_YES )
+ {
+ // Reset menu configuration for currently selected SaveInData
+ GetSaveInData()->Reset();
+
+ Init();
+ }
+ }
+}
+
+OUString SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference< frame::XFrame >& _inout_rxFrame )
+{
+ OUString sModuleID;
+ try
+ {
+ uno::Reference< uno::XComponentContext > xContext(
+ ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(
+ xContext );
+
+ if ( !_inout_rxFrame.is() )
+ _inout_rxFrame = xDesktop->getActiveFrame();
+
+ if ( !_inout_rxFrame.is() )
+ {
+ _inout_rxFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( !_inout_rxFrame.is() && SfxViewFrame::Current() )
+ _inout_rxFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+
+ if ( !_inout_rxFrame.is() )
+ {
+ SAL_WARN( "cui.customize", "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
+ return sModuleID;
+ }
+
+ sModuleID = vcl::CommandInfoProvider::GetModuleIdentifier(_inout_rxFrame);
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+
+ return sModuleID;
+}
+
+OUString SvxConfigPage::GetScriptURL() const
+{
+ OUString result;
+
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xFunctions->get_selected_id());
+ if (pData)
+ {
+ if ( ( pData->nKind == SfxCfgKind::FUNCTION_SLOT ) ||
+ ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT ) ||
+ ( pData->nKind == SfxCfgKind::GROUP_STYLES ) )
+ {
+ result = pData->sCommand;
+ }
+ }
+
+ return result;
+}
+
+OUString SvxConfigPage::GetSelectedDisplayName() const
+{
+ return m_xFunctions->get_selected_text();
+}
+
+bool SvxConfigPage::FillItemSet( SfxItemSet* )
+{
+ bool result = false;
+
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ {
+ OUString sId = m_xSaveInListBox->get_id(i);
+ if (sId != notebookbarTabScope)
+ {
+ SaveInData* pData = weld::fromId<SaveInData*>(sId);
+ result = pData->Apply();
+ }
+ }
+ return result;
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SelectSaveInLocation, weld::ComboBox&, void)
+{
+ OUString sId = m_xSaveInListBox->get_active_id();
+ if (sId != notebookbarTabScope)
+ pCurrentSaveInData = weld::fromId<SaveInData*>(sId);
+ Init();
+}
+
+void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry const * pToSelect )
+{
+ int nSelectionPos = m_xTopLevelListBox->get_active();
+ m_xTopLevelListBox->clear();
+
+ if ( GetSaveInData() && GetSaveInData()->GetEntries() )
+ {
+ for (auto const& entryData : *GetSaveInData()->GetEntries())
+ {
+ OUString sId(weld::toId(entryData));
+ m_xTopLevelListBox->append(sId, SvxConfigPageHelper::stripHotKey(entryData->GetName()));
+
+ if (entryData == pToSelect)
+ nSelectionPos = m_xTopLevelListBox->get_count() - 1;
+
+ AddSubMenusToUI( SvxConfigPageHelper::stripHotKey( entryData->GetName() ), entryData );
+ }
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
+ DBG_ASSERT( GetSaveInData()->GetEntries() ,
+ "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
+ }
+#endif
+
+ nSelectionPos = (nSelectionPos != -1 && nSelectionPos < m_xTopLevelListBox->get_count()) ?
+ nSelectionPos : m_xTopLevelListBox->get_count() - 1;
+
+ m_xTopLevelListBox->set_active(nSelectionPos);
+ SelectElement();
+}
+
+void SvxConfigPage::AddSubMenusToUI(
+ std::u16string_view rBaseTitle, SvxConfigEntry const * pParentData )
+{
+ for (auto const& entryData : *pParentData->GetEntries())
+ {
+ if (entryData->IsPopup())
+ {
+ OUString subMenuTitle = OUString::Concat(rBaseTitle) + aMenuSeparatorStr + SvxConfigPageHelper::stripHotKey(entryData->GetName());
+
+ OUString sId(weld::toId(entryData));
+ m_xTopLevelListBox->append(sId, subMenuTitle);
+
+ AddSubMenusToUI( subMenuTitle, entryData );
+ }
+ }
+}
+
+SvxEntries* SvxConfigPage::FindParentForChild(
+ SvxEntries* pRootEntries, SvxConfigEntry* pChildData )
+{
+ for (auto const& entryData : *pRootEntries)
+ {
+
+ if (entryData == pChildData)
+ {
+ return pRootEntries;
+ }
+ else if (entryData->IsPopup())
+ {
+ SvxEntries* result =
+ FindParentForChild( entryData->GetEntries(), pChildData );
+
+ if ( result != nullptr )
+ {
+ return result;
+ }
+ }
+ }
+ return nullptr;
+}
+
+SvxConfigEntry *SvxConfigPage::CreateCommandFromSelection(const OUString &aURL)
+{
+ OUString aDisplayName;
+
+ if ( aURL.isEmpty() ) {
+ return nullptr;
+ }
+
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aURL, m_aModuleId);
+
+ if ( typeid(*pCurrentSaveInData) == typeid(ContextMenuSaveInData) )
+ aDisplayName = vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties);
+ else if ( typeid(*pCurrentSaveInData) == typeid(MenuSaveInData) )
+ aDisplayName = vcl::CommandInfoProvider::GetMenuLabelForCommand(aProperties);
+ else
+ aDisplayName = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+
+ SvxConfigEntry* toret =
+ new SvxConfigEntry( aDisplayName, aURL, false, /*bParentData*/false );
+
+ toret->SetUserDefined();
+
+ if ( aDisplayName.isEmpty() )
+ toret->SetName( GetSelectedDisplayName() );
+
+ return toret;
+}
+
+bool SvxConfigPage::IsCommandInMenuList(const SvxConfigEntry *pEntryData,
+ const SvxEntries *pEntries)
+{
+ bool toret = false;
+
+ if ( pEntries != nullptr
+ && pEntryData != nullptr )
+ {
+ for (auto const& entry : *pEntries)
+ {
+ if ( entry->GetCommand() == pEntryData->GetCommand() )
+ {
+ toret = true;
+ break;
+ }
+ }
+ }
+
+ return toret;
+}
+
+int SvxConfigPage::AddFunction(int nTarget, bool bAllowDuplicates)
+{
+ int toret = -1;
+ OUString aURL = GetScriptURL();
+ SvxConfigEntry* pParent = GetTopLevelSelection();
+
+ if ( aURL.isEmpty() || pParent == nullptr )
+ {
+ return -1;
+ }
+
+
+ SvxConfigEntry * pNewEntryData = CreateCommandFromSelection( aURL );
+
+ // check that this function is not already in the menu
+ if ( !bAllowDuplicates
+ && IsCommandInMenuList( pNewEntryData, pParent->GetEntries() )
+ )
+ {
+ delete pNewEntryData;
+ } else {
+ toret = AppendEntry( pNewEntryData, nTarget );
+ }
+
+ UpdateButtonStates();
+ return toret;
+}
+
+int SvxConfigPage::AppendEntry(
+ SvxConfigEntry* pNewEntryData,
+ int nTarget)
+{
+ SvxConfigEntry* pTopLevelSelection = GetTopLevelSelection();
+
+ if (pTopLevelSelection == nullptr)
+ return -1;
+
+ // Grab the entries list for the currently selected menu
+ SvxEntries* pEntries = pTopLevelSelection->GetEntries();
+
+ int nNewEntry = -1;
+ int nCurEntry =
+ nTarget != -1 ? nTarget : m_xContentsListBox->get_selected_index();
+
+ OUString sId(weld::toId(pNewEntryData));
+
+ if (nCurEntry == -1 || nCurEntry == m_xContentsListBox->n_children() - 1)
+ {
+ pEntries->push_back( pNewEntryData );
+ m_xContentsListBox->insert(-1, sId);
+ nNewEntry = m_xContentsListBox->n_children() - 1;
+ }
+ else
+ {
+ SvxConfigEntry* pEntryData =
+ weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nCurEntry));
+
+ SvxEntries::iterator iter = pEntries->begin();
+ SvxEntries::const_iterator end = pEntries->end();
+
+ // Advance the iterator to the data for currently selected entry
+ sal_uInt16 nPos = 0;
+ while (*iter != pEntryData && ++iter != end)
+ {
+ ++nPos;
+ }
+
+ // Now step past it to the entry after the currently selected one
+ ++iter;
+ ++nPos;
+
+ // Now add the new entry to the UI and to the parent's list
+ if ( iter != end )
+ {
+ pEntries->insert( iter, pNewEntryData );
+ m_xContentsListBox->insert(nPos, sId);
+ nNewEntry = nPos;
+ }
+ }
+
+ if (nNewEntry != -1)
+ {
+ m_xContentsListBox->select(nNewEntry);
+ m_xContentsListBox->scroll_to_row(nNewEntry);
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+ }
+
+ return nNewEntry;
+}
+
+namespace
+{
+ template<typename itertype> void TmplInsertEntryIntoUI(SvxConfigEntry* pNewEntryData, weld::TreeView& rTreeView, itertype& rIter, SaveInData* pSaveInData,
+ VirtualDevice& rDropDown, bool bMenu)
+ {
+ OUString sId(weld::toId(pNewEntryData));
+
+ rTreeView.set_id(rIter, sId);
+
+ if (pNewEntryData->IsSeparator())
+ {
+ rTreeView.set_text(rIter, "----------------------------------", 0);
+ }
+ else
+ {
+ auto xImage = pSaveInData->GetImage(pNewEntryData->GetCommand());
+ if (xImage.is())
+ rTreeView.set_image(rIter, xImage, -1);
+ OUString aName = SvxConfigPageHelper::stripHotKey( pNewEntryData->GetName() );
+ rTreeView.set_text(rIter, aName, 0);
+ }
+
+ if (bMenu) // menus
+ {
+ if (pNewEntryData->IsPopup() || pNewEntryData->GetStyle() & css::ui::ItemStyle::DROP_DOWN)
+ rTreeView.set_image(rIter, rDropDown, 1);
+ else
+ rTreeView.set_image(rIter, css::uno::Reference<css::graphic::XGraphic>(), 1);
+ }
+ }
+}
+
+void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry* pNewEntryData, weld::TreeView& rTreeView, int nPos, bool bMenu)
+{
+ TmplInsertEntryIntoUI<int>(pNewEntryData, rTreeView, nPos, GetSaveInData(),
+ m_xContentsListBox->get_dropdown_image(), bMenu);
+}
+
+void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry* pNewEntryData, weld::TreeView& rTreeView, weld::TreeIter& rIter, bool bMenu)
+{
+ TmplInsertEntryIntoUI<weld::TreeIter>(pNewEntryData, rTreeView, rIter, GetSaveInData(),
+ m_xContentsListBox->get_dropdown_image(), bMenu);
+}
+
+IMPL_LINK(SvxConfigPage, MoveHdl, weld::Button&, rButton, void)
+{
+ MoveEntry(&rButton == m_xMoveUpButton.get());
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, FunctionDoubleClickHdl, weld::TreeView&, bool)
+{
+ if (m_xAddCommandButton->get_sensitive())
+ m_xAddCommandButton->clicked();
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SelectFunctionHdl, weld::TreeView&, void)
+{
+ // GetScriptURL() returns a non-empty string if a
+ // valid command is selected on the left box
+ OUString aSelectCommand = GetScriptURL();
+ bool bIsValidCommand = !aSelectCommand.isEmpty();
+
+ // Enable/disable Add and Remove buttons depending on current selection
+ if (bIsValidCommand)
+ {
+ m_xAddCommandButton->set_sensitive(true);
+ m_xRemoveCommandButton->set_sensitive(true);
+
+ if (SfxHelp::IsHelpInstalled())
+ {
+ m_xDescriptionField->set_text(m_xFunctions->GetHelpText(false));
+ }
+ else
+ {
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xFunctions->get_selected_id());
+ if (pData)
+ {
+ bool bIsExperimental
+ = vcl::CommandInfoProvider::IsExperimental(pData->sCommand, m_aModuleId);
+
+ OUString aExperimental = "\n" + CuiResId(RID_CUISTR_COMMANDEXPERIMENTAL);
+ OUString aLabel = CuiResId(RID_CUISTR_COMMANDLABEL) + ": " + pData->sLabel + "\n";
+ OUString aName = CuiResId(RID_CUISTR_COMMANDNAME) + ": " + pData->sCommand + "\n";
+ OUString aTip = CuiResId(RID_CUISTR_COMMANDTIP) + ": " + pData->sTooltip;
+ if (bIsExperimental)
+ m_xDescriptionField->set_text(aLabel + aName + aTip + aExperimental);
+ else
+ m_xDescriptionField->set_text(aLabel + aName + aTip);
+ }
+ }
+ }
+ else
+ {
+
+ m_xAddCommandButton->set_sensitive(false);
+ m_xRemoveCommandButton->set_sensitive(false);
+
+ m_xDescriptionField->set_text("");
+ }
+
+ UpdateButtonStates();
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, ImplUpdateDataHdl, Timer*, void)
+{
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
+ SelectFunctionHdl(m_xFunctions->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SearchUpdateHdl, weld::Entry&, void)
+{
+ m_aUpdateDataTimer.Start();
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, FocusOut_Impl, weld::Widget&, void)
+{
+ if (m_aUpdateDataTimer.IsActive())
+ {
+ m_aUpdateDataTimer.Stop();
+ m_aUpdateDataTimer.Invoke();
+ }
+}
+
+void SvxConfigPage::MoveEntry(bool bMoveUp)
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ int nSourceEntry = rTreeView.get_selected_index();
+ int nTargetEntry = -1;
+ int nToSelect = -1;
+
+ if (nSourceEntry == -1)
+ {
+ return;
+ }
+
+ if ( bMoveUp )
+ {
+ // Move Up is just a Move Down with the source and target reversed
+ nTargetEntry = nSourceEntry;
+ nSourceEntry = nTargetEntry - 1;
+ nToSelect = nSourceEntry;
+ }
+ else
+ {
+ nTargetEntry = nSourceEntry + 1;
+ nToSelect = nTargetEntry;
+ }
+
+ if (MoveEntryData(nSourceEntry, nTargetEntry))
+ {
+ rTreeView.swap(nSourceEntry, nTargetEntry);
+ rTreeView.select(nToSelect);
+ rTreeView.scroll_to_row(nToSelect);
+
+ UpdateButtonStates();
+ }
+}
+
+bool SvxConfigPage::MoveEntryData(int nSourceEntry, int nTargetEntry)
+{
+ //#i53677#
+ if (nSourceEntry == -1 || nTargetEntry == -1)
+ {
+ return false;
+ }
+
+ // Grab the entries list for the currently selected menu
+ SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
+
+ SvxConfigEntry* pSourceData =
+ weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nSourceEntry));
+
+ SvxConfigEntry* pTargetData =
+ weld::fromId<SvxConfigEntry*>(m_xContentsListBox->get_id(nTargetEntry));
+
+ if ( pSourceData == nullptr || pTargetData == nullptr )
+ return false;
+
+ // remove the source entry from our list
+ SvxConfigPageHelper::RemoveEntry( pEntries, pSourceData );
+
+ SvxEntries::iterator iter = pEntries->begin();
+ SvxEntries::const_iterator end = pEntries->end();
+
+ // advance the iterator to the position of the target entry
+ while (*iter != pTargetData && ++iter != end) ;
+
+ // insert the source entry at the position after the target
+ pEntries->insert( ++iter, pSourceData );
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+
+ return true;
+}
+
+SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
+ weld::Window* pParent, SvxEntries* entries,
+ SvxConfigEntry const * selection, bool bCreateMenu )
+ : GenericDialogController(pParent, "cui/ui/movemenu.ui", "MoveMenuDialog")
+ , m_xMenuBox(m_xBuilder->weld_widget("namebox"))
+ , m_xMenuNameEdit(m_xBuilder->weld_entry("menuname"))
+ , m_xMenuListBox(m_xBuilder->weld_tree_view("menulist"))
+ , m_xMoveUpButton(m_xBuilder->weld_button("up"))
+ , m_xMoveDownButton(m_xBuilder->weld_button("down"))
+{
+ m_xMenuListBox->set_size_request(-1, m_xMenuListBox->get_height_rows(12));
+
+ // Copy the entries list passed in
+ if ( entries != nullptr )
+ {
+ mpEntries.reset( new SvxEntries );
+ for (auto const& entry : *entries)
+ {
+ m_xMenuListBox->append(weld::toId(entry),
+ SvxConfigPageHelper::stripHotKey(entry->GetName()));
+ mpEntries->push_back(entry);
+ if (entry == selection)
+ {
+ m_xMenuListBox->select(m_xMenuListBox->n_children() - 1);
+ }
+ }
+ }
+
+ if ( bCreateMenu )
+ {
+ // Generate custom name for new menu
+ OUString prefix = CuiResId( RID_CUISTR_NEW_MENU );
+
+ OUString newname = SvxConfigPageHelper::generateCustomName( prefix, entries );
+ OUString newurl = SvxConfigPageHelper::generateCustomMenuURL( mpEntries.get() );
+
+ SvxConfigEntry* pNewEntryData =
+ new SvxConfigEntry( newname, newurl, true, /*bParentData*/false );
+ pNewEntryData->SetName( newname );
+ pNewEntryData->SetUserDefined();
+ pNewEntryData->SetMain();
+
+ m_sNewMenuEntryId = weld::toId(pNewEntryData);
+ m_xMenuListBox->append(m_sNewMenuEntryId,
+ SvxConfigPageHelper::stripHotKey(pNewEntryData->GetName()));
+ m_xMenuListBox->select(m_xMenuListBox->n_children() - 1);
+
+ if (mpEntries)
+ mpEntries->push_back(pNewEntryData);
+
+ m_xMenuNameEdit->set_text(newname);
+ m_xMenuNameEdit->connect_changed(LINK(this, SvxMainMenuOrganizerDialog, ModifyHdl));
+ }
+ else
+ {
+ // hide name label and textfield
+ m_xMenuBox->hide();
+ // change the title
+ m_xDialog->set_title(CuiResId(RID_CUISTR_MOVE_MENU));
+ }
+
+ m_xMenuListBox->connect_changed(LINK(this, SvxMainMenuOrganizerDialog, SelectHdl));
+
+ m_xMoveUpButton->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog, MoveHdl));
+ m_xMoveDownButton->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog, MoveHdl));
+
+ UpdateButtonStates();
+}
+
+SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog, ModifyHdl, weld::Entry&, void)
+{
+ // if the Edit control is empty do not change the name
+ if (m_xMenuNameEdit->get_text().isEmpty())
+ {
+ return;
+ }
+
+ SvxConfigEntry* pNewEntryData = weld::fromId<SvxConfigEntry*>(m_sNewMenuEntryId);
+ pNewEntryData->SetName(m_xMenuNameEdit->get_text());
+
+ const int nNewMenuPos = m_xMenuListBox->find_id(m_sNewMenuEntryId);
+ const int nOldSelection = m_xMenuListBox->get_selected_index();
+ m_xMenuListBox->remove(nNewMenuPos);
+ m_xMenuListBox->insert(nNewMenuPos, pNewEntryData->GetName(), &m_sNewMenuEntryId, nullptr, nullptr);
+ m_xMenuListBox->select(nOldSelection);
+}
+
+IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog, SelectHdl, weld::TreeView&, void)
+{
+ UpdateButtonStates();
+}
+
+void SvxMainMenuOrganizerDialog::UpdateButtonStates()
+{
+ // Disable Up and Down buttons depending on current selection
+ const int nSelected = m_xMenuListBox->get_selected_index();
+ m_xMoveUpButton->set_sensitive(nSelected > 0);
+ m_xMoveDownButton->set_sensitive(nSelected != -1 && nSelected < m_xMenuListBox->n_children() - 1);
+}
+
+IMPL_LINK( SvxMainMenuOrganizerDialog, MoveHdl, weld::Button&, rButton, void )
+{
+ int nSourceEntry = m_xMenuListBox->get_selected_index();
+ if (nSourceEntry == -1)
+ return;
+
+ int nTargetEntry;
+
+ if (&rButton == m_xMoveDownButton.get())
+ {
+ nTargetEntry = nSourceEntry + 1;
+ }
+ else
+ {
+ // Move Up is just a Move Down with the source and target reversed
+ nTargetEntry = nSourceEntry - 1;
+ }
+
+ OUString sId = m_xMenuListBox->get_id(nSourceEntry);
+ OUString sEntry = m_xMenuListBox->get_text(nSourceEntry);
+ m_xMenuListBox->remove(nSourceEntry);
+ m_xMenuListBox->insert(nTargetEntry, sEntry, &sId, nullptr, nullptr);
+ m_xMenuListBox->select(nTargetEntry);
+
+ std::swap(mpEntries->at(nSourceEntry), mpEntries->at(nTargetEntry));
+
+ UpdateButtonStates();
+}
+
+SvxConfigEntry* SvxMainMenuOrganizerDialog::GetSelectedEntry()
+{
+ const int nSelected(m_xMenuListBox->get_selected_index());
+ if (nSelected == -1)
+ return nullptr;
+ return weld::fromId<SvxConfigEntry*>(m_xMenuListBox->get_id(nSelected));
+}
+
+SvxConfigEntry::SvxConfigEntry( OUString aDisplayName,
+ OUString aCommandURL, bool bPopup, bool bParentData )
+ : nId( 1 )
+ , aLabel(std::move(aDisplayName))
+ , aCommand(std::move(aCommandURL))
+ , bPopUp(bPopup)
+ , bStrEdited( false )
+ , bIsUserDefined( false )
+ , bIsMain( false )
+ , bIsParentData( bParentData )
+ , bIsModified( false )
+ , bIsVisible( true )
+ , nStyle( 0 )
+{
+ if (bPopUp)
+ {
+ mpEntries.reset( new SvxEntries );
+ }
+}
+
+SvxConfigEntry::~SvxConfigEntry()
+{
+ if (mpEntries)
+ {
+ for (auto const& entry : *mpEntries)
+ {
+ delete entry;
+ }
+ }
+}
+
+bool SvxConfigEntry::IsMovable() const
+{
+ return !IsPopup() || IsMain();
+}
+
+bool SvxConfigEntry::IsDeletable() const
+{
+ return !IsMain() || IsUserDefined();
+}
+
+bool SvxConfigEntry::IsRenamable() const
+{
+ return !IsMain() || IsUserDefined();
+}
+
+ToolbarSaveInData::ToolbarSaveInData(
+ const uno::Reference < css::ui::XUIConfigurationManager >& xCfgMgr,
+ const uno::Reference < css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool docConfig ) :
+
+ SaveInData ( xCfgMgr, xParentCfgMgr, aModuleId, docConfig ),
+ m_aDescriptorContainer ( ITEM_DESCRIPTOR_CONTAINER )
+
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ // Initialize the m_xPersistentWindowState variable which is used
+ // to get the default properties of system toolbars such as name
+ uno::Reference< container::XNameAccess > xPWSS = css::ui::theWindowStateConfiguration::get( xContext );
+
+ xPWSS->getByName( aModuleId ) >>= m_xPersistentWindowState;
+}
+
+ToolbarSaveInData::~ToolbarSaveInData()
+{
+}
+
+sal_Int32 ToolbarSaveInData::GetSystemStyle( const OUString& rResourceURL )
+{
+ sal_Int32 result = 0;
+
+ if ( rResourceURL.startsWith( "private" ) &&
+ m_xPersistentWindowState.is() &&
+ m_xPersistentWindowState->hasByName( rResourceURL ) )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+ uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
+
+ if ( a >>= aProps )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aProps) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_STYLE )
+ {
+ prop.Value >>= result;
+ break;
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // do nothing, a default value is returned
+ }
+ }
+
+ return result;
+}
+
+void ToolbarSaveInData::SetSystemStyle(
+ const uno::Reference< frame::XFrame >& xFrame,
+ const OUString& rResourceURL,
+ sal_Int32 nStyle )
+{
+ // change the style using the API
+ SetSystemStyle( rResourceURL, nStyle );
+
+ // this code is a temporary hack as the UI is not updating after
+ // changing the toolbar style via the API
+ uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ vcl::Window *window = nullptr;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ uno::Any a = xPropSet->getPropertyValue( "LayoutManager" );
+ a >>= xLayoutManager;
+ }
+
+ if ( xLayoutManager.is() )
+ {
+ uno::Reference< css::ui::XUIElement > xUIElement =
+ xLayoutManager->getElement( rResourceURL );
+
+ // check reference before we call getRealInterface. The layout manager
+ // can only provide references for elements that have been created
+ // before. It's possible that the current element is not available.
+ uno::Reference< css::awt::XWindow > xWindow;
+ if ( xUIElement.is() )
+ xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY );
+
+ window = VCLUnoHelper::GetWindow( xWindow );
+ }
+
+ if ( window == nullptr || window->GetType() != WindowType::TOOLBOX )
+ return;
+
+ ToolBox* toolbox = static_cast<ToolBox*>(window);
+
+ if ( nStyle == 0 )
+ {
+ toolbox->SetButtonType( ButtonType::SYMBOLONLY );
+ }
+ else if ( nStyle == 1 )
+ {
+ toolbox->SetButtonType( ButtonType::TEXT );
+ }
+ if ( nStyle == 2 )
+ {
+ toolbox->SetButtonType( ButtonType::SYMBOLTEXT );
+ }
+}
+
+void ToolbarSaveInData::SetSystemStyle(
+ const OUString& rResourceURL,
+ sal_Int32 nStyle )
+{
+ if ( !(rResourceURL.startsWith( "private" ) &&
+ m_xPersistentWindowState.is() &&
+ m_xPersistentWindowState->hasByName( rResourceURL )) )
+ return;
+
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+
+ uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
+
+ if ( a >>= aProps )
+ {
+ for ( beans::PropertyValue& prop : asNonConstRange(aProps) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_STYLE )
+ {
+ prop.Value <<= nStyle;
+ break;
+ }
+ }
+ }
+
+ uno::Reference< container::XNameReplace >
+ xNameReplace( m_xPersistentWindowState, uno::UNO_QUERY );
+
+ xNameReplace->replaceByName( rResourceURL, uno::Any( aProps ) );
+ }
+ catch ( uno::Exception& )
+ {
+ // do nothing, a default value is returned
+ TOOLS_WARN_EXCEPTION("cui.customize", "Exception setting toolbar style");
+ }
+}
+
+OUString ToolbarSaveInData::GetSystemUIName( const OUString& rResourceURL )
+{
+ OUString result;
+
+ if ( rResourceURL.startsWith( "private" ) &&
+ m_xPersistentWindowState.is() &&
+ m_xPersistentWindowState->hasByName( rResourceURL ) )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+ uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
+
+ if ( a >>= aProps )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aProps) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ prop.Value >>= result;
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // do nothing, an empty UIName will be returned
+ }
+ }
+
+ if ( rResourceURL.startsWith( ".uno" ) &&
+ m_xCommandToLabelMap.is() &&
+ m_xCommandToLabelMap->hasByName( rResourceURL ) )
+ {
+ uno::Any a;
+ try
+ {
+ a = m_xCommandToLabelMap->getByName( rResourceURL );
+
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ if ( a >>= aPropSeq )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aPropSeq) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_LABEL )
+ {
+ prop.Value >>= result;
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // not a system command name
+ }
+ }
+
+ return result;
+}
+
+SvxEntries* ToolbarSaveInData::GetEntries()
+{
+ typedef std::unordered_map<OUString, bool > ToolbarInfo;
+
+ ToolbarInfo aToolbarInfo;
+
+ if ( pRootEntry == nullptr )
+ {
+
+ pRootEntry.reset( new SvxConfigEntry( "MainToolbars", OUString(), true, /*bParentData*/false) );
+
+ const uno::Sequence< uno::Sequence < beans::PropertyValue > > info =
+ GetConfigManager()->getUIElementsInfo(
+ css::ui::UIElementType::TOOLBAR );
+
+ for ( uno::Sequence<beans::PropertyValue> const & props : info )
+ {
+ OUString url;
+ OUString systemname;
+ OUString uiname;
+
+ for ( const beans::PropertyValue& prop : props )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ prop.Value >>= url;
+ systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
+ }
+ else if ( prop.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ prop.Value >>= uiname;
+ }
+ }
+
+ try
+ {
+ uno::Reference< container::XIndexAccess > xToolbarSettings =
+ GetConfigManager()->getSettings( url, false );
+
+ if ( uiname.isEmpty() )
+ {
+ // try to get the name from m_xPersistentWindowState
+ uiname = GetSystemUIName( url );
+
+ if ( uiname.isEmpty() )
+ {
+ uiname = systemname;
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ uiname, url, true, /*bParentData*/false );
+
+ pEntry->SetMain();
+ pEntry->SetStyle( GetSystemStyle( url ) );
+
+
+ // insert into std::unordered_map to filter duplicates from the parent
+ aToolbarInfo.emplace( systemname, true );
+
+ if ( systemname.startsWith( CUSTOM_TOOLBAR_STR ) )
+ {
+ pEntry->SetUserDefined();
+ }
+ else
+ {
+ pEntry->SetUserDefined( false );
+ }
+
+ pRootEntry->GetEntries()->push_back( pEntry );
+
+ LoadToolbar( xToolbarSettings, pEntry );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // TODO, handle resourceURL with no settings
+ }
+ }
+
+ uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
+ if ( xParentCfgMgr.is() )
+ {
+ // Retrieve also the parent toolbars to make it possible
+ // to configure module toolbars and save them into the document
+ // config manager.
+ const uno::Sequence< uno::Sequence < beans::PropertyValue > > info_ =
+ xParentCfgMgr->getUIElementsInfo(
+ css::ui::UIElementType::TOOLBAR );
+
+ for ( uno::Sequence<beans::PropertyValue> const & props : info_ )
+ {
+ OUString url;
+ OUString systemname;
+ OUString uiname;
+
+ for ( const beans::PropertyValue& prop : props )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ prop.Value >>= url;
+ systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
+ }
+ else if ( prop.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ prop.Value >>= uiname;
+ }
+ }
+
+ // custom toolbars of the parent are not visible in the document layer
+ OUString custom(CUSTOM_TOOLBAR_STR);
+ if ( systemname.startsWith( custom ) )
+ continue;
+
+ // check if toolbar is already in the document layer
+ ToolbarInfo::const_iterator pIter = aToolbarInfo.find( systemname );
+ if ( pIter == aToolbarInfo.end() )
+ {
+ aToolbarInfo.emplace( systemname, true );
+
+ try
+ {
+ uno::Reference< container::XIndexAccess > xToolbarSettings =
+ xParentCfgMgr->getSettings( url, false );
+
+ if ( uiname.isEmpty() )
+ {
+ // try to get the name from m_xPersistentWindowState
+ uiname = GetSystemUIName( url );
+
+ if ( uiname.isEmpty() )
+ {
+ uiname = systemname;
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ uiname, url, true, true );
+
+ pEntry->SetMain();
+ pEntry->SetStyle( GetSystemStyle( url ) );
+
+ if ( systemname.startsWith( custom ) )
+ {
+ pEntry->SetUserDefined();
+ }
+ else
+ {
+ pEntry->SetUserDefined( false );
+ }
+
+ pRootEntry->GetEntries()->push_back( pEntry );
+
+ LoadToolbar( xToolbarSettings, pEntry );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // TODO, handle resourceURL with no settings
+ }
+ }
+ }
+ }
+
+ std::sort( GetEntries()->begin(), GetEntries()->end(), SvxConfigPageHelper::EntrySort );
+ }
+
+ return pRootEntry->GetEntries();
+}
+
+void
+ToolbarSaveInData::SetEntries( std::unique_ptr<SvxEntries> pNewEntries )
+{
+ pRootEntry->SetEntries( std::move(pNewEntries) );
+}
+
+bool
+ToolbarSaveInData::HasURL( const OUString& rURL )
+{
+ for (auto const& entry : *GetEntries())
+ {
+ if (entry->GetCommand() == rURL)
+ {
+ return !entry->IsParentData();
+ }
+ }
+ return false;
+}
+
+bool ToolbarSaveInData::HasSettings()
+{
+ // return true if there is at least one toolbar entry
+ return !GetEntries()->empty();
+}
+
+void ToolbarSaveInData::Reset()
+{
+ // reset each toolbar by calling removeSettings for its toolbar URL
+ for (auto const& entry : *GetEntries())
+ {
+ try
+ {
+ const OUString& url = entry->GetCommand();
+ GetConfigManager()->removeSettings( url );
+ }
+ catch ( uno::Exception& )
+ {
+ // error occurred removing the settings
+ // TODO - add error dialog in future?
+ }
+ }
+
+ // persist changes to toolbar storage
+ PersistChanges( GetConfigManager() );
+
+ // now delete the root SvxConfigEntry the next call to GetEntries()
+ // causes it to be reinitialised
+ pRootEntry.reset();
+
+ // reset all icons to default
+ try
+ {
+ GetImageManager()->reset();
+ PersistChanges( GetImageManager() );
+ }
+ catch ( uno::Exception& )
+ {
+ SAL_WARN("cui.customize", "Error resetting all icons when resetting toolbars");
+ }
+}
+
+bool ToolbarSaveInData::Apply()
+{
+ // toolbar changes are instantly applied
+ return false;
+}
+
+void ToolbarSaveInData::ApplyToolbar(
+ uno::Reference< container::XIndexContainer > const & rToolbarBar,
+ uno::Reference< lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry const * pToolbarData )
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ for (auto const& entry : *pToolbarData->GetEntries())
+ {
+ if (entry->IsPopup())
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertToolbarEntry(entry);
+
+ uno::Reference< container::XIndexContainer > xSubMenuBar(
+ rFactory->createInstanceWithContext( xContext ),
+ uno::UNO_QUERY );
+
+ sal_Int32 nIndex = aPropValueSeq.getLength();
+ aPropValueSeq.realloc( nIndex + 1 );
+ auto pPropValueSeq = aPropValueSeq.getArray();
+ pPropValueSeq[nIndex].Name = m_aDescriptorContainer;
+ pPropValueSeq[nIndex].Value <<= xSubMenuBar;
+ rToolbarBar->insertByIndex(
+ rToolbarBar->getCount(), uno::Any( aPropValueSeq ));
+
+ ApplyToolbar(xSubMenuBar, rFactory, entry);
+ }
+ else if (entry->IsSeparator())
+ {
+ rToolbarBar->insertByIndex(
+ rToolbarBar->getCount(), uno::Any( m_aSeparatorSeq ));
+ }
+ else
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertToolbarEntry(entry);
+
+ rToolbarBar->insertByIndex(
+ rToolbarBar->getCount(), uno::Any( aPropValueSeq ));
+ }
+ }
+}
+
+void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry* pToolbar )
+{
+ // Apply new toolbar structure to our settings container
+ uno::Reference< container::XIndexAccess > xSettings =
+ GetConfigManager()->createSettings();
+
+ uno::Reference< container::XIndexContainer > xIndexContainer (
+ xSettings, uno::UNO_QUERY );
+
+ uno::Reference< lang::XSingleComponentFactory > xFactory (
+ xSettings, uno::UNO_QUERY );
+
+ ApplyToolbar( xIndexContainer, xFactory, pToolbar );
+
+ uno::Reference< beans::XPropertySet > xProps(
+ xSettings, uno::UNO_QUERY );
+
+ if ( pToolbar->IsUserDefined() )
+ {
+ xProps->setPropertyValue(
+ ITEM_DESCRIPTOR_UINAME,
+ uno::Any( pToolbar->GetName() ) );
+ }
+
+ try
+ {
+ if ( GetConfigManager()->hasSettings( pToolbar->GetCommand() ) )
+ {
+ GetConfigManager()->replaceSettings(
+ pToolbar->GetCommand(), xSettings );
+ }
+ else
+ {
+ GetConfigManager()->insertSettings(
+ pToolbar->GetCommand(), xSettings );
+ if ( pToolbar->IsParentData() )
+ pToolbar->SetParentData( false );
+ }
+ }
+ catch ( css::uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
+ }
+
+ PersistChanges( GetConfigManager() );
+}
+
+void ToolbarSaveInData::CreateToolbar( SvxConfigEntry* pToolbar )
+{
+ // show the new toolbar in the UI also
+ uno::Reference< container::XIndexAccess >
+ xSettings = GetConfigManager()->createSettings();
+
+ uno::Reference< beans::XPropertySet >
+ xPropertySet( xSettings, uno::UNO_QUERY );
+
+ xPropertySet->setPropertyValue(
+ ITEM_DESCRIPTOR_UINAME,
+ uno::Any( pToolbar->GetName() ) );
+
+ try
+ {
+ GetConfigManager()->insertSettings( pToolbar->GetCommand(), xSettings );
+ }
+ catch ( css::uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
+ }
+
+ GetEntries()->push_back( pToolbar );
+
+ PersistChanges( GetConfigManager() );
+}
+
+void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry* pToolbar )
+{
+ try
+ {
+ OUString url = pToolbar->GetCommand();
+ GetConfigManager()->removeSettings( url );
+ SvxConfigPageHelper::RemoveEntry( GetEntries(), pToolbar );
+ delete pToolbar;
+
+ PersistChanges( GetConfigManager() );
+
+ // remove the persistent window state data
+ css::uno::Reference< css::container::XNameContainer > xNameContainer(
+ m_xPersistentWindowState, css::uno::UNO_QUERY_THROW );
+
+ xNameContainer->removeByName( url );
+ }
+ catch ( uno::Exception& )
+ {
+ // error occurred removing the settings
+ }
+}
+
+void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry* pToolbar )
+{
+ OUString url = pToolbar->GetCommand();
+
+ // Restore of toolbar is done by removing it from
+ // its configuration manager and then getting it again
+ bool bParentToolbar = pToolbar->IsParentData();
+
+ // Cannot restore parent toolbar
+ if ( bParentToolbar )
+ return;
+
+ try
+ {
+ GetConfigManager()->removeSettings( url );
+ pToolbar->GetEntries()->clear();
+ PersistChanges( GetConfigManager() );
+ }
+ catch ( uno::Exception& )
+ {
+ // if an error occurs removing the settings then just return
+ return;
+ }
+
+ // Now reload the toolbar settings
+ try
+ {
+ uno::Reference< container::XIndexAccess > xToolbarSettings;
+ if ( IsDocConfig() )
+ {
+ xToolbarSettings = GetParentConfigManager()->getSettings( url, false );
+ pToolbar->SetParentData();
+ }
+ else
+ xToolbarSettings = GetConfigManager()->getSettings( url, false );
+
+ LoadToolbar( xToolbarSettings, pToolbar );
+
+ // After reloading, ensure that the icon is reset of each entry
+ // in the toolbar
+ uno::Sequence< OUString > aURLSeq( 1 );
+ auto pURLSeq = aURLSeq.getArray();
+ for (auto const& entry : *pToolbar->GetEntries())
+ {
+ pURLSeq[ 0 ] = entry->GetCommand();
+
+ try
+ {
+ GetImageManager()->removeImages( SvxConfigPageHelper::GetImageType(), aURLSeq );
+ }
+ catch ( uno::Exception& )
+ {
+ SAL_WARN("cui.customize", "Error restoring icon when resetting toolbar");
+ }
+ }
+ PersistChanges( GetImageManager() );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // cannot find the resource URL after removing it
+ // so no entry will appear in the toolbar list
+ }
+}
+
+void ToolbarSaveInData::LoadToolbar(
+ const uno::Reference< container::XIndexAccess >& xToolbarSettings,
+ SvxConfigEntry const * pParentData )
+{
+ SvxEntries* pEntries = pParentData->GetEntries();
+
+ for ( sal_Int32 nIndex = 0; nIndex < xToolbarSettings->getCount(); ++nIndex )
+ {
+ OUString aCommandURL;
+ OUString aLabel;
+ bool bIsVisible;
+ sal_Int32 nStyle;
+
+ sal_uInt16 nType( css::ui::ItemType::DEFAULT );
+
+ bool bItem = SvxConfigPageHelper::GetToolbarItemData( xToolbarSettings, nIndex, aCommandURL,
+ aLabel, nType, bIsVisible, nStyle );
+
+ if ( bItem )
+ {
+ bool bIsUserDefined = true;
+
+ if ( nType == css::ui::ItemType::DEFAULT )
+ {
+ uno::Any a;
+ try
+ {
+ a = m_xCommandToLabelMap->getByName( aCommandURL );
+ bIsUserDefined = false;
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ bIsUserDefined = true;
+ }
+
+ bool bUseDefaultLabel = false;
+ // If custom label not set retrieve it from the command
+ // to info service
+ if ( aLabel.isEmpty() )
+ {
+ bUseDefaultLabel = true;
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ if ( a >>= aPropSeq )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aPropSeq) )
+ {
+ if ( prop.Name == "Name" )
+ {
+ prop.Value >>= aLabel;
+ break;
+ }
+ }
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ aLabel, aCommandURL, false, /*bParentData*/false );
+
+ pEntry->SetUserDefined( bIsUserDefined );
+ pEntry->SetVisible( bIsVisible );
+ pEntry->SetStyle( nStyle );
+
+ if ( !bUseDefaultLabel )
+ pEntry->SetName( aLabel );
+
+ pEntries->push_back( pEntry );
+ }
+ else
+ {
+ SvxConfigEntry* pEntry = new SvxConfigEntry;
+ pEntry->SetUserDefined( bIsUserDefined );
+ pEntries->push_back( pEntry );
+ }
+ }
+ }
+}
+
+SvxNewToolbarDialog::SvxNewToolbarDialog(weld::Window* pWindow, const OUString& rName)
+ : GenericDialogController(pWindow, "cui/ui/newtoolbardialog.ui", "NewToolbarDialog")
+ , m_xEdtName(m_xBuilder->weld_entry("edit"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+ , m_xSaveInListBox(m_xBuilder->weld_combo_box("savein"))
+{
+ m_xEdtName->set_text(rName);
+ m_xEdtName->select_region(0, -1);
+}
+
+SvxNewToolbarDialog::~SvxNewToolbarDialog()
+{
+}
+
+/*******************************************************************************
+*
+* The SvxIconSelectorDialog class
+*
+*******************************************************************************/
+SvxIconSelectorDialog::SvxIconSelectorDialog(weld::Window *pWindow,
+ uno::Reference< css::ui::XImageManager > xImageManager,
+ uno::Reference< css::ui::XImageManager > xParentImageManager)
+ : GenericDialogController(pWindow, "cui/ui/iconselectordialog.ui", "IconSelector")
+ , m_xImageManager(std::move(xImageManager))
+ , m_xParentImageManager(std::move(xParentImageManager))
+ , m_xTbSymbol(new ValueSet(m_xBuilder->weld_scrolled_window("symbolswin", true)))
+ , m_xTbSymbolWin(new weld::CustomWeld(*m_xBuilder, "symbolsToolbar", *m_xTbSymbol))
+ , m_xFtNote(m_xBuilder->weld_label("noteLabel"))
+ , m_xBtnImport(m_xBuilder->weld_button("importButton"))
+ , m_xBtnDelete(m_xBuilder->weld_button("deleteButton"))
+{
+ typedef std::unordered_map< OUString, bool > ImageInfo;
+
+ m_nExpectedSize = 16;
+ if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE)
+ m_nExpectedSize = 24;
+ else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32)
+ m_nExpectedSize = 32;
+
+ if ( m_nExpectedSize != 16 )
+ {
+ m_xFtNote->set_label(SvxConfigPageHelper::replaceSixteen(m_xFtNote->get_label(), m_nExpectedSize));
+ }
+
+ m_xTbSymbol->SetStyle(m_xTbSymbol->GetStyle() | WB_ITEMBORDER | WB_VSCROLL);
+ m_xTbSymbol->SetColCount(11);
+ m_xTbSymbol->SetLineCount(5);
+ m_xTbSymbol->SetItemWidth(m_nExpectedSize);
+ m_xTbSymbol->SetItemHeight(m_nExpectedSize);
+ m_xTbSymbol->SetExtraSpacing(6);
+ Size aSize(m_xTbSymbol->CalcWindowSizePixel(Size(m_nExpectedSize, m_nExpectedSize), 11, 5));
+ m_xTbSymbol->set_size_request(aSize.Width(), aSize.Height());
+
+ uno::Reference< uno::XComponentContext > xComponentContext =
+ ::comphelper::getProcessComponentContext();
+
+ m_xGraphProvider.set( graphic::GraphicProvider::create( xComponentContext ) );
+
+ uno::Reference< css::util::XPathSettings > xPathSettings =
+ css::util::thePathSettings::get( xComponentContext );
+
+
+ OUString aDirectory = xPathSettings->getUserConfig();
+
+ sal_Int32 aCount = aDirectory.getLength();
+
+ if ( aCount > 0 )
+ {
+ sal_Unicode aChar = aDirectory[ aCount-1 ];
+ if ( aChar != '/')
+ {
+ aDirectory += "/";
+ }
+ }
+ else
+ {
+ m_xBtnImport->set_sensitive(false);
+ }
+
+ aDirectory += "soffice.cfg/import";
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
+ css::embed::FileSystemStorageFactory::create( xComponentContext ) );
+
+ uno::Sequence< uno::Any > aArgs{ uno::Any(aDirectory),
+ uno::Any(css::embed::ElementModes::READWRITE) };
+
+ uno::Reference< css::embed::XStorage > xStorage(
+ xStorageFactory->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
+
+ uno::Sequence<uno::Any> aProp(comphelper::InitAnyPropertySequence(
+ {
+ {"UserConfigStorage", uno::Any(xStorage)},
+ {"OpenMode", uno::Any(css::embed::ElementModes::READWRITE)}
+ }));
+ m_xImportedImageManager = css::ui::ImageManager::create( xComponentContext );
+ m_xImportedImageManager->initialize(aProp);
+
+ ImageInfo aImageInfo1;
+ if ( m_xImportedImageManager.is() )
+ {
+ const uno::Sequence< OUString > names = m_xImportedImageManager->getAllImageNames( SvxConfigPageHelper::GetImageType() );
+ for (auto const & name : names )
+ aImageInfo1.emplace( name, false );
+ }
+
+ uno::Sequence< OUString > name( 1 );
+ auto pname = name.getArray();
+ for (auto const& elem : aImageInfo1)
+ {
+ pname[ 0 ] = elem.first;
+ uno::Sequence< uno::Reference< graphic::XGraphic> > graphics = m_xImportedImageManager->getImages( SvxConfigPageHelper::GetImageType(), name );
+ if ( graphics.hasElements() )
+ {
+ m_aGraphics.push_back(graphics[0]);
+ Image img(graphics[0]);
+ m_xTbSymbol->InsertItem(m_aGraphics.size(), img, elem.first);
+ }
+ }
+
+ ImageInfo aImageInfo;
+
+ if ( m_xParentImageManager.is() )
+ {
+ const uno::Sequence< OUString > names = m_xParentImageManager->getAllImageNames( SvxConfigPageHelper::GetImageType() );
+ for ( auto const & i : names )
+ aImageInfo.emplace( i, false );
+ }
+
+ const uno::Sequence< OUString > names = m_xImageManager->getAllImageNames( SvxConfigPageHelper::GetImageType() );
+ for ( auto const & i : names )
+ {
+ ImageInfo::iterator pIter = aImageInfo.find( i );
+ if ( pIter != aImageInfo.end() )
+ pIter->second = true;
+ else
+ aImageInfo.emplace( i, true );
+ }
+
+ // large growth factor, expecting many entries
+ for (auto const& elem : aImageInfo)
+ {
+ pname[ 0 ] = elem.first;
+
+ uno::Sequence< uno::Reference< graphic::XGraphic> > graphics;
+ try
+ {
+ if (elem.second)
+ graphics = m_xImageManager->getImages( SvxConfigPageHelper::GetImageType(), name );
+ else
+ graphics = m_xParentImageManager->getImages( SvxConfigPageHelper::GetImageType(), name );
+ }
+ catch ( uno::Exception& )
+ {
+ // can't get sequence for this name so it will not be
+ // added to the list
+ }
+
+ if ( graphics.hasElements() )
+ {
+ Image img(graphics[0]);
+ if (!img.GetBitmapEx().IsEmpty())
+ {
+ m_aGraphics.push_back(graphics[0]);
+ m_xTbSymbol->InsertItem(m_aGraphics.size(), img, elem.first);
+ }
+ }
+ }
+
+ m_xBtnDelete->set_sensitive( false );
+ m_xTbSymbol->SetSelectHdl( LINK(this, SvxIconSelectorDialog, SelectHdl) );
+ m_xBtnImport->connect_clicked( LINK(this, SvxIconSelectorDialog, ImportHdl) );
+ m_xBtnDelete->connect_clicked( LINK(this, SvxIconSelectorDialog, DeleteHdl) );
+}
+
+SvxIconSelectorDialog::~SvxIconSelectorDialog()
+{
+}
+
+uno::Reference< graphic::XGraphic> SvxIconSelectorDialog::GetSelectedIcon()
+{
+ uno::Reference<graphic::XGraphic> result;
+
+ sal_uInt16 nId = m_xTbSymbol->GetSelectedItemId();
+
+ if (nId)
+ {
+ result = m_aGraphics[nId - 1];
+ }
+
+ return result;
+}
+
+IMPL_LINK_NOARG(SvxIconSelectorDialog, SelectHdl, ValueSet*, void)
+{
+ sal_uInt16 nId = m_xTbSymbol->GetSelectedItemId();
+
+ if (!nId)
+ {
+ m_xBtnDelete->set_sensitive(false);
+ return;
+ }
+
+ OUString aSelImageText = m_xTbSymbol->GetItemText(nId);
+ if (m_xImportedImageManager->hasImage(SvxConfigPageHelper::GetImageType(), aSelImageText))
+ {
+ m_xBtnDelete->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxIconSelectorDialog, ImportHdl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aImportDialog(
+ css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
+ FileDialogFlags::Graphic | FileDialogFlags::MultiSelection, m_xDialog.get());
+ aImportDialog.SetContext(sfx2::FileDialogHelper::IconImport);
+
+ // disable the link checkbox in the dialog
+ uno::Reference< css::ui::dialogs::XFilePickerControlAccess >
+ xController( aImportDialog.GetFilePicker(), uno::UNO_QUERY);
+ if ( xController.is() )
+ {
+ xController->enableControl(
+ css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK,
+ false);
+ }
+
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+ sal_uInt16 nFilter = rFilter.GetImportFormatNumberForShortName(u"png");
+ aImportDialog.SetCurrentFilter(rFilter.GetImportFormatName(nFilter));
+
+ if ( ERRCODE_NONE == aImportDialog.Execute() )
+ {
+ uno::Sequence< OUString > paths = aImportDialog.GetMPath();
+ ImportGraphics ( paths );
+ }
+}
+
+IMPL_LINK_NOARG(SvxIconSelectorDialog, DeleteHdl, weld::Button&, void)
+{
+ OUString message = CuiResId( RID_CUISTR_DELETE_ICON_CONFIRM );
+
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::OkCancel,
+ message));
+ if (xWarn->run() != RET_OK)
+ return;
+
+ sal_uInt16 nId = m_xTbSymbol->GetSelectedItemId();
+
+ OUString aSelImageText = m_xTbSymbol->GetItemText( nId );
+ uno::Sequence< OUString > URLs { aSelImageText };
+ m_xTbSymbol->RemoveItem(nId);
+ m_xImportedImageManager->removeImages( SvxConfigPageHelper::GetImageType(), URLs );
+ if ( m_xImportedImageManager->isModified() )
+ {
+ m_xImportedImageManager->store();
+ }
+}
+
+bool SvxIconSelectorDialog::ReplaceGraphicItem(
+ const OUString& aURL )
+{
+ uno::Reference< graphic::XGraphic > xGraphic;
+ uno::Sequence< beans::PropertyValue > aMediaProps{ comphelper::makePropertyValue("URL", aURL) };
+
+ css::awt::Size aSize;
+ bool bOK = false;
+ try
+ {
+ xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
+
+ uno::Reference< beans::XPropertySet > props =
+ m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
+ uno::Any a = props->getPropertyValue( "SizePixel" );
+ a >>= aSize;
+ if (0 == aSize.Width || 0 == aSize.Height)
+ return false;
+ else
+ bOK = true;
+ }
+ catch ( uno::Exception& )
+ {
+ return false;
+ }
+
+ bool bResult( false );
+ size_t nCount = m_xTbSymbol->GetItemCount();
+ for (size_t n = 0; n < nCount; ++n)
+ {
+ sal_uInt16 nId = m_xTbSymbol->GetItemId( n );
+
+ if ( m_xTbSymbol->GetItemText( nId ) == aURL )
+ {
+ try
+ {
+ // replace/insert image with provided URL
+ size_t nPos = nId - 1;
+ assert(nPos == m_xTbSymbol->GetItemPos(nId));
+ m_xTbSymbol->RemoveItem(nId);
+
+ Image aImage( xGraphic );
+ if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
+ {
+ BitmapEx aBitmap = aImage.GetBitmapEx();
+ BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, m_nExpectedSize);
+ aImage = Image( aBitmapex);
+ }
+ m_xTbSymbol->InsertItem(nId, aImage, aURL, nPos); //modify
+
+ m_aGraphics[nPos] = Graphic(aImage.GetBitmapEx()).GetXGraphic();
+
+ m_xImportedImageManager->replaceImages( SvxConfigPageHelper::GetImageType(), { aURL }, { xGraphic } );
+ m_xImportedImageManager->store();
+
+ bResult = true;
+ break;
+ }
+ catch ( css::uno::Exception& )
+ {
+ break;
+ }
+ }
+ }
+
+ return bResult;
+}
+
+namespace
+{
+ OUString ReplaceIconName(std::u16string_view rMessage)
+ {
+ OUString name;
+ OUString message = CuiResId( RID_CUISTR_REPLACE_ICON_WARNING );
+ OUString placeholder("%ICONNAME" );
+ sal_Int32 pos = message.indexOf( placeholder );
+ if ( pos != -1 )
+ {
+ name = message.replaceAt(
+ pos, placeholder.getLength(), rMessage );
+ }
+ return name;
+ }
+
+ class SvxIconReplacementDialog
+ {
+ private:
+ std::unique_ptr<weld::MessageDialog> m_xQueryBox;
+ public:
+ SvxIconReplacementDialog(weld::Window *pParent, std::u16string_view rMessage, bool bYestoAll)
+ : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Warning, VclButtonsType::NONE, ReplaceIconName(rMessage)))
+ {
+ m_xQueryBox->set_title(CuiResId(RID_CUISTR_REPLACE_ICON_CONFIRM));
+ m_xQueryBox->add_button(GetStandardText(StandardButtonType::Yes), 2);
+ if (bYestoAll)
+ m_xQueryBox->add_button(CuiResId(RID_CUISTR_YESTOALL), 5);
+ m_xQueryBox->add_button(GetStandardText(StandardButtonType::No), 4);
+ m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), 6);
+ m_xQueryBox->set_default_response(2);
+ }
+ short run() { return m_xQueryBox->run(); }
+ };
+}
+
+void SvxIconSelectorDialog::ImportGraphics(
+ const uno::Sequence< OUString >& rPaths )
+{
+ std::vector< OUString > rejected( rPaths.getLength() );
+ sal_Int32 rejectedCount = 0;
+
+ sal_uInt16 ret = 0;
+ sal_Int32 aIndex;
+ OUString aIconName;
+
+ if ( rPaths.getLength() == 1 )
+ {
+ if ( m_xImportedImageManager->hasImage( SvxConfigPageHelper::GetImageType(), rPaths[0] ) )
+ {
+ aIndex = rPaths[0].lastIndexOf( '/' );
+ aIconName = rPaths[0].copy( aIndex+1 );
+ SvxIconReplacementDialog aDlg(m_xDialog.get(), aIconName, false);
+ ret = aDlg.run();
+ if ( ret == 2 )
+ {
+ ReplaceGraphicItem( rPaths[0] );
+ }
+ }
+ else
+ {
+ if ( !ImportGraphic( rPaths[0] ) )
+ {
+ rejected[0] = rPaths[0];
+ rejectedCount = 1;
+ }
+ }
+ }
+ else
+ {
+ OUString aSourcePath( rPaths[0] );
+ if ( rPaths[0].lastIndexOf( '/' ) != rPaths[0].getLength() -1 )
+ aSourcePath = rPaths[0] + "/";
+
+ for ( sal_Int32 i = 1; i < rPaths.getLength(); ++i )
+ {
+ OUString aPath = aSourcePath + rPaths[i];
+ if ( m_xImportedImageManager->hasImage( SvxConfigPageHelper::GetImageType(), aPath ) )
+ {
+ aIndex = rPaths[i].lastIndexOf( '/' );
+ aIconName = rPaths[i].copy( aIndex+1 );
+ SvxIconReplacementDialog aDlg(m_xDialog.get(), aIconName, true);
+ ret = aDlg.run();
+ if ( ret == 2 )
+ {
+ ReplaceGraphicItem( aPath );
+ }
+ else if ( ret == 5 )
+ {
+ for ( sal_Int32 k = i; k < rPaths.getLength(); ++k )
+ {
+ aPath = aSourcePath + rPaths[k];
+ bool bHasReplaced = ReplaceGraphicItem( aPath );
+
+ if ( !bHasReplaced )
+ {
+ bool result = ImportGraphic( aPath );
+ if ( !result )
+ {
+ rejected[ rejectedCount ] = rPaths[i];
+ ++rejectedCount;
+ }
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ bool result = ImportGraphic( aSourcePath + rPaths[i] );
+ if ( !result )
+ {
+ rejected[ rejectedCount ] = rPaths[i];
+ ++rejectedCount;
+ }
+ }
+ }
+ }
+
+ if ( rejectedCount == 0 )
+ return;
+
+ OUStringBuffer message;
+ OUString fPath;
+ if (rejectedCount > 1)
+ fPath = OUString::Concat(rPaths[0].subView(8)) + "/";
+ for ( sal_Int32 i = 0; i < rejectedCount; ++i )
+ {
+ message.append(fPath + rejected[i] + "\n");
+ }
+
+ SvxIconChangeDialog aDialog(m_xDialog.get(), message.makeStringAndClear());
+ aDialog.run();
+}
+
+bool SvxIconSelectorDialog::ImportGraphic( const OUString& aURL )
+{
+ bool result = false;
+
+ uno::Sequence< beans::PropertyValue > aMediaProps{ comphelper::makePropertyValue("URL", aURL) };
+
+ try
+ {
+ uno::Reference< beans::XPropertySet > props =
+ m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
+
+ uno::Any a = props->getPropertyValue("SizePixel");
+
+ uno::Reference< graphic::XGraphic > xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
+ if ( xGraphic.is() )
+ {
+ bool bOK = true;
+ css::awt::Size aSize;
+
+ a >>= aSize;
+ if ( 0 == aSize.Width || 0 == aSize.Height )
+ bOK = false;
+
+ Image aImage( xGraphic );
+
+ if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
+ {
+ BitmapEx aBitmap = aImage.GetBitmapEx();
+ BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, m_nExpectedSize);
+ aImage = Image( aBitmapex);
+ }
+ if ( bOK && !!aImage )
+ {
+ m_aGraphics.push_back(Graphic(aImage.GetBitmapEx()).GetXGraphic());
+ m_xTbSymbol->InsertItem(m_aGraphics.size(), aImage, aURL);
+
+ uno::Sequence<OUString> aImportURL { aURL };
+ uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph{ xGraphic };
+ m_xImportedImageManager->insertImages( SvxConfigPageHelper::GetImageType(), aImportURL, aImportGraph );
+ if ( m_xImportedImageManager->isModified() )
+ {
+ m_xImportedImageManager->store();
+ }
+
+ result = true;
+ }
+ else
+ {
+ SAL_WARN("cui.customize", "could not create Image from XGraphic");
+ }
+ }
+ else
+ {
+ SAL_WARN("cui.customize", "could not get query XGraphic");
+ }
+ }
+ catch( uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Caught exception importing XGraphic");
+ }
+ return result;
+}
+
+/*******************************************************************************
+*
+* The SvxIconChangeDialog class added for issue83555
+*
+*******************************************************************************/
+SvxIconChangeDialog::SvxIconChangeDialog(weld::Window *pWindow, const OUString& rMessage)
+ : MessageDialogController(pWindow, "cui/ui/iconchangedialog.ui", "IconChange", "grid")
+ , m_xLineEditDescription(m_xBuilder->weld_text_view("addrTextview"))
+{
+ m_xLineEditDescription->set_size_request(m_xLineEditDescription->get_approximate_digit_width() * 48,
+ m_xLineEditDescription->get_text_height() * 8);
+ m_xLineEditDescription->set_text(rMessage);
+}
+
+SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& rTreeView)
+ : weld::ReorderingDropTarget(rTreeView)
+ , m_rPage(rPage)
+{
+}
+
+sal_Int8 SvxConfigPageFunctionDropTarget::ExecuteDrop(const ExecuteDropEvent& rEvt)
+{
+ sal_Int8 nRet = weld::ReorderingDropTarget::ExecuteDrop(rEvt);
+ m_rPage.ListModified();
+ return nRet;;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/cfgutil.cxx b/cui/source/customize/cfgutil.cxx
new file mode 100644
index 000000000..6b39170e1
--- /dev/null
+++ b/cui/source/customize/cfgutil.cxx
@@ -0,0 +1,1270 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cfgutil.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/ui/theUICategoryDescription.hpp>
+
+#include <basic/basmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <sfx2/minfitem.hxx>
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/lok.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <svtools/imagemgr.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <dialmgr.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/commandevent.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <sfx2/sidebar/ResourceManager.hxx>
+#include <sfx2/sidebar/Context.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+
+SfxStylesInfo_Impl::SfxStylesInfo_Impl()
+{}
+
+void SfxStylesInfo_Impl::init(const OUString& rModuleName, const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ m_aModuleName = rModuleName;
+ m_xDoc = xModel;
+}
+
+const char CMDURL_STYLEPROT_ONLY[] = ".uno:StyleApply?";
+const char CMDURL_SPART_ONLY [] = "Style:string=";
+const char CMDURL_FPART_ONLY [] = "FamilyName:string=";
+
+constexpr OUStringLiteral STYLEPROP_UINAME = u"DisplayName";
+
+OUString SfxStylesInfo_Impl::generateCommand(
+ std::u16string_view sFamily, std::u16string_view sStyle)
+{
+ return OUString::Concat(".uno:StyleApply?Style:string=")
+ + sStyle
+ + "&FamilyName:string="
+ + sFamily;
+}
+
+bool SfxStylesInfo_Impl::parseStyleCommand(SfxStyleInfo_Impl& aStyle)
+{
+ static const sal_Int32 LEN_STYLEPROT = strlen(CMDURL_STYLEPROT_ONLY);
+ static const sal_Int32 LEN_SPART = strlen(CMDURL_SPART_ONLY);
+ static const sal_Int32 LEN_FPART = strlen(CMDURL_FPART_ONLY);
+
+ if (!aStyle.sCommand.startsWith(CMDURL_STYLEPROT_ONLY))
+ return false;
+
+ aStyle.sFamily.clear();
+ aStyle.sStyle.clear();
+
+ sal_Int32 nCmdLen = aStyle.sCommand.getLength();
+ OUString sCmdArgs = aStyle.sCommand.copy(LEN_STYLEPROT, nCmdLen-LEN_STYLEPROT);
+ sal_Int32 i = sCmdArgs.indexOf('&');
+ if (i<0)
+ return false;
+
+ OUString sArg = sCmdArgs.copy(0, i);
+ if (sArg.startsWith(CMDURL_SPART_ONLY))
+ aStyle.sStyle = sArg.copy(LEN_SPART);
+ else if (sArg.startsWith(CMDURL_FPART_ONLY))
+ aStyle.sFamily = sArg.copy(LEN_FPART);
+
+ sArg = sCmdArgs.copy(i+1, sCmdArgs.getLength()-i-1);
+ if (sArg.startsWith(CMDURL_SPART_ONLY))
+ aStyle.sStyle = sArg.copy(LEN_SPART);
+ else if (sArg.startsWith(CMDURL_FPART_ONLY))
+ aStyle.sFamily = sArg.copy(LEN_FPART);
+
+ return !(aStyle.sFamily.isEmpty() || aStyle.sStyle.isEmpty());
+}
+
+void SfxStylesInfo_Impl::getLabel4Style(SfxStyleInfo_Impl& aStyle)
+{
+ try
+ {
+ css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::container::XNameAccess > xFamilies;
+ if (xModel.is())
+ xFamilies = xModel->getStyleFamilies();
+
+ css::uno::Reference< css::container::XNameAccess > xStyleSet;
+ if (xFamilies.is())
+ xFamilies->getByName(aStyle.sFamily) >>= xStyleSet;
+
+ css::uno::Reference< css::beans::XPropertySet > xStyle;
+ if (xStyleSet.is())
+ xStyleSet->getByName(aStyle.sStyle) >>= xStyle;
+
+ aStyle.sLabel.clear();
+ if (xStyle.is())
+ xStyle->getPropertyValue(STYLEPROP_UINAME) >>= aStyle.sLabel;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { aStyle.sLabel.clear(); }
+
+ if (aStyle.sLabel.isEmpty())
+ {
+ aStyle.sLabel = aStyle.sCommand;
+ }
+}
+
+std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyleFamilies() const
+{
+ // It's an optional interface!
+ css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
+ if (!xModel.is())
+ return std::vector< SfxStyleInfo_Impl >();
+
+ css::uno::Reference< css::container::XNameAccess > xCont = xModel->getStyleFamilies();
+ const css::uno::Sequence< OUString > lFamilyNames = xCont->getElementNames();
+ std::vector< SfxStyleInfo_Impl > lFamilies;
+ for (const auto& aFamily : lFamilyNames)
+ {
+ if ((aFamily == "CellStyles" && m_aModuleName != "com.sun.star.sheet.SpreadsheetDocument") ||
+ aFamily == "cell" || aFamily == "table" || aFamily == "Default")
+ continue;
+
+ SfxStyleInfo_Impl aFamilyInfo;
+ aFamilyInfo.sFamily = aFamily;
+
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xFamilyInfo;
+ xCont->getByName(aFamilyInfo.sFamily) >>= xFamilyInfo;
+ if (!xFamilyInfo.is())
+ {
+ // TODO_AS currently there is no support for an UIName property .. use internal family name instead
+ aFamilyInfo.sLabel = aFamilyInfo.sFamily;
+ }
+ else
+ xFamilyInfo->getPropertyValue(STYLEPROP_UINAME) >>= aFamilyInfo.sLabel;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { return std::vector< SfxStyleInfo_Impl >(); }
+
+ lFamilies.push_back(aFamilyInfo);
+ }
+
+ return lFamilies;
+}
+
+std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyles(const OUString& sFamily)
+{
+ css::uno::Sequence< OUString > lStyleNames;
+ css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameAccess > xFamilies = xModel->getStyleFamilies();
+ css::uno::Reference< css::container::XNameAccess > xStyleSet;
+ try
+ {
+ xFamilies->getByName(sFamily) >>= xStyleSet;
+ lStyleNames = xStyleSet->getElementNames();
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { return std::vector< SfxStyleInfo_Impl >(); }
+
+ std::vector< SfxStyleInfo_Impl > lStyles;
+ sal_Int32 c = lStyleNames.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ SfxStyleInfo_Impl aStyleInfo;
+ aStyleInfo.sFamily = sFamily;
+ aStyleInfo.sStyle = lStyleNames[i];
+ aStyleInfo.sCommand = SfxStylesInfo_Impl::generateCommand(aStyleInfo.sFamily, aStyleInfo.sStyle);
+
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xStyle;
+ xStyleSet->getByName(aStyleInfo.sStyle) >>= xStyle;
+ if (!xStyle.is())
+ continue;
+ xStyle->getPropertyValue("DisplayName") >>= aStyleInfo.sLabel;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+
+ lStyles.push_back(aStyleInfo);
+ }
+ return lStyles;
+}
+
+OUString CuiConfigFunctionListBox::GetHelpText( bool bConsiderParent )
+{
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
+ if (pData)
+ {
+ if ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
+ {
+ if (bConsiderParent)
+ return Application::GetHelp()->GetHelpText(pData->sCommand, m_xTreeView.get());
+ else
+ return Application::GetHelp()->GetHelpText(pData->sCommand, static_cast<weld::Widget*>(nullptr));
+ }
+ else if ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
+ {
+ return pData->sHelpText;
+ }
+ }
+ return OUString();
+}
+
+OUString CuiConfigFunctionListBox::GetCurCommand() const
+{
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
+ if (!pData)
+ return OUString();
+ return pData->sCommand;
+}
+
+OUString CuiConfigFunctionListBox::GetCurLabel() const
+{
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
+ if (!pData)
+ return OUString();
+ if (!pData->sLabel.isEmpty())
+ return pData->sLabel;
+ return pData->sCommand;
+}
+
+CuiConfigFunctionListBox::CuiConfigFunctionListBox(std::unique_ptr<weld::TreeView> xTreeView)
+ : m_xTreeView(std::move(xTreeView))
+ , m_xScratchIter(m_xTreeView->make_iterator())
+{
+ m_xTreeView->make_sorted();
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35, m_xTreeView->get_height_rows(9));
+ m_xTreeView->connect_query_tooltip(LINK(this, CuiConfigFunctionListBox, QueryTooltip));
+}
+
+CuiConfigFunctionListBox::~CuiConfigFunctionListBox()
+{
+ ClearAll();
+}
+
+IMPL_LINK(CuiConfigFunctionListBox, QueryTooltip, const weld::TreeIter&, rIter, OUString)
+{
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter));
+ if (!pData)
+ return OUString();
+ OUString aLabel = CuiResId(RID_CUISTR_COMMANDLABEL) + ": ";
+ OUString aName = CuiResId(RID_CUISTR_COMMANDNAME) + ": ";
+ OUString aTip = CuiResId(RID_CUISTR_COMMANDTIP) + ": ";
+ return aLabel + pData->sLabel + "\n" + aName + pData->sCommand+ "\n" + aTip + pData->sTooltip;
+}
+
+void CuiConfigFunctionListBox::ClearAll()
+/* Description
+ Deletes all entries in the FunctionListBox, all UserData and all
+ possibly existing MacroInfo.
+*/
+{
+ sal_uInt16 nCount = aArr.size();
+ for ( sal_uInt16 i=0; i<nCount; ++i )
+ {
+ SfxGroupInfo_Impl *pData = aArr[i].get();
+
+ if ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
+ {
+ OUString* pScriptURI = static_cast<OUString*>(pData->pObject);
+ delete pScriptURI;
+ }
+
+ if ( pData->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER )
+ {
+ XInterface* xi = static_cast<XInterface *>(pData->pObject);
+ if (xi != nullptr)
+ {
+ xi->release();
+ }
+ }
+ }
+
+ aArr.clear();
+ m_xTreeView->clear();
+}
+
+OUString CuiConfigFunctionListBox::GetSelectedScriptURI() const
+{
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(get_selected_id());
+ if (pData && pData->nKind == SfxCfgKind::FUNCTION_SCRIPT)
+ return *static_cast<OUString*>(pData->pObject);
+ return OUString();
+}
+
+struct SvxConfigGroupBoxResource_Impl
+{
+ OUString m_sMyMacros;
+ OUString m_sProdMacros;
+ OUString m_sMacros;
+ OUString m_sDlgMacros;
+ OUString m_aStrGroupStyles;
+ OUString m_aStrGroupSidebarDecks;
+
+ SvxConfigGroupBoxResource_Impl();
+};
+
+SvxConfigGroupBoxResource_Impl::SvxConfigGroupBoxResource_Impl() :
+ m_sMyMacros(CuiResId(RID_CUISTR_MYMACROS)),
+ m_sProdMacros(CuiResId(RID_CUISTR_PRODMACROS)),
+ m_sMacros(CuiResId(RID_CUISTR_BASICMACROS)),
+ m_sDlgMacros(CuiResId(RID_CUISTR_PRODMACROS)),
+ m_aStrGroupStyles(CuiResId(RID_CUISTR_GROUP_STYLES)),
+ m_aStrGroupSidebarDecks(CuiResId(RID_CUISTR_GROUP_SIDEBARDECKS))
+{
+}
+
+void CuiConfigGroupListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
+{
+ m_pStylesInfo = pStyles;
+}
+
+namespace
+{
+
+ /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
+ component by implementing XScriptInvocationContext.
+ @return
+ the model which supports the embedded scripts, or <NULL/> if it cannot find such a
+ model
+ */
+ Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
+ {
+ Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
+ if ( !xScripts.is() )
+ {
+ Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
+ if ( xContext.is() )
+ xScripts = xContext->getScriptContainer();
+ }
+
+ return Reference< XModel >( xScripts, UNO_QUERY );
+ }
+
+
+ Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
+ {
+ Reference< XModel > xDocument;
+
+ // examine our associated frame
+ try
+ {
+ OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
+ if ( _rxFrame.is() )
+ {
+ // first try the model in the frame
+ Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
+ xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
+
+ if ( !xDocument.is() )
+ {
+ // if there is no suitable document in the frame, try the controller
+ xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+
+ return xDocument;
+ }
+}
+
+CuiConfigGroupListBox::CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView)
+ : xImp(new SvxConfigGroupBoxResource_Impl())
+ , m_pFunctionListBox(nullptr)
+ , m_pStylesInfo(nullptr)
+ , m_xTreeView(std::move(xTreeView))
+ , m_xScratchIter(m_xTreeView->make_iterator())
+{
+ m_xTreeView->connect_expanding(LINK(this, CuiConfigGroupListBox, ExpandingHdl));
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35, m_xTreeView->get_height_rows(9));
+}
+
+CuiConfigGroupListBox::~CuiConfigGroupListBox()
+{
+ ClearAll();
+}
+
+void CuiConfigGroupListBox::ClearAll()
+{
+ sal_uInt16 nCount = aArr.size();
+ for ( sal_uInt16 i=0; i<nCount; ++i )
+ {
+ SfxGroupInfo_Impl *pData = aArr[i].get();
+ if (pData->nKind == SfxCfgKind::GROUP_STYLES && pData->pObject)
+ {
+ SfxStyleInfo_Impl* pStyle = static_cast<SfxStyleInfo_Impl*>(pData->pObject);
+ delete pStyle;
+ }
+ else if (pData->nKind == SfxCfgKind::FUNCTION_SCRIPT && pData->pObject )
+ {
+ OUString* pScriptURI = static_cast<OUString*>(pData->pObject);
+ delete pScriptURI;
+ }
+ else if (pData->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER)
+ {
+ XInterface* xi = static_cast<XInterface *>(pData->pObject);
+ if (xi != nullptr)
+ {
+ xi->release();
+ }
+ }
+ }
+
+ aArr.clear();
+ m_xTreeView->clear();
+}
+
+void CuiConfigGroupListBox::InitModule()
+{
+ try
+ {
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
+ sal_Int32 c1 = lGroups.getLength();
+ sal_Int32 i1 = 0;
+
+ if ( c1 )
+ {
+ // Add All Commands category
+ aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_ALLFUNCTIONS, 0));
+ m_xTreeView->append(weld::toId(aArr.back().get()), CuiResId(RID_CUISTR_ALLFUNCTIONS));
+ }
+
+ for (i1=0; i1<c1; ++i1)
+ {
+ sal_Int16 nGroupID = lGroups[i1];
+ OUString sGroupID = OUString::number(nGroupID);
+ OUString sGroupName ;
+
+ try
+ {
+ m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
+ if (sGroupName.isEmpty())
+ continue;
+ }
+ catch(const css::container::NoSuchElementException&)
+ { continue; }
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, nGroupID ) );
+ m_xTreeView->append(weld::toId(aArr.back().get()), sGroupName);
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+void CuiConfigGroupListBox::FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
+ const weld::TreeIter* pParentEntry)
+{
+ try {
+ if ( xRootNode->hasChildNodes() )
+ {
+ // tdf#120362: Don't ask to enable disabled Java when filling script list
+ css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
+
+ const Sequence< Reference< browse::XBrowseNode > > children =
+ xRootNode->getChildNodes();
+ bool bIsRootNode = false;
+
+ OUString user("user");
+ OUString share("share");
+ if ( xRootNode->getName() == "Root" )
+ {
+ bIsRootNode = true;
+ }
+
+ //To mimic current starbasic behaviour we
+ //need to make sure that only the current document
+ //is displayed in the config tree. Tests below
+ //set the bDisplay flag to FALSE if the current
+ //node is a first level child of the Root and is NOT
+ //either the current document, user or share
+ OUString currentDocTitle;
+ Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
+ if ( xDocument.is() )
+ {
+ currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
+ }
+
+ for ( Reference< browse::XBrowseNode > const & theChild : children )
+ {
+ bool bDisplay = true;
+ OUString uiName = theChild->getName();
+ if ( bIsRootNode )
+ {
+ if ( ! (uiName == user || uiName == share ||
+ uiName == currentDocTitle ) )
+ {
+ bDisplay=false;
+ }
+ else
+ {
+ if ( uiName == user )
+ {
+ uiName = xImp->m_sMyMacros;
+ }
+ else if ( uiName == share )
+ {
+ uiName = xImp->m_sProdMacros;
+ }
+ }
+ }
+ if (theChild->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
+ {
+// We call acquire on the XBrowseNode so that it does not
+// get autodestructed and become invalid when accessed later.
+ theChild->acquire();
+
+ bool bChildOnDemand = false;
+
+ if ( theChild->hasChildNodes() )
+ {
+ const Sequence< Reference< browse::XBrowseNode > > grandchildren =
+ theChild->getChildNodes();
+
+ for ( const auto& rxNode : grandchildren )
+ {
+ if ( rxNode->getType() == browse::BrowseNodeTypes::CONTAINER )
+ {
+ bChildOnDemand = true;
+ break;
+ }
+ }
+ }
+
+ OUString aImage = GetImage(theChild, m_xContext, bIsRootNode);
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
+ 0, static_cast<void *>( theChild.get())));
+
+ OUString sId(weld::toId(aArr.back().get()));
+ m_xTreeView->insert(pParentEntry, -1, &uiName, &sId, nullptr, nullptr, bChildOnDemand, m_xScratchIter.get());
+ m_xTreeView->set_image(*m_xScratchIter, aImage);
+ }
+ }
+ }
+ }
+ catch (RuntimeException&) {
+ // do nothing, the entry will not be displayed in the UI
+ }
+}
+
+void CuiConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchInformation>& xCommands)
+{
+ m_pFunctionListBox->freeze();
+ for (const auto & rInfo : xCommands)
+ {
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rInfo.Command, m_sModuleLongName);
+
+ OUString sUIName = MapCommand2UIName(rInfo.Command);
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SLOT, 0 ) );
+ SfxGroupInfo_Impl* pGrpInfo = aArr.back().get();
+ pGrpInfo->sCommand = rInfo.Command;
+ pGrpInfo->sLabel = sUIName;
+ pGrpInfo->sTooltip = vcl::CommandInfoProvider::GetTooltipForCommand(rInfo.Command, aProperties, m_xFrame);
+ m_pFunctionListBox->append(weld::toId(pGrpInfo), sUIName);
+ }
+ m_pFunctionListBox->thaw();
+}
+
+void CuiConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& sModuleLongName,
+ bool bEventMode)
+{
+ m_xTreeView->freeze();
+ ClearAll(); // Remove all old entries from treelist box
+
+ m_xContext = xContext;
+ m_xFrame = xFrame;
+ if( bEventMode )
+ {
+ m_sModuleLongName = sModuleLongName;
+ m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
+ m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
+ m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
+
+ InitModule();
+ }
+
+ SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
+ // Add Scripting Framework entries
+ Reference< browse::XBrowseNode > rootNode;
+ try
+ {
+ Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( m_xContext );
+ rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Caught some exception whilst retrieving browse nodes from factory");
+ // TODO exception handling
+ }
+
+
+ if ( rootNode.is() )
+ {
+ if ( bEventMode )
+ {
+ //We call acquire on the XBrowseNode so that it does not
+ //get autodestructed and become invalid when accessed later.
+ rootNode->acquire();
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0,
+ static_cast<void *>(rootNode.get())));
+ OUString aTitle(xImp->m_sDlgMacros);
+ OUString sId(weld::toId(aArr.back().get()));
+ m_xTreeView->insert(nullptr, -1, &aTitle, &sId, nullptr, nullptr, true, nullptr);
+ }
+ else
+ {
+ //We are only showing scripts not slot APIs so skip
+ //Root node and show location nodes
+ FillScriptList(rootNode, nullptr);
+ }
+ }
+
+ // add styles and sidebar decks
+ if ( bEventMode )
+ {
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) ); // TODO last parameter should contain user data
+ OUString sStyle(xImp->m_aStrGroupStyles);
+ OUString sId(weld::toId(aArr.back().get()));
+ m_xTreeView->insert(nullptr, -1, &sStyle, &sId, nullptr, nullptr, true, nullptr);
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SIDEBARDECKS, 0));
+ OUString sSidebarDecks(xImp->m_aStrGroupSidebarDecks);
+ sId = weld::toId(aArr.back().get());
+ m_xTreeView->insert(nullptr, -1, &sSidebarDecks, &sId, nullptr, nullptr, false, nullptr);
+ }
+
+ m_xTreeView->thaw();
+ m_xTreeView->scroll_to_row(0);
+ m_xTreeView->select(0);
+}
+
+OUString CuiConfigGroupListBox::GetImage(
+ const Reference< browse::XBrowseNode >& node,
+ Reference< XComponentContext > const & xCtx,
+ bool bIsRootNode)
+{
+ OUString aImage;
+ if ( bIsRootNode )
+ {
+ if (node->getName() == "user" || node->getName() == "share" )
+ {
+ aImage = RID_CUIBMP_HARDDISK;
+ }
+ else
+ {
+ OUString factoryURL;
+ OUString nodeName = node->getName();
+ Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
+ if ( xDocumentModel.is() )
+ {
+ Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
+ // get the long name of the document:
+ OUString appModule( xModuleManager->identify(
+ xDocumentModel ) );
+ Sequence<beans::PropertyValue> moduleDescr;
+ Any aAny = xModuleManager->getByName(appModule);
+ if( !( aAny >>= moduleDescr ) )
+ {
+ throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
+ }
+ beans::PropertyValue const * pmoduleDescr =
+ moduleDescr.getConstArray();
+ for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
+ {
+ if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
+ {
+ pmoduleDescr[ pos ].Value >>= factoryURL;
+ SAL_INFO("cui.customize", "factory url for doc images is " << factoryURL);
+ break;
+ }
+ }
+ }
+ if( !factoryURL.isEmpty() )
+ {
+ aImage = SvFileInformationManager::GetFileImageId(INetURLObject(factoryURL));
+ }
+ else
+ {
+ aImage = RID_CUIBMP_DOC;
+ }
+ }
+ }
+ else
+ {
+ if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
+ aImage = RID_CUIBMP_MACRO;
+ else
+ aImage = RID_CUIBMP_LIB;
+ }
+ return aImage;
+}
+
+Reference< XInterface >
+CuiConfigGroupListBox::getDocumentModel( Reference< XComponentContext > const & xCtx, std::u16string_view docName )
+{
+ Reference< XInterface > xModel;
+ Reference< frame::XDesktop2 > desktop = frame::Desktop::create( xCtx );
+
+ Reference< container::XEnumerationAccess > componentsAccess =
+ desktop->getComponents();
+ Reference< container::XEnumeration > components =
+ componentsAccess->createEnumeration();
+ while (components->hasMoreElements())
+ {
+ Reference< frame::XModel > model(
+ components->nextElement(), UNO_QUERY );
+ if ( model.is() )
+ {
+ OUString sTdocUrl =
+ ::comphelper::DocumentInfo::getDocumentTitle( model );
+ if( sTdocUrl == docName )
+ {
+ xModel = model;
+ break;
+ }
+ }
+ }
+ return xModel;
+}
+
+OUString CuiConfigGroupListBox::MapCommand2UIName(const OUString& sCommand)
+{
+ OUString sUIName;
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xModuleConf;
+ m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
+ if (xModuleConf.is())
+ {
+ ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
+ sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(css::uno::Exception&)
+ { sUIName.clear(); }
+
+ // fallback for missing UINames !?
+ if (sUIName.isEmpty())
+ {
+ sUIName = sCommand;
+ }
+
+ return sUIName;
+}
+
+void CuiConfigGroupListBox::GroupSelected()
+/* Description
+ A function group or a basic module has been selected.
+ All functions/macros are displayed in the functionlistbox.
+*/
+{
+ std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+ if (!m_xTreeView->get_selected(xIter.get()))
+ return;
+
+ SfxGroupInfo_Impl *pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter));
+ m_pFunctionListBox->freeze();
+ m_pFunctionListBox->ClearAll();
+
+ switch ( pInfo->nKind )
+ {
+ case SfxCfgKind::GROUP_ALLFUNCTIONS:
+ {
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider( m_xFrame, UNO_QUERY );
+ bool bValidIter = m_xTreeView->get_iter_first(*xIter);
+ while (bValidIter)
+ {
+ SfxGroupInfo_Impl *pCurrentInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter));
+ if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
+ {
+ css::uno::Sequence< css::frame::DispatchInformation > lCommands;
+ try
+ {
+ lCommands = xProvider->getConfigurableDispatchInformation( pCurrentInfo->nUniqueID );
+ FillFunctionsList( lCommands );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ }
+ }
+ bValidIter = m_xTreeView->iter_next(*xIter);
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_FUNCTION :
+ {
+ sal_uInt16 nGroup = pInfo->nUniqueID;
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
+ FillFunctionsList( lCommands );
+ break;
+ }
+
+ case SfxCfgKind::GROUP_SCRIPTCONTAINER:
+ {
+ if (!m_xTreeView->iter_has_child(*xIter))
+ {
+ Reference< browse::XBrowseNode > rootNode(
+ static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
+
+ try {
+ if ( rootNode->hasChildNodes() )
+ {
+ const Sequence< Reference< browse::XBrowseNode > > children =
+ rootNode->getChildNodes();
+
+ for ( const Reference< browse::XBrowseNode >& childNode : children )
+ {
+ if (childNode->getType() == browse::BrowseNodeTypes::SCRIPT)
+ {
+ OUString uri, description;
+
+ Reference < beans::XPropertySet >xPropSet( childNode, UNO_QUERY );
+ if (!xPropSet.is())
+ {
+ continue;
+ }
+
+ Any value =
+ xPropSet->getPropertyValue("URI");
+ value >>= uri;
+
+ try
+ {
+ value = xPropSet->getPropertyValue("Description");
+ value >>= description;
+ }
+ catch (Exception &) {
+ // do nothing, the description will be empty
+ }
+
+ OUString* pScriptURI = new OUString( uri );
+
+ OUString aImage = GetImage(childNode, Reference< XComponentContext >(), false);
+ m_pFunctionListBox->aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
+ m_pFunctionListBox->aArr.back()->sCommand = uri;
+ m_pFunctionListBox->aArr.back()->sLabel = childNode->getName();
+ m_pFunctionListBox->aArr.back()->sHelpText = description;
+
+ OUString sId(weld::toId(m_pFunctionListBox->aArr.back().get()));
+ m_pFunctionListBox->append(sId, childNode->getName(), aImage);
+ }
+ }
+ }
+ }
+ catch (RuntimeException&) {
+ // do nothing, the entry will not be displayed in the UI
+ }
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_STYLES :
+ {
+ SfxStyleInfo_Impl* pFamily = static_cast<SfxStyleInfo_Impl*>(pInfo->pObject);
+ if (pFamily)
+ {
+ const std::vector< SfxStyleInfo_Impl > lStyles = m_pStylesInfo->getStyles(pFamily->sFamily);
+ for (auto const& lStyle : lStyles)
+ {
+ SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(lStyle);
+ m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0, pStyle));
+ m_pFunctionListBox->aArr.back()->sCommand = pStyle->sCommand;
+ m_pFunctionListBox->aArr.back()->sLabel = pStyle->sLabel;
+ OUString sId(weld::toId(m_pFunctionListBox->aArr.back().get()));
+ m_pFunctionListBox->append(sId, pStyle->sLabel);
+ }
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_SIDEBARDECKS:
+ {
+ sfx2::sidebar::ResourceManager aResourceManager;
+ sfx2::sidebar::Context aContext(m_sModuleLongName, OUString());
+ sfx2::sidebar::ResourceManager::DeckContextDescriptorContainer aDecks;
+ aResourceManager.GetMatchingDecks(aDecks, aContext, false, m_xFrame->getController());
+
+ for (auto const& rDeck : aDecks)
+ {
+ const OUString sCommand = ".uno:SidebarDeck." + rDeck.msId;
+ m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_SIDEBARDECKS, 0,
+ nullptr));
+ m_pFunctionListBox->aArr.back()->sCommand = sCommand;
+ m_pFunctionListBox->aArr.back()->sLabel = rDeck.msId;
+ m_pFunctionListBox->aArr.back()->sTooltip =
+ vcl::CommandInfoProvider::GetCommandShortcut(sCommand, m_xFrame);
+ m_pFunctionListBox->append(weld::toId(m_pFunctionListBox->aArr.back().get()),
+ rDeck.msId);
+ }
+
+ break;
+ }
+
+ default:
+ // Do nothing, the list box will stay empty
+ SAL_INFO( "cui.customize", "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind) );
+ break;
+ }
+
+ m_pFunctionListBox->thaw();
+
+ if (m_pFunctionListBox->n_children())
+ m_pFunctionListBox->select(0);
+}
+
+/* Description
+ A basic or a library is opened.
+*/
+IMPL_LINK(CuiConfigGroupListBox, ExpandingHdl, const weld::TreeIter&, rIter, bool)
+{
+ SfxGroupInfo_Impl *pInfo = weld::fromId<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter));
+ switch ( pInfo->nKind )
+ {
+ case SfxCfgKind::GROUP_SCRIPTCONTAINER:
+ {
+ if (!m_xTreeView->iter_has_child(rIter))
+ {
+ Reference< browse::XBrowseNode > rootNode(
+ static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
+ FillScriptList(rootNode, &rIter);
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_STYLES:
+ {
+ if (!m_xTreeView->iter_has_child(rIter))
+ {
+ const std::vector<SfxStyleInfo_Impl> lStyleFamilies = m_pStylesInfo->getStyleFamilies();
+ for (auto const& lStyleFamily : lStyleFamilies)
+ {
+ SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(lStyleFamily);
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, pFamily ));
+ OUString sId(weld::toId(aArr.back().get()));
+ m_xTreeView->insert(&rIter, -1, &pFamily->sLabel, &sId, nullptr, nullptr, false, nullptr);
+ }
+ }
+ break;
+ }
+
+ default:
+ OSL_FAIL( "Wrong group type!" );
+ break;
+ }
+ return true;
+}
+
+#if HAVE_FEATURE_SCRIPTING
+void CuiConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
+{
+ SelectMacro( pItem->GetBasicManager()->GetName(),
+ pItem->GetQualifiedName() );
+}
+
+void CuiConfigGroupListBox::SelectMacro( std::u16string_view rBasic,
+ std::u16string_view rMacro )
+{
+ const OUString aBasicName(OUString::Concat(rBasic) + " " + xImp->m_sMacros);
+ size_t nIdx {rMacro.rfind('.')};
+ const std::u16string_view aMethod( rMacro.substr(nIdx == std::u16string_view::npos ? 0 : nIdx + 1) );
+ std::u16string_view aLib;
+ std::u16string_view aModule;
+ if ( nIdx>0 && nIdx != std::u16string_view::npos )
+ {
+ // string contains at least 2 tokens
+ nIdx = rMacro.rfind('.', nIdx);
+ if (nIdx != std::u16string_view::npos)
+ {
+ // string contains at least 3 tokens
+ aLib = o3tl::getToken(rMacro, 0, '.' );
+ sal_Int32 nIdx2 = nIdx + 1;
+ aModule = o3tl::getToken(rMacro, 0, '.', nIdx2 );
+ }
+ }
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator();
+ if (!m_xTreeView->get_iter_first(*xIter))
+ return;
+
+ do
+ {
+ OUString aEntryBas = m_xTreeView->get_text(*xIter);
+ if (aEntryBas == aBasicName)
+ {
+ m_xTreeView->expand_row(*xIter);
+ std::unique_ptr<weld::TreeIter> xLibIter = m_xTreeView->make_iterator(xIter.get());
+ if (m_xTreeView->get_iter_first(*xLibIter))
+ {
+ do
+ {
+ OUString aEntryLib = m_xTreeView->get_text(*xLibIter);
+ if (aEntryLib == aLib)
+ {
+ m_xTreeView->expand_row(*xLibIter);
+ std::unique_ptr<weld::TreeIter> xModIter = m_xTreeView->make_iterator(xLibIter.get());
+ if (m_xTreeView->get_iter_first(*xModIter))
+ {
+ do
+ {
+ OUString aEntryMod = m_xTreeView->get_text(*xModIter);
+ if ( aEntryMod == aModule )
+ {
+ m_xTreeView->expand_row(*xModIter);
+ m_xTreeView->scroll_to_row(*xModIter);
+ m_xTreeView->select(*xModIter);
+ for (int i = 0, nCount = m_pFunctionListBox->n_children(); i < nCount; ++i)
+ {
+ OUString aEntryMethod = m_pFunctionListBox->get_text(i);
+ if (aEntryMethod == aMethod)
+ {
+ m_pFunctionListBox->select(i);
+ m_pFunctionListBox->scroll_to_row(i);
+ return;
+ }
+ }
+ }
+ } while (m_xTreeView->iter_next_sibling(*xModIter));
+ }
+ }
+ } while (m_xTreeView->iter_next_sibling(*xLibIter));
+ }
+ }
+ } while (m_xTreeView->iter_next_sibling(*xIter));
+}
+#endif
+
+/*
+ * Implementation of SvxScriptSelectorDialog
+ *
+ * This dialog is used for selecting Slot API commands
+ * and Scripting Framework Scripts.
+ */
+
+SvxScriptSelectorDialog::SvxScriptSelectorDialog(
+ weld::Window* pParent, const css::uno::Reference< css::frame::XFrame >& xFrame)
+ : GenericDialogController(pParent, "cui/ui/macroselectordialog.ui", "MacroSelectorDialog")
+ , m_xDialogDescription(m_xBuilder->weld_label("helpmacro"))
+ , m_xCategories(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("categories")))
+ , m_xCommands(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("commands")))
+ , m_xLibraryFT(m_xBuilder->weld_label("libraryft"))
+ , m_xMacronameFT(m_xBuilder->weld_label("macronameft"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xCancelButton(m_xBuilder->weld_button("cancel"))
+ , m_xDescriptionText(m_xBuilder->weld_text_view("description"))
+ , m_xDescriptionFrame(m_xBuilder->weld_frame("descriptionframe"))
+{
+ m_xCancelButton->show();
+ m_xDialogDescription->show();
+ m_xOKButton->show();
+
+ m_xLibraryFT->set_visible(true);
+ m_xMacronameFT->set_visible(true);
+
+ const OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
+ m_xCategories->SetFunctionListBox(m_xCommands.get());
+ m_xCategories->Init(comphelper::getProcessComponentContext(), xFrame, aModuleName, /*bShowSlots*/false);
+
+ m_xCategories->connect_changed(
+ LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
+ m_xCommands->connect_changed( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
+ m_xCommands->connect_row_activated( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
+ m_xCommands->connect_popup_menu( LINK( this, SvxScriptSelectorDialog, ContextMenuHdl ) );
+
+ m_xOKButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
+ m_xCancelButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
+
+ m_sDefaultDesc = m_xDescriptionText->get_text();
+
+ // Support style commands
+ uno::Reference<frame::XController> xController;
+ uno::Reference<frame::XModel> xModel;
+ if (xFrame.is())
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+
+ m_aStylesInfo.init(aModuleName, xModel);
+ m_xCategories->SetStylesInfo(&m_aStylesInfo);
+
+ UpdateUI();
+
+ if (comphelper::LibreOfficeKit::isActive())
+ m_xDescriptionFrame->hide();
+}
+
+SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
+{
+}
+
+IMPL_LINK(SvxScriptSelectorDialog, SelectHdl, weld::TreeView&, rCtrl, void)
+{
+ if (&rCtrl == &m_xCategories->get_widget())
+ {
+ m_xCategories->GroupSelected();
+ }
+ UpdateUI();
+}
+
+IMPL_LINK_NOARG(SvxScriptSelectorDialog, FunctionDoubleClickHdl, weld::TreeView&, bool)
+{
+ if (m_xOKButton->get_sensitive())
+ ClickHdl(*m_xOKButton);
+ return true;
+}
+
+IMPL_LINK(SvxScriptSelectorDialog, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
+{
+ weld::TreeView& xTreeView = m_xCommands->get_widget();
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu || !xTreeView.n_children())
+ return false;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(&xTreeView, "modules/BasicIDE/ui/sortmenu.ui"));
+ std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu("sortmenu"));
+ std::unique_ptr<weld::Menu> xDropMenu(xBuilder->weld_menu("sortsubmenu"));
+ xDropMenu->set_active("alphabetically", xTreeView.get_sort_order());
+ xDropMenu->set_active("properorder", !xTreeView.get_sort_order());
+
+ OString sCommand(xPopup->popup_at_rect(&xTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
+ if (sCommand == "alphabetically")
+ {
+ xTreeView.make_sorted();
+ }
+ else if (sCommand == "properorder")
+ {
+ xTreeView.make_unsorted();
+ m_xCategories->GroupSelected();
+ }
+ else if (!sCommand.isEmpty())
+ {
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
+ }
+
+ return true;
+}
+
+// Check if command is selected and enable the OK button accordingly
+// Grab the help text for this id if available and update the description field
+void
+SvxScriptSelectorDialog::UpdateUI()
+{
+ OUString url = GetScriptURL();
+ if ( !url.isEmpty() )
+ {
+ OUString sMessage = m_xCommands->GetHelpText();
+ m_xDescriptionText->set_text(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
+
+ m_xOKButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xDescriptionText->set_text(m_sDefaultDesc);
+ m_xOKButton->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SvxScriptSelectorDialog, ClickHdl, weld::Button&, rButton, void)
+{
+ if (&rButton == m_xCancelButton.get())
+ {
+ m_xDialog->response(RET_CANCEL);
+ }
+ else if (&rButton == m_xOKButton.get())
+ {
+ m_xDialog->response(RET_OK);
+ }
+}
+
+void
+SvxScriptSelectorDialog::SetRunLabel()
+{
+ m_xOKButton->set_label(CuiResId(RID_CUISTR_SELECTOR_RUN));
+}
+
+OUString
+SvxScriptSelectorDialog::GetScriptURL() const
+{
+ OUString result;
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xCommands->make_iterator();
+ if (m_xCommands->get_selected(xIter.get()))
+ {
+ SfxGroupInfo_Impl *pData = weld::fromId<SfxGroupInfo_Impl*>(m_xCommands->get_id(*xIter));
+ if ( ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
+ || ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
+ || ( pData->nKind == SfxCfgKind::GROUP_STYLES )
+ )
+ {
+ result = pData->sCommand;
+ }
+ }
+
+ return result;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/eventdlg.cxx b/cui/source/customize/eventdlg.cxx
new file mode 100644
index 000000000..54ebcdefa
--- /dev/null
+++ b/cui/source/customize/eventdlg.cxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <unotools/configmgr.hxx>
+#include <rtl/ustring.hxx>
+
+#include "eventdlg.hxx"
+#include "macropg_impl.hxx"
+
+#include <cfg.hxx>
+
+using namespace ::com::sun::star;
+
+
+SvxEventConfigPage::SvxEventConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet,
+ SvxEventConfigPage::EarlyInit)
+ : SvxMacroTabPage_(pPage, pController, "cui/ui/eventsconfigpage.ui", "EventsConfigPage", rSet)
+ , m_xSaveInListBox(m_xBuilder->weld_combo_box("savein"))
+{
+ mpImpl->xEventLB = m_xBuilder->weld_tree_view("events");
+ mpImpl->xAssignPB = m_xBuilder->weld_button("macro");
+ mpImpl->xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->xAssignComponentPB = m_xBuilder->weld_button("component");
+
+ mpImpl->xEventLB->set_size_request(mpImpl->xEventLB->get_approximate_digit_width() * 70,
+ mpImpl->xEventLB->get_height_rows(20));
+
+ InitResources();
+
+ m_xSaveInListBox->connect_changed( LINK( this, SvxEventConfigPage,
+ SelectHdl_Impl ) );
+
+ uno::Reference< frame::XGlobalEventBroadcaster > xSupplier =
+ frame::theGlobalEventBroadcaster::get(::comphelper::getProcessComponentContext());
+
+ m_xAppEvents = xSupplier->getEvents();
+ m_xSaveInListBox->append(OUString::boolean(true), utl::ConfigManager::getProductName());
+ m_xSaveInListBox->set_active(0);
+}
+
+void SvxEventConfigPage::LateInit( const uno::Reference< frame::XFrame >& _rxFrame )
+{
+ SetFrame( _rxFrame );
+ ImplInitDocument();
+
+ InitAndSetHandler( m_xAppEvents, m_xDocumentEvents, m_xDocumentModifiable );
+
+ SelectHdl_Impl( *m_xSaveInListBox );
+}
+
+SvxEventConfigPage::~SvxEventConfigPage()
+{
+}
+
+void SvxEventConfigPage::ImplInitDocument()
+{
+ uno::Reference< frame::XFrame > xFrame( GetFrame() );
+ OUString aModuleId = SvxConfigPage::GetFrameWithDefaultAndIdentify( xFrame );
+ if ( !xFrame.is() )
+ return;
+
+ try
+ {
+ uno::Reference< frame::XModel > xModel;
+ if ( !SvxConfigPage::CanConfig( aModuleId ) )
+ return;
+
+ uno::Reference< frame::XController > xController =
+ xFrame->getController();
+
+ if ( xController.is() )
+ {
+ xModel = xController->getModel();
+ }
+
+ if ( !xModel.is() )
+ return;
+
+ uno::Reference< document::XEventsSupplier > xSupplier( xModel, uno::UNO_QUERY );
+
+ if ( xSupplier.is() )
+ {
+ m_xDocumentEvents = xSupplier->getEvents();
+ m_xDocumentModifiable.set(xModel, css::uno::UNO_QUERY);
+
+ OUString aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
+
+ m_xSaveInListBox->append(OUString::boolean(false), aTitle);
+ m_xSaveInListBox->set_active(m_xSaveInListBox->get_count() - 1);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+}
+
+IMPL_LINK_NOARG( SvxEventConfigPage, SelectHdl_Impl, weld::ComboBox&, void )
+{
+ bool bApp = m_xSaveInListBox->get_active_id().toBoolean();
+
+ if (bApp)
+ {
+ SetReadOnly( false );
+ SvxMacroTabPage_::DisplayAppEvents( true );
+ }
+ else
+ {
+ bool isReadonly = false;
+
+ uno::Reference< frame::XDesktop2 > xFramesSupplier = frame::Desktop::create(
+ ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< frame::XFrame > xFrame =
+ xFramesSupplier->getActiveFrame();
+
+ if ( xFrame.is() )
+ {
+ uno::Reference< frame::XController > xController =
+ xFrame->getController();
+
+ if ( xController.is() )
+ {
+ uno::Reference< frame::XStorable > xStorable(
+ xController->getModel(), uno::UNO_QUERY );
+ isReadonly = xStorable->isReadonly();
+ }
+ }
+
+ SetReadOnly( isReadonly );
+ SvxMacroTabPage_::DisplayAppEvents( false );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/eventdlg.hxx b/cui/source/customize/eventdlg.hxx
new file mode 100644
index 000000000..2d368e982
--- /dev/null
+++ b/cui/source/customize/eventdlg.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <macropg.hxx>
+
+#include <com/sun/star/frame/XFrame.hpp>
+
+class SvxEventConfigPage : public SvxMacroTabPage_
+{
+ css::uno::Reference< css::container::XNameReplace > m_xAppEvents;
+ css::uno::Reference< css::container::XNameReplace > m_xDocumentEvents;
+ css::uno::Reference< css::util::XModifiable > m_xDocumentModifiable;
+
+ std::unique_ptr<weld::ComboBox> m_xSaveInListBox;
+
+ DECL_LINK( SelectHdl_Impl, weld::ComboBox&, void );
+
+ SvxEventConfigPage (const SvxEventConfigPage &) = delete;
+ SvxEventConfigPage & operator= (const SvxEventConfigPage &) = delete;
+
+public:
+
+ /// this is only to let callers know that there is a LateInit which *must* be called
+ struct EarlyInit { };
+ SvxEventConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet, EarlyInit);
+ virtual ~SvxEventConfigPage() override;
+
+ void LateInit( const css::uno::Reference< css::frame::XFrame >& _rxFrame );
+
+private:
+ void ImplInitDocument();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/macropg.cxx b/cui/source/customize/macropg.cxx
new file mode 100644
index 000000000..7e3ff8bc3
--- /dev/null
+++ b/cui/source/customize/macropg.cxx
@@ -0,0 +1,663 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <macropg.hxx>
+#include <svl/eitem.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <bitmaps.hlst>
+#include <cfgutil.hxx>
+#include <dialmgr.hxx>
+#include <helpids.h>
+#include <headertablistbox.hxx>
+#include "macropg_impl.hxx"
+#include <o3tl/safeint.hxx>
+#include <svl/macitem.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <comphelper/namedvaluecollection.hxx>
+#include <o3tl/string_view.hxx>
+#include <utility>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+constexpr OUStringLiteral aVndSunStarUNO = u"vnd.sun.star.UNO:";
+
+SvxMacroTabPage_Impl::SvxMacroTabPage_Impl( const SfxItemSet& rAttrSet )
+ : bReadOnly(false)
+ , bIDEDialogMode(false)
+{
+ const SfxPoolItem* pItem;
+ if ( SfxItemState::SET == rAttrSet.GetItemState( SID_ATTR_MACROITEM, false, &pItem ) )
+ bIDEDialogMode = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+}
+
+MacroEventListBox::MacroEventListBox(std::unique_ptr<weld::TreeView> xTreeView)
+ : m_xTreeView(std::move(xTreeView))
+{
+ m_xTreeView->set_help_id(HID_MACRO_HEADERTABLISTBOX);
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 70, m_xTreeView->get_height_rows(9));
+}
+
+// assign button ("Add Command") is enabled only if it is not read only
+// delete button ("Remove Command") is enabled if a current binding exists
+// and it is not read only
+void SvxMacroTabPage_::EnableButtons()
+{
+ int nEvent = mpImpl->xEventLB->get_selected_index();
+ if (nEvent != -1)
+ {
+ mpImpl->xDeletePB->set_sensitive( !mpImpl->bReadOnly );
+ mpImpl->xAssignPB->set_sensitive( !mpImpl->bReadOnly );
+ if( mpImpl->xAssignComponentPB )
+ mpImpl->xAssignComponentPB->set_sensitive( !mpImpl->bReadOnly );
+ }
+}
+
+SvxMacroTabPage_::SvxMacroTabPage_(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription,
+ const OString& rID, const SfxItemSet& rAttrSet)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, &rAttrSet)
+ , bDocModified(false)
+ , bAppEvents(false)
+ , bInitialized(false)
+{
+ mpImpl.reset( new SvxMacroTabPage_Impl( rAttrSet ) );
+}
+
+SvxMacroTabPage_::~SvxMacroTabPage_()
+{
+ mpImpl.reset();
+}
+
+void SvxMacroTabPage_::InitResources()
+{
+ // Note: the order here controls the order in which the events are displayed in the UI!
+
+ // the event name to UI string mappings for App Events
+ aDisplayNames.emplace_back( "OnStartApp", RID_CUISTR_EVENT_STARTAPP );
+ aDisplayNames.emplace_back( "OnCloseApp", RID_CUISTR_EVENT_CLOSEAPP );
+ aDisplayNames.emplace_back( "OnCreate", RID_CUISTR_EVENT_CREATEDOC );
+ aDisplayNames.emplace_back( "OnNew", RID_CUISTR_EVENT_NEWDOC );
+ aDisplayNames.emplace_back( "OnLoadFinished", RID_CUISTR_EVENT_LOADDOCFINISHED );
+ aDisplayNames.emplace_back( "OnLoad", RID_CUISTR_EVENT_OPENDOC );
+ aDisplayNames.emplace_back( "OnPrepareUnload", RID_CUISTR_EVENT_PREPARECLOSEDOC );
+ aDisplayNames.emplace_back( "OnUnload", RID_CUISTR_EVENT_CLOSEDOC ) ;
+ aDisplayNames.emplace_back( "OnViewCreated", RID_CUISTR_EVENT_VIEWCREATED );
+ aDisplayNames.emplace_back( "OnPrepareViewClosing", RID_CUISTR_EVENT_PREPARECLOSEVIEW );
+ aDisplayNames.emplace_back( "OnViewClosed", RID_CUISTR_EVENT_CLOSEVIEW ) ;
+ aDisplayNames.emplace_back( "OnFocus", RID_CUISTR_EVENT_ACTIVATEDOC );
+ aDisplayNames.emplace_back( "OnUnfocus", RID_CUISTR_EVENT_DEACTIVATEDOC );
+ aDisplayNames.emplace_back( "OnSave", RID_CUISTR_EVENT_SAVEDOC );
+ aDisplayNames.emplace_back( "OnSaveDone", RID_CUISTR_EVENT_SAVEDOCDONE );
+ aDisplayNames.emplace_back( "OnSaveFailed", RID_CUISTR_EVENT_SAVEDOCFAILED );
+ aDisplayNames.emplace_back( "OnSaveAs", RID_CUISTR_EVENT_SAVEASDOC );
+ aDisplayNames.emplace_back( "OnSaveAsDone", RID_CUISTR_EVENT_SAVEASDOCDONE );
+ aDisplayNames.emplace_back( "OnSaveAsFailed", RID_CUISTR_EVENT_SAVEASDOCFAILED );
+ aDisplayNames.emplace_back( "OnCopyTo", RID_CUISTR_EVENT_COPYTODOC );
+ aDisplayNames.emplace_back( "OnCopyToDone", RID_CUISTR_EVENT_COPYTODOCDONE );
+ aDisplayNames.emplace_back( "OnCopyToFailed", RID_CUISTR_EVENT_COPYTODOCFAILED );
+ aDisplayNames.emplace_back( "OnPrint", RID_CUISTR_EVENT_PRINTDOC );
+ aDisplayNames.emplace_back( "OnModifyChanged", RID_CUISTR_EVENT_MODIFYCHANGED );
+ aDisplayNames.emplace_back( "OnTitleChanged", RID_CUISTR_EVENT_TITLECHANGED );
+
+ // application specific events
+ aDisplayNames.emplace_back( "OnMailMerge", RID_CUISTR_EVENT_MAILMERGE );
+ aDisplayNames.emplace_back( "OnMailMergeFinished", RID_CUISTR_EVENT_MAILMERGE_END );
+ aDisplayNames.emplace_back( "OnFieldMerge", RID_CUISTR_EVENT_FIELDMERGE );
+ aDisplayNames.emplace_back( "OnFieldMergeFinished", RID_CUISTR_EVENT_FIELDMERGE_FINISHED );
+ aDisplayNames.emplace_back( "OnPageCountChange", RID_CUISTR_EVENT_PAGECOUNTCHANGE );
+ aDisplayNames.emplace_back( "OnSubComponentOpened", RID_CUISTR_EVENT_SUBCOMPONENT_OPENED );
+ aDisplayNames.emplace_back( "OnSubComponentClosed", RID_CUISTR_EVENT_SUBCOMPONENT_CLOSED );
+ aDisplayNames.emplace_back( "OnSelect", RID_CUISTR_EVENT_SELECTIONCHANGED );
+ aDisplayNames.emplace_back( "OnDoubleClick", RID_CUISTR_EVENT_DOUBLECLICK );
+ aDisplayNames.emplace_back( "OnRightClick", RID_CUISTR_EVENT_RIGHTCLICK );
+ aDisplayNames.emplace_back( "OnCalculate", RID_CUISTR_EVENT_CALCULATE );
+ aDisplayNames.emplace_back( "OnChange", RID_CUISTR_EVENT_CONTENTCHANGED );
+
+ // the event name to UI string mappings for forms & dialogs
+
+ aDisplayNames.emplace_back( "approveAction", RID_CUISTR_EVENT_APPROVEACTIONPERFORMED );
+ aDisplayNames.emplace_back( "actionPerformed", RID_CUISTR_EVENT_ACTIONPERFORMED );
+ aDisplayNames.emplace_back( "changed", RID_CUISTR_EVENT_CHANGED );
+ aDisplayNames.emplace_back( "textChanged", RID_CUISTR_EVENT_TEXTCHANGED );
+ aDisplayNames.emplace_back( "itemStateChanged", RID_CUISTR_EVENT_ITEMSTATECHANGED );
+ aDisplayNames.emplace_back( "focusGained", RID_CUISTR_EVENT_FOCUSGAINED );
+ aDisplayNames.emplace_back( "focusLost", RID_CUISTR_EVENT_FOCUSLOST );
+ aDisplayNames.emplace_back( "keyPressed", RID_CUISTR_EVENT_KEYTYPED );
+ aDisplayNames.emplace_back( "keyReleased", RID_CUISTR_EVENT_KEYUP );
+ aDisplayNames.emplace_back( "mouseEntered", RID_CUISTR_EVENT_MOUSEENTERED );
+ aDisplayNames.emplace_back( "mouseDragged", RID_CUISTR_EVENT_MOUSEDRAGGED );
+ aDisplayNames.emplace_back( "mouseMoved", RID_CUISTR_EVENT_MOUSEMOVED );
+ aDisplayNames.emplace_back( "mousePressed", RID_CUISTR_EVENT_MOUSEPRESSED );
+ aDisplayNames.emplace_back( "mouseReleased", RID_CUISTR_EVENT_MOUSERELEASED );
+ aDisplayNames.emplace_back( "mouseExited", RID_CUISTR_EVENT_MOUSEEXITED );
+ aDisplayNames.emplace_back( "approveReset", RID_CUISTR_EVENT_APPROVERESETTED );
+ aDisplayNames.emplace_back( "resetted", RID_CUISTR_EVENT_RESETTED );
+ aDisplayNames.emplace_back( "approveSubmit", RID_CUISTR_EVENT_SUBMITTED );
+ aDisplayNames.emplace_back( "approveUpdate", RID_CUISTR_EVENT_BEFOREUPDATE );
+ aDisplayNames.emplace_back( "updated", RID_CUISTR_EVENT_AFTERUPDATE );
+ aDisplayNames.emplace_back( "loaded", RID_CUISTR_EVENT_LOADED );
+ aDisplayNames.emplace_back( "reloading", RID_CUISTR_EVENT_RELOADING );
+ aDisplayNames.emplace_back( "reloaded", RID_CUISTR_EVENT_RELOADED );
+ aDisplayNames.emplace_back( "unloading", RID_CUISTR_EVENT_UNLOADING );
+ aDisplayNames.emplace_back( "unloaded", RID_CUISTR_EVENT_UNLOADED );
+ aDisplayNames.emplace_back( "confirmDelete", RID_CUISTR_EVENT_CONFIRMDELETE );
+ aDisplayNames.emplace_back( "approveRowChange", RID_CUISTR_EVENT_APPROVEROWCHANGE );
+ aDisplayNames.emplace_back( "rowChanged", RID_CUISTR_EVENT_ROWCHANGE );
+ aDisplayNames.emplace_back( "approveCursorMove", RID_CUISTR_EVENT_POSITIONING );
+ aDisplayNames.emplace_back( "cursorMoved", RID_CUISTR_EVENT_POSITIONED );
+ aDisplayNames.emplace_back( "approveParameter", RID_CUISTR_EVENT_APPROVEPARAMETER );
+ aDisplayNames.emplace_back( "errorOccured", RID_CUISTR_EVENT_ERROROCCURRED );
+ aDisplayNames.emplace_back( "adjustmentValueChanged", RID_CUISTR_EVENT_ADJUSTMENTVALUECHANGED );
+}
+
+// the following method is called when the user clicks OK
+// We use the contents of the hashes to replace the settings
+bool SvxMacroTabPage_::FillItemSet( SfxItemSet* /*rSet*/ )
+{
+ try
+ {
+ OUString eventName;
+ if( m_xAppEvents.is() )
+ {
+ for (auto const& appEvent : m_appEventsHash)
+ {
+ eventName = appEvent.first;
+ try
+ {
+ m_xAppEvents->replaceByName( eventName, GetPropsByName( eventName, m_appEventsHash ) );
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+ }
+ }
+ if( m_xDocEvents.is() && bDocModified )
+ {
+ for (auto const& docEvent : m_docEventsHash)
+ {
+ eventName = docEvent.first;
+ try
+ {
+ m_xDocEvents->replaceByName( eventName, GetPropsByName( eventName, m_docEventsHash ) );
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+ }
+ // if we have a valid XModifiable (in the case of doc events)
+ // call setModified(true)
+ // in principle this should not be necessary (see issue ??)
+ if(m_xModifiable.is())
+ {
+ m_xModifiable->setModified( true );
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ // what is the return value about??
+ return false;
+}
+
+// the following method clears the bindings in the hashes for both doc & app
+void SvxMacroTabPage_::Reset( const SfxItemSet* )
+{
+ // called once in creation - don't reset the data this time
+ if(!bInitialized)
+ {
+ bInitialized = true;
+ return;
+ }
+
+ try
+ {
+ if( m_xAppEvents.is() )
+ {
+ for (auto & appEvent : m_appEventsHash)
+ {
+ appEvent.second.second.clear();
+ }
+ }
+ if( m_xDocEvents.is() && bDocModified )
+ {
+ for (auto & docEvent : m_docEventsHash)
+ {
+ docEvent.second.second.clear();
+ }
+ // if we have a valid XModifiable (in the case of doc events)
+ // call setModified(true)
+ if(m_xModifiable.is())
+ {
+ m_xModifiable->setModified( true );
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ DisplayAppEvents(bAppEvents);
+}
+
+void SvxMacroTabPage_::SetReadOnly( bool bSet )
+{
+ mpImpl->bReadOnly = bSet;
+}
+
+bool SvxMacroTabPage_::IsReadOnly() const
+{
+ return mpImpl->bReadOnly;
+}
+
+namespace
+{
+ std::u16string_view GetEventDisplayText(std::u16string_view rURL)
+ {
+ if (rURL.empty())
+ return std::u16string_view();
+ bool bUNO = o3tl::starts_with(rURL, aVndSunStarUNO);
+ std::u16string_view aPureMethod;
+ if (bUNO)
+ {
+ aPureMethod = rURL.substr(aVndSunStarUNO.getLength());
+ }
+ else
+ {
+ aPureMethod = rURL.substr(strlen("vnd.sun.star.script:"));
+ aPureMethod = aPureMethod.substr( 0, aPureMethod.find( '?' ) );
+ }
+ return aPureMethod;
+ }
+
+ OUString GetEventDisplayImage(std::u16string_view rURL)
+ {
+ if (rURL.empty())
+ return OUString();
+ size_t nIndex = rURL.find(aVndSunStarUNO);
+ bool bUNO = nIndex == 0;
+ return bUNO ? OUString(RID_SVXBMP_COMPONENT) : OUString(RID_SVXBMP_MACRO);
+ }
+}
+
+// displays the app events if appEvents=true, otherwise displays the doc events
+void SvxMacroTabPage_::DisplayAppEvents( bool appEvents)
+{
+ bAppEvents = appEvents;
+
+ mpImpl->xEventLB->freeze();
+ mpImpl->xEventLB->clear();
+ EventsHash* eventsHash;
+ Reference< container::XNameReplace> nameReplace;
+ if(bAppEvents)
+ {
+ eventsHash = &m_appEventsHash;
+ nameReplace = m_xAppEvents;
+ }
+ else
+ {
+ eventsHash = &m_docEventsHash;
+ nameReplace = m_xDocEvents;
+ }
+ // have to use the original XNameReplace since the hash iterators do
+ // not guarantee the order in which the elements are returned
+ if(!nameReplace.is())
+ {
+ mpImpl->xEventLB->thaw();
+ return;
+ }
+
+ for (auto const& displayableEvent : aDisplayNames)
+ {
+ OUString sEventName( OUString::createFromAscii( displayableEvent.pAsciiEventName ) );
+ if ( !nameReplace->hasByName( sEventName ) )
+ continue;
+
+ EventsHash::iterator h_it = eventsHash->find( sEventName );
+ if( h_it == eventsHash->end() )
+ {
+ OSL_FAIL( "SvxMacroTabPage_::DisplayAppEvents: something's suspicious here!" );
+ continue;
+ }
+
+ OUString eventURL = h_it->second.second;
+ OUString displayName(CuiResId(displayableEvent.pEventResourceID));
+
+ int nRow = mpImpl->xEventLB->n_children();
+ mpImpl->xEventLB->append(sEventName, displayName);
+ mpImpl->xEventLB->set_image(nRow, GetEventDisplayImage(eventURL), 1);
+ mpImpl->xEventLB->set_text(nRow, OUString(GetEventDisplayText(eventURL)), 2);
+ }
+
+ mpImpl->xEventLB->thaw();
+
+ if (mpImpl->xEventLB->n_children())
+ {
+ mpImpl->xEventLB->select(0);
+ mpImpl->xEventLB->scroll_to_row(0);
+ }
+
+ EnableButtons();
+}
+
+// select event handler on the listbox
+IMPL_LINK_NOARG( SvxMacroTabPage_, SelectEvent_Impl, weld::TreeView&, void)
+{
+ int nEntry = mpImpl->xEventLB->get_selected_index();
+
+ if (nEntry == -1)
+ {
+ DBG_ASSERT(false, "Where does the empty entry come from?" );
+ return;
+ }
+
+ EnableButtons();
+}
+
+IMPL_LINK( SvxMacroTabPage_, AssignDeleteHdl_Impl, weld::Button&, rBtn, void )
+{
+ GenericHandler_Impl(this, &rBtn);
+}
+
+IMPL_LINK_NOARG( SvxMacroTabPage_, DoubleClickHdl_Impl, weld::TreeView&, bool)
+{
+ GenericHandler_Impl(this, nullptr);
+ return true;
+}
+
+// handler for double click on the listbox, and for the assign/delete buttons
+void SvxMacroTabPage_::GenericHandler_Impl(SvxMacroTabPage_* pThis, const weld::Button* pBtn)
+{
+ SvxMacroTabPage_Impl* pImpl = pThis->mpImpl.get();
+ weld::TreeView& rListBox = *pImpl->xEventLB;
+ int nEntry = rListBox.get_selected_index();
+ if (nEntry == -1)
+ {
+ DBG_ASSERT(false, "Where does the empty entry come from?");
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != pImpl->xDeletePB.get() && pImpl->xAssignPB->get_sensitive();
+
+ OUString sEventName = rListBox.get_id(nEntry);
+
+ OUString sEventURL;
+ OUString sEventType;
+ if(pThis->bAppEvents)
+ {
+ EventsHash::iterator h_it = pThis->m_appEventsHash.find(sEventName);
+ if(h_it != pThis->m_appEventsHash.end() )
+ {
+ sEventType = h_it->second.first;
+ sEventURL = h_it->second.second;
+ }
+ }
+ else
+ {
+ EventsHash::iterator h_it = pThis->m_docEventsHash.find(sEventName);
+ if(h_it != pThis->m_docEventsHash.end() )
+ {
+ sEventType = h_it->second.first;
+ sEventURL = h_it->second.second;
+ }
+ }
+
+ bool bDoubleClick = (pBtn == nullptr);
+ bool bUNOAssigned = sEventURL.startsWith( aVndSunStarUNO );
+ if( pBtn == pImpl->xDeletePB.get() )
+ {
+ // delete pressed
+ sEventType = "Script" ;
+ sEventURL.clear();
+ if(!pThis->bAppEvents)
+ pThis->bDocModified = true;
+ }
+ else if ( ( ( pBtn != nullptr )
+ && ( pBtn == pImpl->xAssignComponentPB.get() )
+ )
+ || ( bDoubleClick
+ && bUNOAssigned
+ )
+ )
+ {
+ AssignComponentDialog aAssignDlg(pThis->GetFrameWeld(), sEventURL);
+
+ short ret = aAssignDlg.run();
+ if( ret )
+ {
+ sEventType = "UNO";
+ sEventURL = aAssignDlg.getURL();
+ if(!pThis->bAppEvents)
+ pThis->bDocModified = true;
+ }
+ }
+ else if( bAssEnabled )
+ {
+ // assign pressed
+ SvxScriptSelectorDialog aDlg(pThis->GetFrameWeld(), pThis->GetFrame());
+ short ret = aDlg.run();
+ if ( ret )
+ {
+ sEventType = "Script";
+ sEventURL = aDlg.GetScriptURL();
+ if(!pThis->bAppEvents)
+ pThis->bDocModified = true;
+ }
+ }
+
+ // update the hashes
+ if(pThis->bAppEvents)
+ {
+ EventsHash::iterator h_it = pThis->m_appEventsHash.find(sEventName);
+ h_it->second.first = sEventType;
+ h_it->second.second = sEventURL;
+ }
+ else
+ {
+ EventsHash::iterator h_it = pThis->m_docEventsHash.find(sEventName);
+ h_it->second.first = sEventType;
+ h_it->second.second = sEventURL;
+ }
+
+ rListBox.set_image(nEntry, GetEventDisplayImage(sEventURL), 1);
+ rListBox.set_text(nEntry, OUString(GetEventDisplayText(sEventURL)), 2);
+
+ rListBox.select(nEntry );
+ rListBox.scroll_to_row(nEntry);
+
+ pThis->EnableButtons();
+}
+
+// pass in the XNameReplace.
+// can remove the 3rd arg once issue ?? is fixed
+void SvxMacroTabPage_::InitAndSetHandler( const Reference< container::XNameReplace>& xAppEvents, const Reference< container::XNameReplace>& xDocEvents, const Reference< util::XModifiable >& xModifiable )
+{
+ m_xAppEvents = xAppEvents;
+ m_xDocEvents = xDocEvents;
+ m_xModifiable = xModifiable;
+ Link<weld::Button&,void> aLnk(LINK(this, SvxMacroTabPage_, AssignDeleteHdl_Impl ));
+ mpImpl->xDeletePB->connect_clicked(aLnk);
+ mpImpl->xAssignPB->connect_clicked(aLnk);
+ if( mpImpl->xAssignComponentPB )
+ mpImpl->xAssignComponentPB->connect_clicked( aLnk );
+ mpImpl->xEventLB->connect_row_activated( LINK(this, SvxMacroTabPage_, DoubleClickHdl_Impl ) );
+ mpImpl->xEventLB->connect_changed( LINK( this, SvxMacroTabPage_, SelectEvent_Impl ));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(mpImpl->xEventLB->get_approximate_digit_width() * 32),
+ mpImpl->xEventLB->get_checkbox_column_width()
+ };
+ mpImpl->xEventLB->set_column_fixed_widths(aWidths);
+
+ mpImpl->xEventLB->show();
+ mpImpl->xEventLB->set_sensitive(true);
+
+ if(!m_xAppEvents.is())
+ {
+ return;
+ }
+ Sequence< OUString > eventNames = m_xAppEvents->getElementNames();
+ sal_Int32 nEventCount = eventNames.getLength();
+ for(sal_Int32 nEvent = 0; nEvent < nEventCount; ++nEvent )
+ {
+ //need exception handling here
+ try
+ {
+ m_appEventsHash[ eventNames[nEvent] ] = GetPairFromAny( m_xAppEvents->getByName( eventNames[nEvent] ) );
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ if(!m_xDocEvents.is())
+ return;
+
+ eventNames = m_xDocEvents->getElementNames();
+ nEventCount = eventNames.getLength();
+ for(sal_Int32 nEvent = 0; nEvent < nEventCount; ++nEvent )
+ {
+ try
+ {
+ m_docEventsHash[ eventNames[nEvent] ] = GetPairFromAny( m_xDocEvents->getByName( eventNames[nEvent] ) );
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+}
+
+// returns the two props EventType & Script for a given event name
+Any SvxMacroTabPage_::GetPropsByName( const OUString& eventName, EventsHash& eventsHash )
+{
+ const std::pair< OUString, OUString >& rAssignedEvent( eventsHash[ eventName ] );
+
+ Any aReturn;
+ ::comphelper::NamedValueCollection aProps;
+ if ( !(rAssignedEvent.first.isEmpty() || rAssignedEvent.second.isEmpty()) )
+ {
+ aProps.put( "EventType", rAssignedEvent.first );
+ aProps.put( "Script", rAssignedEvent.second );
+ }
+ aReturn <<= aProps.getPropertyValues();
+
+ return aReturn;
+}
+
+// converts the Any returned by GetByName into a pair which can be stored in
+// the EventHash
+std::pair< OUString, OUString > SvxMacroTabPage_::GetPairFromAny( const Any& aAny )
+{
+ Sequence< beans::PropertyValue > props;
+ OUString type, url;
+ if( aAny >>= props )
+ {
+ ::comphelper::NamedValueCollection aProps( props );
+ type = aProps.getOrDefault( "EventType", type );
+ url = aProps.getOrDefault( "Script", url );
+ }
+ return std::make_pair( type, url );
+}
+
+SvxMacroTabPage::SvxMacroTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const Reference< frame::XFrame >& _rxDocumentFrame,
+ const SfxItemSet& rSet,
+ Reference< container::XNameReplace > const & xNameReplace,
+ sal_uInt16 nSelectedIndex)
+ : SvxMacroTabPage_(pPage, pController, "cui/ui/macroassignpage.ui", "MacroAssignPage", rSet)
+{
+ mpImpl->xEventLB = m_xBuilder->weld_tree_view("assignments");
+ mpImpl->xEventLB->set_size_request(mpImpl->xEventLB->get_approximate_digit_width() * 70,
+ mpImpl->xEventLB->get_height_rows(9));
+ mpImpl->xAssignPB = m_xBuilder->weld_button("assign");
+ mpImpl->xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->xAssignComponentPB = m_xBuilder->weld_button("component");
+
+ SetFrame( _rxDocumentFrame );
+
+ if( !mpImpl->bIDEDialogMode )
+ {
+ mpImpl->xAssignComponentPB->hide();
+ mpImpl->xAssignComponentPB->set_sensitive(false);
+ }
+
+ InitResources();
+
+ InitAndSetHandler( xNameReplace, Reference< container::XNameReplace>(nullptr), Reference< util::XModifiable >(nullptr));
+ DisplayAppEvents(true);
+ mpImpl->xEventLB->select(nSelectedIndex);
+}
+
+SvxMacroAssignDlg::SvxMacroAssignDlg(weld::Window* pParent, const Reference< frame::XFrame >& _rxDocumentFrame, const SfxItemSet& rSet,
+ const Reference< container::XNameReplace >& xNameReplace, sal_uInt16 nSelectedIndex)
+ : SvxMacroAssignSingleTabDialog(pParent, rSet)
+{
+ SetTabPage(std::make_unique<SvxMacroTabPage>(get_content_area(), this, _rxDocumentFrame, rSet, xNameReplace, nSelectedIndex));
+}
+
+IMPL_LINK_NOARG(AssignComponentDialog, ButtonHandler, weld::Button&, void)
+{
+ OUString aMethodName = mxMethodEdit->get_text();
+ maURL.clear();
+ if( !aMethodName.isEmpty() )
+ {
+ maURL = aVndSunStarUNO;
+ maURL += aMethodName;
+ }
+ m_xDialog->response(RET_OK);
+}
+
+AssignComponentDialog::AssignComponentDialog(weld::Window* pParent, OUString aURL)
+ : GenericDialogController(pParent, "cui/ui/assigncomponentdialog.ui", "AssignComponent")
+ , maURL(std::move( aURL ))
+ , mxMethodEdit(m_xBuilder->weld_entry("methodEntry"))
+ , mxOKButton(m_xBuilder->weld_button("ok"))
+{
+ mxOKButton->connect_clicked(LINK(this, AssignComponentDialog, ButtonHandler));
+
+ OUString aMethodName;
+ if( maURL.startsWith( aVndSunStarUNO ) )
+ {
+ aMethodName = maURL.copy( aVndSunStarUNO.getLength() );
+ }
+ mxMethodEdit->set_text(aMethodName);
+ mxMethodEdit->select_region(0, -1);
+}
+
+AssignComponentDialog::~AssignComponentDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxMacroAssignSingleTabDialog, OKHdl_Impl, weld::Button&, void)
+{
+ m_xSfxPage->FillItemSet(nullptr);
+ m_xDialog->response(RET_OK);
+}
+
+SvxMacroAssignSingleTabDialog::SvxMacroAssignSingleTabDialog(weld::Window *pParent,
+ const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet, "cui/ui/macroassigndialog.ui", "MacroAssignDialog")
+{
+ GetOKButton().connect_clicked(LINK(this, SvxMacroAssignSingleTabDialog, OKHdl_Impl));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/macropg_impl.hxx b/cui/source/customize/macropg_impl.hxx
new file mode 100644
index 000000000..63d2f2ae2
--- /dev/null
+++ b/cui/source/customize/macropg_impl.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <svl/itemset.hxx>
+#include <vcl/weld.hxx>
+
+class SvxMacroTabPage_Impl
+{
+public:
+ explicit SvxMacroTabPage_Impl( const SfxItemSet& rAttrSet );
+
+ std::unique_ptr<weld::Button> xAssignPB;
+ std::unique_ptr<weld::Button> xAssignComponentPB;
+ std::unique_ptr<weld::Button> xDeletePB;
+ std::unique_ptr<weld::TreeView> xEventLB;
+ bool bReadOnly;
+ bool bIDEDialogMode;
+};
+
+class AssignComponentDialog : public weld::GenericDialogController
+{
+private:
+ OUString maURL;
+
+ std::unique_ptr<weld::Entry> mxMethodEdit;
+ std::unique_ptr<weld::Button> mxOKButton;
+
+ DECL_LINK(ButtonHandler, weld::Button&, void);
+
+public:
+ AssignComponentDialog(weld::Window* pParent, OUString aURL);
+ virtual ~AssignComponentDialog() override;
+
+ const OUString& getURL() const { return maURL; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/AdditionsDialog.cxx b/cui/source/dialogs/AdditionsDialog.cxx
new file mode 100644
index 000000000..c26a0d974
--- /dev/null
+++ b/cui/source/dialogs/AdditionsDialog.cxx
@@ -0,0 +1,871 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <sal/config.h>
+
+#include <algorithm>
+#include <cmath>
+
+#include <config_folders.h>
+
+#include <AdditionsDialog.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#include <sal/log.hxx>
+
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <unotools/textsearch.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <ucbhelper/content.hxx>
+
+#include <com/sun/star/deployment/DeploymentException.hpp>
+#include <com/sun/star/deployment/ExtensionManager.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/CommandFailedException.hpp>
+
+#include <com/sun/star/task/XInteractionApprove.hpp>
+
+#include <orcus/json_document_tree.hpp>
+#include <orcus/json_parser.hpp>
+#include <orcus/config.hpp>
+
+#define PAGE_SIZE 30
+
+using namespace css;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::XComponentContext;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::graphic::GraphicProvider;
+using ::com::sun::star::graphic::XGraphicProvider;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::graphic::XGraphic;
+
+using namespace com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::beans;
+
+namespace
+{
+// Gets the content of the given URL and returns as a standard string
+std::string ucbGet(const OUString& rURL)
+{
+ try
+ {
+ auto const s = utl::UcbStreamHelper::CreateStream(rURL, StreamMode::STD_READ);
+ if (!s)
+ {
+ SAL_WARN("cui.dialogs", "CreateStream <" << rURL << "> failed");
+ return {};
+ }
+ std::string response_body;
+ do
+ {
+ char buf[4096];
+ auto const n = s->ReadBytes(buf, sizeof buf);
+ response_body.append(buf, n);
+ } while (s->good());
+ if (s->bad())
+ {
+ SAL_WARN("cui.dialogs", "Reading <" << rURL << "> failed with " << s->GetError());
+ return {};
+ }
+ return response_body;
+ }
+ catch (css::uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Download failed");
+ return {};
+ }
+}
+
+// Downloads and saves the file at the given rURL to a local path (sFolderURL/fileName)
+void ucbDownload(const OUString& rURL, const OUString& sFolderURL, const OUString& fileName)
+{
+ try
+ {
+ ucbhelper::Content(sFolderURL, {}, comphelper::getProcessComponentContext())
+ .transferContent(ucbhelper::Content(rURL, {}, comphelper::getProcessComponentContext()),
+ ucbhelper::InsertOperation::Copy, fileName,
+ css::ucb::NameClash::OVERWRITE);
+ }
+ catch (css::uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Download failed");
+ }
+}
+
+void parseResponse(const std::string& rResponse, std::vector<AdditionInfo>& aAdditions)
+{
+ orcus::json::document_tree aJsonDoc;
+ orcus::json_config aConfig;
+
+ if (rResponse.empty())
+ return;
+
+ try
+ {
+ aJsonDoc.load(rResponse, aConfig);
+ }
+ catch (const orcus::json::parse_error&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Invalid JSON file from the extensions API");
+ return;
+ }
+
+ auto aDocumentRoot = aJsonDoc.get_document_root();
+ if (aDocumentRoot.type() != orcus::json::node_t::object)
+ {
+ SAL_WARN("cui.dialogs", "invalid root entries: " << rResponse);
+ return;
+ }
+
+ auto resultsArray = aDocumentRoot.child("extension");
+
+ for (size_t i = 0; i < resultsArray.child_count(); ++i)
+ {
+ auto arrayElement = resultsArray.child(i);
+
+ try
+ {
+ AdditionInfo aNewAddition = {
+ OStringToOUString(arrayElement.child("id").string_value(), RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("name").string_value(), RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("author").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("url").string_value(), RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("screenshotURL").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("extensionIntroduction").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("extensionDescription").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(
+ arrayElement.child("releases").child(0).child("compatibility").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(
+ arrayElement.child("releases").child(0).child("releaseName").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(
+ arrayElement.child("releases").child(0).child("license").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("commentNumber").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("commentURL").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("rating").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(arrayElement.child("downloadNumber").string_value(),
+ RTL_TEXTENCODING_UTF8),
+ OStringToOUString(
+ arrayElement.child("releases").child(0).child("downloadURL").string_value(),
+ RTL_TEXTENCODING_UTF8)
+ };
+
+ aAdditions.push_back(aNewAddition);
+ }
+ catch (orcus::json::document_error& e)
+ {
+ // This usually happens when one of the values is null (type() == orcus::json::node_t::null)
+ // TODO: Allow null values in additions.
+ SAL_WARN("cui.dialogs", "Additions JSON parse error: " << e.what());
+ }
+ }
+}
+
+bool getPreviewFile(const AdditionInfo& aAdditionInfo, OUString& sPreviewFile)
+{
+ uno::Reference<ucb::XSimpleFileAccess3> xFileAccess
+ = ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext());
+
+ // copy the images to the user's additions folder
+ OUString userFolder = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
+ "/" SAL_CONFIGFILE("bootstrap") "::UserInstallation}";
+ rtl::Bootstrap::expandMacros(userFolder);
+ userFolder += "/user/additions/" + aAdditionInfo.sExtensionID + "/";
+
+ OUString aPreviewFile(INetURLObject(aAdditionInfo.sScreenshotURL).getName());
+ OUString aPreviewURL = aAdditionInfo.sScreenshotURL;
+
+ try
+ {
+ osl::Directory::createPath(userFolder);
+
+ if (!xFileAccess->exists(userFolder + aPreviewFile))
+ ucbDownload(aPreviewURL, userFolder, aPreviewFile);
+ }
+ catch (const uno::Exception&)
+ {
+ return false;
+ }
+ sPreviewFile = userFolder + aPreviewFile;
+ return true;
+}
+
+void LoadImage(std::u16string_view rPreviewFile, std::shared_ptr<AdditionsItem> pCurrentItem)
+{
+ const sal_Int8 Margin = 6;
+
+ SolarMutexGuard aGuard;
+
+ GraphicFilter aFilter;
+ Graphic aGraphic;
+
+ INetURLObject aURLObj(rPreviewFile);
+
+ // for VCL to be able to create bitmaps / do visual changes in the thread
+ aFilter.ImportGraphic(aGraphic, aURLObj);
+ BitmapEx aBmp = aGraphic.GetBitmapEx();
+ Size aBmpSize = aBmp.GetSizePixel();
+ Size aThumbSize(pCurrentItem->m_xImageScreenshot->get_size_request());
+ if (!aBmp.IsEmpty())
+ {
+ double aScale;
+ if (aBmpSize.Width() > aThumbSize.Width() - 2 * Margin)
+ {
+ aScale = static_cast<double>(aBmpSize.Width()) / (aThumbSize.Width() - 2 * Margin);
+ aBmp.Scale(Size(aBmpSize.Width() / aScale, aBmpSize.Height() / aScale));
+ }
+ else if (aBmpSize.Height() > aThumbSize.Height() - 2 * Margin)
+ {
+ aScale = static_cast<double>(aBmpSize.Height()) / (aThumbSize.Height() - 2 * Margin);
+ aBmp.Scale(Size(aBmpSize.Width() / aScale, aBmpSize.Height() / aScale));
+ };
+ aBmpSize = aBmp.GetSizePixel();
+ }
+
+ ScopedVclPtr<VirtualDevice> xVirDev = pCurrentItem->m_xImageScreenshot->create_virtual_device();
+ xVirDev->SetOutputSizePixel(aThumbSize);
+ //white background since images come with a white border
+ xVirDev->SetBackground(Wallpaper(COL_WHITE));
+ xVirDev->Erase();
+ xVirDev->DrawBitmapEx(Point(aThumbSize.Width() / 2 - aBmpSize.Width() / 2, Margin), aBmp);
+ pCurrentItem->m_xImageScreenshot->set_image(xVirDev.get());
+ xVirDev.disposeAndClear();
+}
+
+} // End of the anonymous namespace
+
+SearchAndParseThread::SearchAndParseThread(AdditionsDialog* pDialog, const bool isFirstLoading)
+ : Thread("cuiAdditionsSearchThread")
+ , m_pAdditionsDialog(pDialog)
+ , m_bExecute(true)
+ , m_bIsFirstLoading(isFirstLoading)
+{
+}
+
+SearchAndParseThread::~SearchAndParseThread() {}
+
+void SearchAndParseThread::Append(AdditionInfo& additionInfo)
+{
+ if (!m_bExecute)
+ return;
+ OUString aPreviewFile;
+ bool bResult = getPreviewFile(additionInfo, aPreviewFile); // info vector json data
+
+ if (!bResult)
+ {
+ SAL_INFO("cui.dialogs", "Couldn't get the preview file. Skipping: " << aPreviewFile);
+ return;
+ }
+
+ SolarMutexGuard aGuard;
+
+ auto newItem = std::make_shared<AdditionsItem>(m_pAdditionsDialog->m_xContentGrid.get(),
+ m_pAdditionsDialog, additionInfo);
+ m_pAdditionsDialog->m_aAdditionsItems.push_back(newItem);
+ std::shared_ptr<AdditionsItem> aCurrentItem = m_pAdditionsDialog->m_aAdditionsItems.back();
+
+ LoadImage(aPreviewFile, aCurrentItem);
+ m_pAdditionsDialog->m_nCurrentListItemCount++;
+
+ if (m_pAdditionsDialog->m_nCurrentListItemCount == m_pAdditionsDialog->m_nMaxItemCount)
+ {
+ if (m_pAdditionsDialog->m_nCurrentListItemCount
+ != m_pAdditionsDialog->m_aAllExtensionsVector.size())
+ aCurrentItem->m_xButtonShowMore->set_visible(true);
+ }
+}
+
+void SearchAndParseThread::Search()
+{
+ m_pAdditionsDialog->m_searchOptions.searchString
+ = m_pAdditionsDialog->m_xEntrySearch->get_text();
+ utl::TextSearch textSearch(m_pAdditionsDialog->m_searchOptions);
+
+ size_t nIteration = 0;
+ for (auto& rInfo : m_pAdditionsDialog->m_aAllExtensionsVector)
+ {
+ if (m_pAdditionsDialog->m_nCurrentListItemCount == m_pAdditionsDialog->m_nMaxItemCount)
+ break;
+
+ OUString sExtensionName = rInfo.sName;
+ OUString sExtensionDescription = rInfo.sDescription;
+
+ if (!m_pAdditionsDialog->m_xEntrySearch->get_text().isEmpty()
+ && !textSearch.searchForward(sExtensionName)
+ && !textSearch.searchForward(sExtensionDescription))
+ {
+ continue;
+ }
+ else
+ {
+ if (nIteration >= m_pAdditionsDialog->m_nCurrentListItemCount)
+ Append(rInfo);
+ nIteration++;
+ }
+ }
+ CheckInstalledExtensions();
+}
+
+void SearchAndParseThread::CheckInstalledExtensions()
+{
+ const uno::Sequence<uno::Sequence<uno::Reference<deployment::XPackage>>> xAllPackages
+ = m_pAdditionsDialog->getInstalledExtensions();
+
+ if (!xAllPackages.hasElements())
+ return;
+
+ OUString currentExtensionName;
+
+ for (auto& package : xAllPackages)
+ {
+ for (auto& extensionVersion : package)
+ {
+ if (extensionVersion.is())
+ {
+ currentExtensionName = extensionVersion->getName();
+ if (currentExtensionName.isEmpty())
+ continue;
+
+ m_pAdditionsDialog->m_searchOptions.searchString = currentExtensionName;
+ utl::TextSearch textSearch(m_pAdditionsDialog->m_searchOptions);
+
+ for (auto& rInfo : m_pAdditionsDialog->m_aAdditionsItems)
+ {
+ OUString sExtensionDownloadURL = rInfo->m_sDownloadURL;
+
+ if (!textSearch.searchForward(sExtensionDownloadURL))
+ {
+ continue;
+ }
+ else
+ {
+ SolarMutexGuard aGuard;
+ rInfo->m_xButtonInstall->set_sensitive(false);
+ rInfo->m_xButtonInstall->set_label(
+ CuiResId(RID_CUISTR_ADDITIONS_INSTALLEDBUTTON));
+ }
+ }
+ }
+ }
+ }
+}
+
+void SearchAndParseThread::execute()
+{
+ OUString sProgress;
+ if (m_bIsFirstLoading)
+ sProgress = CuiResId(RID_CUISTR_ADDITIONS_LOADING);
+ else
+ sProgress = CuiResId(RID_CUISTR_ADDITIONS_SEARCHING);
+
+ m_pAdditionsDialog->SetProgress(
+ sProgress); // Loading or searching according to being first call or not
+
+ if (m_bIsFirstLoading)
+ {
+ std::string sResponse = ucbGet(m_pAdditionsDialog->m_sURL);
+ parseResponse(sResponse, m_pAdditionsDialog->m_aAllExtensionsVector);
+ std::sort(m_pAdditionsDialog->m_aAllExtensionsVector.begin(),
+ m_pAdditionsDialog->m_aAllExtensionsVector.end(),
+ AdditionsDialog::sortByDownload);
+ Search();
+ }
+ else // Searching
+ {
+ Search();
+ }
+
+ if (!m_bExecute)
+ return;
+
+ SolarMutexGuard aGuard;
+ sProgress.clear();
+ m_pAdditionsDialog->SetProgress(sProgress);
+}
+
+AdditionsDialog::AdditionsDialog(weld::Window* pParent, const OUString& sAdditionsTag)
+ : GenericDialogController(pParent, "cui/ui/additionsdialog.ui", "AdditionsDialog")
+ , m_aSearchDataTimer("AdditionsDialog SearchDataTimer")
+ , m_xEntrySearch(m_xBuilder->weld_entry("entrySearch"))
+ , m_xButtonClose(m_xBuilder->weld_button("buttonClose"))
+ , m_xMenuButtonSettings(m_xBuilder->weld_menu_button("buttonGear"))
+ , m_xContentWindow(m_xBuilder->weld_scrolled_window("contentWindow"))
+ , m_xContentGrid(m_xBuilder->weld_container("contentGrid"))
+ , m_xLabelProgress(m_xBuilder->weld_label("labelProgress"))
+ , m_xGearBtn(m_xBuilder->weld_menu_button("buttonGear"))
+{
+ m_xGearBtn->connect_selected(LINK(this, AdditionsDialog, GearHdl));
+ m_xGearBtn->set_item_active("gear_sort_voting", true);
+
+ m_aSearchDataTimer.SetInvokeHandler(LINK(this, AdditionsDialog, ImplUpdateDataHdl));
+ m_aSearchDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+
+ m_xEntrySearch->connect_changed(LINK(this, AdditionsDialog, SearchUpdateHdl));
+ m_xEntrySearch->connect_focus_out(LINK(this, AdditionsDialog, FocusOut_Impl));
+ m_xButtonClose->connect_clicked(LINK(this, AdditionsDialog, CloseButtonHdl));
+
+ m_sTag = sAdditionsTag;
+ m_nMaxItemCount = PAGE_SIZE; // Dialog initialization item count
+ m_nCurrentListItemCount = 0; // First, there is no item on the list.
+
+ OUString titlePrefix = CuiResId(RID_CUISTR_ADDITIONS_DIALOG_TITLE_PREFIX);
+ if (!m_sTag.isEmpty())
+ { // tdf#142564 localize extension category names
+ OUString sDialogTitle = "";
+ if (sAdditionsTag == "Templates")
+ {
+ sDialogTitle = CuiResId(RID_CUISTR_ADDITIONS_TEMPLATES);
+ }
+ else if (sAdditionsTag == "Dictionary")
+ {
+ sDialogTitle = CuiResId(RID_CUISTR_ADDITIONS_DICTIONARY);
+ }
+ else if (sAdditionsTag == "Gallery")
+ {
+ sDialogTitle = CuiResId(RID_CUISTR_ADDITIONS_GALLERY);
+ }
+ else if (sAdditionsTag == "Icons")
+ {
+ sDialogTitle = CuiResId(RID_CUISTR_ADDITIONS_ICONS);
+ }
+ else if (sAdditionsTag == "Color Palette")
+ {
+ sDialogTitle = CuiResId(RID_CUISTR_ADDITIONS_PALETTES);
+ }
+ this->set_title(sDialogTitle);
+ }
+ else
+ {
+ this->set_title(titlePrefix);
+ m_sTag = "allextensions"; // Means empty parameter
+ }
+
+ OUString sEncodedURLPart = INetURLObject::encode(m_sTag, INetURLObject::PART_PCHAR,
+ INetURLObject::EncodeMechanism::All);
+
+ //FIXME: Temporary URL - v0 is not using actual api
+ OUString rURL = "https://extensions.libreoffice.org/api/v0/" + sEncodedURLPart + ".json";
+ m_sURL = rURL;
+
+ m_xExtensionManager
+ = deployment::ExtensionManager::get(::comphelper::getProcessComponentContext());
+
+ //Initialize search util
+ m_searchOptions.AlgorithmType2 = css::util::SearchAlgorithms2::ABSOLUTE;
+ m_searchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_searchOptions.searchFlag |= (css::util::SearchFlags::REG_NOT_BEGINOFLINE
+ | css::util::SearchFlags::REG_NOT_ENDOFLINE);
+ m_pSearchThread = new SearchAndParseThread(this, true);
+ m_pSearchThread->launch();
+}
+
+AdditionsDialog::~AdditionsDialog()
+{
+ if (m_pSearchThread.is())
+ {
+ m_pSearchThread->StopExecution();
+ // Release the solar mutex, so the thread is not affected by the race
+ // when it's after the m_bExecute check but before taking the solar
+ // mutex.
+ SolarMutexReleaser aReleaser;
+ m_pSearchThread->join();
+ }
+}
+
+uno::Sequence<uno::Sequence<uno::Reference<deployment::XPackage>>>
+AdditionsDialog::getInstalledExtensions()
+{
+ uno::Sequence<uno::Sequence<uno::Reference<deployment::XPackage>>> xAllPackages;
+
+ try
+ {
+ xAllPackages = m_xExtensionManager->getAllExtensions(
+ uno::Reference<task::XAbortChannel>(), uno::Reference<ucb::XCommandEnvironment>());
+ }
+ catch (const deployment::DeploymentException&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ }
+ catch (const ucb::CommandFailedException&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ }
+ catch (const ucb::CommandAbortedException&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ }
+ catch (const lang::IllegalArgumentException& e)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException(e.Message, e.Context, anyEx);
+ }
+ return xAllPackages;
+}
+
+void AdditionsDialog::SetProgress(const OUString& rProgress)
+{
+ if (rProgress.isEmpty())
+ {
+ m_xLabelProgress->hide();
+ m_xButtonClose->set_sensitive(true);
+ }
+ else
+ {
+ SolarMutexGuard aGuard;
+ m_xLabelProgress->show();
+ m_xLabelProgress->set_label(rProgress);
+ m_xDialog->resize_to_request(); //TODO
+ }
+}
+
+void AdditionsDialog::ClearList()
+{
+ // for VCL to be able to destroy bitmaps
+ SolarMutexGuard aGuard;
+
+ for (auto& item : this->m_aAdditionsItems)
+ {
+ item->m_xContainer->hide();
+ }
+ this->m_aAdditionsItems.clear();
+}
+
+void AdditionsDialog::RefreshUI()
+{
+ if (m_pSearchThread.is())
+ m_pSearchThread->StopExecution();
+ ClearList();
+ m_nCurrentListItemCount = 0;
+ m_nMaxItemCount = PAGE_SIZE;
+ m_pSearchThread = new SearchAndParseThread(this, false);
+ m_pSearchThread->launch();
+}
+
+bool AdditionsDialog::sortByRating(const AdditionInfo& a, const AdditionInfo& b)
+{
+ return a.sRating.toDouble() > b.sRating.toDouble();
+}
+
+bool AdditionsDialog::sortByComment(const AdditionInfo& a, const AdditionInfo& b)
+{
+ return a.sCommentNumber.toUInt32() > b.sCommentNumber.toUInt32();
+}
+
+bool AdditionsDialog::sortByDownload(const AdditionInfo& a, const AdditionInfo& b)
+{
+ return a.sDownloadNumber.toUInt32() > b.sDownloadNumber.toUInt32();
+}
+
+AdditionsItem::AdditionsItem(weld::Widget* pParent, AdditionsDialog* pParentDialog,
+ const AdditionInfo& additionInfo)
+ : m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/additionsfragment.ui"))
+ , m_xContainer(m_xBuilder->weld_widget("additionsEntry"))
+ , m_xImageScreenshot(m_xBuilder->weld_image("imageScreenshot"))
+ , m_xButtonInstall(m_xBuilder->weld_button("buttonInstall"))
+ , m_xLinkButtonWebsite(m_xBuilder->weld_link_button("btnWebsite"))
+ , m_xLabelName(m_xBuilder->weld_label("lbName"))
+ , m_xLabelAuthor(m_xBuilder->weld_label("labelAuthor"))
+ , m_xLabelDesc(m_xBuilder->weld_label("labelDesc")) // no change (print description)
+ , m_xLabelDescription(m_xBuilder->weld_label("labelDescription"))
+ , m_xLabelLicense(m_xBuilder->weld_label("lbLicenseText"))
+ , m_xLabelVersion(m_xBuilder->weld_label("lbVersionText"))
+ , m_xLabelComments(m_xBuilder->weld_label("labelComments")) // no change
+ , m_xLinkButtonComments(m_xBuilder->weld_link_button("linkButtonComments"))
+ , m_xImageVoting1(m_xBuilder->weld_image("imageVoting1"))
+ , m_xImageVoting2(m_xBuilder->weld_image("imageVoting2"))
+ , m_xImageVoting3(m_xBuilder->weld_image("imageVoting3"))
+ , m_xImageVoting4(m_xBuilder->weld_image("imageVoting4"))
+ , m_xImageVoting5(m_xBuilder->weld_image("imageVoting5"))
+ , m_xLabelNoVoting(m_xBuilder->weld_label("votingLabel"))
+ , m_xImageDownloadNumber(m_xBuilder->weld_image("imageDownloadNumber"))
+ , m_xLabelDownloadNumber(m_xBuilder->weld_label("labelDownloadNumber"))
+ , m_xButtonShowMore(m_xBuilder->weld_button("buttonShowMore"))
+ , m_pParentDialog(pParentDialog)
+ , m_sDownloadURL("")
+ , m_sExtensionID("")
+{
+ SolarMutexGuard aGuard;
+
+ // AdditionsItem set location
+ m_xContainer->set_grid_left_attach(0);
+ m_xContainer->set_grid_top_attach(pParentDialog->m_aAdditionsItems.size());
+
+ // Set maximum length of the extension title
+ OUString sExtensionName;
+ const sal_Int32 maxExtensionNameLength = 30;
+
+ if (additionInfo.sName.getLength() > maxExtensionNameLength)
+ {
+ std::u16string_view sShortName = additionInfo.sName.subView(0, maxExtensionNameLength - 3);
+ sExtensionName = OUString::Concat(sShortName) + "...";
+ }
+ else
+ {
+ sExtensionName = additionInfo.sName;
+ }
+
+ m_xLabelName->set_label(sExtensionName);
+
+ double aExtensionRating = additionInfo.sRating.toDouble();
+ switch (std::isnan(aExtensionRating) ? 0 : int(std::clamp(aExtensionRating, 0.0, 5.0)))
+ {
+ case 5:
+ m_xImageVoting5->set_from_icon_name("cmd/sc_stars-full.png");
+ [[fallthrough]];
+ case 4:
+ m_xImageVoting4->set_from_icon_name("cmd/sc_stars-full.png");
+ [[fallthrough]];
+ case 3:
+ m_xImageVoting3->set_from_icon_name("cmd/sc_stars-full.png");
+ [[fallthrough]];
+ case 2:
+ m_xImageVoting2->set_from_icon_name("cmd/sc_stars-full.png");
+ [[fallthrough]];
+ case 1:
+ m_xImageVoting1->set_from_icon_name("cmd/sc_stars-full.png");
+ break;
+ }
+
+ m_xLinkButtonWebsite->set_uri(additionInfo.sExtensionURL);
+ m_xLabelDescription->set_label(additionInfo.sIntroduction);
+
+ if (!additionInfo.sAuthorName.equalsIgnoreAsciiCase("null"))
+ m_xLabelAuthor->set_label(additionInfo.sAuthorName);
+
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xLabelLicense->set_label(additionInfo.sLicense);
+ m_xLabelVersion->set_label(">=" + additionInfo.sCompatibleVersion);
+ m_xLinkButtonComments->set_label(additionInfo.sCommentNumber);
+ m_xLinkButtonComments->set_uri(additionInfo.sCommentURL);
+ m_xLabelDownloadNumber->set_label(additionInfo.sDownloadNumber);
+ m_pParentDialog = pParentDialog;
+ m_sDownloadURL = additionInfo.sDownloadURL;
+ m_sExtensionID = additionInfo.sExtensionID;
+
+ m_xButtonShowMore->connect_clicked(LINK(this, AdditionsItem, ShowMoreHdl));
+ m_xButtonInstall->connect_clicked(LINK(this, AdditionsItem, InstallHdl));
+}
+
+bool AdditionsItem::getExtensionFile(OUString& sExtensionFile)
+{
+ uno::Reference<ucb::XSimpleFileAccess3> xFileAccess
+ = ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext());
+
+ // copy the extensions' files to the user's additions folder
+ OUString userFolder = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
+ "/" SAL_CONFIGFILE("bootstrap") "::UserInstallation}";
+ rtl::Bootstrap::expandMacros(userFolder);
+ userFolder += "/user/additions/" + m_sExtensionID + "/";
+
+ OUString aExtensionsFile(INetURLObject(m_sDownloadURL).getName());
+ OUString aExtensionsURL = m_sDownloadURL;
+
+ try
+ {
+ osl::Directory::createPath(userFolder);
+
+ if (!xFileAccess->exists(userFolder + aExtensionsFile))
+ ucbDownload(aExtensionsURL, userFolder, aExtensionsFile);
+ }
+ catch (const uno::Exception&)
+ {
+ return false;
+ }
+ sExtensionFile = userFolder + aExtensionsFile;
+ return true;
+}
+
+IMPL_LINK_NOARG(AdditionsDialog, ImplUpdateDataHdl, Timer*, void) { RefreshUI(); }
+
+IMPL_LINK_NOARG(AdditionsDialog, SearchUpdateHdl, weld::Entry&, void)
+{
+ m_aSearchDataTimer.Start();
+}
+
+IMPL_LINK_NOARG(AdditionsDialog, FocusOut_Impl, weld::Widget&, void)
+{
+ if (m_aSearchDataTimer.IsActive())
+ {
+ m_aSearchDataTimer.Stop();
+ m_aSearchDataTimer.Invoke();
+ }
+}
+
+IMPL_LINK_NOARG(AdditionsDialog, CloseButtonHdl, weld::Button&, void)
+{
+ if (m_pSearchThread.is())
+ m_pSearchThread->StopExecution();
+ this->response(RET_CLOSE);
+}
+
+IMPL_LINK_NOARG(AdditionsItem, ShowMoreHdl, weld::Button&, void)
+{
+ this->m_xButtonShowMore->set_visible(false);
+ m_pParentDialog->m_nMaxItemCount += PAGE_SIZE;
+ if (m_pParentDialog->m_pSearchThread.is())
+ m_pParentDialog->m_pSearchThread->StopExecution();
+ m_pParentDialog->m_pSearchThread = new SearchAndParseThread(m_pParentDialog, false);
+ m_pParentDialog->m_pSearchThread->launch();
+}
+
+IMPL_LINK_NOARG(AdditionsItem, InstallHdl, weld::Button&, void)
+{
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLING));
+ m_xButtonInstall->set_sensitive(false);
+ OUString aExtensionFile;
+ bool bResult = getExtensionFile(aExtensionFile); // info vector json data
+
+ if (!bResult)
+ {
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xButtonInstall->set_sensitive(true);
+
+ SAL_INFO("cui.dialogs", "Couldn't get the extension file.");
+ return;
+ }
+
+ rtl::Reference<TmpRepositoryCommandEnv> pCmdEnv = new TmpRepositoryCommandEnv();
+ uno::Reference<task::XAbortChannel> xAbortChannel;
+ try
+ {
+ m_pParentDialog->m_xExtensionManager->addExtension(
+ aExtensionFile, uno::Sequence<beans::NamedValue>(), "user", xAbortChannel, pCmdEnv);
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLEDBUTTON));
+ }
+ catch (const ucb::CommandFailedException)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xButtonInstall->set_sensitive(true);
+ }
+ catch (const ucb::CommandAbortedException)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xButtonInstall->set_sensitive(true);
+ }
+ catch (const deployment::DeploymentException)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xButtonInstall->set_sensitive(true);
+ }
+ catch (const lang::IllegalArgumentException)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xButtonInstall->set_sensitive(true);
+ }
+ catch (const css::uno::Exception)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "");
+ m_xButtonInstall->set_label(CuiResId(RID_CUISTR_ADDITIONS_INSTALLBUTTON));
+ m_xButtonInstall->set_sensitive(true);
+ }
+}
+
+// TmpRepositoryCommandEnv
+
+TmpRepositoryCommandEnv::TmpRepositoryCommandEnv() {}
+
+TmpRepositoryCommandEnv::~TmpRepositoryCommandEnv() {}
+// XCommandEnvironment
+
+uno::Reference<task::XInteractionHandler> TmpRepositoryCommandEnv::getInteractionHandler()
+{
+ return this;
+}
+
+uno::Reference<ucb::XProgressHandler> TmpRepositoryCommandEnv::getProgressHandler() { return this; }
+
+// XInteractionHandler
+void TmpRepositoryCommandEnv::handle(uno::Reference<task::XInteractionRequest> const& xRequest)
+{
+ OSL_ASSERT(xRequest->getRequest().getValueTypeClass() == uno::TypeClass_EXCEPTION);
+
+ bool approve = true;
+
+ // select:
+ uno::Sequence<Reference<task::XInteractionContinuation>> conts(xRequest->getContinuations());
+ Reference<task::XInteractionContinuation> const* pConts = conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for (sal_Int32 pos = 0; pos < len; ++pos)
+ {
+ if (approve)
+ {
+ uno::Reference<task::XInteractionApprove> xInteractionApprove(pConts[pos],
+ uno::UNO_QUERY);
+ if (xInteractionApprove.is())
+ {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ }
+}
+
+// XProgressHandler
+void TmpRepositoryCommandEnv::push(uno::Any const& /*Status*/) {}
+
+void TmpRepositoryCommandEnv::update(uno::Any const& /*Status */) {}
+
+void TmpRepositoryCommandEnv::pop() {}
+
+IMPL_LINK(AdditionsDialog, GearHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "gear_sort_voting")
+ {
+ std::sort(m_aAllExtensionsVector.begin(), m_aAllExtensionsVector.end(), sortByRating);
+ }
+ else if (rIdent == "gear_sort_comments")
+ {
+ std::sort(m_aAllExtensionsVector.begin(), m_aAllExtensionsVector.end(), sortByComment);
+ }
+ else if (rIdent == "gear_sort_downloads")
+ {
+ std::sort(m_aAllExtensionsVector.begin(), m_aAllExtensionsVector.end(), sortByDownload);
+ }
+ // After the sorting, UI will be refreshed to update extension list.
+ RefreshUI();
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/DiagramDialog.cxx b/cui/source/dialogs/DiagramDialog.cxx
new file mode 100644
index 000000000..c53bafe94
--- /dev/null
+++ b/cui/source/dialogs/DiagramDialog.cxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+* This file is part of the LibreOffice project.
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#include <DiagramDialog.hxx>
+
+#include <comphelper/dispatchcommand.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdundo.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <svx/diagram/datamodel.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
+
+DiagramDialog::DiagramDialog(weld::Window* pWindow, SdrObjGroup& rDiagram)
+ : GenericDialogController(pWindow, "cui/ui/diagramdialog.ui", "DiagramDialog")
+ , m_rDiagram(rDiagram)
+ , m_nUndos(0)
+ , mpBtnOk(m_xBuilder->weld_button("btnOk"))
+ , mpBtnCancel(m_xBuilder->weld_button("btnCancel"))
+ , mpBtnAdd(m_xBuilder->weld_button("btnAdd"))
+ , mpBtnRemove(m_xBuilder->weld_button("btnRemove"))
+ , mpTreeDiagram(m_xBuilder->weld_tree_view("treeDiagram"))
+ , mpTextAdd(m_xBuilder->weld_text_view("textAdd"))
+{
+ mpBtnCancel->connect_clicked(LINK(this, DiagramDialog, OnAddCancel));
+ mpBtnAdd->connect_clicked(LINK(this, DiagramDialog, OnAddClick));
+ mpBtnRemove->connect_clicked(LINK(this, DiagramDialog, OnRemoveClick));
+
+ populateTree(nullptr, OUString());
+
+ // expand all items
+ weld::TreeView* pTreeDiagram = mpTreeDiagram.get();
+ pTreeDiagram->all_foreach([pTreeDiagram](weld::TreeIter& rEntry) {
+ pTreeDiagram->expand_row(rEntry);
+ return false;
+ });
+}
+
+IMPL_LINK_NOARG(DiagramDialog, OnAddCancel, weld::Button&, void)
+{
+ // If the user cancels the dialog, undo all changes done so far. It may
+ // even be feasible to then delete the redo-stack, since it stays
+ // available (?) - but it does no harm either...
+ while (0 != m_nUndos)
+ {
+ comphelper::dispatchCommand(".uno:Undo", {});
+ m_nUndos--;
+ }
+
+ m_xDialog->response(RET_CANCEL);
+}
+
+IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, void)
+{
+ if (!m_rDiagram.isDiagram())
+ return;
+
+ OUString sText = mpTextAdd->get_text();
+ const std::shared_ptr< svx::diagram::IDiagramHelper >& pDiagramHelper(m_rDiagram.getDiagramHelper());
+
+ if (pDiagramHelper && !sText.isEmpty())
+ {
+ SdrModel& rDrawModel(m_rDiagram.getSdrModelFromSdrObject());
+ const bool bUndo(rDrawModel.IsUndoEnabled());
+ svx::diagram::DiagramDataStatePtr aStartState;
+
+ if (bUndo)
+ {
+ // rescue all start state Diagram-defining data
+ aStartState = pDiagramHelper->extractDiagramDataState();
+ }
+
+ OUString sNodeId = pDiagramHelper->addNode(sText);
+
+ if (bUndo)
+ {
+ // create undo action. That will internally secure the
+ // current Diagram-defining data as end state
+ rDrawModel.AddUndo(
+ rDrawModel.GetSdrUndoFactory().CreateUndoDiagramModelData(m_rDiagram, aStartState));
+ m_nUndos++;
+ }
+
+ std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+ mpTreeDiagram->insert(nullptr, -1, &sText, &sNodeId, nullptr, nullptr, false, pEntry.get());
+ mpTreeDiagram->select(*pEntry);
+ comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
+ }
+}
+
+IMPL_LINK_NOARG(DiagramDialog, OnRemoveClick, weld::Button&, void)
+{
+ if (!m_rDiagram.isDiagram())
+ return;
+
+ std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+ const std::shared_ptr< svx::diagram::IDiagramHelper >& pDiagramHelper(m_rDiagram.getDiagramHelper());
+
+ if (pDiagramHelper && mpTreeDiagram->get_selected(pEntry.get()))
+ {
+ SdrModel& rDrawModel(m_rDiagram.getSdrModelFromSdrObject());
+ const bool bUndo(rDrawModel.IsUndoEnabled());
+ svx::diagram::DiagramDataStatePtr aStartState;
+
+ if (bUndo)
+ {
+ // rescue all start state Diagram-defining data
+ aStartState = pDiagramHelper->extractDiagramDataState();
+ }
+
+ if (pDiagramHelper->removeNode(mpTreeDiagram->get_id(*pEntry)))
+ {
+ if (bUndo)
+ {
+ // create undo action. That will internally secure the
+ // current Diagram-defining data as end state
+ rDrawModel.AddUndo(rDrawModel.GetSdrUndoFactory().CreateUndoDiagramModelData(
+ m_rDiagram, aStartState));
+ m_nUndos++;
+ }
+
+ mpTreeDiagram->remove(*pEntry);
+ comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
+ }
+ }
+}
+
+void DiagramDialog::populateTree(const weld::TreeIter* pParent, const OUString& rParentId)
+{
+ if (!m_rDiagram.isDiagram())
+ return;
+
+ const std::shared_ptr< svx::diagram::IDiagramHelper >& pDiagramHelper(m_rDiagram.getDiagramHelper());
+
+ if (!pDiagramHelper)
+ return;
+
+ auto aItems = pDiagramHelper->getChildren(rParentId);
+ for (auto& aItem : aItems)
+ {
+ std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+ mpTreeDiagram->insert(pParent, -1, &aItem.second, &aItem.first, nullptr, nullptr, false,
+ pEntry.get());
+ populateTree(pEntry.get(), aItem.first);
+ }
+}
+
+DiagramDialog::~DiagramDialog() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/FontFeaturesDialog.cxx b/cui/source/dialogs/FontFeaturesDialog.cxx
new file mode 100644
index 000000000..a129191b3
--- /dev/null
+++ b/cui/source/dialogs/FontFeaturesDialog.cxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <FontFeaturesDialog.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <utility>
+#include <vcl/font/FeatureParser.hxx>
+#include <FontFeatures.hxx>
+#include <unordered_set>
+
+using namespace css;
+
+namespace cui
+{
+FontFeaturesDialog::FontFeaturesDialog(weld::Window* pParent, OUString aFontName)
+ : GenericDialogController(pParent, "cui/ui/fontfeaturesdialog.ui", "FontFeaturesDialog")
+ , m_sFontName(std::move(aFontName))
+ , m_xContentWindow(m_xBuilder->weld_scrolled_window("contentWindow"))
+ , m_xContentGrid(m_xBuilder->weld_container("contentGrid"))
+ , m_xPreviewWindow(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWindow))
+{
+ initialize();
+}
+
+FontFeaturesDialog::~FontFeaturesDialog() {}
+
+static sal_Int32 makeEnumComboBox(weld::ComboBox& rNameBox,
+ vcl::font::FeatureDefinition const& rFeatureDefinition,
+ uint32_t nDefault)
+{
+ sal_Int32 nRes = 0;
+ int count = 0;
+ for (vcl::font::FeatureParameter const& rParameter : rFeatureDefinition.getEnumParameters())
+ {
+ rNameBox.append(OUString::number(rParameter.getCode()), rParameter.getDescription());
+ if (rParameter.getCode() == nDefault)
+ nRes = count;
+ ++count;
+ }
+ return nRes;
+}
+
+void FontFeaturesDialog::initialize()
+{
+ ScopedVclPtrInstance<VirtualDevice> aVDev(*Application::GetDefaultDevice(),
+ DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+ std::vector<vcl::font::Feature> rFontFeatures = getFontFeatureList(m_sFontName, *aVDev);
+
+ std::unordered_set<sal_uInt32> aDoneFeatures;
+ std::vector<vcl::font::Feature> rFilteredFontFeatures;
+
+ for (vcl::font::Feature const& rFontFeature : rFontFeatures)
+ {
+ sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
+ if (!aDoneFeatures.insert(nFontFeatureCode).second)
+ continue;
+ rFilteredFontFeatures.push_back(rFontFeature);
+ }
+
+ int nRowHeight = fillGrid(rFilteredFontFeatures);
+
+ m_xContentWindow->set_size_request(
+ -1, std::min(std::max(m_xContentWindow->get_preferred_size().Height(),
+ m_xContentGrid->get_preferred_size().Height()),
+ static_cast<tools::Long>(300L)));
+
+ if (nRowHeight)
+ {
+ // tdf#141333 use row height + the 6 px spacing of contentGrid
+ m_xContentWindow->vadjustment_set_step_increment(nRowHeight + 6);
+ }
+
+ updateFontPreview();
+}
+
+int FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures)
+{
+ int nRowHeight(0);
+
+ vcl::font::FeatureParser aParser(m_sFontName);
+ auto aExistingFeatures = aParser.getFeaturesMap();
+
+ sal_Int32 i = 0;
+ for (vcl::font::Feature const& rFontFeature : rFontFeatures)
+ {
+ sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
+
+ vcl::font::FeatureDefinition aDefinition;
+ if (rFontFeature.m_aDefinition)
+ aDefinition = rFontFeature.m_aDefinition;
+ if (!aDefinition)
+ aDefinition = { nFontFeatureCode, "" };
+
+ m_aFeatureItems.emplace_back(m_xContentGrid.get());
+
+ uint32_t nValue = 0;
+ if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end())
+ nValue = aExistingFeatures.at(nFontFeatureCode);
+ else
+ nValue = aDefinition.getDefault();
+
+ FontFeatureItem& aCurrentItem = m_aFeatureItems.back();
+ aCurrentItem.m_aFeatureCode = nFontFeatureCode;
+ aCurrentItem.m_nDefault = aDefinition.getDefault();
+
+ sal_Int32 nGridPositionX = (i % 2) * 2;
+ sal_Int32 nGridPositionY = i / 2;
+ aCurrentItem.m_xContainer->set_grid_left_attach(nGridPositionX);
+ aCurrentItem.m_xContainer->set_grid_top_attach(nGridPositionY);
+
+ Link<weld::ComboBox&, void> aComboBoxSelectHandler
+ = LINK(this, FontFeaturesDialog, ComboBoxSelectedHdl);
+ Link<weld::Toggleable&, void> aCheckBoxToggleHandler
+ = LINK(this, FontFeaturesDialog, CheckBoxToggledHdl);
+
+ if (aDefinition.getType() == vcl::font::FeatureParameterType::ENUM)
+ {
+ aCurrentItem.m_xText->set_label(aDefinition.getDescription());
+ aCurrentItem.m_xText->show();
+
+ sal_Int32 nInit = makeEnumComboBox(*aCurrentItem.m_xCombo, aDefinition, nValue);
+
+ aCurrentItem.m_xCombo->set_active(nInit);
+ aCurrentItem.m_xCombo->connect_changed(aComboBoxSelectHandler);
+ aCurrentItem.m_xCombo->show();
+ }
+ else
+ {
+ aCurrentItem.m_xCheck->set_active(nValue > 0);
+ aCurrentItem.m_xCheck->set_label(aDefinition.getDescription());
+ aCurrentItem.m_xCheck->connect_toggled(aCheckBoxToggleHandler);
+ aCurrentItem.m_xCheck->show();
+ }
+
+ nRowHeight
+ = std::max<int>(nRowHeight, aCurrentItem.m_xContainer->get_preferred_size().Height());
+
+ i++;
+ }
+
+ return nRowHeight;
+}
+
+void FontFeaturesDialog::updateFontPreview()
+{
+ vcl::Font rPreviewFont = m_aPreviewWindow.GetFont();
+ vcl::Font rPreviewFontCJK = m_aPreviewWindow.GetCJKFont();
+ vcl::Font rPreviewFontCTL = m_aPreviewWindow.GetCTLFont();
+
+ OUString sNewFontName = createFontNameWithFeatures();
+
+ rPreviewFont.SetFamilyName(sNewFontName);
+ rPreviewFontCJK.SetFamilyName(sNewFontName);
+ rPreviewFontCTL.SetFamilyName(sNewFontName);
+
+ m_aPreviewWindow.SetFont(rPreviewFont, rPreviewFontCJK, rPreviewFontCTL);
+}
+
+IMPL_LINK_NOARG(FontFeaturesDialog, CheckBoxToggledHdl, weld::Toggleable&, void)
+{
+ updateFontPreview();
+}
+
+IMPL_LINK_NOARG(FontFeaturesDialog, ComboBoxSelectedHdl, weld::ComboBox&, void)
+{
+ updateFontPreview();
+}
+
+OUString FontFeaturesDialog::createFontNameWithFeatures()
+{
+ OUString sResultFontName;
+ OUStringBuffer sNameSuffix;
+ bool bFirst = true;
+
+ for (const FontFeatureItem& rItem : m_aFeatureItems)
+ {
+ if (rItem.m_xCheck->get_visible())
+ {
+ if (sal_uInt32(rItem.m_xCheck->get_active()) != rItem.m_nDefault)
+ {
+ if (!bFirst)
+ sNameSuffix.append(vcl::font::FeatureSeparator);
+ else
+ bFirst = false;
+
+ sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
+ if (!rItem.m_xCheck->get_active())
+ sNameSuffix.append("=0");
+ }
+ }
+ else if (rItem.m_xCombo->get_visible() && rItem.m_xText->get_visible())
+ {
+ sal_Int32 nSelection = rItem.m_xCombo->get_active_id().toInt32();
+ if (nSelection != int(rItem.m_nDefault))
+ {
+ if (!bFirst)
+ sNameSuffix.append(vcl::font::FeatureSeparator);
+ else
+ bFirst = false;
+
+ sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
+ sNameSuffix.append("=");
+ sNameSuffix.append(OUString::number(nSelection));
+ }
+ }
+ }
+ sResultFontName = vcl::font::trimFontNameFeatures(m_sFontName);
+ if (!sNameSuffix.isEmpty())
+ sResultFontName
+ += OUStringChar(vcl::font::FeaturePrefix) + sNameSuffix.makeStringAndClear();
+ return sResultFontName;
+}
+
+short FontFeaturesDialog::run()
+{
+ short nResult = GenericDialogController::run();
+ if (nResult == RET_OK)
+ {
+ m_sResultFontName = createFontNameWithFeatures();
+ }
+ return nResult;
+}
+
+} // end svx namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/GraphicTestsDialog.cxx b/cui/source/dialogs/GraphicTestsDialog.cxx
new file mode 100644
index 000000000..ad0c25aab
--- /dev/null
+++ b/cui/source/dialogs/GraphicTestsDialog.cxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <comphelper/backupfilehelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/DirectoryHelper.hxx>
+#include <osl/file.hxx>
+#include <svx/FileExportedDialog.hxx>
+#include <unotools/ZipPackageHelper.hxx>
+#include <GraphicsTestsDialog.hxx>
+#include <vcl/test/GraphicsRenderTests.hxx>
+#include <svl/svlresid.hxx>
+#include <svl/svl.hrc>
+#include <vcl/svapp.hxx>
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <ImageViewerDialog.hxx>
+
+GraphicTestEntry::GraphicTestEntry(weld::Container* pParent, weld::Dialog* pDialog,
+ OUString aTestName, OUString aTestStatus, Bitmap aTestBitmap)
+ : m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/graphictestentry.ui"))
+ , m_xContainer(m_xBuilder->weld_container("gptestbox"))
+ , m_xTestLabel(m_xBuilder->weld_label("gptestlabel"))
+ , m_xTestButton(m_xBuilder->weld_button("gptestbutton"))
+ , m_xResultBitmap(aTestBitmap)
+{
+ m_xParentDialog = pDialog;
+ m_xTestLabel->set_label(aTestName);
+ m_xTestButton->set_label(aTestStatus);
+ m_xTestButton->set_tooltip_text(aTestName);
+ m_xTestButton->set_background(
+ aTestStatus == SvlResId(GRTSTR_PASSED)
+ ? COL_LIGHTGREEN
+ : aTestStatus == SvlResId(GRTSTR_QUIRKY)
+ ? COL_YELLOW
+ : aTestStatus == SvlResId(GRTSTR_FAILED) ? COL_LIGHTRED : COL_LIGHTGRAY);
+ m_xTestButton->connect_clicked(LINK(this, GraphicTestEntry, HandleResultViewRequest));
+ m_xContainer->show();
+}
+
+IMPL_LINK(GraphicTestEntry, HandleResultViewRequest, weld::Button&, rButton, void)
+{
+ if (rButton.get_label() == SvlResId(GRTSTR_SKIPPED))
+ {
+ return;
+ }
+ ImageViewerDialog m_ImgVwDialog(m_xParentDialog, BitmapEx(m_xResultBitmap),
+ rButton.get_tooltip_text());
+ m_ImgVwDialog.run();
+}
+
+GraphicsTestsDialog::GraphicsTestsDialog(weld::Container* pParent)
+ : GenericDialogController(pParent, "cui/ui/graphictestdlg.ui", "GraphicTestsDialog")
+ , m_xResultLog(m_xBuilder->weld_text_view("gptest_txtVW"))
+ , m_xDownloadResults(m_xBuilder->weld_button("gptest_downld"))
+ , m_xContainerBox(m_xBuilder->weld_box("gptest_box"))
+{
+ OUString userProfile = comphelper::BackupFileHelper::getUserProfileURL();
+ m_xZipFileUrl = userProfile + "/GraphicTestResults.zip";
+ m_xCreateFolderUrl = userProfile + "/GraphicTestResults";
+ osl::Directory::create(m_xCreateFolderUrl);
+ m_xDownloadResults->connect_clicked(LINK(this, GraphicsTestsDialog, HandleDownloadRequest));
+}
+
+short GraphicsTestsDialog::run()
+{
+ GraphicsRenderTests aTestObject;
+ aTestObject.run(true);
+ OUString aResultLog
+ = aTestObject.getResultString(true) + "\n" + CuiResId(RID_CUISTR_CLICK_RESULT);
+ m_xResultLog->set_text(aResultLog);
+ sal_Int32 nTestNumber = 0;
+ for (VclTestResult& test : aTestObject.getTestResults())
+ {
+ auto xGpTest = std::make_unique<GraphicTestEntry>(m_xContainerBox.get(), m_xDialog.get(),
+ test.getTestName(), test.getStatus(true),
+ test.getBitmap());
+ m_xContainerBox->reorder_child(xGpTest->get_widget(), nTestNumber++);
+ m_xGraphicTestEntries.push_back(std::move(xGpTest));
+ }
+ return GenericDialogController::run();
+}
+
+IMPL_LINK_NOARG(GraphicsTestsDialog, HandleDownloadRequest, weld::Button&, void)
+{
+ osl::File::remove(m_xZipFileUrl); // Remove the previous export
+ try
+ {
+ utl::ZipPackageHelper aZipHelper(comphelper::getProcessComponentContext(), m_xZipFileUrl);
+ aZipHelper.addFolderWithContent(aZipHelper.getRootFolder(), m_xCreateFolderUrl);
+ aZipHelper.savePackage();
+ }
+ catch (const std::exception&)
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(
+ Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning,
+ VclButtonsType::Ok, CuiResId(RID_CUISTR_ZIPFAIL)));
+ xBox->run();
+ return;
+ }
+ FileExportedDialog aDialog(m_xDialog.get(), CuiResId(RID_CUISTR_SAVED));
+ aDialog.run();
+}
+
+GraphicsTestsDialog::~GraphicsTestsDialog()
+{
+ comphelper::DirectoryHelper::deleteDirRecursively(m_xCreateFolderUrl);
+}
diff --git a/cui/source/dialogs/ImageViewerDialog.cxx b/cui/source/dialogs/ImageViewerDialog.cxx
new file mode 100644
index 000000000..b245c8c08
--- /dev/null
+++ b/cui/source/dialogs/ImageViewerDialog.cxx
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/virdev.hxx>
+#include <ImageViewerDialog.hxx>
+
+ImageViewerDialog::ImageViewerDialog(weld::Dialog* pParent, BitmapEx aBitmap, OUString atitle)
+ : GenericDialogController(pParent, "cui/ui/imageviewer.ui", "ImageViewerDialog")
+ , m_xDisplayImage(m_xBuilder->weld_image("ImgVW_mainImage"))
+{
+ m_xDialog->set_title(atitle);
+ aBitmap.Scale(Size(300, 300), BmpScaleFlag::Fast);
+ ScopedVclPtr<VirtualDevice> m_pVirDev = m_xDisplayImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aBitmap.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aBitmap);
+ m_xDisplayImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+}
diff --git a/cui/source/dialogs/QrCodeGenDialog.cxx b/cui/source/dialogs/QrCodeGenDialog.cxx
new file mode 100644
index 000000000..e028d4d10
--- /dev/null
+++ b/cui/source/dialogs/QrCodeGenDialog.cxx
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <QrCodeGenDialog.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <tools/stream.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <unotools/streamwrap.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+
+#if ENABLE_ZXING
+#include <rtl/strbuf.hxx>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#endif
+
+#include <BarcodeFormat.h>
+#include <BitArray.h>
+#include <BitMatrix.h>
+#include <MultiFormatWriter.h>
+#include <TextUtfEncoding.h>
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+#endif // ENABLE_ZXING
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/drawing/BarCode.hpp>
+#include <com/sun/star/drawing/BarCodeErrorCorrection.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::container;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::sheet;
+using namespace css::text;
+using namespace css::drawing;
+using namespace css::graphic;
+
+namespace
+{
+#if ENABLE_ZXING
+// Implementation adapted from the answer: https://stackoverflow.com/questions/10789059/create-qr-code-in-vector-image/60638350#60638350
+OString ConvertToSVGFormat(const ZXing::BitMatrix& bitmatrix)
+{
+ OStringBuffer sb;
+ const int width = bitmatrix.width();
+ const int height = bitmatrix.height();
+ ZXing::BitArray row(width);
+ sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 "
+ + OString::number(width) + " " + OString::number(height)
+ + "\" stroke=\"none\">\n"
+ "<path d=\"");
+ for (int i = 0; i < height; ++i)
+ {
+ bitmatrix.getRow(i, row);
+ for (int j = 0; j < width; ++j)
+ {
+ if (row.get(j))
+ {
+ sb.append("M" + OString::number(j) + "," + OString::number(i) + "h1v1h-1z");
+ }
+ }
+ }
+ sb.append("\"/>\n</svg>");
+ return sb.toString();
+}
+
+std::string GetBarCodeType(int type)
+{
+ switch (type)
+ {
+ case 1:
+ return "Code128";
+ default:
+ return "QRCode";
+ }
+}
+
+OString GenerateQRCode(std::u16string_view aQRText, tools::Long aQRECC, int aQRBorder, int aQRType)
+{
+ // Associated ZXing error correction levels (0-8) to our constants arbitrarily.
+ int bqrEcc = 1;
+
+ switch (aQRECC)
+ {
+ case css::drawing::BarCodeErrorCorrection::LOW:
+ {
+ bqrEcc = 1;
+ break;
+ }
+ case css::drawing::BarCodeErrorCorrection::MEDIUM:
+ {
+ bqrEcc = 3;
+ break;
+ }
+ case css::drawing::BarCodeErrorCorrection::QUARTILE:
+ {
+ bqrEcc = 5;
+ break;
+ }
+ case css::drawing::BarCodeErrorCorrection::HIGH:
+ {
+ bqrEcc = 7;
+ break;
+ }
+ }
+
+ OString o = OUStringToOString(aQRText, RTL_TEXTENCODING_UTF8);
+ std::string QRText(o.getStr(), o.getLength());
+ ZXing::BarcodeFormat format = ZXing::BarcodeFormatFromString(GetBarCodeType(aQRType));
+ auto writer = ZXing::MultiFormatWriter(format).setMargin(aQRBorder).setEccLevel(bqrEcc);
+ writer.setEncoding(ZXing::CharacterSet::UTF8);
+ ZXing::BitMatrix bitmatrix = writer.encode(ZXing::TextUtfEncoding::FromUtf8(QRText), 0, 0);
+ return ConvertToSVGFormat(bitmatrix);
+}
+#endif
+
+} // anonymous namespace
+
+QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference<XModel> xModel,
+ bool bEditExisting)
+ : GenericDialogController(pParent, "cui/ui/qrcodegen.ui", "QrCodeGenDialog")
+ , m_xModel(std::move(xModel))
+ , m_xEdittext(m_xBuilder->weld_text_view("edit_text"))
+ , m_xECC{ m_xBuilder->weld_radio_button("button_low"),
+ m_xBuilder->weld_radio_button("button_medium"),
+ m_xBuilder->weld_radio_button("button_quartile"),
+ m_xBuilder->weld_radio_button("button_high") }
+ , m_xSpinBorder(m_xBuilder->weld_spin_button("edit_margin"))
+ , m_xComboType(m_xBuilder->weld_combo_box("choose_type"))
+#if ENABLE_ZXING
+ , mpParent(pParent)
+#endif
+{
+ m_xEdittext->set_size_request(m_xEdittext->get_approximate_digit_width() * 28,
+ m_xEdittext->get_height_rows(6));
+ if (!bEditExisting)
+ {
+ OUString sSelection;
+ // TODO: This only works in Writer doc. Should also work in shapes
+ Reference<XIndexAccess> xSelections(m_xModel->getCurrentSelection(), UNO_QUERY);
+ if (xSelections.is())
+ {
+ Reference<XTextRange> xSelection(xSelections->getByIndex(0), UNO_QUERY);
+ if (xSelection.is())
+ sSelection = xSelection->getString();
+ }
+ if (!sSelection.isEmpty())
+ m_xEdittext->set_text(sSelection);
+ m_xEdittext->select_region(0, -1);
+ return;
+ }
+
+ Reference<container::XIndexAccess> xIndexAccess(m_xModel->getCurrentSelection(),
+ UNO_QUERY_THROW);
+ Reference<XPropertySet> xProps(xIndexAccess->getByIndex(0), UNO_QUERY_THROW);
+
+ // Read properties from selected QR Code
+ css::drawing::BarCode aBarCode;
+ xProps->getPropertyValue("BarCodeProperties") >>= aBarCode;
+
+ m_xEdittext->set_text(aBarCode.Payload);
+
+ //Get Error Correction Constant from selected QR Code
+ GetErrorCorrection(aBarCode.ErrorCorrection);
+
+ m_xSpinBorder->set_value(aBarCode.Border);
+
+ m_xComboType->set_active(aBarCode.Type);
+
+ // Mark this as existing shape
+ m_xExistingShapeProperties = xProps;
+}
+
+short QrCodeGenDialog::run()
+{
+#if ENABLE_ZXING
+ short nRet;
+ while (true)
+ {
+ nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ {
+ try
+ {
+ Apply();
+ break;
+ }
+ catch (const std::exception&)
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
+ mpParent, VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_QRCODEDATALONG)));
+ xBox->run();
+ }
+ }
+ else
+ break;
+ }
+ return nRet;
+#else
+ return RET_CANCEL;
+#endif
+}
+
+void QrCodeGenDialog::Apply()
+{
+#if ENABLE_ZXING
+ css::drawing::BarCode aBarCode;
+ aBarCode.Payload = m_xEdittext->get_text();
+ aBarCode.Type = m_xComboType->get_active();
+
+ bool bLowECCActive(m_xECC[0]->get_active());
+ bool bMediumECCActive(m_xECC[1]->get_active());
+ bool bQuartileECCActive(m_xECC[2]->get_active());
+
+ if (bLowECCActive)
+ {
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::LOW;
+ }
+ else if (bMediumECCActive)
+ {
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::MEDIUM;
+ }
+ else if (bQuartileECCActive)
+ {
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::QUARTILE;
+ }
+ else
+ {
+ aBarCode.ErrorCorrection = css::drawing::BarCodeErrorCorrection::HIGH;
+ }
+
+ aBarCode.Border = m_xSpinBorder->get_value();
+
+ // Read svg and replace placeholder texts
+ OString aSvgImage = GenerateQRCode(aBarCode.Payload, aBarCode.ErrorCorrection, aBarCode.Border,
+ aBarCode.Type);
+
+ // Insert/Update graphic
+ SvMemoryStream aSvgStream(4096, 4096);
+ aSvgStream.WriteOString(aSvgImage);
+ Reference<XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(aSvgStream));
+ Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
+ Reference<XGraphicProvider> xProvider = css::graphic::GraphicProvider::create(xContext);
+
+ Sequence<PropertyValue> aMediaProperties{ comphelper::makePropertyValue("InputStream",
+ xInputStream) };
+ Reference<XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties));
+
+ bool bIsExistingQRCode = m_xExistingShapeProperties.is();
+ Reference<XPropertySet> xShapeProps;
+ if (bIsExistingQRCode)
+ xShapeProps = m_xExistingShapeProperties;
+ else
+ xShapeProps.set(Reference<lang::XMultiServiceFactory>(m_xModel, UNO_QUERY_THROW)
+ ->createInstance("com.sun.star.drawing.GraphicObjectShape"),
+ UNO_QUERY);
+
+ xShapeProps->setPropertyValue("Graphic", Any(xGraphic));
+
+ // Set QRCode properties
+ xShapeProps->setPropertyValue("BarCodeProperties", Any(aBarCode));
+
+ if (bIsExistingQRCode)
+ return;
+
+ // Default size
+ Reference<XShape> xShape(xShapeProps, UNO_QUERY);
+ awt::Size aShapeSize;
+ aShapeSize.Height = 4000;
+ aShapeSize.Width = 4000;
+ xShape->setSize(aShapeSize);
+
+ // Default anchoring
+ xShapeProps->setPropertyValue("AnchorType", Any(TextContentAnchorType_AT_PARAGRAPH));
+
+ const Reference<XServiceInfo> xServiceInfo(m_xModel, UNO_QUERY_THROW);
+
+ // Writer
+ if (xServiceInfo->supportsService("com.sun.star.text.TextDocument"))
+ {
+ Reference<XTextContent> xTextContent(xShape, UNO_QUERY_THROW);
+ Reference<XTextViewCursorSupplier> xViewCursorSupplier(m_xModel->getCurrentController(),
+ UNO_QUERY_THROW);
+ Reference<XTextViewCursor> xCursor = xViewCursorSupplier->getViewCursor();
+ // use cursor's XText - it might be in table cell, frame, ...
+ Reference<XText> const xText(xCursor->getText());
+ assert(xText.is());
+ xText->insertTextContent(xCursor, xTextContent, true);
+ return;
+ }
+
+ // Calc
+ else if (xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
+ {
+ Reference<XPropertySet> xSheetCell(m_xModel->getCurrentSelection(), UNO_QUERY_THROW);
+ awt::Point aCellPosition;
+ xSheetCell->getPropertyValue("Position") >>= aCellPosition;
+ xShape->setPosition(aCellPosition);
+
+ Reference<XSpreadsheetView> xView(m_xModel->getCurrentController(), UNO_QUERY_THROW);
+ Reference<XSpreadsheet> xSheet(xView->getActiveSheet(), UNO_SET_THROW);
+ Reference<XDrawPageSupplier> xDrawPageSupplier(xSheet, UNO_QUERY_THROW);
+ Reference<XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage(), UNO_SET_THROW);
+ Reference<XShapes> xShapes(xDrawPage, UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+ return;
+ }
+
+ //Impress and Draw
+ else if (xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument")
+ || xServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument"))
+ {
+ Reference<XDrawView> xView(m_xModel->getCurrentController(), UNO_QUERY_THROW);
+ Reference<XDrawPage> xPage(xView->getCurrentPage(), UNO_SET_THROW);
+ Reference<XShapes> xShapes(xPage, UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+ return;
+ }
+
+ else
+ {
+ //Not implemented for math,base and other apps.
+ throw uno::RuntimeException("Not implemented");
+ }
+#endif
+}
+
+void QrCodeGenDialog::GetErrorCorrection(tools::Long ErrorCorrection)
+{
+ switch (ErrorCorrection)
+ {
+ case css::drawing::BarCodeErrorCorrection::LOW:
+ {
+ m_xECC[0]->set_active(true);
+ break;
+ }
+ case css::drawing::BarCodeErrorCorrection::MEDIUM:
+ {
+ m_xECC[1]->set_active(true);
+ break;
+ }
+ case css::drawing::BarCodeErrorCorrection::QUARTILE:
+ {
+ m_xECC[2]->set_active(true);
+ break;
+ }
+ case css::drawing::BarCodeErrorCorrection::HIGH:
+ {
+ m_xECC[3]->set_active(true);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SignSignatureLineDialog.cxx b/cui/source/dialogs/SignSignatureLineDialog.cxx
new file mode 100644
index 000000000..94306764b
--- /dev/null
+++ b/cui/source/dialogs/SignSignatureLineDialog.cxx
@@ -0,0 +1,258 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SignSignatureLineDialog.hxx>
+
+#include <sal/log.hxx>
+#include <sal/types.h>
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#include <comphelper/graphicmimetype.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/xoutbmp.hxx>
+#include <utility>
+#include <vcl/graph.hxx>
+#include <vcl/weld.hxx>
+#include <svx/signaturelinehelper.hxx>
+#include <tools/urlobj.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+
+using namespace comphelper;
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::frame;
+using namespace css::text;
+using namespace css::graphic;
+using namespace css::security;
+using namespace css::ui::dialogs;
+
+SignSignatureLineDialog::SignSignatureLineDialog(weld::Widget* pParent, Reference<XModel> xModel)
+ : SignatureLineDialogBase(pParent, std::move(xModel), "cui/ui/signsignatureline.ui",
+ "SignSignatureLineDialog")
+ , m_xEditName(m_xBuilder->weld_entry("edit_name"))
+ , m_xEditComment(m_xBuilder->weld_text_view("edit_comment"))
+ , m_xBtnLoadImage(m_xBuilder->weld_button("btn_load_image"))
+ , m_xBtnClearImage(m_xBuilder->weld_button("btn_clear_image"))
+ , m_xBtnChooseCertificate(m_xBuilder->weld_button("btn_select_certificate"))
+ , m_xBtnSign(m_xBuilder->weld_button("ok"))
+ , m_xLabelHint(m_xBuilder->weld_label("label_hint"))
+ , m_xLabelHintText(m_xBuilder->weld_label("label_hint_text"))
+ , m_xLabelAddComment(m_xBuilder->weld_label("label_add_comment"))
+ , m_bShowSignDate(false)
+{
+ Reference<container::XIndexAccess> xIndexAccess(m_xModel->getCurrentSelection(),
+ UNO_QUERY_THROW);
+ m_xShapeProperties.set(xIndexAccess->getByIndex(0), UNO_QUERY_THROW);
+
+ bool bIsSignatureLine(false);
+ m_xShapeProperties->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine;
+ if (!bIsSignatureLine)
+ {
+ SAL_WARN("cui.dialogs", "No signature line selected!");
+ return;
+ }
+
+ m_xBtnLoadImage->connect_clicked(LINK(this, SignSignatureLineDialog, loadImage));
+ m_xBtnClearImage->connect_clicked(LINK(this, SignSignatureLineDialog, clearImage));
+ m_xBtnChooseCertificate->connect_clicked(
+ LINK(this, SignSignatureLineDialog, chooseCertificate));
+ m_xEditName->connect_changed(LINK(this, SignSignatureLineDialog, entryChanged));
+
+ // Read properties from selected signature line
+ m_xShapeProperties->getPropertyValue("SignatureLineId") >>= m_aSignatureLineId;
+ m_xShapeProperties->getPropertyValue("SignatureLineSuggestedSignerName")
+ >>= m_aSuggestedSignerName;
+ m_xShapeProperties->getPropertyValue("SignatureLineSuggestedSignerTitle")
+ >>= m_aSuggestedSignerTitle;
+ OUString aSigningInstructions;
+ m_xShapeProperties->getPropertyValue("SignatureLineSigningInstructions")
+ >>= aSigningInstructions;
+ m_xShapeProperties->getPropertyValue("SignatureLineShowSignDate") >>= m_bShowSignDate;
+ bool bCanAddComment(false);
+ m_xShapeProperties->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment;
+
+ if (aSigningInstructions.isEmpty())
+ {
+ m_xLabelHint->hide();
+ m_xLabelHintText->hide();
+ }
+ else
+ {
+ m_xLabelHintText->set_label(aSigningInstructions);
+ }
+
+ if (bCanAddComment)
+ {
+ m_xEditComment->set_size_request(m_xEditComment->get_approximate_digit_width() * 48,
+ m_xEditComment->get_text_height() * 5);
+ }
+ else
+ {
+ m_xLabelAddComment->hide();
+ m_xEditComment->hide();
+ m_xEditComment->set_size_request(0, 0);
+ }
+
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, loadImage, weld::Button&, void)
+{
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ sfx2::FileDialogHelper aHelper(TemplateDescription::FILEOPEN_PREVIEW, FileDialogFlags::NONE,
+ m_xDialog.get());
+ aHelper.SetContext(sfx2::FileDialogHelper::SignatureLine);
+ Reference<XFilePicker3> xFilePicker = aHelper.GetFilePicker();
+ if (!xFilePicker->execute())
+ return;
+
+ Sequence<OUString> aSelectedFiles = xFilePicker->getSelectedFiles();
+ if (!aSelectedFiles.hasElements())
+ return;
+
+ Reference<XGraphicProvider> xProvider = GraphicProvider::create(xContext);
+ Sequence<PropertyValue> aMediaProperties{ comphelper::makePropertyValue("URL",
+ aSelectedFiles[0]) };
+ m_xSignatureImage = xProvider->queryGraphic(aMediaProperties);
+ m_sOriginalImageBtnLabel = m_xBtnLoadImage->get_label();
+
+ INetURLObject aObj(aSelectedFiles[0]);
+ m_xBtnLoadImage->set_label(aObj.GetLastName());
+
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, clearImage, weld::Button&, void)
+{
+ m_xSignatureImage.set(nullptr);
+ m_xBtnLoadImage->set_label(m_sOriginalImageBtnLabel);
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, chooseCertificate, weld::Button&, void)
+{
+ // Document needs to be saved before selecting a certificate
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if (!pShell || !pShell->PrepareForSigning(m_xDialog.get()))
+ return;
+
+ Reference<XCertificate> xSignCertificate
+ = svx::SignatureLineHelper::getSignatureCertificate(pShell, m_xDialog.get());
+
+ if (xSignCertificate.is())
+ {
+ m_xSelectedCertifate = xSignCertificate;
+ m_xBtnChooseCertificate->set_label(
+ svx::SignatureLineHelper::getSignerName(xSignCertificate));
+ }
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, entryChanged, weld::Entry&, void) { ValidateFields(); }
+
+void SignSignatureLineDialog::ValidateFields()
+{
+ bool bEnableSignBtn = m_xSelectedCertifate.is()
+ && (!m_xEditName->get_text().isEmpty() || m_xSignatureImage.is());
+ m_xBtnSign->set_sensitive(bEnableSignBtn);
+
+ m_xEditName->set_sensitive(!m_xSignatureImage.is());
+ m_xBtnLoadImage->set_sensitive(m_xEditName->get_text().isEmpty());
+ m_xBtnClearImage->set_sensitive(m_xSignatureImage.is());
+}
+
+void SignSignatureLineDialog::Apply()
+{
+ if (!m_xSelectedCertifate.is())
+ {
+ SAL_WARN("cui.dialogs", "No certificate selected!");
+ return;
+ }
+
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if (!pShell)
+ {
+ SAL_WARN("cui.dialogs", "No SfxObjectShell!");
+ return;
+ }
+
+ Reference<XGraphic> xValidGraphic = getSignedGraphic(true);
+ Reference<XGraphic> xInvalidGraphic = getSignedGraphic(false);
+ pShell->SignSignatureLine(m_xDialog.get(), m_aSignatureLineId, m_xSelectedCertifate,
+ xValidGraphic, xInvalidGraphic, m_xEditComment->get_text());
+}
+
+css::uno::Reference<css::graphic::XGraphic> SignSignatureLineDialog::getSignedGraphic(bool bValid)
+{
+ // Read svg and replace placeholder texts
+ OUString aSvgImage(svx::SignatureLineHelper::getSignatureImage());
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", getCDataString(m_aSuggestedSignerName));
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_TITLE]", getCDataString(m_aSuggestedSignerTitle));
+
+ OUString aIssuerLine
+ = CuiResId(RID_CUISTR_SIGNATURELINE_SIGNED_BY)
+ .replaceFirst("%1", svx::SignatureLineHelper::getSignerName(m_xSelectedCertifate));
+ aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", getCDataString(aIssuerLine));
+ if (bValid)
+ aSvgImage = aSvgImage.replaceAll("[INVALID_SIGNATURE]", "");
+
+ OUString aDate;
+ if (m_bShowSignDate && bValid)
+ {
+ aDate = svx::SignatureLineHelper::getLocalizedDate();
+ }
+ aSvgImage = aSvgImage.replaceAll("[DATE]", aDate);
+
+ // Custom signature image
+ if (m_xSignatureImage.is())
+ {
+ OUString aGraphicInBase64;
+ Graphic aGraphic(m_xSignatureImage);
+ if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64, false))
+ SAL_WARN("cui.dialogs", "Could not convert graphic to base64");
+
+ OUString aImagePart = "<image y=\"825\" x=\"1300\" "
+ "xlink:href=\"data:[MIMETYPE];base64,[BASE64_IMG]>\" "
+ "preserveAspectRatio=\"xMidYMid\" height=\"1520\" "
+ "width=\"7600\" />";
+ aImagePart = aImagePart.replaceAll(
+ "[MIMETYPE]", GraphicMimeTypeHelper::GetMimeTypeForXGraphic(m_xSignatureImage));
+ aImagePart = aImagePart.replaceAll("[BASE64_IMG]", aGraphicInBase64);
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE_IMAGE]", aImagePart);
+
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", "");
+ }
+ else
+ {
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE_IMAGE]", "");
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", getCDataString(m_xEditName->get_text()));
+ }
+
+ // Create graphic
+ return svx::SignatureLineHelper::importSVG(aSvgImage);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SignatureLineDialog.cxx b/cui/source/dialogs/SignatureLineDialog.cxx
new file mode 100644
index 000000000..224dcdecd
--- /dev/null
+++ b/cui/source/dialogs/SignatureLineDialog.cxx
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SignatureLineDialog.hxx>
+
+#include <comphelper/xmltools.hxx>
+#include <utility>
+#include <vcl/weld.hxx>
+#include <svx/signaturelinehelper.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::container;
+using namespace css::frame;
+using namespace css::lang;
+using namespace css::frame;
+using namespace css::sheet;
+using namespace css::text;
+using namespace css::drawing;
+using namespace css::graphic;
+
+SignatureLineDialog::SignatureLineDialog(weld::Widget* pParent, Reference<XModel> xModel,
+ bool bEditExisting)
+ : SignatureLineDialogBase(pParent, std::move(xModel), "cui/ui/signatureline.ui",
+ "SignatureLineDialog")
+ , m_xEditName(m_xBuilder->weld_entry("edit_name"))
+ , m_xEditTitle(m_xBuilder->weld_entry("edit_title"))
+ , m_xEditEmail(m_xBuilder->weld_entry("edit_email"))
+ , m_xEditInstructions(m_xBuilder->weld_text_view("edit_instructions"))
+ , m_xCheckboxCanAddComments(m_xBuilder->weld_check_button("checkbox_can_add_comments"))
+ , m_xCheckboxShowSignDate(m_xBuilder->weld_check_button("checkbox_show_sign_date"))
+{
+ m_xEditInstructions->set_size_request(m_xEditInstructions->get_approximate_digit_width() * 48,
+ m_xEditInstructions->get_text_height() * 5);
+
+ // No signature line selected - start with empty dialog and set some default values
+ if (!bEditExisting)
+ {
+ m_xCheckboxCanAddComments->set_active(true);
+ m_xCheckboxShowSignDate->set_active(true);
+ return;
+ }
+
+ Reference<container::XIndexAccess> xIndexAccess(m_xModel->getCurrentSelection(),
+ UNO_QUERY_THROW);
+ Reference<XPropertySet> xProps(xIndexAccess->getByIndex(0), UNO_QUERY_THROW);
+
+ // Read properties from selected signature line
+ xProps->getPropertyValue("SignatureLineId") >>= m_aSignatureLineId;
+ OUString aSuggestedSignerName;
+ xProps->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName;
+ m_xEditName->set_text(aSuggestedSignerName);
+ OUString aSuggestedSignerTitle;
+ xProps->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle;
+ m_xEditTitle->set_text(aSuggestedSignerTitle);
+ OUString aSuggestedSignerEmail;
+ xProps->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail;
+ m_xEditEmail->set_text(aSuggestedSignerEmail);
+ OUString aSigningInstructions;
+ xProps->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions;
+ m_xEditInstructions->set_text(aSigningInstructions);
+ bool bCanAddComments = false;
+ xProps->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComments;
+ m_xCheckboxCanAddComments->set_active(bCanAddComments);
+ bool bShowSignDate = false;
+ xProps->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate;
+ m_xCheckboxShowSignDate->set_active(bShowSignDate);
+
+ // Mark this as existing shape
+ m_xExistingShapeProperties = xProps;
+}
+
+void SignatureLineDialog::Apply()
+{
+ if (m_aSignatureLineId.isEmpty())
+ m_aSignatureLineId
+ = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_ASCII_US);
+ OUString aSignerName(m_xEditName->get_text());
+ OUString aSignerTitle(m_xEditTitle->get_text());
+ OUString aSignerEmail(m_xEditEmail->get_text());
+ OUString aSigningInstructions(m_xEditInstructions->get_text());
+ bool bCanAddComments(m_xCheckboxCanAddComments->get_active());
+ bool bShowSignDate(m_xCheckboxShowSignDate->get_active());
+
+ // Read svg and replace placeholder texts
+ OUString aSvgImage(svx::SignatureLineHelper::getSignatureImage());
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", getCDataString(aSignerName));
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_TITLE]", getCDataString(aSignerTitle));
+
+ // These are only filled if the signature line is signed.
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", "");
+ aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", "");
+ aSvgImage = aSvgImage.replaceAll("[INVALID_SIGNATURE]", "");
+ aSvgImage = aSvgImage.replaceAll("[DATE]", "");
+
+ // Insert/Update graphic
+ Reference<XGraphic> xGraphic = svx::SignatureLineHelper::importSVG(aSvgImage);
+
+ bool bIsExistingSignatureLine = m_xExistingShapeProperties.is();
+ Reference<XPropertySet> xShapeProps;
+ if (bIsExistingSignatureLine)
+ xShapeProps = m_xExistingShapeProperties;
+ else
+ xShapeProps.set(Reference<lang::XMultiServiceFactory>(m_xModel, UNO_QUERY_THROW)
+ ->createInstance("com.sun.star.drawing.GraphicObjectShape"),
+ UNO_QUERY);
+
+ xShapeProps->setPropertyValue("Graphic", Any(xGraphic));
+ xShapeProps->setPropertyValue("SignatureLineUnsignedImage", Any(xGraphic));
+
+ // Set signature line properties
+ xShapeProps->setPropertyValue("IsSignatureLine", Any(true));
+ xShapeProps->setPropertyValue("SignatureLineId", Any(m_aSignatureLineId));
+ if (!aSignerName.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSuggestedSignerName", Any(aSignerName));
+ if (!aSignerTitle.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSuggestedSignerTitle", Any(aSignerTitle));
+ if (!aSignerEmail.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSuggestedSignerEmail", Any(aSignerEmail));
+ if (!aSigningInstructions.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSigningInstructions",
+ Any(aSigningInstructions));
+ xShapeProps->setPropertyValue("SignatureLineShowSignDate", Any(bShowSignDate));
+ xShapeProps->setPropertyValue("SignatureLineCanAddComment", Any(bCanAddComments));
+
+ if (bIsExistingSignatureLine)
+ return;
+
+ // Default size
+ Reference<XShape> xShape(xShapeProps, UNO_QUERY);
+ awt::Size aShapeSize;
+ aShapeSize.Height = 3000;
+ aShapeSize.Width = 6000;
+ xShape->setSize(aShapeSize);
+
+ // Default anchoring
+ xShapeProps->setPropertyValue("AnchorType", Any(TextContentAnchorType_AT_PARAGRAPH));
+
+ // Writer
+ const Reference<XTextDocument> xTextDocument(m_xModel, UNO_QUERY);
+ if (xTextDocument.is())
+ {
+ Reference<XTextContent> xTextContent(xShape, UNO_QUERY_THROW);
+ Reference<XTextViewCursorSupplier> xViewCursorSupplier(m_xModel->getCurrentController(),
+ UNO_QUERY_THROW);
+ Reference<XTextViewCursor> xCursor = xViewCursorSupplier->getViewCursor();
+ // use cursor's XText - it might be in table cell, frame, ...
+ Reference<XText> const xText(xCursor->getText());
+ assert(xText.is());
+ xText->insertTextContent(xCursor, xTextContent, true);
+ return;
+ }
+
+ // Calc
+ const Reference<XSpreadsheetDocument> xSpreadsheetDocument(m_xModel, UNO_QUERY);
+ if (!xSpreadsheetDocument.is())
+ return;
+
+ Reference<XPropertySet> xSheetCell(m_xModel->getCurrentSelection(), UNO_QUERY_THROW);
+ awt::Point aCellPosition;
+ xSheetCell->getPropertyValue("Position") >>= aCellPosition;
+ xShape->setPosition(aCellPosition);
+
+ Reference<XSpreadsheetView> xView(m_xModel->getCurrentController(), UNO_QUERY_THROW);
+ Reference<XSpreadsheet> xSheet(xView->getActiveSheet(), UNO_SET_THROW);
+ Reference<XDrawPageSupplier> xDrawPageSupplier(xSheet, UNO_QUERY_THROW);
+ Reference<XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage(), UNO_SET_THROW);
+ Reference<XShapes> xShapes(xDrawPage, UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SignatureLineDialogBase.cxx b/cui/source/dialogs/SignatureLineDialogBase.cxx
new file mode 100644
index 000000000..4e591124b
--- /dev/null
+++ b/cui/source/dialogs/SignatureLineDialogBase.cxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SignatureLineDialogBase.hxx>
+
+#include <utility>
+
+#include <vcl/weld.hxx>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::frame;
+
+SignatureLineDialogBase::SignatureLineDialogBase(weld::Widget* pParent, Reference<XModel> xModel,
+ const OUString& rUIFile, const OString& rDialogId)
+ : GenericDialogController(pParent, rUIFile, rDialogId)
+ , m_xModel(std::move(xModel))
+{
+}
+
+short SignatureLineDialogBase::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+OUString SignatureLineDialogBase::getCDataString(std::u16string_view rString)
+{
+ return OUString::Concat("<![CDATA[") + rString + "]]>";
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SpellAttrib.hxx b/cui/source/dialogs/SpellAttrib.hxx
new file mode 100644
index 000000000..cdc0cf266
--- /dev/null
+++ b/cui/source/dialogs/SpellAttrib.hxx
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/linguistic2/XProofreader.hpp>
+#include <utility>
+
+namespace svx{
+struct SpellErrorDescription
+{
+ bool bIsGrammarError;
+ OUString sErrorText;
+ OUString sDialogTitle;
+ OUString sExplanation;
+ OUString sExplanationURL;
+ css::lang::Locale aLocale;
+ css::uno::Reference< css::linguistic2::XProofreader > xGrammarChecker;
+ css::uno::Sequence< OUString > aSuggestions;
+ OUString sRuleId;
+
+ SpellErrorDescription( bool bGrammar,
+ OUString aText,
+ css::lang::Locale _aLocale,
+ const css::uno::Sequence< OUString >& rSuggestions,
+ css::uno::Reference< css::linguistic2::XProofreader > _xGrammarChecker,
+ const OUString* pDialogTitle = nullptr,
+ const OUString* pExplanation = nullptr,
+ const OUString* pRuleId = nullptr,
+ const OUString* pExplanationURL = nullptr ) :
+ bIsGrammarError( bGrammar ),
+ sErrorText(std::move( aText )),
+ sDialogTitle( ),
+ sExplanation( ),
+ sExplanationURL( ),
+ aLocale(std::move( _aLocale )),
+ xGrammarChecker(std::move( _xGrammarChecker )),
+ aSuggestions( rSuggestions )
+ {
+ if( pDialogTitle )
+ sDialogTitle = *pDialogTitle;
+ if( pExplanation )
+ sExplanation = *pExplanation;
+ if( pExplanationURL )
+ sExplanationURL = *pExplanationURL;
+ if( pRuleId )
+ sRuleId = *pRuleId;
+ };
+
+ SpellErrorDescription()
+ : bIsGrammarError(false)
+ {
+ }
+
+ bool operator==( const SpellErrorDescription& rDesc ) const
+ {
+ return bIsGrammarError == rDesc.bIsGrammarError &&
+ sErrorText == rDesc.sErrorText &&
+ aLocale.Language == rDesc.aLocale.Language &&
+ aLocale.Country == rDesc.aLocale.Country &&
+ aLocale.Variant == rDesc.aLocale.Variant &&
+ aSuggestions == rDesc.aSuggestions &&
+ xGrammarChecker == rDesc.xGrammarChecker &&
+ sDialogTitle == rDesc.sDialogTitle &&
+ sExplanation == rDesc.sExplanation &&
+ sExplanationURL == rDesc.sExplanationURL &&
+ sRuleId == rDesc.sRuleId;
+ }
+
+ css::uno::Sequence<css::uno::Any> toSequence() const
+ {
+ css::uno::Sequence<css::uno::Any> aEntries{ css::uno::Any(bIsGrammarError),
+ css::uno::Any(sErrorText),
+ css::uno::Any(sDialogTitle),
+ css::uno::Any(sExplanation),
+ css::uno::Any(sExplanationURL),
+ css::uno::Any(aLocale),
+ css::uno::Any(xGrammarChecker),
+ css::uno::Any(aSuggestions),
+ css::uno::Any(sRuleId) };
+ return aEntries;
+ }
+
+ void fromSequence(const css::uno::Sequence<css::uno::Any>& rEntries)
+ {
+ rEntries[0] >>= bIsGrammarError;
+ rEntries[1] >>= sErrorText;
+ rEntries[2] >>= sDialogTitle;
+ rEntries[3] >>= sExplanation;
+ rEntries[4] >>= sExplanationURL;
+ rEntries[5] >>= aLocale;
+ rEntries[6] >>= xGrammarChecker;
+ rEntries[7] >>= aSuggestions;
+ rEntries[8] >>= sRuleId;
+ }
+};
+
+}//namespace svx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx
new file mode 100644
index 000000000..e233dffff
--- /dev/null
+++ b/cui/source/dialogs/SpellDialog.cxx
@@ -0,0 +1,2099 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include "SpellAttrib.hxx"
+#include <sfx2/bindings.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/viewfrm.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svl/undo.hxx>
+#include <tools/debug.hxx>
+#include <unotools/lingucfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/splwrap.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/wghtitem.hxx>
+#include <linguistic/misc.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
+#include <sfx2/app.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/specialchars.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/texteng.hxx>
+#include <vcl/weld.hxx>
+#include <svx/SpellDialogChildWindow.hxx>
+#include <SpellDialog.hxx>
+#include <optlingu.hxx>
+#include <treeopt.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svtools/langtab.hxx>
+#include <sal/log.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <comphelper/lok.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::linguistic2;
+using namespace linguistic;
+
+
+// struct SpellDialog_Impl ---------------------------------------------
+
+struct SpellDialog_Impl
+{
+ Sequence< Reference< XDictionary > > aDics;
+};
+
+
+#define SPELLUNDO_START 200
+
+#define SPELLUNDO_CHANGE_LANGUAGE (SPELLUNDO_START + 1)
+#define SPELLUNDO_CHANGE_TEXTENGINE (SPELLUNDO_START + 2)
+#define SPELLUNDO_CHANGE_NEXTERROR (SPELLUNDO_START + 3)
+#define SPELLUNDO_CHANGE_ADD_TO_DICTIONARY (SPELLUNDO_START + 4)
+#define SPELLUNDO_CHANGE_GROUP (SPELLUNDO_START + 5) //undo list
+#define SPELLUNDO_MOVE_ERROREND (SPELLUNDO_START + 6)
+#define SPELLUNDO_UNDO_EDIT_MODE (SPELLUNDO_START + 7)
+#define SPELLUNDO_ADD_IGNORE_RULE (SPELLUNDO_START + 8)
+
+namespace svx{
+class SpellUndoAction_Impl : public SfxUndoAction
+{
+ sal_uInt16 m_nId;
+ const Link<SpellUndoAction_Impl&,void>& m_rActionLink;
+ //undo of button enabling
+ bool m_bEnableChangePB;
+ bool m_bEnableChangeAllPB;
+ //undo of MarkNextError - used in change and change all, ignore and ignore all
+ tools::Long m_nOldErrorStart;
+ tools::Long m_nOldErrorEnd;
+ bool m_bIsErrorLanguageSelected;
+ //undo of AddToDictionary
+ Reference<XDictionary> m_xDictionary;
+ OUString m_sAddedWord;
+ //move end of error - ::ChangeMarkedWord()
+ tools::Long m_nOffset;
+
+public:
+ SpellUndoAction_Impl(sal_uInt16 nId, const Link<SpellUndoAction_Impl&,void>& rActionLink) :
+ m_nId(nId),
+ m_rActionLink( rActionLink),
+ m_bEnableChangePB(false),
+ m_bEnableChangeAllPB(false),
+ m_nOldErrorStart(-1),
+ m_nOldErrorEnd(-1),
+ m_bIsErrorLanguageSelected(false),
+ m_nOffset(0)
+ {}
+
+ virtual void Undo() override;
+ sal_uInt16 GetId() const;
+
+ void SetEnableChangePB(){m_bEnableChangePB = true;}
+ bool IsEnableChangePB() const {return m_bEnableChangePB;}
+
+ void SetEnableChangeAllPB(){m_bEnableChangeAllPB = true;}
+ bool IsEnableChangeAllPB() const {return m_bEnableChangeAllPB;}
+
+ void SetErrorMove(tools::Long nOldStart, tools::Long nOldEnd)
+ {
+ m_nOldErrorStart = nOldStart;
+ m_nOldErrorEnd = nOldEnd;
+ }
+ tools::Long GetOldErrorStart() const { return m_nOldErrorStart;}
+ tools::Long GetOldErrorEnd() const { return m_nOldErrorEnd;}
+
+ void SetErrorLanguageSelected(bool bSet){ m_bIsErrorLanguageSelected = bSet;}
+ bool IsErrorLanguageSelected() const {return m_bIsErrorLanguageSelected;}
+
+ void SetDictionary(const Reference<XDictionary>& xDict) { m_xDictionary = xDict; }
+ const Reference<XDictionary>& GetDictionary() const { return m_xDictionary; }
+ void SetAddedWord(const OUString& rWord) {m_sAddedWord = rWord;}
+ const OUString& GetAddedWord() const { return m_sAddedWord;}
+
+ void SetOffset(tools::Long nSet) {m_nOffset = nSet;}
+ tools::Long GetOffset() const {return m_nOffset;}
+};
+}//namespace svx
+using namespace ::svx;
+
+void SpellUndoAction_Impl::Undo()
+{
+ m_rActionLink.Call(*this);
+}
+
+
+sal_uInt16 SpellUndoAction_Impl::GetId()const
+{
+ return m_nId;
+}
+
+// class SvxSpellCheckDialog ---------------------------------------------
+
+SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow,
+ weld::Window * pParent, SfxBindings* _pBindings)
+ : SfxModelessDialogController (_pBindings, pChildWindow,
+ pParent, "cui/ui/spellingdialog.ui", "SpellingDialog")
+ , aDialogUndoLink(LINK (this, SpellDialog, DialogUndoHdl))
+ , m_pInitHdlEvent(nullptr)
+ , bFocusLocked(true)
+ , rParent(*pChildWindow)
+ , pImpl( new SpellDialog_Impl )
+ , m_xAltTitle(m_xBuilder->weld_label("alttitleft"))
+ , m_xResumeFT(m_xBuilder->weld_label("resumeft"))
+ , m_xNoSuggestionsFT(m_xBuilder->weld_label("nosuggestionsft"))
+ , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("languagelb")))
+ , m_xExplainFT(m_xBuilder->weld_label("explain"))
+ , m_xExplainLink(m_xBuilder->weld_link_button("explainlink"))
+ , m_xNotInDictFT(m_xBuilder->weld_label("notindictft"))
+ , m_xSentenceED(new SentenceEditWindow_Impl)
+ , m_xSuggestionFT(m_xBuilder->weld_label("suggestionsft"))
+ , m_xSuggestionLB(m_xBuilder->weld_tree_view("suggestionslb"))
+ , m_xIgnorePB(m_xBuilder->weld_button("ignore"))
+ , m_xIgnoreAllPB(m_xBuilder->weld_button("ignoreall"))
+ , m_xIgnoreRulePB(m_xBuilder->weld_button("ignorerule"))
+ , m_xAddToDictPB(m_xBuilder->weld_button("add"))
+ , m_xAddToDictMB(m_xBuilder->weld_menu_button("addmb"))
+ , m_xChangePB(m_xBuilder->weld_button("change"))
+ , m_xChangeAllPB(m_xBuilder->weld_button("changeall"))
+ , m_xAutoCorrPB(m_xBuilder->weld_button("autocorrect"))
+ , m_xCheckGrammarCB(m_xBuilder->weld_check_button("checkgrammar"))
+ , m_xOptionsPB(m_xBuilder->weld_button("options"))
+ , m_xUndoPB(m_xBuilder->weld_button("undo"))
+ , m_xClosePB(m_xBuilder->weld_button("close"))
+ , m_xToolbar(m_xBuilder->weld_toolbar("toolbar"))
+ , m_xSentenceEDWeld(new weld::CustomWeld(*m_xBuilder, "sentence", *m_xSentenceED))
+{
+ m_xSentenceED->SetSpellDialog(this);
+ m_xSentenceED->Init(m_xToolbar.get());
+
+ m_sTitleSpellingGrammar = m_xDialog->get_title();
+ m_sTitleSpelling = m_xAltTitle->get_label();
+
+ // fdo#68794 set initial title for cases where no text has been processed
+ // yet to show its language attributes
+ OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
+ m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle.replaceFirst("$LANGUAGE ($LOCATION)", "")));
+
+ m_sResumeST = m_xResumeFT->get_label();
+ m_sNoSuggestionsST = m_xNoSuggestionsFT->strip_mnemonic(m_xNoSuggestionsFT->get_label());
+
+ Size aEdSize(m_xSuggestionLB->get_approximate_digit_width() * 60,
+ m_xSuggestionLB->get_height_rows(6));
+ m_xSuggestionLB->set_size_request(aEdSize.Width(), -1);
+ m_sIgnoreOnceST = m_xIgnorePB->get_label();
+ m_xAddToDictMB->set_help_id(m_xAddToDictPB->get_help_id());
+ xSpell = LinguMgr::GetSpellChecker();
+
+ Init_Impl();
+
+ // disable controls if service is missing
+ m_xDialog->set_sensitive(xSpell.is());
+
+ //InitHdl wants to use virtual methods, so it
+ //can't be called during the ctor, so init
+ //it on next event cycle post-ctor
+ m_pInitHdlEvent = Application::PostUserEvent(LINK(this, SpellDialog, InitHdl));
+}
+
+SpellDialog::~SpellDialog()
+{
+ if (m_pInitHdlEvent)
+ Application::RemoveUserEvent(m_pInitHdlEvent);
+ if (pImpl)
+ {
+ // save possibly modified user-dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ SaveDictionaries( xDicList );
+
+ pImpl.reset();
+ }
+}
+
+void SpellDialog::Init_Impl()
+{
+ // initialize handler
+ m_xClosePB->connect_clicked(LINK( this, SpellDialog, CancelHdl ) );
+ m_xChangePB->connect_clicked(LINK( this, SpellDialog, ChangeHdl ) );
+ m_xChangeAllPB->connect_clicked(LINK( this, SpellDialog, ChangeAllHdl ) );
+ m_xIgnorePB->connect_clicked(LINK( this, SpellDialog, IgnoreHdl ) );
+ m_xIgnoreAllPB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
+ m_xIgnoreRulePB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
+ m_xUndoPB->connect_clicked(LINK( this, SpellDialog, UndoHdl ) );
+
+ m_xAutoCorrPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
+ m_xCheckGrammarCB->connect_toggled( LINK( this, SpellDialog, CheckGrammarHdl ));
+ m_xOptionsPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
+
+ m_xSuggestionLB->connect_row_activated( LINK( this, SpellDialog, DoubleClickChangeHdl ) );
+
+ m_xSentenceED->SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
+
+ m_xAddToDictMB->connect_selected(LINK ( this, SpellDialog, AddToDictSelectHdl ) );
+ m_xAddToDictPB->connect_clicked(LINK ( this, SpellDialog, AddToDictClickHdl ) );
+
+ m_xLanguageLB->connect_changed(LINK( this, SpellDialog, LanguageSelectHdl ) );
+
+ // initialize language ListBox
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::SPELL_USED, false, false, true);
+
+ m_xSentenceED->ClearModifyFlag();
+ LinguMgr::GetChangeAllList()->clear();
+}
+
+void SpellDialog::UpdateBoxes_Impl(bool bCallFromSelectHdl)
+{
+ sal_Int32 i;
+ m_xSuggestionLB->clear();
+
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+
+ LanguageType nAltLanguage = LANGUAGE_NONE;
+ Sequence< OUString > aNewWords;
+ bool bIsGrammarError = false;
+ if( bSpellErrorDescription )
+ {
+ nAltLanguage = LanguageTag::convertToLanguageType( aSpellErrorDescription.aLocale );
+ aNewWords = aSpellErrorDescription.aSuggestions;
+ bIsGrammarError = aSpellErrorDescription.bIsGrammarError;
+ m_xExplainLink->set_uri( aSpellErrorDescription.sExplanationURL );
+ m_xExplainFT->set_label( aSpellErrorDescription.sExplanation );
+ }
+ if( bSpellErrorDescription && !aSpellErrorDescription.sDialogTitle.isEmpty() )
+ {
+ // use this function to apply the correct image to be used...
+ SetTitle_Impl( nAltLanguage );
+ // then change the title to the one to be actually used
+ m_xDialog->set_title(m_xDialog->strip_mnemonic(aSpellErrorDescription.sDialogTitle));
+ }
+ else
+ SetTitle_Impl( nAltLanguage );
+ if( !bCallFromSelectHdl )
+ m_xLanguageLB->set_active_id( nAltLanguage );
+ int nDicts = InitUserDicts();
+
+ // enter alternatives
+ const OUString *pNewWords = aNewWords.getConstArray();
+ const sal_Int32 nSize = aNewWords.getLength();
+ for ( i = 0; i < nSize; ++i )
+ {
+ OUString aTmp( pNewWords[i] );
+ if (m_xSuggestionLB->find_text(aTmp) == -1)
+ m_xSuggestionLB->append_text(aTmp);
+ }
+ if(!nSize)
+ m_xSuggestionLB->append_text(m_sNoSuggestionsST);
+ m_xAutoCorrPB->set_sensitive( nSize > 0 );
+
+ m_xSuggestionFT->set_sensitive(nSize > 0);
+ m_xSuggestionLB->set_sensitive(nSize > 0);
+ if( nSize )
+ {
+ m_xSuggestionLB->select(0);
+ }
+ m_xChangePB->set_sensitive( nSize > 0);
+ m_xChangeAllPB->set_sensitive(nSize > 0);
+ bool bShowChangeAll = !bIsGrammarError;
+ m_xChangeAllPB->set_visible( bShowChangeAll );
+ m_xExplainFT->set_visible( !bShowChangeAll );
+ m_xLanguageLB->set_sensitive( bShowChangeAll );
+ m_xIgnoreAllPB->set_visible( bShowChangeAll );
+
+ m_xAddToDictMB->set_visible( bShowChangeAll && nDicts > 1 && !comphelper::LibreOfficeKit::isActive());
+ m_xAddToDictPB->set_visible( bShowChangeAll && nDicts <= 1 && !comphelper::LibreOfficeKit::isActive());
+ m_xIgnoreRulePB->set_visible( !bShowChangeAll );
+ m_xIgnoreRulePB->set_sensitive(bSpellErrorDescription && !aSpellErrorDescription.sRuleId.isEmpty());
+ m_xAutoCorrPB->set_visible( bShowChangeAll && rParent.HasAutoCorrection() );
+
+ bool bOldShowGrammar = m_xCheckGrammarCB->get_visible();
+ bool bOldShowExplain = m_xExplainLink->get_visible();
+
+ m_xCheckGrammarCB->set_visible(rParent.HasGrammarChecking());
+ m_xExplainLink->set_visible(!m_xExplainLink->get_uri().isEmpty());
+ if (m_xExplainFT->get_label().isEmpty())
+ {
+ m_xExplainFT->hide();
+ m_xExplainLink->hide();
+ }
+
+ if (bOldShowExplain != m_xExplainLink->get_visible() || bOldShowGrammar != m_xCheckGrammarCB->get_visible())
+ m_xDialog->resize_to_request();
+}
+
+void SpellDialog::SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bIgnoreCurrentError)
+{
+ //initially or after the last error of a sentence MarkNextError will fail
+ //then GetNextSentence() has to be called followed again by MarkNextError()
+ //MarkNextError is not initially called if the UndoEdit mode is active
+ bool bNextSentence = false;
+ if (!m_xSentenceED)
+ {
+ return;
+ }
+
+ if(!((!m_xSentenceED->IsUndoEditMode() && m_xSentenceED->MarkNextError( bIgnoreCurrentError, xSpell )) ||
+ ( bNextSentence = GetNextSentence_Impl(pGuard, bUseSavedSentence, m_xSentenceED->IsUndoEditMode()) && m_xSentenceED->MarkNextError( false, xSpell ))))
+ return;
+
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+ if (bSpellErrorDescription)
+ {
+ UpdateBoxes_Impl();
+ weld::Widget* aControls[] =
+ {
+ m_xNotInDictFT.get(),
+ m_xSentenceED->GetDrawingArea(),
+ m_xLanguageFT.get()
+ };
+ for (weld::Widget* pWidget : aControls)
+ pWidget->set_sensitive(true);
+ }
+ if( bNextSentence )
+ {
+ //remove undo if a new sentence is active
+ m_xSentenceED->ResetUndo();
+ m_xUndoPB->set_sensitive(false);
+ }
+}
+/* Initialize, asynchronous to prevent virtual calls
+ from a constructor
+ */
+IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void)
+{
+ m_pInitHdlEvent = nullptr;
+ m_xDialog->freeze();
+ //show or hide AutoCorrect depending on the modules abilities
+ m_xAutoCorrPB->set_visible(rParent.HasAutoCorrection());
+ SpellContinue_Impl(nullptr);
+ m_xSentenceED->ResetUndo();
+ m_xUndoPB->set_sensitive(false);
+
+ // get current language
+ UpdateBoxes_Impl();
+
+ // fill dictionary PopupMenu
+ InitUserDicts();
+
+ LockFocusChanges(true);
+ if(m_xSentenceED->IsEnabled())
+ m_xSentenceED->GrabFocus();
+ else if( m_xChangePB->get_sensitive() )
+ m_xChangePB->grab_focus();
+ else if( m_xIgnorePB->get_sensitive() )
+ m_xIgnorePB->grab_focus();
+ else if( m_xClosePB->get_sensitive() )
+ m_xClosePB->grab_focus();
+ LockFocusChanges(false);
+ //show grammar CheckBox depending on the modules abilities
+ m_xCheckGrammarCB->set_active(rParent.IsGrammarChecking());
+ m_xDialog->thaw();
+};
+
+IMPL_LINK( SpellDialog, ExtClickHdl, weld::Button&, rBtn, void )
+{
+ if (m_xOptionsPB.get() == &rBtn)
+ StartSpellOptDlg_Impl();
+ else if (m_xAutoCorrPB.get() == &rBtn)
+ {
+ //get the currently selected wrong word
+ OUString sCurrentErrorText = m_xSentenceED->GetErrorText();
+ //get the wrong word from the XSpellAlternative
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+ if (bSpellErrorDescription)
+ {
+ OUString sWrong(aSpellErrorDescription.sErrorText);
+ //if the word has not been edited in the MultiLineEdit then
+ //the current suggestion should be used
+ //if it's not the 'no suggestions' entry
+ if(sWrong == sCurrentErrorText &&
+ m_xSuggestionLB->get_sensitive() && m_xSuggestionLB->get_selected_index() != -1 &&
+ m_sNoSuggestionsST != m_xSuggestionLB->get_selected_text())
+ {
+ sCurrentErrorText = m_xSuggestionLB->get_selected_text();
+ }
+ if(sWrong != sCurrentErrorText)
+ {
+ SvxPrepareAutoCorrect( sWrong, sCurrentErrorText );
+ LanguageType eLang = GetSelectedLang_Impl();
+ rParent.AddAutoCorrection( sWrong, sCurrentErrorText, eLang );
+ //correct the word immediately
+ ChangeHdl(*m_xAutoCorrPB);
+ }
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SpellDialog, CheckGrammarHdl, weld::Toggleable&, void)
+{
+ rParent.SetGrammarChecking(m_xCheckGrammarCB->get_active());
+ Impl_Restore(true);
+}
+
+void SpellDialog::StartSpellOptDlg_Impl()
+{
+ SfxItemSetFixed<SID_AUTOSPELL_CHECK,SID_AUTOSPELL_CHECK> aSet( SfxGetpApp()->GetPool() );
+ SfxSingleTabDialogController aDlg(m_xDialog.get(), &aSet, "cui/ui/spelloptionsdialog.ui", "SpellOptionsDialog");
+
+ std::unique_ptr<SfxTabPage> xPage = SvxLinguTabPage::Create(aDlg.get_content_area(), &aDlg, &aSet);
+ static_cast<SvxLinguTabPage*>(xPage.get())->HideGroups( GROUP_MODULES );
+ aDlg.SetTabPage(std::move(xPage));
+ if (RET_OK == aDlg.run())
+ {
+ InitUserDicts();
+ const SfxItemSet* pOutSet = aDlg.GetOutputItemSet();
+ if(pOutSet)
+ OfaTreeOptionsDialog::ApplyLanguageOptions(*pOutSet);
+ }
+}
+
+namespace
+{
+ OUString getDotReplacementString(const OUString &rErrorText, const OUString &rSuggestedReplacement)
+ {
+ OUString aString = rErrorText;
+
+ //dots are sometimes part of the spelled word but they are not necessarily part of the replacement
+ bool bDot = aString.endsWith(".");
+
+ aString = rSuggestedReplacement;
+
+ if(bDot && (aString.isEmpty() || !aString.endsWith(".")))
+ aString += ".";
+
+ return aString;
+ }
+}
+
+OUString SpellDialog::getReplacementString() const
+{
+ OUString sOrigString = m_xSentenceED->GetErrorText();
+
+ OUString sReplacement(sOrigString);
+
+ if(m_xSuggestionLB->get_sensitive() &&
+ m_xSuggestionLB->get_selected_index() != -1 &&
+ m_sNoSuggestionsST != m_xSuggestionLB->get_selected_text())
+ sReplacement = m_xSuggestionLB->get_selected_text();
+
+ return getDotReplacementString(sOrigString, sReplacement);
+}
+
+IMPL_LINK_NOARG(SpellDialog, DoubleClickChangeHdl, weld::TreeView&, bool)
+{
+ ChangeHdl(*m_xChangePB);
+ return true;
+}
+
+/* tdf#132822 start an undo group in ctor and close it in the dtor. This can
+ then be passed to SpellContinue_Impl which can delete it in advance of its
+ natural scope to force closing the undo group if SpellContinue_Impl needs to
+ fetch a new paragraph and discard all undo information which can only be
+ done properly if there are no open undo groups */
+class UndoChangeGroupGuard
+{
+private:
+ SentenceEditWindow_Impl& m_rSentenceED;
+public:
+ UndoChangeGroupGuard(SentenceEditWindow_Impl& rSentenceED)
+ : m_rSentenceED(rSentenceED)
+ {
+ m_rSentenceED.UndoActionStart(SPELLUNDO_CHANGE_GROUP);
+ }
+ ~UndoChangeGroupGuard()
+ {
+ m_rSentenceED.UndoActionEnd();
+ }
+};
+
+IMPL_LINK_NOARG(SpellDialog, ChangeHdl, weld::Button&, void)
+{
+ if (m_xSentenceED->IsUndoEditMode())
+ {
+ SpellContinue_Impl();
+ }
+ else
+ {
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+ OUString aString = getReplacementString();
+ m_xSentenceED->ChangeMarkedWord(aString, GetSelectedLang_Impl());
+ SpellContinue_Impl(&xGuard);
+ }
+ if(!m_xChangePB->get_sensitive())
+ m_xIgnorePB->grab_focus();
+}
+
+IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, weld::Button&, void)
+{
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+ OUString aString = getReplacementString();
+ LanguageType eLang = GetSelectedLang_Impl();
+
+ // add new word to ChangeAll list
+ OUString aOldWord( m_xSentenceED->GetErrorText() );
+ SvxPrepareAutoCorrect( aOldWord, aString );
+ Reference<XDictionary> aXDictionary = LinguMgr::GetChangeAllList();
+ DictionaryError nAdded = AddEntryToDic( aXDictionary,
+ aOldWord, true,
+ aString );
+
+ if(nAdded == DictionaryError::NONE)
+ {
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
+ pAction->SetDictionary(aXDictionary);
+ pAction->SetAddedWord(aOldWord);
+ m_xSentenceED->AddUndoAction(std::move(pAction));
+ }
+
+ m_xSentenceED->ChangeMarkedWord(aString, eLang);
+ SpellContinue_Impl(&xGuard);
+}
+
+IMPL_LINK( SpellDialog, IgnoreAllHdl, weld::Button&, rButton, void )
+{
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+ // add word to IgnoreAll list
+ Reference< XDictionary > aXDictionary = LinguMgr::GetIgnoreAllList();
+ //in case the error has been changed manually it has to be restored
+ m_xSentenceED->RestoreCurrentError();
+ if (&rButton == m_xIgnoreRulePB.get())
+ {
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+ try
+ {
+ if( bSpellErrorDescription && aSpellErrorDescription.xGrammarChecker.is() )
+ {
+ aSpellErrorDescription.xGrammarChecker->ignoreRule(aSpellErrorDescription.sRuleId,
+ aSpellErrorDescription.aLocale);
+ // refresh the layout (workaround to launch a dictionary event)
+ aXDictionary->setActive(false);
+ aXDictionary->setActive(true);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ }
+ }
+ else
+ {
+ OUString sErrorText(m_xSentenceED->GetErrorText());
+ DictionaryError nAdded = AddEntryToDic( aXDictionary,
+ sErrorText, false,
+ OUString() );
+ if (nAdded == DictionaryError::NONE)
+ {
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
+ pAction->SetDictionary(aXDictionary);
+ pAction->SetAddedWord(sErrorText);
+ m_xSentenceED->AddUndoAction(std::move(pAction));
+ }
+ }
+
+ SpellContinue_Impl(&xGuard);
+}
+
+IMPL_LINK_NOARG(SpellDialog, UndoHdl, weld::Button&, void)
+{
+ m_xSentenceED->Undo();
+ if(!m_xSentenceED->GetUndoActionCount())
+ m_xUndoPB->set_sensitive(false);
+}
+
+
+IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl&, rAction, void )
+{
+ switch(rAction.GetId())
+ {
+ case SPELLUNDO_CHANGE_TEXTENGINE:
+ {
+ if(rAction.IsEnableChangePB())
+ m_xChangePB->set_sensitive(false);
+ if(rAction.IsEnableChangeAllPB())
+ m_xChangeAllPB->set_sensitive(false);
+ }
+ break;
+ case SPELLUNDO_CHANGE_NEXTERROR:
+ {
+ m_xSentenceED->MoveErrorMarkTo(static_cast<sal_Int32>(rAction.GetOldErrorStart()),
+ static_cast<sal_Int32>(rAction.GetOldErrorEnd()),
+ false);
+ if(rAction.IsErrorLanguageSelected())
+ {
+ UpdateBoxes_Impl();
+ }
+ }
+ break;
+ case SPELLUNDO_CHANGE_ADD_TO_DICTIONARY:
+ {
+ if(rAction.GetDictionary().is())
+ rAction.GetDictionary()->remove(rAction.GetAddedWord());
+ }
+ break;
+ case SPELLUNDO_MOVE_ERROREND :
+ {
+ if(rAction.GetOffset() != 0)
+ m_xSentenceED->MoveErrorEnd(rAction.GetOffset());
+ }
+ break;
+ case SPELLUNDO_UNDO_EDIT_MODE :
+ {
+ //refill the dialog with the currently spelled sentence - throw away all changes
+ SpellContinue_Impl(nullptr, true);
+ }
+ break;
+ case SPELLUNDO_ADD_IGNORE_RULE:
+ //undo of ignored rules is not supported
+ break;
+ }
+}
+
+void SpellDialog::Impl_Restore(bool bUseSavedSentence)
+{
+ //clear the "ChangeAllList"
+ LinguMgr::GetChangeAllList()->clear();
+ //get a new sentence
+ m_xSentenceED->SetText(OUString());
+ m_xSentenceED->ResetModified();
+ //Resolves: fdo#39348 refill the dialog with the currently spelled sentence
+ SpellContinue_Impl(nullptr, bUseSavedSentence);
+ m_xIgnorePB->set_label(m_sIgnoreOnceST);
+}
+
+IMPL_LINK_NOARG(SpellDialog, IgnoreHdl, weld::Button&, void)
+{
+ if (m_sResumeST == m_xIgnorePB->get_label())
+ {
+ Impl_Restore(false);
+ }
+ else
+ {
+ //in case the error has been changed manually it has to be restored,
+ // since the users choice now was to ignore the error
+ m_xSentenceED->RestoreCurrentError();
+
+ // the word is being ignored
+ SpellContinue_Impl(nullptr, false, true);
+ }
+}
+
+void SpellDialog::Close()
+{
+ if (IsClosing())
+ return;
+
+ // We have to call ToggleChildWindow directly; calling SfxDispatcher's
+ // Execute() does not work here when we are in a document with protected
+ // section - in that case, the cursor can move from the editable field to
+ // the protected area, and the slots get disabled because of
+ // SfxDisableFlags::SwOnProtectedCursor (see FN_SPELL_GRAMMAR_DIALOG in .sdi).
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if (pViewFrame)
+ pViewFrame->ToggleChildWindow(rParent.GetType());
+}
+
+LanguageType SpellDialog::GetSelectedLang_Impl() const
+{
+ LanguageType nLang = m_xLanguageLB->get_active_id();
+ return nLang;
+}
+
+IMPL_LINK_NOARG(SpellDialog, LanguageSelectHdl, weld::ComboBox&, void)
+{
+ //If selected language changes, then add->list should be regenerated to
+ //match
+ InitUserDicts();
+
+ //if currently an error is selected then search for alternatives for
+ //this word and fill the alternatives ListBox accordingly
+ OUString sError = m_xSentenceED->GetErrorText();
+ m_xSuggestionLB->clear();
+ if (!sError.isEmpty())
+ {
+ LanguageType eLanguage = m_xLanguageLB->get_active_id();
+ Reference <XSpellAlternatives> xAlt = xSpell->spell( sError, static_cast<sal_uInt16>(eLanguage),
+ Sequence< PropertyValue >() );
+ if( xAlt.is() )
+ m_xSentenceED->SetAlternatives( xAlt );
+ else
+ {
+ m_xSentenceED->ChangeMarkedWord( sError, eLanguage );
+ SpellContinue_Impl();
+ }
+
+ m_xSentenceED->AddUndoAction(std::make_unique<SpellUndoAction_Impl>(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink));
+ }
+ SpellDialog::UpdateBoxes_Impl(true);
+}
+
+void SpellDialog::SetTitle_Impl(LanguageType nLang)
+{
+ OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
+ sTitle = sTitle.replaceFirst( "$LANGUAGE ($LOCATION)", SvtLanguageTable::GetLanguageString(nLang) );
+ m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle));
+}
+
+int SpellDialog::InitUserDicts()
+{
+ const LanguageType nLang = m_xLanguageLB->get_active_id();
+
+ const Reference< XDictionary > *pDic = nullptr;
+
+ // get list of dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ // add active, positive dictionary to dic-list (if not already done).
+ // This is to ensure that there is at least on dictionary to which
+ // words could be added.
+ Reference< XDictionary > xDic( LinguMgr::GetStandardDic() );
+ if (xDic.is())
+ xDic->setActive( true );
+
+ pImpl->aDics = xDicList->getDictionaries();
+ }
+
+ SvtLinguConfig aCfg;
+
+ // list suitable dictionaries
+ bool bEnable = false;
+ const sal_Int32 nSize = pImpl->aDics.getLength();
+ pDic = pImpl->aDics.getConstArray();
+ m_xAddToDictMB->clear();
+ sal_uInt16 nItemId = 1; // menu items should be enumerated from 1 and not 0
+ for (sal_Int32 i = 0; i < nSize; ++i)
+ {
+ uno::Reference< linguistic2::XDictionary > xDicTmp = pDic[i];
+ if (!xDicTmp.is() || LinguMgr::GetIgnoreAllList() == xDicTmp)
+ continue;
+
+ uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY );
+ LanguageType nActLanguage = LanguageTag( xDicTmp->getLocale() ).getLanguageType();
+ if( xDicTmp->isActive()
+ && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE
+ && (nLang == nActLanguage || LANGUAGE_NONE == nActLanguage )
+ && (!xStor.is() || !xStor->isReadonly()) )
+ {
+ bEnable = true;
+
+ OUString aDictionaryImageUrl;
+ uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
+ if (xSvcInfo.is())
+ {
+ aDictionaryImageUrl = aCfg.GetSpellAndGrammarContextDictionaryImage(
+ xSvcInfo->getImplementationName());
+ }
+
+ m_xAddToDictMB->append_item(OUString::number(nItemId), xDicTmp->getName(), aDictionaryImageUrl);
+
+ ++nItemId;
+ }
+ }
+ m_xAddToDictMB->set_sensitive( bEnable );
+ m_xAddToDictPB->set_sensitive( bEnable );
+
+ int nDicts = nItemId-1;
+
+ m_xAddToDictMB->set_visible(nDicts > 1 && !comphelper::LibreOfficeKit::isActive());
+ m_xAddToDictPB->set_visible(nDicts <= 1 && !comphelper::LibreOfficeKit::isActive());
+
+ return nDicts;
+}
+
+IMPL_LINK_NOARG(SpellDialog, AddToDictClickHdl, weld::Button&, void)
+{
+ AddToDictionaryExecute(OString::number(1));
+}
+
+IMPL_LINK(SpellDialog, AddToDictSelectHdl, const OString&, rIdent, void)
+{
+ AddToDictionaryExecute(rIdent);
+}
+
+void SpellDialog::AddToDictionaryExecute(const OString& rItemId)
+{
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+
+ //GetErrorText() returns the current error even if the text is already
+ //manually changed
+ const OUString aNewWord = m_xSentenceED->GetErrorText();
+
+ OUString aDicName(m_xAddToDictMB->get_item_label(rItemId));
+
+ uno::Reference< linguistic2::XDictionary > xDic;
+ uno::Reference< linguistic2::XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ xDic = xDicList->getDictionaryByName( aDicName );
+
+ DictionaryError nAddRes = DictionaryError::UNKNOWN;
+ if (xDic.is())
+ {
+ nAddRes = AddEntryToDic( xDic, aNewWord, false, OUString() );
+ // save modified user-dictionary if it is persistent
+ uno::Reference< frame::XStorable > xSavDic( xDic, uno::UNO_QUERY );
+ if (xSavDic.is())
+ xSavDic->store();
+
+ if (nAddRes == DictionaryError::NONE)
+ {
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
+ pAction->SetDictionary( xDic );
+ pAction->SetAddedWord( aNewWord );
+ m_xSentenceED->AddUndoAction( std::move(pAction) );
+ }
+ // failed because there is already an entry?
+ if (DictionaryError::NONE != nAddRes && xDic->getEntry( aNewWord ).is())
+ nAddRes = DictionaryError::NONE;
+ }
+ if (DictionaryError::NONE != nAddRes)
+ {
+ SvxDicError(m_xDialog.get(), nAddRes);
+ return; // don't continue
+ }
+
+ // go on
+ SpellContinue_Impl(&xGuard);
+}
+
+IMPL_LINK_NOARG(SpellDialog, ModifyHdl, LinkParamNone*, void)
+{
+ m_xSuggestionLB->unselect_all();
+ m_xSuggestionLB->set_sensitive(false);
+ m_xAutoCorrPB->set_sensitive(false);
+ std::unique_ptr<SpellUndoAction_Impl> pSpellAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink));
+ if(!m_xChangeAllPB->get_sensitive())
+ {
+ m_xChangeAllPB->set_sensitive(true);
+ pSpellAction->SetEnableChangeAllPB();
+ }
+ if(!m_xChangePB->get_sensitive())
+ {
+ m_xChangePB->set_sensitive(true);
+ pSpellAction->SetEnableChangePB();
+ }
+ m_xSentenceED->AddUndoAction(std::move(pSpellAction));
+}
+
+IMPL_LINK_NOARG(SpellDialog, CancelHdl, weld::Button&, void)
+{
+ //apply changes and ignored text parts first - if there are any
+ if (m_xSentenceED->IsModified())
+ {
+ rParent.ApplyChangedSentence(m_xSentenceED->CreateSpellPortions(), false);
+ }
+ Close();
+}
+
+void SpellDialog::ToplevelFocusChanged()
+{
+ /* #i38338#
+ * FIXME: LoseFocus and GetFocus are signals from vcl that
+ * a window actually got/lost the focus, it never should be
+ * forwarded from another window, that is simply wrong.
+ * FIXME: overriding the virtual methods GetFocus and LoseFocus
+ * in SpellDialogChildWindow by making them pure is at least questionable.
+ * The only sensible thing would be to call the new Method differently,
+ * e.g. DialogGot/LostFocus or so.
+ */
+ if (!m_xDialog->get_visible() || bFocusLocked)
+ return;
+
+ if (m_xDialog->has_toplevel_focus())
+ {
+ //notify the child window of the focus change
+ rParent.GetFocus();
+ }
+ else
+ {
+ //notify the child window of the focus change
+ rParent.LoseFocus();
+ }
+}
+
+void SpellDialog::Activate()
+{
+ SfxModelessDialogController::Activate();
+ ToplevelFocusChanged();
+}
+
+void SpellDialog::Deactivate()
+{
+ SfxModelessDialogController::Deactivate();
+ ToplevelFocusChanged();
+}
+
+void SpellDialog::InvalidateDialog()
+{
+ if( bFocusLocked )
+ return;
+ m_xIgnorePB->set_label(m_sResumeST);
+ weld::Widget* aDisableArr[] =
+ {
+ m_xNotInDictFT.get(),
+ m_xSentenceED->GetDrawingArea(),
+ m_xSuggestionFT.get(),
+ m_xSuggestionLB.get(),
+ m_xLanguageFT.get(),
+ m_xLanguageLB->get_widget(),
+ m_xIgnoreAllPB.get(),
+ m_xIgnoreRulePB.get(),
+ m_xAddToDictMB.get(),
+ m_xAddToDictPB.get(),
+ m_xChangePB.get(),
+ m_xChangeAllPB.get(),
+ m_xAutoCorrPB.get(),
+ m_xUndoPB.get()
+ };
+ for (weld::Widget* pWidget : aDisableArr)
+ pWidget->set_sensitive(false);
+
+ SfxModelessDialogController::Deactivate();
+}
+
+bool SpellDialog::GetNextSentence_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bRecheck)
+{
+ bool bRet = false;
+ if(!bUseSavedSentence)
+ {
+ //apply changes and ignored text parts
+ rParent.ApplyChangedSentence(m_xSentenceED->CreateSpellPortions(), bRecheck);
+ }
+ m_xSentenceED->ResetIgnoreErrorsAt();
+ m_xSentenceED->ResetModified();
+ SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence( bRecheck );
+ if(!bUseSavedSentence)
+ m_aSavedSentence = aSentence;
+ bool bHasReplaced = false;
+ while(!aSentence.empty())
+ {
+ //apply all changes that are already part of the "ChangeAllList"
+ //returns true if the list still contains errors after the changes have been applied
+
+ if(!ApplyChangeAllList_Impl(aSentence, bHasReplaced))
+ {
+ rParent.ApplyChangedSentence(aSentence, bRecheck);
+ aSentence = rParent.GetNextWrongSentence( bRecheck );
+ }
+ else
+ break;
+ }
+
+ if(!aSentence.empty())
+ {
+ OUStringBuffer sText;
+ for (auto const& elem : aSentence)
+ {
+ // hidden text has to be ignored
+ if(!elem.bIsHidden)
+ sText.append(elem.sText);
+ }
+ // tdf#132822 fire undo-stack UndoActionEnd to close undo stack because we're about to throw away the paragraph entirely
+ if (pGuard)
+ pGuard->reset();
+ m_xSentenceED->SetText(sText.makeStringAndClear());
+ sal_Int32 nStartPosition = 0;
+ sal_Int32 nEndPosition = 0;
+
+ for (auto const& elem : aSentence)
+ {
+ // hidden text has to be ignored
+ if(!elem.bIsHidden)
+ {
+ nEndPosition += elem.sText.getLength();
+ if(elem.xAlternatives.is())
+ {
+ SpellErrorDescription aDesc( false, elem.xAlternatives->getWord(),
+ elem.xAlternatives->getLocale(), elem.xAlternatives->getAlternatives(), nullptr);
+ SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG);
+ aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
+ m_xSentenceED->SetAttrib(aSpellErrorDescription, nStartPosition, nEndPosition);
+ }
+ else if(elem.bIsGrammarError )
+ {
+ beans::PropertyValues aProperties = elem.aGrammarError.aProperties;
+ OUString sFullCommentURL;
+ sal_Int32 i = 0;
+ while ( sFullCommentURL.isEmpty() && i < aProperties.getLength() )
+ {
+ if ( aProperties[i].Name == "FullCommentURL" )
+ {
+ uno::Any aValue = aProperties[i].Value;
+ aValue >>= sFullCommentURL;
+ }
+ ++i;
+ }
+
+ SpellErrorDescription aDesc( true,
+ elem.sText,
+ LanguageTag::convertToLocale( elem.eLanguage ),
+ elem.aGrammarError.aSuggestions,
+ elem.xGrammarChecker,
+ &elem.sDialogTitle,
+ &elem.aGrammarError.aFullComment,
+ &elem.aGrammarError.aRuleIdentifier,
+ &sFullCommentURL );
+
+ SfxGrabBagItem aSpellErrorDescriptionItem(EE_CHAR_GRABBAG);
+ aSpellErrorDescriptionItem.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
+ m_xSentenceED->SetAttrib(aSpellErrorDescriptionItem, nStartPosition, nEndPosition);
+ }
+
+ if (elem.bIsField)
+ m_xSentenceED->SetAttrib(SvxColorItem(COL_LIGHTGRAY, EE_CHAR_BKGCOLOR), nStartPosition, nEndPosition);
+ m_xSentenceED->SetAttrib(SvxLanguageItem(elem.eLanguage, EE_CHAR_LANGUAGE), nStartPosition, nEndPosition);
+ nStartPosition = nEndPosition;
+ }
+ }
+ //the edit field needs to be modified to apply the change from the ApplyChangeAllList
+ if(!bHasReplaced)
+ m_xSentenceED->ClearModifyFlag();
+ m_xSentenceED->ResetUndo();
+ m_xUndoPB->set_sensitive(false);
+ bRet = nStartPosition > 0;
+ }
+ return bRet;
+}
+/*-------------------------------------------------------------------------
+ replace errors that have a replacement in the ChangeAllList
+ returns false if the result doesn't contain errors after the replacement
+ -----------------------------------------------------------------------*/
+bool SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasReplaced)
+{
+ bHasReplaced = false;
+ bool bRet = true;
+ Reference<XDictionary> xChangeAll = LinguMgr::GetChangeAllList();
+ if(!xChangeAll->getCount())
+ return bRet;
+ bRet = false;
+ for (auto & elem : rSentence)
+ {
+ if(elem.xAlternatives.is())
+ {
+ const OUString &rString = elem.sText;
+
+ Reference<XDictionaryEntry> xEntry = xChangeAll->getEntry(rString);
+
+ if(xEntry.is())
+ {
+ elem.sText = getDotReplacementString(rString, xEntry->getReplacementText());
+ elem.xAlternatives = nullptr;
+ bHasReplaced = true;
+ }
+ else
+ bRet = true;
+ }
+ else if( elem.bIsGrammarError )
+ bRet = true;
+ }
+ return bRet;
+}
+
+SentenceEditWindow_Impl::SentenceEditWindow_Impl()
+ : m_pSpellDialog(nullptr)
+ , m_pToolbar(nullptr)
+ , m_nErrorStart(0)
+ , m_nErrorEnd(0)
+ , m_bIsUndoEditMode(false)
+{
+}
+
+void SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ Size aSize(pDrawingArea->get_approximate_digit_width() * 60,
+ pDrawingArea->get_text_height() * 6);
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+ WeldEditView::SetDrawingArea(pDrawingArea);
+ // tdf#132288 don't merge equal adjacent attributes
+ m_xEditEngine->DisableAttributeExpanding();
+
+ // tdf#142631 use document background color in this widget
+ Color aBgColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+ rDevice.SetBackground(aBgColor);
+ m_xEditView->SetBackgroundColor(aBgColor);
+ m_xEditEngine->SetBackgroundColor(aBgColor);
+}
+
+SentenceEditWindow_Impl::~SentenceEditWindow_Impl()
+{
+}
+
+namespace
+{
+ const EECharAttrib* FindCharAttrib(int nPosition, sal_uInt16 nWhich, std::vector<EECharAttrib>& rAttribList)
+ {
+ for (auto it = rAttribList.rbegin(); it != rAttribList.rend(); ++it)
+ {
+ const auto& rTextAtr = *it;
+ if (rTextAtr.pAttr->Which() != nWhich)
+ continue;
+ if (rTextAtr.nStart <= nPosition && rTextAtr.nEnd >= nPosition)
+ {
+ return &rTextAtr;
+ }
+ }
+
+ return nullptr;
+ }
+
+ void ExtractErrorDescription(const EECharAttrib& rEECharAttrib, SpellErrorDescription& rSpellErrorDescription)
+ {
+ css::uno::Sequence<css::uno::Any> aSequence;
+ static_cast<const SfxGrabBagItem*>(rEECharAttrib.pAttr)->GetGrabBag().find("SpellErrorDescription")->second >>= aSequence;
+ rSpellErrorDescription.fromSequence(aSequence);
+ }
+}
+
+/*-------------------------------------------------------------------------
+ The selection before inputting a key may have a range or not
+ and it may be inside or outside of field or error attributes.
+ A range may include the attribute partially, completely or together
+ with surrounding text. It may also contain more than one attribute
+ or no attribute at all.
+ Depending on this starting conditions some actions are necessary:
+ Attempts to delete a field are only allowed if the selection is the same
+ as the field's selection. Otherwise the field has to be selected and the key
+ input action has to be skipped.
+ Input of text at the start of the field requires the field attribute to be
+ corrected - it is not allowed to grow.
+
+ In case of errors the appending of text should grow the error attribute because
+ that is what the user usually wants to do.
+
+ Backspace at the start of the attribute requires to find out if a field ends
+ directly in front of the cursor position. In case of a field this attribute has to be
+ selected otherwise the key input method is allowed.
+
+ All changes outside of the error attributes switch the dialog mode to a "Undo edit" state that
+ removes all visible attributes and switches off further attribute checks.
+ Undo in this restarts the dialog with a current sentence newly presented.
+ All changes to the sentence are undone including the ones before the "Undo edit state" has been reached
+
+ We end up with 9 types of selection
+ 1 (LEFT_NO) - no range, start of attribute - can also be 3 at the same time
+ 2 (INSIDE_NO) - no range, inside of attribute
+ 3 (RIGHT_NO) - no range, end of attribute - can also be 1 at the same time
+ 4 (FULL) - range, same as attribute
+ 5 (INSIDE_YES) - range, inside of the attribute
+ 6 (BRACE)- range, from outside of the attribute to the inside or
+ including the complete attribute and something outside,
+ maybe more than one attribute
+ 7 (OUTSIDE_NO) - no range, not at an attribute
+ 8 (OUTSIDE_YES) - range, completely outside of all attributes
+
+ What has to be done depending on the attribute type involved
+ possible actions: UE - Undo edit mode
+ CO - Continue, no additional action is required
+ FS - Field has to be completely selected
+ EX - The attribute has to be expanded to include the added text
+
+ 1 - backspace delete any other
+ UE on field FS on error CO on field FS on error CO
+
+ 2 - on field FS on error C
+ 3 - backspace delete any other
+ on field FS on error CO UE on field UE on error EX
+
+ if 1 and 3 happen to apply both then backspace and other handling is 1 delete is 3
+
+ 4 - on field UE and on error CO
+ 5 - on field FS and on error CO
+ 6 - on field FS and on error UE
+ 7 - UE
+ 8 - UE
+ -----------------------------------------------------------------------*/
+#define INVALID 0
+#define LEFT_NO 1
+#define INSIDE_NO 2
+#define RIGHT_NO 3
+#define FULL 4
+#define INSIDE_YES 5
+#define BRACE 6
+#define OUTSIDE_NO 7
+#define OUTSIDE_YES 8
+
+#define ACTION_UNDOEDIT 0
+#define ACTION_CONTINUE 1
+#define ACTION_SELECTFIELD 2
+#define ACTION_EXPAND 3
+
+bool SentenceEditWindow_Impl::KeyInput(const KeyEvent& rKeyEvt)
+{
+ if (rKeyEvt.GetKeyCode().GetCode() == KEY_TAB)
+ return false;
+
+ bool bConsumed = false;
+
+ bool bChange = TextEngine::DoesKeyChangeText( rKeyEvt );
+ if (bChange && !IsUndoEditMode())
+ {
+ bConsumed = true;
+
+ ESelection aCurrentSelection(m_xEditView->GetSelection());
+ aCurrentSelection.Adjust();
+
+ //determine if the selection contains a field
+ bool bHasFieldLeft = false;
+ bool bHasErrorLeft = false;
+
+ bool bHasRange = aCurrentSelection.HasRange();
+ sal_uInt8 nSelectionType = 0; // invalid type!
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ auto nCursor = aCurrentSelection.nStartPos;
+ const EECharAttrib* pBackAttr = FindCharAttrib(nCursor, EE_CHAR_BKGCOLOR, aAttribList);
+ const EECharAttrib* pErrorAttr = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ const EECharAttrib* pBackAttrLeft = nullptr;
+ const EECharAttrib* pErrorAttrLeft = nullptr;
+
+ bool bHasField = pBackAttr != nullptr && (bHasRange || pBackAttr->nEnd > nCursor);
+ bool bHasError = pErrorAttr != nullptr && (bHasRange || pErrorAttr->nEnd > nCursor);
+ if (bHasRange)
+ {
+ if (pBackAttr &&
+ pBackAttr->nStart == aCurrentSelection.nStartPos &&
+ pBackAttr->nEnd == aCurrentSelection.nEndPos)
+ {
+ nSelectionType = FULL;
+ }
+ else if (pErrorAttr &&
+ pErrorAttr->nStart <= aCurrentSelection.nStartPos &&
+ pErrorAttr->nEnd >= aCurrentSelection.nEndPos)
+ {
+ nSelectionType = INSIDE_YES;
+ }
+ else
+ {
+ nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO;
+ while (nCursor < aCurrentSelection.nEndPos)
+ {
+ ++nCursor;
+ const EECharAttrib* pIntBackAttr = FindCharAttrib(nCursor, EE_CHAR_BKGCOLOR, aAttribList);
+ const EECharAttrib* pIntErrorAttr = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ //if any attr has been found then BRACE
+ if (pIntBackAttr || pIntErrorAttr)
+ nSelectionType = BRACE;
+ //the field has to be selected
+ if (pIntBackAttr && !pBackAttr)
+ pBackAttr = pIntBackAttr;
+ bHasField |= pIntBackAttr != nullptr;
+ }
+ }
+ }
+ else
+ {
+ //no range selection: then 1 2 3 and 8 are possible
+ const EECharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr;
+ if (pCurAttr)
+ {
+ nSelectionType = pCurAttr->nStart == aCurrentSelection.nStartPos ?
+ LEFT_NO : pCurAttr->nEnd == aCurrentSelection.nEndPos ? RIGHT_NO : INSIDE_NO;
+ }
+ else
+ nSelectionType = OUTSIDE_NO;
+
+ bHasFieldLeft = pBackAttr && pBackAttr->nEnd == nCursor;
+ if(bHasFieldLeft)
+ {
+ pBackAttrLeft = pBackAttr;
+ pBackAttr = nullptr;
+ }
+ bHasErrorLeft = pErrorAttr && pErrorAttr->nEnd == nCursor;
+ if(bHasErrorLeft)
+ {
+ pErrorAttrLeft = pErrorAttr;
+ pErrorAttr = nullptr;
+ }
+
+ //check previous position if this exists
+ //that is a redundant in the case the attribute found above already is on the left cursor side
+ //but it's o.k. for two errors/fields side by side
+ if (nCursor)
+ {
+ --nCursor;
+ pBackAttrLeft = FindCharAttrib(nCursor, EE_CHAR_BKGCOLOR, aAttribList);
+ pErrorAttrLeft = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ bHasFieldLeft = pBackAttrLeft !=nullptr;
+ bHasErrorLeft = pErrorAttrLeft != nullptr;
+ ++nCursor;
+ }
+ }
+ //Here we have to determine if the error found is the one currently active
+ bool bIsErrorActive = (pErrorAttr && pErrorAttr->nStart == m_nErrorStart) ||
+ (pErrorAttrLeft && pErrorAttrLeft->nStart == m_nErrorStart);
+
+ SAL_WARN_IF(
+ nSelectionType == INVALID, "cui.dialogs",
+ "selection type not set");
+
+ const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
+ bool bDelete = rKeyCode.GetCode() == KEY_DELETE;
+ bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE;
+
+ sal_Int8 nAction = ACTION_CONTINUE;
+ switch(nSelectionType)
+ {
+// 1 - backspace delete any other
+// UE on field FS on error CO on field FS on error CO
+ case LEFT_NO :
+ if(bBackspace)
+ {
+ nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
+ //to force the use of pBackAttrLeft
+ pBackAttr = nullptr;
+ }
+ else if(bDelete)
+ nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
+ else
+ nAction = bHasError && !nCursor ? ACTION_CONTINUE :
+ bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT;
+ break;
+// 2 - on field FS on error C
+ case INSIDE_NO :
+ nAction = bHasField ? ACTION_SELECTFIELD :
+ bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT;
+ break;
+// 3 - backspace delete any other
+// on field FS on error CO UE on field UE on error EX
+ case RIGHT_NO :
+ if(bBackspace)
+ nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE;
+ else if(bDelete)
+ nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT;
+ else
+ nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND :
+ bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT;
+ break;
+// 4 - on field UE and on error CO
+ case FULL :
+ nAction = ACTION_UNDOEDIT;
+ break;
+// 5 - on field FS and on error CO
+ case INSIDE_YES :
+ nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
+ break;
+// 6 - on field FS and on error UE
+ case BRACE :
+ nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
+ break;
+// 7 - UE
+// 8 - UE
+ case OUTSIDE_NO :
+ case OUTSIDE_YES:
+ nAction = ACTION_UNDOEDIT;
+ break;
+ }
+ //save the current paragraph
+ sal_Int32 nCurrentLen = m_xEditEngine->GetText().getLength();
+ if (nAction != ACTION_SELECTFIELD)
+ {
+ m_xEditView->PostKeyEvent(rKeyEvt);
+ }
+ else
+ {
+ const EECharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft;
+ if (pCharAttr)
+ m_xEditView->SetSelection(ESelection(0, pCharAttr->nStart, 0, pCharAttr->nEnd));
+ }
+ if(nAction == ACTION_EXPAND)
+ {
+ DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error");
+ //text has been added on the right and only the 'error attribute has to be corrected
+ if (pErrorAttrLeft)
+ {
+ SpellErrorDescription aSpellErrorDescription;
+ ExtractErrorDescription(*pErrorAttrLeft, aSpellErrorDescription);
+
+ std::unique_ptr<SfxPoolItem> xNewError(pErrorAttrLeft->pAttr->Clone());
+ sal_Int32 nStart = pErrorAttrLeft->nStart;
+ sal_Int32 nEnd = pErrorAttrLeft->nEnd + 1;
+ m_xEditEngine->RemoveAttribs(ESelection(0, nStart, 0, nEnd), false, EE_CHAR_GRABBAG);
+ SetAttrib(*xNewError, nStart, nEnd);
+ //only active errors move the mark
+ if (bIsErrorActive)
+ {
+ bool bGrammar = aSpellErrorDescription.bIsGrammarError;
+ MoveErrorMarkTo(nStart, nEnd, bGrammar);
+ }
+ }
+ //text has been added on the left then the error attribute has to be expanded and the
+ //field attribute on the right - if any - has to be contracted
+ else if (pErrorAttr)
+ {
+ SpellErrorDescription aSpellErrorDescription;
+ ExtractErrorDescription(*pErrorAttr, aSpellErrorDescription);
+
+ //determine the change
+ sal_Int32 nAddedChars = m_xEditEngine->GetText().getLength() - nCurrentLen;
+
+ std::unique_ptr<SfxPoolItem> xNewError(pErrorAttr->pAttr->Clone());
+ sal_Int32 nStart = pErrorAttr->nStart + nAddedChars;
+ sal_Int32 nEnd = pErrorAttr->nEnd + nAddedChars;
+ m_xEditEngine->RemoveAttribs(ESelection(0, nStart, 0, nEnd), false, EE_CHAR_GRABBAG);
+ nStart = pErrorAttr->nStart;
+ SetAttrib(*xNewError, nStart, nEnd);
+ //only if the error is active the mark is moved here
+ if (bIsErrorActive)
+ {
+ bool bGrammar = aSpellErrorDescription.bIsGrammarError;
+ MoveErrorMarkTo(nStart, nEnd, bGrammar);
+ }
+ xNewError.reset();
+
+ if (pBackAttrLeft)
+ {
+ std::unique_ptr<SfxPoolItem> xNewBack(pBackAttrLeft->pAttr->Clone());
+ sal_Int32 _nStart = pBackAttrLeft->nStart + nAddedChars;
+ sal_Int32 _nEnd = pBackAttrLeft->nEnd + nAddedChars;
+ m_xEditEngine->RemoveAttribs(ESelection(0, _nStart, 0, _nEnd), false, EE_CHAR_BKGCOLOR);
+ _nStart = pBackAttrLeft->nStart;
+ SetAttrib(*xNewBack, _nStart, _nEnd);
+ }
+ }
+ }
+ else if(nAction == ACTION_UNDOEDIT)
+ {
+ SetUndoEditMode(true);
+ }
+ //make sure the error positions are correct after text changes
+ //the old attribute may have been deleted
+ //all changes inside of the current error leave the error attribute at the current
+ //start position
+ if (!IsUndoEditMode() && bIsErrorActive)
+ {
+ const EECharAttrib* pFontColor = FindCharAttrib(nCursor, EE_CHAR_COLOR, aAttribList);
+ const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_GRABBAG, aAttribList);
+ if (pFontColor && pErrorAttrib)
+ {
+ m_nErrorStart = pFontColor->nStart;
+ m_nErrorEnd = pFontColor->nEnd;
+ if (pErrorAttrib->nStart != m_nErrorStart || pErrorAttrib->nEnd != m_nErrorEnd)
+ {
+ std::unique_ptr<SfxPoolItem> xNewError(pErrorAttrib->pAttr->Clone());
+ assert(pErrorAttr);
+ m_xEditEngine->RemoveAttribs(ESelection(0, pErrorAttr->nStart, 0, pErrorAttr->nEnd), false, EE_CHAR_GRABBAG);
+ SetAttrib(*xNewError, m_nErrorStart, m_nErrorEnd);
+ }
+ }
+ }
+ //this is not a modification anymore
+ if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode)
+ CallModifyLink();
+ }
+ else
+ bConsumed = m_xEditView->PostKeyEvent(rKeyEvt);
+
+ return bConsumed;
+}
+
+void SentenceEditWindow_Impl::Init(weld::Toolbar* pToolbar)
+{
+ m_pToolbar = pToolbar;
+ m_pToolbar->connect_clicked(LINK(this,SentenceEditWindow_Impl,ToolbarHdl));
+}
+
+IMPL_LINK(SentenceEditWindow_Impl, ToolbarHdl, const OString&, rCurItemId, void)
+{
+ if (rCurItemId == "paste")
+ {
+ m_xEditView->Paste();
+ CallModifyLink();
+ }
+ else if (rCurItemId == "insert")
+ {
+ if (auto pImplFncGetSpecialChars = vcl::GetGetSpecialCharsFunction())
+ {
+ OUString aChars = pImplFncGetSpecialChars(GetDrawingArea(), m_xEditEngine->GetStandardFont(0));
+ if (!aChars.isEmpty())
+ {
+ ESelection aCurrentSelection(m_xEditView->GetSelection());
+ m_xEditEngine->QuickInsertText(aChars, aCurrentSelection);
+ CallModifyLink();
+ }
+ }
+ }
+}
+
+bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css::uno::Reference<css::linguistic2::XSpellChecker1>& xSpell )
+{
+ if (bIgnoreCurrentError)
+ m_aIgnoreErrorsAt.insert( m_nErrorStart );
+
+ const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
+
+ if (m_nErrorEnd >= nTextLen - 1)
+ return false;
+ //if it's not already modified the modified flag has to be reset at the end of the marking
+ bool bModified = IsModified();
+ bool bRet = false;
+ const sal_Int32 nOldErrorStart = m_nErrorStart;
+ const sal_Int32 nOldErrorEnd = m_nErrorEnd;
+
+ //create a cursor behind the end of the last error
+ //- or at 0 at the start of the sentence
+ sal_Int32 nCursor(m_nErrorEnd ? m_nErrorEnd + 1 : 0);
+
+ //search for SpellErrorDescription
+ SpellErrorDescription aSpellErrorDescription;
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ //iterate over the text and search for the next error that maybe has
+ //to be replace by a ChangeAllList replacement
+ bool bGrammarError = false;
+ while (nCursor < nTextLen)
+ {
+ const SpellErrorDescription* pSpellErrorDescription = nullptr;
+ const EECharAttrib* pEECharAttrib = nullptr;
+
+ sal_Int32 nMinPos = nTextLen + 1;
+ for (const auto& rTextAtr : aAttribList)
+ {
+ if (rTextAtr.pAttr->Which() != EE_CHAR_GRABBAG)
+ continue;
+ if (rTextAtr.nEnd > nCursor && rTextAtr.nStart < nMinPos)
+ {
+ nMinPos = rTextAtr.nStart;
+ pEECharAttrib = &rTextAtr;
+ }
+ }
+
+ if (pEECharAttrib)
+ {
+ ExtractErrorDescription(*pEECharAttrib, aSpellErrorDescription);
+
+ bGrammarError = aSpellErrorDescription.bIsGrammarError;
+ m_nErrorStart = pEECharAttrib->nStart;
+ m_nErrorEnd = pEECharAttrib->nEnd;
+
+ pSpellErrorDescription = &aSpellErrorDescription;
+ }
+
+ nCursor = std::max(nCursor, nMinPos); // move forward if possible
+
+ // maybe the error found here is already in the ChangeAllList and has to be replaced
+ Reference<XDictionary> xChangeAll = LinguMgr::GetChangeAllList();
+ Reference<XDictionaryEntry> xEntry;
+
+ if (xChangeAll->getCount() && pSpellErrorDescription &&
+ (xEntry = xChangeAll->getEntry( pSpellErrorDescription->sErrorText )).is())
+ {
+ OUString sReplacement(getDotReplacementString(GetErrorText(), xEntry->getReplacementText()));
+
+ int nLenChange = ChangeMarkedWord(sReplacement, LanguageTag::convertToLanguageType(pSpellErrorDescription->aLocale));
+
+ nCursor += sReplacement.getLength();
+
+ if (nLenChange)
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+ // maybe the error found here is already added to the dictionary and has to be ignored
+ }
+ else if(pSpellErrorDescription && !bGrammarError &&
+ xSpell->isValid(GetErrorText(),
+ static_cast<sal_uInt16>(LanguageTag::convertToLanguageType( pSpellErrorDescription->aLocale )),
+ Sequence< PropertyValue >() ))
+ {
+ ++nCursor;
+ }
+ else
+ break;
+ }
+
+ //if an attrib has been found search for the end of the error string
+ if (nCursor < nTextLen)
+ {
+ MoveErrorMarkTo(nCursor, m_nErrorEnd, bGrammarError);
+ bRet = true;
+ //add an undo action
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_NEXTERROR, GetSpellDialog()->aDialogUndoLink));
+ pAction->SetErrorMove(nOldErrorStart, nOldErrorEnd);
+
+ if (GetErrorDescription(aSpellErrorDescription, nOldErrorStart))
+ {
+ pAction->SetErrorLanguageSelected(aSpellErrorDescription.aSuggestions.hasElements() &&
+ LanguageTag(aSpellErrorDescription.aLocale).getLanguageType() == GetSpellDialog()->m_xLanguageLB->get_active_id());
+ }
+ else
+ pAction->SetErrorLanguageSelected(false);
+
+ AddUndoAction(std::move(pAction));
+ }
+ else
+ m_nErrorStart = m_nErrorEnd = nTextLen;
+ if( !bModified )
+ ClearModifyFlag();
+ SpellDialog* pSpellDialog = GetSpellDialog();
+ pSpellDialog->m_xIgnorePB->set_sensitive(bRet);
+ pSpellDialog->m_xIgnoreAllPB->set_sensitive(bRet);
+ pSpellDialog->m_xAutoCorrPB->set_sensitive(bRet);
+ pSpellDialog->m_xAddToDictMB->set_sensitive(bRet);
+ pSpellDialog->m_xAddToDictPB->set_sensitive(bRet);
+ return bRet;
+}
+
+void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_Int32 nStart, sal_Int32 nEnd, bool bGrammarError)
+{
+ ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_COLOR);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL);
+
+ // tdf#116566 Use color defined in the current Color Scheme
+ Color aSpellErrorCollor = svtools::ColorConfig().GetColorValue(svtools::SPELL).nColor;
+
+ // TODO: Create a new Color Scheme entry for grammar mistakes and use it below
+ // instead of using hardcoded COL_LIGHTBLUE
+ SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
+ aSet.Put(SvxColorItem(bGrammarError ? COL_LIGHTBLUE : aSpellErrorCollor, EE_CHAR_COLOR));
+ aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT));
+ aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT_CJK));
+ aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT_CTL));
+
+ m_xEditEngine->QuickSetAttribs(aSet, ESelection(0, nStart, 0, nEnd));
+
+ // Set the selection so the editview will autoscroll to make this visible
+ // unless (tdf#133958) the selection already overlaps this range
+ ESelection aCurrentSelection = m_xEditView->GetSelection();
+ aCurrentSelection.Adjust();
+ bool bCurrentSelectionInRange = nStart <= aCurrentSelection.nEndPos && aCurrentSelection.nStartPos <= nEnd;
+ if (!bCurrentSelectionInRange)
+ {
+ m_xEditView->SetSelection(ESelection(0, nStart));
+ }
+
+ Invalidate();
+
+ m_nErrorStart = nStart;
+ m_nErrorEnd = nEnd;
+}
+
+int SentenceEditWindow_Impl::ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage)
+{
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ //calculate length changes
+ auto nDiffLen = rNewWord.getLength() - m_nErrorEnd + m_nErrorStart;
+ //Remove spell error attribute
+ m_xEditEngine->UndoActionStart(SPELLUNDO_MOVE_ERROREND);
+ const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_GRABBAG, aAttribList);
+ DBG_ASSERT(pErrorAttrib, "no error attribute found");
+ bool bSpellErrorDescription = false;
+ SpellErrorDescription aSpellErrorDescription;
+ if (pErrorAttrib)
+ {
+ ExtractErrorDescription(*pErrorAttrib, aSpellErrorDescription);
+ m_xEditEngine->RemoveAttribs(ESelection(0, pErrorAttrib->nStart, 0, pErrorAttrib->nEnd), false, EE_CHAR_GRABBAG);
+ bSpellErrorDescription = true;
+ }
+
+ const EECharAttrib* pBackAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_BKGCOLOR, aAttribList);
+
+ ESelection aSel(0, m_nErrorStart, 0, m_nErrorEnd);
+ m_xEditEngine->QuickInsertText(rNewWord, aSel);
+
+ const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
+
+ if (nDiffLen)
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ if (!m_nErrorStart)
+ {
+ //attributes following an error at the start of the text are not moved but expanded from the
+ //text engine - this is done to keep full-paragraph-attributes
+ //in the current case that handling is not desired
+ const EECharAttrib* pLangAttrib = FindCharAttrib(m_nErrorEnd, EE_CHAR_LANGUAGE, aAttribList);
+
+ if (pLangAttrib && !pLangAttrib->nStart && pLangAttrib->nEnd == nTextLen)
+ {
+ LanguageType eNewLanguage = static_cast<const SvxLanguageItem*>(pLangAttrib->pAttr)->GetLanguage();
+ m_xEditEngine->RemoveAttribs(ESelection(0, pLangAttrib->nStart, 0, pLangAttrib->nEnd), false, EE_CHAR_LANGUAGE);
+ SetAttrib(SvxLanguageItem(eNewLanguage, EE_CHAR_LANGUAGE), m_nErrorEnd + nDiffLen, nTextLen);
+ }
+ }
+
+ // undo expanded attributes!
+ if (pBackAttrib && pBackAttrib->nStart < m_nErrorStart && pBackAttrib->nEnd == m_nErrorEnd + nDiffLen)
+ {
+ std::unique_ptr<SfxPoolItem> xNewBackground(pBackAttrib->pAttr->Clone());
+ const sal_Int32 nStart = pBackAttrib->nStart;
+
+ m_xEditEngine->RemoveAttribs(ESelection(0, pBackAttrib->nStart, 0, pBackAttrib->nEnd), false, EE_CHAR_BKGCOLOR);
+
+ SetAttrib(*xNewBackground, nStart, m_nErrorStart);
+ }
+ m_xEditEngine->SetModified();
+
+ //adjust end position
+ tools::Long nEndTemp = m_nErrorEnd;
+ nEndTemp += nDiffLen;
+ m_nErrorEnd = static_cast<sal_Int32>(nEndTemp);
+
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink));
+ pAction->SetOffset(nDiffLen);
+ AddUndoAction(std::move(pAction));
+ if (bSpellErrorDescription)
+ {
+ SfxGrabBagItem aSpellErrorDescriptionItem(EE_CHAR_GRABBAG);
+ aSpellErrorDescriptionItem.GetGrabBag()["SpellErrorDescription"] <<= aSpellErrorDescription.toSequence();
+ SetAttrib(aSpellErrorDescriptionItem, m_nErrorStart, m_nErrorEnd);
+ }
+ SetAttrib(SvxLanguageItem(eLanguage, EE_CHAR_LANGUAGE), m_nErrorStart, m_nErrorEnd);
+ m_xEditEngine->UndoActionEnd();
+
+ Invalidate();
+
+ return nDiffLen;
+}
+
+OUString SentenceEditWindow_Impl::GetErrorText() const
+{
+ return m_xEditEngine->GetText(ESelection(0, m_nErrorStart, 0, m_nErrorEnd));
+}
+
+bool SentenceEditWindow_Impl::GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, sal_Int32 nPosition)
+{
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ if (const EECharAttrib* pEECharAttrib = FindCharAttrib(nPosition, EE_CHAR_GRABBAG, aAttribList))
+ {
+ ExtractErrorDescription(*pEECharAttrib, rSpellErrorDescription);
+ return true;
+ }
+
+ return false;
+}
+
+bool SentenceEditWindow_Impl::GetAlternatives(SpellErrorDescription& rSpellErrorDescription)
+{
+ return GetErrorDescription(rSpellErrorDescription, m_nErrorStart);
+}
+
+void SentenceEditWindow_Impl::RestoreCurrentError()
+{
+ SpellErrorDescription aSpellErrorDescription;
+ if (GetErrorDescription(aSpellErrorDescription, m_nErrorStart))
+ {
+ if (aSpellErrorDescription.sErrorText != GetErrorText() )
+ ChangeMarkedWord(aSpellErrorDescription.sErrorText, LanguageTag::convertToLanguageType(aSpellErrorDescription.aLocale));
+ }
+}
+
+void SentenceEditWindow_Impl::SetAlternatives( const Reference< XSpellAlternatives>& xAlt )
+{
+ OUString aWord;
+ lang::Locale aLocale;
+ uno::Sequence< OUString > aAlts;
+ if (xAlt.is())
+ {
+ aWord = xAlt->getWord();
+ aLocale = xAlt->getLocale();
+ aAlts = xAlt->getAlternatives();
+ }
+ SpellErrorDescription aDesc( false, aWord, std::move(aLocale), aAlts, nullptr);
+ SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG);
+ aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
+ SetAttrib(aSpellErrorDescription, m_nErrorStart, m_nErrorEnd);
+}
+
+void SentenceEditWindow_Impl::SetAttrib(const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd)
+{
+ SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
+ aSet.Put(rItem);
+ m_xEditEngine->QuickSetAttribs(aSet, ESelection(0, nStart, 0, nEnd));
+ Invalidate();
+}
+
+void SentenceEditWindow_Impl::SetText( const OUString& rStr )
+{
+ m_nErrorStart = m_nErrorEnd = 0;
+ m_xEditEngine->SetText(rStr);
+}
+
+namespace {
+
+struct LanguagePosition_Impl
+{
+ sal_Int32 nPosition;
+ LanguageType eLanguage;
+
+ LanguagePosition_Impl(sal_Int32 nPos, LanguageType eLang) :
+ nPosition(nPos),
+ eLanguage(eLang)
+ {}
+};
+
+}
+
+typedef std::vector<LanguagePosition_Impl> LanguagePositions_Impl;
+
+static void lcl_InsertBreakPosition_Impl(
+ LanguagePositions_Impl& rBreakPositions, sal_Int32 nInsert, LanguageType eLanguage)
+{
+ LanguagePositions_Impl::iterator aStart = rBreakPositions.begin();
+ while(aStart != rBreakPositions.end())
+ {
+ if(aStart->nPosition == nInsert)
+ {
+ //the language of following starts has to overwrite
+ //the one of previous ends
+ aStart->eLanguage = eLanguage;
+ return;
+ }
+ else if(aStart->nPosition > nInsert)
+ {
+
+ rBreakPositions.insert(aStart, LanguagePosition_Impl(nInsert, eLanguage));
+ return;
+ }
+ else
+ ++aStart;
+ }
+ rBreakPositions.emplace_back(nInsert, eLanguage);
+}
+
+/*-------------------------------------------------------------------------
+ Returns the text in spell portions. Each portion contains text with an
+ equal language and attribute. The spell alternatives are empty.
+ -----------------------------------------------------------------------*/
+svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
+{
+ svx::SpellPortions aRet;
+
+ const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ if (nTextLen)
+ {
+ int nCursor(0);
+ LanguagePositions_Impl aBreakPositions;
+ const EECharAttrib* pLastLang = nullptr;
+ const EECharAttrib* pLastError = nullptr;
+ LanguageType eLang = LANGUAGE_DONTKNOW;
+ const EECharAttrib* pError = nullptr;
+ while (nCursor < nTextLen)
+ {
+ const EECharAttrib* pLang = FindCharAttrib(nCursor, EE_CHAR_LANGUAGE, aAttribList);
+ if(pLang && pLang != pLastLang)
+ {
+ eLang = static_cast<const SvxLanguageItem*>(pLang->pAttr)->GetLanguage();
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->nStart, eLang);
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->nEnd, eLang);
+ pLastLang = pLang;
+ }
+ pError = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ if (pError && pLastError != pError)
+ {
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pError->nStart, eLang);
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pError->nEnd, eLang);
+ pLastError = pError;
+
+ }
+ ++nCursor;
+ }
+
+ if (aBreakPositions.empty())
+ {
+ //if all content has been overwritten the attributes may have been removed, too
+ svx::SpellPortion aPortion1;
+ aPortion1.eLanguage = GetSpellDialog()->GetSelectedLang_Impl();
+
+ aPortion1.sText = m_xEditEngine->GetText(ESelection(0, 0, 0, nTextLen));
+
+ aRet.push_back(aPortion1);
+ }
+ else
+ {
+ LanguagePositions_Impl::iterator aStart = aBreakPositions.begin();
+ //start should always be Null
+ eLang = aStart->eLanguage;
+ sal_Int32 nStart = aStart->nPosition;
+ DBG_ASSERT(!nStart, "invalid start position - language attribute missing?");
+ ++aStart;
+
+ while(aStart != aBreakPositions.end())
+ {
+ svx::SpellPortion aPortion1;
+ aPortion1.eLanguage = eLang;
+
+ aPortion1.sText = m_xEditEngine->GetText(ESelection(0, nStart, 0, aStart->nPosition));
+
+ bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end();
+ if( bIsIgnoreError )
+ {
+ aPortion1.bIgnoreThisError = true;
+ }
+ aRet.push_back(aPortion1);
+ nStart = aStart->nPosition;
+ eLang = aStart->eLanguage;
+ ++aStart;
+ }
+ }
+
+ // quick partly fix of #i71318. Correct fix needs to patch the EditEngine itself...
+ // this one will only prevent text from disappearing. It may to not have the
+ // correct language and will probably not spell checked...
+ const sal_uInt32 nPara = m_xEditEngine->GetParagraphCount();
+ if (nPara > 1)
+ {
+ OUStringBuffer aLeftOverText;
+ for (sal_uInt32 i = 1; i < nPara; ++i)
+ {
+ aLeftOverText.append("\x0a"); // the manual line break...
+ aLeftOverText.append(m_xEditEngine->GetText(i));
+ }
+ if (pError)
+ { // we need to add a new portion containing the left-over text
+ svx::SpellPortion aPortion2;
+ aPortion2.eLanguage = eLang;
+ aPortion2.sText = aLeftOverText.makeStringAndClear();
+ aRet.push_back( aPortion2 );
+ }
+ else
+ { // we just need to append the left-over text to the last portion (which had no errors)
+ aRet[ aRet.size() - 1 ].sText += aLeftOverText;
+ }
+ }
+ }
+
+ return aRet;
+}
+
+void SentenceEditWindow_Impl::Undo()
+{
+ SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager();
+ DBG_ASSERT(GetUndoActionCount(), "no undo actions available" );
+ if(!GetUndoActionCount())
+ return;
+ bool bSaveUndoEdit = IsUndoEditMode();
+ SpellUndoAction_Impl* pUndoAction;
+ //if the undo edit mode is active then undo all changes until the UNDO_EDIT_MODE action has been found
+ do
+ {
+ pUndoAction = static_cast<SpellUndoAction_Impl*>(rUndoMgr.GetUndoAction());
+ rUndoMgr.Undo();
+ }while(bSaveUndoEdit && SPELLUNDO_UNDO_EDIT_MODE != pUndoAction->GetId() && GetUndoActionCount());
+
+ if(bSaveUndoEdit || SPELLUNDO_CHANGE_GROUP == pUndoAction->GetId())
+ GetSpellDialog()->UpdateBoxes_Impl();
+}
+
+void SentenceEditWindow_Impl::ResetUndo()
+{
+ SfxUndoManager& rUndo = m_xEditEngine->GetUndoManager();
+ rUndo.Clear();
+}
+
+void SentenceEditWindow_Impl::AddUndoAction( std::unique_ptr<SfxUndoAction> pAction )
+{
+ SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager();
+ rUndoMgr.AddUndoAction(std::move(pAction));
+ GetSpellDialog()->m_xUndoPB->set_sensitive(true);
+}
+
+size_t SentenceEditWindow_Impl::GetUndoActionCount() const
+{
+ return m_xEditEngine->GetUndoManager().GetUndoActionCount();
+}
+
+void SentenceEditWindow_Impl::UndoActionStart( sal_uInt16 nId )
+{
+ m_xEditEngine->UndoActionStart(nId);
+}
+
+void SentenceEditWindow_Impl::UndoActionEnd()
+{
+ m_xEditEngine->UndoActionEnd();
+}
+
+void SentenceEditWindow_Impl::MoveErrorEnd(tools::Long nOffset)
+{
+ // Shouldn't we always add the real signed value instead???
+ if(nOffset > 0)
+ m_nErrorEnd = m_nErrorEnd - static_cast<sal_Int32>(nOffset);
+ else
+ m_nErrorEnd = m_nErrorEnd - static_cast<sal_Int32>(-nOffset);
+}
+
+
+void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet)
+{
+ DBG_ASSERT(!bSet || m_bIsUndoEditMode != bSet, "SetUndoEditMode with equal values?");
+ m_bIsUndoEditMode = bSet;
+ //disable all buttons except the Change
+ SpellDialog* pSpellDialog = GetSpellDialog();
+ weld::Widget* aControls[] =
+ {
+ pSpellDialog->m_xChangeAllPB.get(),
+ pSpellDialog->m_xExplainFT.get(),
+ pSpellDialog->m_xIgnoreAllPB.get(),
+ pSpellDialog->m_xIgnoreRulePB.get(),
+ pSpellDialog->m_xIgnorePB.get(),
+ pSpellDialog->m_xSuggestionLB.get(),
+ pSpellDialog->m_xSuggestionFT.get(),
+ pSpellDialog->m_xLanguageFT.get(),
+ pSpellDialog->m_xLanguageLB->get_widget(),
+ pSpellDialog->m_xAddToDictMB.get(),
+ pSpellDialog->m_xAddToDictPB.get(),
+ pSpellDialog->m_xAutoCorrPB.get()
+ };
+ for (weld::Widget* pWidget : aControls)
+ pWidget->set_sensitive(false);
+
+ //remove error marks
+ ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_COLOR);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL);
+ Invalidate();
+
+ //put the appropriate action on the Undo-stack
+ AddUndoAction( std::make_unique<SpellUndoAction_Impl>(
+ SPELLUNDO_UNDO_EDIT_MODE, GetSpellDialog()->aDialogUndoLink) );
+ pSpellDialog->m_xChangePB->set_sensitive(true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/about.cxx b/cui/source/dialogs/about.cxx
new file mode 100644
index 000000000..09717ddec
--- /dev/null
+++ b/cui/source/dialogs/about.cxx
@@ -0,0 +1,278 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <about.hxx>
+
+#include <osl/process.h> //osl_getProcessLocale
+#include <sal/log.hxx> //SAL_WARN
+#include <vcl/settings.hxx> //GetSettings
+#include <vcl/svapp.hxx> //Application::
+#include <vcl/virdev.hxx> //VirtualDevice
+#include <vcl/weld.hxx>
+#include <unotools/resmgr.hxx> //Translate
+
+#include <config_buildid.h> //EXTRA_BUILDID
+#include <config_features.h>
+#include <dialmgr.hxx> //CuiResId
+#include <i18nlangtag/languagetag.hxx>
+#include <sfx2/app.hxx> //SfxApplication::loadBrandSvg
+#include <strings.hrc>
+#include <svtools/langhelp.hxx>
+#include <unotools/bootstrap.hxx> //utl::Bootstrap::getBuildIdData
+#include <unotools/configmgr.hxx> //ConfigManager::
+
+#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
+#include <vcl/unohelp2.hxx>
+
+#include <config_feature_opencl.h>
+#if HAVE_FEATURE_OPENCL
+#include <opencl/openclwrapper.hxx>
+#endif
+#include <officecfg/Office/Calc.hxx>
+#include <officecfg/Office/Common.hxx>
+
+using namespace ::com::sun::star::uno;
+
+AboutDialog::AboutDialog(weld::Window *pParent)
+ : GenericDialogController(pParent, "cui/ui/aboutdialog.ui", "AboutDialog"),
+ m_pCreditsButton(m_xBuilder->weld_link_button("btnCredits")),
+ m_pWebsiteButton(m_xBuilder->weld_link_button("btnWebsite")),
+ m_pReleaseNotesButton(m_xBuilder->weld_link_button("btnReleaseNotes")),
+ m_pCloseButton(m_xBuilder->weld_button("btnClose")),
+ m_pCopyButton(m_xBuilder->weld_button("btnCopyVersion")),
+ m_pBrandImage(m_xBuilder->weld_image("imBrand")),
+ m_pAboutImage(m_xBuilder->weld_image("imAbout")),
+ m_pVersionLabel(m_xBuilder->weld_label("lbVersionString")),
+ m_pBuildCaption(m_xBuilder->weld_label("lbBuild")),
+ m_pBuildLabel(m_xBuilder->weld_link_button("lbBuildString")),
+ m_pEnvLabel(m_xBuilder->weld_label("lbEnvString")),
+ m_pUILabel(m_xBuilder->weld_label("lbUIString")),
+ m_pLocaleLabel(m_xBuilder->weld_label("lbLocaleString")),
+ m_pMiscLabel(m_xBuilder->weld_label("lbMiscString")),
+ m_pCopyrightLabel(m_xBuilder->weld_label("lbCopyright")) {
+
+ // Labels
+ m_pVersionLabel->set_label(GetVersionString());
+
+ OUString sbuildId = GetBuildString();
+ if (IsStringValidGitHash(sbuildId)) {
+ const tools::Long nMaxChar = 25;
+ m_pBuildLabel->set_uri("https://gerrit.libreoffice.org/gitweb?p=core.git;a=log;h="
+ + sbuildId);
+ m_pBuildLabel->set_label(sbuildId.getLength() > nMaxChar ? sbuildId.replaceAt(
+ nMaxChar, sbuildId.getLength() - nMaxChar, u"...")
+ : sbuildId);
+ } else {
+ m_pBuildCaption->hide();
+ m_pBuildLabel->hide();
+ }
+
+ m_pEnvLabel->set_label(Application::GetHWOSConfInfo(1));
+ m_pUILabel->set_label(Application::GetHWOSConfInfo(2));
+ m_pLocaleLabel->set_label(GetLocaleString());
+ m_pMiscLabel->set_label(GetMiscString());
+ m_pCopyrightLabel->set_label(GetCopyrightString());
+
+ // Images
+ const tools::Long nWidth(m_pCopyrightLabel->get_preferred_size().getWidth());
+ BitmapEx aBackgroundBitmap;
+
+ if (SfxApplication::loadBrandSvg(Application::GetSettings()
+ .GetStyleSettings()
+ .GetDialogColor()
+ .IsDark()
+ ? "shell/logo_inverted"
+ : "shell/logo",
+ aBackgroundBitmap, nWidth * 0.8)) {
+ ScopedVclPtr<VirtualDevice> m_pVirDev =
+ m_pBrandImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aBackgroundBitmap.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aBackgroundBitmap);
+ m_pBrandImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+ }
+ if (SfxApplication::loadBrandSvg("shell/about", aBackgroundBitmap, nWidth * 0.9)) {
+ ScopedVclPtr<VirtualDevice> m_pVirDev =
+ m_pAboutImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aBackgroundBitmap.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aBackgroundBitmap);
+ m_pAboutImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+ }
+
+ // Links
+ m_pCreditsButton->set_uri(officecfg::Office::Common::Menus::CreditsURL::get());
+
+ OUString sURL(officecfg::Office::Common::Help::StartCenter::InfoURL::get());
+ localizeWebserviceURI(sURL);
+ m_pWebsiteButton->set_uri(sURL);
+
+ // See also SID_WHATSNEW in sfx2/source/appl/appserv.cxx
+ sURL = officecfg::Office::Common::Menus::ReleaseNotesURL::get() +
+ "?LOvers=" + utl::ConfigManager::getProductVersion() + "&LOlocale=" +
+ LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
+ m_pReleaseNotesButton->set_uri(sURL);
+
+ // Handler
+ m_pCopyButton->connect_clicked(LINK(this, AboutDialog, HandleClick));
+ m_pCloseButton->grab_focus();
+}
+
+AboutDialog::~AboutDialog() {}
+
+bool AboutDialog::IsStringValidGitHash(const OUString &hash) {
+ for (int i = 0; i < hash.getLength(); i++) {
+ if (!std::isxdigit(hash[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+OUString AboutDialog::GetVersionString() {
+ OUString sVersion = CuiResId(TranslateId(nullptr, "%ABOUTBOXPRODUCTVERSION%ABOUTBOXPRODUCTVERSIONSUFFIX"));
+
+#ifdef _WIN64
+ sVersion += " (x64)";
+#elif defined(_WIN32)
+ sVersion += " (x86)";
+#endif
+
+#if HAVE_FEATURE_COMMUNITY_FLAVOR
+ sVersion += " / LibreOffice Community";
+#endif
+
+ return sVersion;
+}
+
+OUString AboutDialog::GetBuildString()
+{
+ OUString sBuildId(utl::Bootstrap::getBuildIdData(""));
+ SAL_WARN_IF(sBuildId.isEmpty(), "cui.dialogs", "No BUILDID in bootstrap file");
+
+ return sBuildId;
+}
+
+OUString AboutDialog::GetLocaleString(const bool bLocalized) {
+
+ OUString sLocaleStr;
+
+ rtl_Locale *pLocale;
+ osl_getProcessLocale(&pLocale);
+ if (pLocale && pLocale->Language) {
+ if (pLocale->Country && rtl_uString_getLength(pLocale->Country) > 0)
+ sLocaleStr = OUString::unacquired(&pLocale->Language) + "_" +
+ OUString::unacquired(&pLocale->Country);
+ else
+ sLocaleStr = OUString(pLocale->Language);
+ if (pLocale->Variant && rtl_uString_getLength(pLocale->Variant) > 0)
+ sLocaleStr += OUString(pLocale->Variant);
+ }
+
+ sLocaleStr = Application::GetSettings().GetLanguageTag().getBcp47() + " (" +
+ sLocaleStr + ")";
+
+ OUString aUILocaleStr =
+ Application::GetSettings().GetUILanguageTag().getBcp47();
+ OUString sUILocaleStr;
+ if (bLocalized)
+ sUILocaleStr = CuiResId(RID_CUISTR_ABOUT_UILOCALE);
+ else
+ sUILocaleStr = Translate::get(RID_CUISTR_ABOUT_UILOCALE, Translate::Create("cui", LanguageTag("en-US")));
+
+ if (sUILocaleStr.indexOf("$LOCALE") == -1) {
+ SAL_WARN("cui.dialogs", "translated uilocale string in translations "
+ "doesn't contain $LOCALE placeholder");
+ sUILocaleStr += " $LOCALE";
+ }
+ sUILocaleStr = sUILocaleStr.replaceAll("$LOCALE", aUILocaleStr);
+
+ return sLocaleStr + "; " + sUILocaleStr;
+}
+
+OUString AboutDialog::GetMiscString() {
+
+ OUString sMisc;
+
+ bool const extra = EXTRA_BUILDID[0] != '\0';
+ // extracted from the 'if' to avoid Clang -Wunreachable-code
+ if (extra) {
+ sMisc = EXTRA_BUILDID "\n";
+ }
+
+ OUString aCalcMode; // Calc calculation mode
+
+#if HAVE_FEATURE_OPENCL
+ bool bOpenCL = openclwrapper::GPUEnv::isOpenCLEnabled();
+ if (bOpenCL)
+ aCalcMode += " CL";
+#else
+ const bool bOpenCL = false;
+#endif
+
+ static const bool bThreadingProhibited =
+ std::getenv("SC_NO_THREADED_CALCULATION");
+ bool bThreadedCalc = officecfg::Office::Calc::Formula::Calculation::
+ UseThreadedCalculationForFormulaGroups::get();
+
+ if (!bThreadingProhibited && !bOpenCL && bThreadedCalc) {
+ aCalcMode += " threaded";
+ }
+
+ if (officecfg::Office::Calc::Defaults::Sheet::JumboSheets::get())
+ {
+ aCalcMode += " Jumbo";
+ }
+
+ if (aCalcMode.isEmpty())
+ aCalcMode = " default";
+ sMisc += "Calc:" + aCalcMode;
+
+ return sMisc;
+}
+
+OUString AboutDialog::GetCopyrightString() {
+ OUString sVendorTextStr(CuiResId(RID_CUISTR_ABOUT_VENDOR));
+ OUString aCopyrightString =
+ sVendorTextStr + "\n" + CuiResId(RID_CUISTR_ABOUT_COPYRIGHT) + "\n";
+
+ if (utl::ConfigManager::getProductName() == "LibreOffice")
+ aCopyrightString += CuiResId(RID_CUISTR_ABOUT_BASED_ON);
+ else
+ aCopyrightString += CuiResId(RID_CUISTR_ABOUT_DERIVED);
+
+ return aCopyrightString;
+}
+
+// special labels to comply with previous version info
+// untranslated English for QA
+IMPL_LINK_NOARG(AboutDialog, HandleClick, weld::Button &, void) {
+ css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard =
+ css::datatransfer::clipboard::SystemClipboard::create(
+ comphelper::getProcessComponentContext());
+
+ OUString sInfo = "Version: " + m_pVersionLabel->get_label() + "\n" // version
+ "Build ID: " + GetBuildString() + "\n" + // build id
+ Application::GetHWOSConfInfo(0,false) + "\n" // env+UI
+ "Locale: " + GetLocaleString(false) + "\n" + // locale
+ GetMiscString(); // misc
+
+ vcl::unohelper::TextDataObject::CopyStringTo(sInfo, xClipboard);
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/colorpicker.cxx b/cui/source/dialogs/colorpicker.cxx
new file mode 100644
index 000000000..341cf5bf0
--- /dev/null
+++ b/cui/source/dialogs/colorpicker.cxx
@@ -0,0 +1,1363 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <svx/hexcolorcontrol.hxx>
+#include <basegfx/color/bcolortools.hxx>
+#include <cmath>
+#include <o3tl/typed_flags_set.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::beans;
+using namespace ::basegfx;
+
+namespace {
+
+enum class UpdateFlags
+{
+ NONE = 0x00,
+ RGB = 0x01,
+ CMYK = 0x02,
+ HSB = 0x04,
+ ColorChooser = 0x08,
+ ColorSlider = 0x10,
+ Hex = 0x20,
+ All = 0x3f,
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<UpdateFlags> : is_typed_flags<UpdateFlags, 0x3f> {};
+}
+
+
+namespace cui
+{
+
+namespace {
+
+enum class ColorComponent {
+ Red,
+ Green,
+ Blue,
+ Hue,
+ Saturation,
+ Brightness,
+ Cyan,
+ Yellow,
+ Magenta,
+ Key,
+};
+
+}
+
+// color space conversion helpers
+
+static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
+{
+ BColor result = basegfx::utils::rgb2hsv( BColor( dR, dG, dB ) );
+
+ dH = result.getX();
+ dS = result.getY();
+ dV = result.getZ();
+}
+
+static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
+{
+ BColor result = basegfx::utils::hsv2rgb( BColor( dH, dS, dV ) );
+
+ dR = result.getRed();
+ dG = result.getGreen();
+ dB = result.getBlue();
+}
+
+// CMYK values from 0 to 1
+static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
+{
+ fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
+ fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
+ fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
+
+ dR = std::clamp( 1.0 - fCyan, 0.0, 1.0 );
+ dG = std::clamp( 1.0 - fMagenta, 0.0, 1.0 );
+ dB = std::clamp( 1.0 - fYellow, 0.0, 1.0 );
+}
+
+// CMY results from 0 to 1
+static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
+{
+ fCyan = 1 - dR;
+ fMagenta = 1 - dG;
+ fYellow = 1 - dB;
+
+ //CMYK and CMY values from 0 to 1
+ fKey = 1.0;
+ if( fCyan < fKey ) fKey = fCyan;
+ if( fMagenta < fKey ) fKey = fMagenta;
+ if( fYellow < fKey ) fKey = fYellow;
+
+ if( fKey >= 1.0 )
+ {
+ //Black
+ fCyan = 0.0;
+ fMagenta = 0.0;
+ fYellow = 0.0;
+ }
+ else
+ {
+ fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
+ fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
+ fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
+ }
+}
+
+namespace {
+
+class ColorPreviewControl : public weld::CustomWidgetController
+{
+private:
+ Color m_aColor;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+public:
+ ColorPreviewControl()
+ {
+ }
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 10,
+ pDrawingArea->get_text_height() * 2);
+ }
+
+ void SetColor(const Color& rCol)
+ {
+ if (rCol != m_aColor)
+ {
+ m_aColor = rCol;
+ Invalidate();
+ }
+ }
+};
+
+}
+
+void ColorPreviewControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ rRenderContext.SetFillColor(m_aColor);
+ rRenderContext.SetLineColor(m_aColor);
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), GetOutputSizePixel()));
+}
+
+namespace {
+
+enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
+
+}
+
+const ColorMode DefaultMode = HUE;
+
+namespace {
+
+class ColorFieldControl : public weld::CustomWidgetController
+{
+public:
+ ColorFieldControl()
+ : meMode( DefaultMode )
+ , mnBaseValue(USHRT_MAX)
+ , mdX( -1.0 )
+ , mdY( -1.0 )
+ , mbMouseCaptured(false)
+ {
+ }
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 40,
+ pDrawingArea->get_text_height() * 10);
+ }
+
+ virtual ~ColorFieldControl() override
+ {
+ mxBitmap.disposeAndClear();
+ }
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+ virtual void Resize() override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
+
+ void UpdateBitmap();
+ void ShowPosition( const Point& rPos, bool bUpdate );
+ void UpdatePosition();
+ void Modify();
+
+ void SetValues(sal_uInt16 nBaseValue, ColorMode eMode, double x, double y);
+ double GetX() const { return mdX;}
+ double GetY() const { return mdY;}
+
+ void SetModifyHdl(const Link<ColorFieldControl&,void>& rLink) { maModifyHdl = rLink; }
+
+private:
+ ColorMode meMode;
+ sal_uInt16 mnBaseValue;
+ double mdX;
+ double mdY;
+ bool mbMouseCaptured;
+ Point maPosition;
+ VclPtr<VirtualDevice> mxBitmap;
+ Link<ColorFieldControl&,void> maModifyHdl;
+ std::vector<sal_uInt8> maRGB_Horiz;
+ std::vector<sal_uInt16> maGrad_Horiz;
+ std::vector<sal_uInt16> maPercent_Horiz;
+ std::vector<sal_uInt8> maRGB_Vert;
+ std::vector<sal_uInt16> maPercent_Vert;
+};
+
+}
+
+void ColorFieldControl::UpdateBitmap()
+{
+ const Size aSize(GetOutputSizePixel());
+
+ if (mxBitmap && mxBitmap->GetOutputSizePixel() != aSize)
+ mxBitmap.disposeAndClear();
+
+ const sal_Int32 nWidth = aSize.Width();
+ const sal_Int32 nHeight = aSize.Height();
+
+ if (nWidth == 0 || nHeight == 0)
+ return;
+
+ if (!mxBitmap)
+ {
+ mxBitmap = VclPtr<VirtualDevice>::Create();
+ mxBitmap->SetOutputSizePixel(aSize);
+
+ maRGB_Horiz.resize( nWidth );
+ maGrad_Horiz.resize( nWidth );
+ maPercent_Horiz.resize( nWidth );
+
+ sal_uInt8* pRGB = maRGB_Horiz.data();
+ sal_uInt16* pGrad = maGrad_Horiz.data();
+ sal_uInt16* pPercent = maPercent_Horiz.data();
+
+ for( sal_Int32 x = 0; x < nWidth; x++ )
+ {
+ *pRGB++ = static_cast<sal_uInt8>((x * 256) / nWidth);
+ *pGrad++ = static_cast<sal_uInt16>((x * 359) / nWidth);
+ *pPercent++ = static_cast<sal_uInt16>((x * 100) / nWidth);
+ }
+
+ maRGB_Vert.resize(nHeight);
+ maPercent_Vert.resize(nHeight);
+
+ pRGB = maRGB_Vert.data();
+ pPercent = maPercent_Vert.data();
+
+ sal_Int32 y = nHeight;
+ while (y--)
+ {
+ *pRGB++ = static_cast<sal_uInt8>((y * 256) / nHeight);
+ *pPercent++ = static_cast<sal_uInt16>((y * 100) / nHeight);
+ }
+ }
+
+ sal_uInt8* pRGB_Horiz = maRGB_Horiz.data();
+ sal_uInt16* pGrad_Horiz = maGrad_Horiz.data();
+ sal_uInt16* pPercent_Horiz = maPercent_Horiz.data();
+ sal_uInt8* pRGB_Vert = maRGB_Vert.data();
+ sal_uInt16* pPercent_Vert = maPercent_Vert.data();
+
+ // this has been unlooped for performance reason, please do not merge back!
+
+ sal_uInt16 y = nHeight,x;
+
+ switch(meMode)
+ {
+ case HUE:
+ while (y--)
+ {
+ sal_uInt16 nBri = pPercent_Vert[y];
+ x = nWidth;
+ while (x--)
+ {
+ sal_uInt16 nSat = pPercent_Horiz[x];
+ mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(mnBaseValue, nSat, nBri));
+ }
+ }
+ break;
+ case SATURATION:
+ while (y--)
+ {
+ sal_uInt16 nBri = pPercent_Vert[y];
+ x = nWidth;
+ while (x--)
+ {
+ sal_uInt16 nHue = pGrad_Horiz[x];
+ mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, mnBaseValue, nBri));
+ }
+ }
+ break;
+ case BRIGHTNESS:
+ while (y--)
+ {
+ sal_uInt16 nSat = pPercent_Vert[y];
+ x = nWidth;
+ while (x--)
+ {
+ sal_uInt16 nHue = pGrad_Horiz[x];
+ mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, mnBaseValue));
+ }
+ }
+ break;
+ case RED:
+ {
+ Color aBitmapColor;
+ aBitmapColor.SetRed(mnBaseValue);
+ while (y--)
+ {
+ aBitmapColor.SetGreen(pRGB_Vert[y]);
+ x = nWidth;
+ while (x--)
+ {
+ aBitmapColor.SetBlue(pRGB_Horiz[x]);
+ mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
+ }
+ }
+ break;
+ }
+ case GREEN:
+ {
+ Color aBitmapColor;
+ aBitmapColor.SetGreen(mnBaseValue);
+ while (y--)
+ {
+ aBitmapColor.SetRed(pRGB_Vert[y]);
+ x = nWidth;
+ while (x--)
+ {
+ aBitmapColor.SetBlue(pRGB_Horiz[x]);
+ mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
+ }
+ }
+ break;
+ }
+ case BLUE:
+ {
+ Color aBitmapColor;
+ aBitmapColor.SetBlue(mnBaseValue);
+ while (y--)
+ {
+ aBitmapColor.SetGreen(pRGB_Vert[y]);
+ x = nWidth;
+ while (x--)
+ {
+ aBitmapColor.SetRed(pRGB_Horiz[x]);
+ mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
+ }
+ }
+ break;
+ }
+ }
+}
+
+constexpr int nCenterOffset = 5;
+
+void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
+{
+ if (!mxBitmap)
+ {
+ UpdateBitmap();
+ Invalidate();
+ }
+
+ if (!mxBitmap)
+ return;
+
+ const Size aSize(mxBitmap->GetOutputSizePixel());
+
+ tools::Long nX = rPos.X();
+ tools::Long nY = rPos.Y();
+ if (nX < 0)
+ nX = 0;
+ else if (nX >= aSize.Width())
+ nX = aSize.Width() - 1;
+
+ if (nY < 0)
+ nY = 0;
+ else if (nY >= aSize.Height())
+ nY = aSize.Height() - 1;
+
+ Point aPos = maPosition;
+ maPosition.setX( nX - nCenterOffset );
+ maPosition.setY( nY - nCenterOffset );
+ Invalidate(tools::Rectangle(aPos, Size(11, 11)));
+ Invalidate(tools::Rectangle(maPosition, Size(11, 11)));
+
+ if (bUpdate)
+ {
+ mdX = double(nX) / double(aSize.Width() - 1.0);
+ mdY = double(aSize.Height() - 1.0 - nY) / double(aSize.Height() - 1.0);
+ }
+}
+
+bool ColorFieldControl::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ CaptureMouse();
+ mbMouseCaptured = true;
+ ShowPosition(rMEvt.GetPosPixel(), true);
+ Modify();
+ return true;
+}
+
+bool ColorFieldControl::MouseMove(const MouseEvent& rMEvt)
+{
+ if (mbMouseCaptured)
+ {
+ ShowPosition(rMEvt.GetPosPixel(), true);
+ Modify();
+ }
+ return true;
+}
+
+bool ColorFieldControl::MouseButtonUp(const MouseEvent&)
+{
+ ReleaseMouse();
+ mbMouseCaptured = false;
+ return true;
+}
+
+void ColorFieldControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ if (!mxBitmap)
+ UpdateBitmap();
+
+ if (!mxBitmap)
+ return;
+
+ Size aSize(GetOutputSizePixel());
+ rRenderContext.DrawOutDev(Point(0, 0), aSize, Point(0, 0), aSize, *mxBitmap);
+
+ // draw circle around current color
+ Point aPos(maPosition.X() + nCenterOffset, maPosition.Y() + nCenterOffset);
+ Color aColor = mxBitmap->GetPixel(aPos);
+ if (aColor.IsDark())
+ rRenderContext.SetLineColor(COL_WHITE);
+ else
+ rRenderContext.SetLineColor(COL_BLACK);
+
+ rRenderContext.SetFillColor();
+ rRenderContext.DrawEllipse(::tools::Rectangle(maPosition, Size(11, 11)));
+}
+
+void ColorFieldControl::Resize()
+{
+ CustomWidgetController::Resize();
+ UpdateBitmap();
+ UpdatePosition();
+}
+
+void ColorFieldControl::Modify()
+{
+ maModifyHdl.Call( *this );
+}
+
+void ColorFieldControl::SetValues(sal_uInt16 nBaseValue, ColorMode eMode, double x, double y)
+{
+ bool bUpdateBitmap = (mnBaseValue != nBaseValue) || (meMode != eMode);
+ if (!bUpdateBitmap && mdX == x && mdY == y)
+ return;
+
+ mnBaseValue = nBaseValue;
+ meMode = eMode;
+ mdX = x;
+ mdY = y;
+
+ if (bUpdateBitmap)
+ UpdateBitmap();
+ UpdatePosition();
+ if (bUpdateBitmap)
+ Invalidate();
+}
+
+void ColorFieldControl::UpdatePosition()
+{
+ Size aSize(GetOutputSizePixel());
+ ShowPosition(Point(static_cast<tools::Long>(mdX * aSize.Width()), static_cast<tools::Long>((1.0 - mdY) * aSize.Height())), false);
+}
+
+namespace {
+
+class ColorSliderControl : public weld::CustomWidgetController
+{
+public:
+ ColorSliderControl();
+ virtual ~ColorSliderControl() override;
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual void Resize() override;
+
+ void UpdateBitmap();
+ void ChangePosition( tools::Long nY );
+ void Modify();
+
+ void SetValue( const Color& rColor, ColorMode eMode, double dValue );
+ double GetValue() const { return mdValue; }
+
+ void SetModifyHdl( const Link<ColorSliderControl&,void>& rLink ) { maModifyHdl = rLink; }
+
+ sal_Int16 GetLevel() const { return mnLevel; }
+
+private:
+ Link<ColorSliderControl&,void> maModifyHdl;
+ Color maColor;
+ ColorMode meMode;
+ VclPtr<VirtualDevice> mxBitmap;
+ sal_Int16 mnLevel;
+ double mdValue;
+};
+
+}
+
+ColorSliderControl::ColorSliderControl()
+ : meMode( DefaultMode )
+ , mnLevel( 0 )
+ , mdValue( -1.0 )
+{
+}
+
+void ColorSliderControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 3, -1);
+}
+
+ColorSliderControl::~ColorSliderControl()
+{
+ mxBitmap.disposeAndClear();
+}
+
+void ColorSliderControl::UpdateBitmap()
+{
+ Size aSize(1, GetOutputSizePixel().Height());
+
+ if (mxBitmap && mxBitmap->GetOutputSizePixel() != aSize)
+ mxBitmap.disposeAndClear();
+
+ if (!mxBitmap)
+ {
+ mxBitmap = VclPtr<VirtualDevice>::Create();
+ mxBitmap->SetOutputSizePixel(aSize);
+ }
+
+ const tools::Long nY = aSize.Height() - 1;
+
+ Color aBitmapColor(maColor);
+
+ sal_uInt16 nHue, nSat, nBri;
+ maColor.RGBtoHSB(nHue, nSat, nBri);
+
+ // this has been unlooped for performance reason, please do not merge back!
+
+ switch (meMode)
+ {
+ case HUE:
+ nSat = 100;
+ nBri = 100;
+ for (tools::Long y = 0; y <= nY; y++)
+ {
+ nHue = static_cast<sal_uInt16>((359 * y) / nY);
+ mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ break;
+
+ case SATURATION:
+ nBri = std::max(sal_uInt16(32), nBri);
+ for (tools::Long y = 0; y <= nY; y++)
+ {
+ nSat = static_cast<sal_uInt16>((100 * y) / nY);
+ mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ break;
+
+ case BRIGHTNESS:
+ for (tools::Long y = 0; y <= nY; y++)
+ {
+ nBri = static_cast<sal_uInt16>((100 * y) / nY);
+ mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ break;
+
+ case RED:
+ for (tools::Long y = 0; y <= nY; y++)
+ {
+ aBitmapColor.SetRed(sal_uInt8((tools::Long(255) * y) / nY));
+ mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
+ }
+ break;
+
+ case GREEN:
+ for (tools::Long y = 0; y <= nY; y++)
+ {
+ aBitmapColor.SetGreen(sal_uInt8((tools::Long(255) * y) / nY));
+ mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
+ }
+ break;
+
+ case BLUE:
+ for (tools::Long y = 0; y <= nY; y++)
+ {
+ aBitmapColor.SetBlue(sal_uInt8((tools::Long(255) * y) / nY));
+ mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
+ }
+ break;
+ }
+}
+
+void ColorSliderControl::ChangePosition(tools::Long nY)
+{
+ const tools::Long nHeight = GetOutputSizePixel().Height() - 1;
+
+ if (nY < 0)
+ nY = 0;
+ else if (nY > nHeight)
+ nY = nHeight;
+
+ mnLevel = nY;
+ mdValue = double(nHeight - nY) / double(nHeight);
+}
+
+bool ColorSliderControl::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ CaptureMouse();
+ ChangePosition(rMEvt.GetPosPixel().Y());
+ Modify();
+ return true;
+}
+
+bool ColorSliderControl::MouseMove(const MouseEvent& rMEvt)
+{
+ if (IsMouseCaptured())
+ {
+ ChangePosition(rMEvt.GetPosPixel().Y());
+ Modify();
+ }
+ return true;
+}
+
+bool ColorSliderControl::MouseButtonUp(const MouseEvent&)
+{
+ ReleaseMouse();
+ return true;
+}
+
+void ColorSliderControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ if (!mxBitmap)
+ UpdateBitmap();
+
+ const Size aSize(GetOutputSizePixel());
+
+ Point aPos;
+ int x = aSize.Width();
+ while (x--)
+ {
+ rRenderContext.DrawOutDev(aPos, aSize, Point(0,0), aSize, *mxBitmap);
+ aPos.AdjustX(1);
+ }
+}
+
+void ColorSliderControl::Resize()
+{
+ CustomWidgetController::Resize();
+ UpdateBitmap();
+}
+
+void ColorSliderControl::Modify()
+{
+ maModifyHdl.Call(*this);
+}
+
+void ColorSliderControl::SetValue(const Color& rColor, ColorMode eMode, double dValue)
+{
+ bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
+ if( bUpdateBitmap || (mdValue != dValue))
+ {
+ maColor = rColor;
+ mdValue = dValue;
+ mnLevel = static_cast<sal_Int16>((1.0-dValue) * GetOutputSizePixel().Height());
+ meMode = eMode;
+ if (bUpdateBitmap)
+ UpdateBitmap();
+ Invalidate();
+ }
+}
+
+namespace {
+
+class ColorPickerDialog : public SfxDialogController
+{
+private:
+ ColorFieldControl m_aColorField;
+ ColorSliderControl m_aColorSlider;
+ ColorPreviewControl m_aColorPreview;
+ ColorPreviewControl m_aColorPrevious;
+
+ std::unique_ptr<weld::CustomWeld> m_xColorField;
+ std::unique_ptr<weld::CustomWeld> m_xColorSlider;
+ std::unique_ptr<weld::CustomWeld> m_xColorPreview;
+ std::unique_ptr<weld::CustomWeld> m_xColorPrevious;
+
+ std::unique_ptr<weld::Widget> m_xFISliderLeft;
+ std::unique_ptr<weld::Widget> m_xFISliderRight;
+ std::unique_ptr<weld::RadioButton> m_xRBRed;
+ std::unique_ptr<weld::RadioButton> m_xRBGreen;
+ std::unique_ptr<weld::RadioButton> m_xRBBlue;
+ std::unique_ptr<weld::RadioButton> m_xRBHue;
+ std::unique_ptr<weld::RadioButton> m_xRBSaturation;
+ std::unique_ptr<weld::RadioButton> m_xRBBrightness;
+
+ std::unique_ptr<weld::SpinButton> m_xMFRed;
+ std::unique_ptr<weld::SpinButton> m_xMFGreen;
+ std::unique_ptr<weld::SpinButton> m_xMFBlue;
+ std::unique_ptr<weld::HexColorControl> m_xEDHex;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xMFHue;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFSaturation;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFBrightness;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xMFCyan;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFMagenta;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFYellow;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFKey;
+
+public:
+ ColorPickerDialog(weld::Window* pParent, Color nColor, sal_Int16 nMode);
+
+ void update_color(UpdateFlags n = UpdateFlags::All);
+
+ DECL_LINK(ColorFieldControlModifydl, ColorFieldControl&, void);
+ DECL_LINK(ColorSliderControlModifyHdl, ColorSliderControl&, void);
+ DECL_LINK(ColorModifyMetricHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(ColorModifySpinHdl, weld::SpinButton&, void);
+ DECL_LINK(ColorModifyEditHdl, weld::Entry&, void);
+ DECL_LINK(ModeModifyHdl, weld::Toggleable&, void);
+
+ Color GetColor() const;
+
+ void setColorComponent(ColorComponent nComp, double dValue);
+
+private:
+ ColorMode meMode;
+
+ double mdRed, mdGreen, mdBlue;
+ double mdHue, mdSat, mdBri;
+ double mdCyan, mdMagenta, mdYellow, mdKey;
+};
+
+}
+
+ColorPickerDialog::ColorPickerDialog(weld::Window* pParent, Color nColor, sal_Int16 nDialogMode)
+ : SfxDialogController(pParent, "cui/ui/colorpickerdialog.ui", "ColorPicker")
+ , m_xColorField(new weld::CustomWeld(*m_xBuilder, "colorField", m_aColorField))
+ , m_xColorSlider(new weld::CustomWeld(*m_xBuilder, "colorSlider", m_aColorSlider))
+ , m_xColorPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aColorPreview))
+ , m_xColorPrevious(new weld::CustomWeld(*m_xBuilder, "previous", m_aColorPrevious))
+ , m_xFISliderLeft(m_xBuilder->weld_widget("leftImage"))
+ , m_xFISliderRight(m_xBuilder->weld_widget("rightImage"))
+ , m_xRBRed(m_xBuilder->weld_radio_button("redRadiobutton"))
+ , m_xRBGreen(m_xBuilder->weld_radio_button("greenRadiobutton"))
+ , m_xRBBlue(m_xBuilder->weld_radio_button("blueRadiobutton"))
+ , m_xRBHue(m_xBuilder->weld_radio_button("hueRadiobutton"))
+ , m_xRBSaturation(m_xBuilder->weld_radio_button("satRadiobutton"))
+ , m_xRBBrightness(m_xBuilder->weld_radio_button("brightRadiobutton"))
+ , m_xMFRed(m_xBuilder->weld_spin_button("redSpinbutton"))
+ , m_xMFGreen(m_xBuilder->weld_spin_button("greenSpinbutton"))
+ , m_xMFBlue(m_xBuilder->weld_spin_button("blueSpinbutton"))
+ , m_xEDHex(new weld::HexColorControl(m_xBuilder->weld_entry("hexEntry")))
+ , m_xMFHue(m_xBuilder->weld_metric_spin_button("hueSpinbutton", FieldUnit::DEGREE))
+ , m_xMFSaturation(m_xBuilder->weld_metric_spin_button("satSpinbutton", FieldUnit::PERCENT))
+ , m_xMFBrightness(m_xBuilder->weld_metric_spin_button("brightSpinbutton", FieldUnit::PERCENT))
+ , m_xMFCyan(m_xBuilder->weld_metric_spin_button("cyanSpinbutton", FieldUnit::PERCENT))
+ , m_xMFMagenta(m_xBuilder->weld_metric_spin_button("magSpinbutton", FieldUnit::PERCENT))
+ , m_xMFYellow(m_xBuilder->weld_metric_spin_button("yellowSpinbutton", FieldUnit::PERCENT))
+ , m_xMFKey(m_xBuilder->weld_metric_spin_button("keySpinbutton", FieldUnit::PERCENT))
+ , meMode( DefaultMode )
+{
+ m_aColorField.SetModifyHdl( LINK( this, ColorPickerDialog, ColorFieldControlModifydl ) );
+ m_aColorSlider.SetModifyHdl( LINK( this, ColorPickerDialog, ColorSliderControlModifyHdl ) );
+
+ int nMargin = (m_xFISliderLeft->get_preferred_size().Height() + 1) / 2;
+ m_xColorSlider->set_margin_top(nMargin);
+ m_xColorSlider->set_margin_bottom(nMargin);
+
+ Link<weld::MetricSpinButton&,void> aLink3( LINK( this, ColorPickerDialog, ColorModifyMetricHdl ) );
+ m_xMFCyan->connect_value_changed( aLink3 );
+ m_xMFMagenta->connect_value_changed( aLink3 );
+ m_xMFYellow->connect_value_changed( aLink3 );
+ m_xMFKey->connect_value_changed( aLink3 );
+
+ m_xMFHue->connect_value_changed( aLink3 );
+ m_xMFSaturation->connect_value_changed( aLink3 );
+ m_xMFBrightness->connect_value_changed( aLink3 );
+
+ Link<weld::SpinButton&,void> aLink4(LINK(this, ColorPickerDialog, ColorModifySpinHdl));
+ m_xMFRed->connect_value_changed(aLink4);
+ m_xMFGreen->connect_value_changed(aLink4);
+ m_xMFBlue->connect_value_changed(aLink4);
+
+ m_xEDHex->connect_changed(LINK(this, ColorPickerDialog, ColorModifyEditHdl));
+
+ Link<weld::Toggleable&,void> aLink2 = LINK( this, ColorPickerDialog, ModeModifyHdl );
+ m_xRBRed->connect_toggled( aLink2 );
+ m_xRBGreen->connect_toggled( aLink2 );
+ m_xRBBlue->connect_toggled( aLink2 );
+ m_xRBHue->connect_toggled( aLink2 );
+ m_xRBSaturation->connect_toggled( aLink2 );
+ m_xRBBrightness->connect_toggled( aLink2 );
+
+ Color aColor(nColor);
+
+ // modify
+ if (nDialogMode == 2)
+ {
+ m_aColorPrevious.SetColor(aColor);
+ m_xColorPrevious->show();
+ }
+
+ mdRed = static_cast<double>(aColor.GetRed()) / 255.0;
+ mdGreen = static_cast<double>(aColor.GetGreen()) / 255.0;
+ mdBlue = static_cast<double>(aColor.GetBlue()) / 255.0;
+
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+
+ update_color();
+}
+
+static int toInt( double dValue, double dRange )
+{
+ return static_cast< int >( std::floor((dValue * dRange) + 0.5 ) );
+}
+
+Color ColorPickerDialog::GetColor() const
+{
+ return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) );
+}
+
+void ColorPickerDialog::update_color( UpdateFlags n )
+{
+ sal_uInt8 nRed = toInt(mdRed,255.0);
+ sal_uInt8 nGreen = toInt(mdGreen,255.0);
+ sal_uInt8 nBlue = toInt(mdBlue,255.0);
+
+ sal_uInt16 nHue = toInt(mdHue, 1.0);
+ sal_uInt16 nSat = toInt(mdSat, 100.0);
+ sal_uInt16 nBri = toInt(mdBri, 100.0);
+
+ if (n & UpdateFlags::RGB) // update RGB
+ {
+ m_xMFRed->set_value(nRed);
+ m_xMFGreen->set_value(nGreen);
+ m_xMFBlue->set_value(nBlue);
+ }
+
+ if (n & UpdateFlags::CMYK) // update CMYK
+ {
+ m_xMFCyan->set_value(toInt(mdCyan, 100.0), FieldUnit::PERCENT);
+ m_xMFMagenta->set_value(toInt(mdMagenta, 100.0), FieldUnit::PERCENT);
+ m_xMFYellow->set_value(toInt(mdYellow, 100.0), FieldUnit::PERCENT);
+ m_xMFKey->set_value(toInt(mdKey, 100.0), FieldUnit::PERCENT);
+ }
+
+ if (n & UpdateFlags::HSB ) // update HSB
+ {
+ m_xMFHue->set_value(nHue, FieldUnit::DEGREE);
+ m_xMFSaturation->set_value(nSat, FieldUnit::PERCENT);
+ m_xMFBrightness->set_value(nBri, FieldUnit::PERCENT);
+ }
+
+ if (n & UpdateFlags::ColorChooser ) // update Color Chooser 1
+ {
+ switch( meMode )
+ {
+ case HUE:
+ m_aColorField.SetValues(nHue, meMode, mdSat, mdBri);
+ break;
+ case SATURATION:
+ m_aColorField.SetValues(nSat, meMode, mdHue / 360.0, mdBri);
+ break;
+ case BRIGHTNESS:
+ m_aColorField.SetValues(nBri, meMode, mdHue / 360.0, mdSat);
+ break;
+ case RED:
+ m_aColorField.SetValues(nRed, meMode, mdBlue, mdGreen);
+ break;
+ case GREEN:
+ m_aColorField.SetValues(nGreen, meMode, mdBlue, mdRed);
+ break;
+ case BLUE:
+ m_aColorField.SetValues(nBlue, meMode, mdRed, mdGreen);
+ break;
+ }
+ }
+
+ Color aColor(nRed, nGreen, nBlue);
+
+ if (n & UpdateFlags::ColorSlider) // update Color Chooser 2
+ {
+ switch (meMode)
+ {
+ case HUE:
+ m_aColorSlider.SetValue(aColor, meMode, mdHue / 360.0);
+ break;
+ case SATURATION:
+ m_aColorSlider.SetValue(aColor, meMode, mdSat);
+ break;
+ case BRIGHTNESS:
+ m_aColorSlider.SetValue(aColor, meMode, mdBri);
+ break;
+ case RED:
+ m_aColorSlider.SetValue(aColor, meMode, mdRed);
+ break;
+ case GREEN:
+ m_aColorSlider.SetValue(aColor, meMode, mdGreen);
+ break;
+ case BLUE:
+ m_aColorSlider.SetValue(aColor, meMode, mdBlue);
+ break;
+ }
+ }
+
+ if (n & UpdateFlags::Hex) // update hex
+ {
+ m_xFISliderLeft->set_margin_top(m_aColorSlider.GetLevel());
+ m_xFISliderRight->set_margin_top(m_aColorSlider.GetLevel());
+ m_xEDHex->SetColor(aColor);
+ }
+ m_aColorPreview.SetColor(aColor);
+}
+
+IMPL_LINK_NOARG(ColorPickerDialog, ColorFieldControlModifydl, ColorFieldControl&, void)
+{
+ double x = m_aColorField.GetX();
+ double y = m_aColorField.GetY();
+
+ switch( meMode )
+ {
+ case HUE:
+ mdSat = x;
+ setColorComponent( ColorComponent::Brightness, y );
+ break;
+ case SATURATION:
+ mdHue = x * 360.0;
+ setColorComponent( ColorComponent::Brightness, y );
+ break;
+ case BRIGHTNESS:
+ mdHue = x * 360.0;
+ setColorComponent( ColorComponent::Saturation, y );
+ break;
+ case RED:
+ mdBlue = x;
+ setColorComponent( ColorComponent::Green, y );
+ break;
+ case GREEN:
+ mdBlue = x;
+ setColorComponent( ColorComponent::Red, y );
+ break;
+ case BLUE:
+ mdRed = x;
+ setColorComponent( ColorComponent::Green, y );
+ break;
+ }
+
+ update_color(UpdateFlags::All & ~UpdateFlags::ColorChooser);
+}
+
+IMPL_LINK_NOARG(ColorPickerDialog, ColorSliderControlModifyHdl, ColorSliderControl&, void)
+{
+ double dValue = m_aColorSlider.GetValue();
+ switch (meMode)
+ {
+ case HUE:
+ setColorComponent( ColorComponent::Hue, dValue * 360.0 );
+ break;
+ case SATURATION:
+ setColorComponent( ColorComponent::Saturation, dValue );
+ break;
+ case BRIGHTNESS:
+ setColorComponent( ColorComponent::Brightness, dValue );
+ break;
+ case RED:
+ setColorComponent( ColorComponent::Red, dValue );
+ break;
+ case GREEN:
+ setColorComponent( ColorComponent::Green, dValue );
+ break;
+ case BLUE:
+ setColorComponent( ColorComponent::Blue, dValue );
+ break;
+ }
+
+ update_color(UpdateFlags::All & ~UpdateFlags::ColorSlider);
+}
+
+IMPL_LINK(ColorPickerDialog, ColorModifyMetricHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ UpdateFlags n = UpdateFlags::NONE;
+
+ if (&rEdit == m_xMFHue.get())
+ {
+ setColorComponent( ColorComponent::Hue, static_cast<double>(m_xMFHue->get_value(FieldUnit::DEGREE)) );
+ n = UpdateFlags::All & ~UpdateFlags::HSB;
+ }
+ else if (&rEdit == m_xMFSaturation.get())
+ {
+ setColorComponent( ColorComponent::Saturation, static_cast<double>(m_xMFSaturation->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::HSB;
+ }
+ else if (&rEdit == m_xMFBrightness.get())
+ {
+ setColorComponent( ColorComponent::Brightness, static_cast<double>(m_xMFBrightness->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::HSB;
+ }
+ else if (&rEdit == m_xMFCyan.get())
+ {
+ setColorComponent( ColorComponent::Cyan, static_cast<double>(m_xMFCyan->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+ else if (&rEdit == m_xMFMagenta.get())
+ {
+ setColorComponent( ColorComponent::Magenta, static_cast<double>(m_xMFMagenta->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+ else if (&rEdit == m_xMFYellow.get())
+ {
+ setColorComponent( ColorComponent::Yellow, static_cast<double>(m_xMFYellow->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+ else if (&rEdit == m_xMFKey.get())
+ {
+ setColorComponent( ColorComponent::Key, static_cast<double>(m_xMFKey->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+
+ if (n != UpdateFlags::NONE)
+ update_color(n);
+}
+
+IMPL_LINK_NOARG(ColorPickerDialog, ColorModifyEditHdl, weld::Entry&, void)
+{
+ UpdateFlags n = UpdateFlags::NONE;
+
+ Color aColor = m_xEDHex->GetColor();
+
+ if (aColor != COL_AUTO && aColor != GetColor())
+ {
+ mdRed = static_cast<double>(aColor.GetRed()) / 255.0;
+ mdGreen = static_cast<double>(aColor.GetGreen()) / 255.0;
+ mdBlue = static_cast<double>(aColor.GetBlue()) / 255.0;
+
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+ n = UpdateFlags::All & ~UpdateFlags::Hex;
+ }
+
+ if (n != UpdateFlags::NONE)
+ update_color(n);
+}
+
+IMPL_LINK(ColorPickerDialog, ColorModifySpinHdl, weld::SpinButton&, rEdit, void)
+{
+ UpdateFlags n = UpdateFlags::NONE;
+
+ if (&rEdit == m_xMFRed.get())
+ {
+ setColorComponent( ColorComponent::Red, static_cast<double>(m_xMFRed->get_value()) / 255.0 );
+ n = UpdateFlags::All & ~UpdateFlags::RGB;
+ }
+ else if (&rEdit == m_xMFGreen.get())
+ {
+ setColorComponent( ColorComponent::Green, static_cast<double>(m_xMFGreen->get_value()) / 255.0 );
+ n = UpdateFlags::All & ~UpdateFlags::RGB;
+ }
+ else if (&rEdit == m_xMFBlue.get())
+ {
+ setColorComponent( ColorComponent::Blue, static_cast<double>(m_xMFBlue->get_value()) / 255.0 );
+ n = UpdateFlags::All & ~UpdateFlags::RGB;
+ }
+
+ if (n != UpdateFlags::NONE)
+ update_color(n);
+}
+
+
+IMPL_LINK_NOARG(ColorPickerDialog, ModeModifyHdl, weld::Toggleable&, void)
+{
+ ColorMode eMode = HUE;
+
+ if (m_xRBRed->get_active())
+ {
+ eMode = RED;
+ }
+ else if (m_xRBGreen->get_active())
+ {
+ eMode = GREEN;
+ }
+ else if (m_xRBBlue->get_active())
+ {
+ eMode = BLUE;
+ }
+ else if (m_xRBSaturation->get_active())
+ {
+ eMode = SATURATION;
+ }
+ else if (m_xRBBrightness->get_active())
+ {
+ eMode = BRIGHTNESS;
+ }
+
+ if (meMode != eMode)
+ {
+ meMode = eMode;
+ update_color(UpdateFlags::ColorChooser | UpdateFlags::ColorSlider);
+ }
+}
+
+void ColorPickerDialog::setColorComponent( ColorComponent nComp, double dValue )
+{
+ switch( nComp )
+ {
+ case ColorComponent::Red:
+ mdRed = dValue;
+ break;
+ case ColorComponent::Green:
+ mdGreen = dValue;
+ break;
+ case ColorComponent::Blue:
+ mdBlue = dValue;
+ break;
+ case ColorComponent::Hue:
+ mdHue = dValue;
+ break;
+ case ColorComponent::Saturation:
+ mdSat = dValue;
+ break;
+ case ColorComponent::Brightness:
+ mdBri = dValue;
+ break;
+ case ColorComponent::Cyan:
+ mdCyan = dValue;
+ break;
+ case ColorComponent::Yellow:
+ mdYellow = dValue;
+ break;
+ case ColorComponent::Magenta:
+ mdMagenta = dValue;
+ break;
+ case ColorComponent::Key:
+ mdKey = dValue;
+ break;
+ }
+
+ if (nComp == ColorComponent::Red || nComp == ColorComponent::Green || nComp == ColorComponent::Blue)
+ {
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+ }
+ else if (nComp == ColorComponent::Hue || nComp == ColorComponent::Saturation || nComp == ColorComponent::Brightness)
+ {
+ HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+ }
+ else
+ {
+ CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ }
+}
+
+typedef ::cppu::WeakComponentImplHelper< XServiceInfo, XExecutableDialog, XAsynchronousExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
+
+namespace {
+
+class ColorPicker : protected ::cppu::BaseMutex, // Struct for right initialization of mutex member! Must be first of baseclasses.
+ public ColorPickerBase
+{
+public:
+ explicit ColorPicker();
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
+
+ // XInitialization
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // XPropertyAccess
+ virtual Sequence< PropertyValue > SAL_CALL getPropertyValues( ) override;
+ virtual void SAL_CALL setPropertyValues( const Sequence< PropertyValue >& aProps ) override;
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
+ virtual sal_Int16 SAL_CALL execute( ) override;
+
+ // XAsynchronousExecutableDialog
+ virtual void SAL_CALL setDialogTitle( const OUString& aTitle ) override;
+ virtual void SAL_CALL startExecuteModal( const css::uno::Reference< css::ui::dialogs::XDialogClosedListener >& xListener ) override;
+
+private:
+ Color mnColor;
+ sal_Int16 mnMode;
+ Reference<css::awt::XWindow> mxParent;
+};
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_cui_ColorPicker_get_implementation(
+ css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire( new ColorPicker );
+}
+
+
+constexpr OUStringLiteral gsColorKey( u"Color" );
+constexpr OUStringLiteral gsModeKey( u"Mode" );
+
+ColorPicker::ColorPicker()
+ : ColorPickerBase( m_aMutex )
+ , mnColor( 0 )
+ , mnMode( 0 )
+{
+}
+
+// XInitialization
+void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments )
+{
+ if( aArguments.getLength() == 1 )
+ {
+ aArguments[0] >>= mxParent;
+ }
+}
+
+// XInitialization
+OUString SAL_CALL ColorPicker::getImplementationName( )
+{
+ return "com.sun.star.cui.ColorPicker";
+}
+
+sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName )
+{
+ return cppu::supportsService(this, sServiceName);
+}
+
+Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames( )
+{
+ return { "com.sun.star.ui.dialogs.ColorPicker",
+ "com.sun.star.ui.dialogs.AsynchronousColorPicker" };
+}
+
+// XPropertyAccess
+Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues( )
+{
+ Sequence< PropertyValue > props{ comphelper::makePropertyValue(gsColorKey, mnColor) };
+ return props;
+}
+
+void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps )
+{
+ for ( const PropertyValue& rProp : aProps )
+ {
+ if( rProp.Name == gsColorKey )
+ {
+ rProp.Value >>= mnColor;
+ }
+ else if( rProp.Name == gsModeKey )
+ {
+ rProp.Value >>= mnMode;
+ }
+ }
+}
+
+// XExecutableDialog
+void SAL_CALL ColorPicker::setTitle( const OUString& )
+{
+}
+
+sal_Int16 SAL_CALL ColorPicker::execute()
+{
+ std::unique_ptr<ColorPickerDialog> xDlg(new ColorPickerDialog(Application::GetFrameWeld(mxParent), mnColor, mnMode));
+ sal_Int16 ret = xDlg->run();
+ if (ret)
+ mnColor = xDlg->GetColor();
+ return ret;
+}
+
+// XAsynchronousExecutableDialog
+void SAL_CALL ColorPicker::setDialogTitle( const OUString& )
+{
+}
+
+void SAL_CALL ColorPicker::startExecuteModal( const css::uno::Reference< css::ui::dialogs::XDialogClosedListener >& xListener )
+{
+ std::shared_ptr<ColorPickerDialog> xDlg = std::make_shared<ColorPickerDialog>(Application::GetFrameWeld(mxParent), mnColor, mnMode);
+ weld::DialogController::runAsync(xDlg, [this, xDlg, xListener] (sal_Int32 nResult) {
+ if (nResult)
+ mnColor = xDlg->GetColor();
+
+ sal_Int16 nRet = static_cast<sal_Int16>(nResult);
+ css::ui::dialogs::DialogClosedEvent aEvent( *this, nRet );
+ xListener->dialogClosed( aEvent );
+ });
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuicharmap.cxx b/cui/source/dialogs/cuicharmap.cxx
new file mode 100644
index 000000000..c6994000e
--- /dev/null
+++ b/cui/source/dialogs/cuicharmap.cxx
@@ -0,0 +1,1283 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <stdio.h>
+
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/itempool.hxx>
+
+#include <rtl/textenc.h>
+#include <svx/ucsubset.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/fontcharmap.hxx>
+#include <vcl/virdev.hxx>
+#include <svl/stritem.hxx>
+#include <o3tl/temporary.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/dispatchcommand.hxx>
+
+#include <dialmgr.hxx>
+#include <cui/cuicharmap.hxx>
+#include <sfx2/app.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/editids.hrc>
+#include <editeng/fontitem.hxx>
+#include <strings.hrc>
+#include <unicode/uchar.h>
+#include <unicode/utypes.h>
+
+using namespace css;
+
+SvxCharacterMap::SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet,
+ css::uno::Reference<css::frame::XFrame> xFrame)
+ : SfxDialogController(pParent, "cui/ui/specialcharacters.ui", "SpecialCharactersDialog")
+ , m_xVirDev(VclPtr<VirtualDevice>::Create())
+ , isSearchMode(true)
+ , m_xFrame(std::move(xFrame))
+ , m_aRecentCharView{SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev)}
+ , m_aFavCharView{SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev)}
+ , m_aShowChar(m_xVirDev)
+ , m_xOKBtn(m_xFrame.is() ? m_xBuilder->weld_button("insert") : m_xBuilder->weld_button("ok"))
+ , m_xFontText(m_xBuilder->weld_label("fontft"))
+ , m_xFontLB(m_xBuilder->weld_combo_box("fontlb"))
+ , m_xSubsetText(m_xBuilder->weld_label("subsetft"))
+ , m_xSubsetLB(m_xBuilder->weld_combo_box("subsetlb"))
+ , m_xSearchText(m_xBuilder->weld_entry("search"))
+ , m_xHexCodeText(m_xBuilder->weld_entry("hexvalue"))
+ , m_xDecimalCodeText(m_xBuilder->weld_entry("decimalvalue"))
+ , m_xFavouritesBtn(m_xBuilder->weld_button("favbtn"))
+ , m_xCharName(m_xBuilder->weld_label("charname"))
+ , m_xRecentGrid(m_xBuilder->weld_widget("viewgrid"))
+ , m_xFavGrid(m_xBuilder->weld_widget("favgrid"))
+ , m_xShowChar(new weld::CustomWeld(*m_xBuilder, "showchar", m_aShowChar))
+ , m_xRecentCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar1", m_aRecentCharView[0]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar2", m_aRecentCharView[1]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar3", m_aRecentCharView[2]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar4", m_aRecentCharView[3]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar5", m_aRecentCharView[4]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar6", m_aRecentCharView[5]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar7", m_aRecentCharView[6]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar8", m_aRecentCharView[7]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar9", m_aRecentCharView[8]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar10", m_aRecentCharView[9]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar11", m_aRecentCharView[10]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar12", m_aRecentCharView[11]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar13", m_aRecentCharView[12]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar14", m_aRecentCharView[13]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar15", m_aRecentCharView[14]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar16", m_aRecentCharView[15])}
+ , m_xFavCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar1", m_aFavCharView[0]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar2", m_aFavCharView[1]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar3", m_aFavCharView[2]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar4", m_aFavCharView[3]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar5", m_aFavCharView[4]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar6", m_aFavCharView[5]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar7", m_aFavCharView[6]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar8", m_aFavCharView[7]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar9", m_aFavCharView[8]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar10", m_aFavCharView[9]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar11", m_aFavCharView[10]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar12", m_aFavCharView[11]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar13", m_aFavCharView[12]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar14", m_aFavCharView[13]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar15", m_aFavCharView[14]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar16", m_aFavCharView[15])}
+ , m_xShowSet(new SvxShowCharSet(m_xBuilder->weld_scrolled_window("showscroll", true), m_xVirDev))
+ , m_xShowSetArea(new weld::CustomWeld(*m_xBuilder, "showcharset", *m_xShowSet))
+ , m_xSearchSet(new SvxSearchCharSet(m_xBuilder->weld_scrolled_window("searchscroll", true), m_xVirDev))
+ , m_xSearchSetArea(new weld::CustomWeld(*m_xBuilder, "searchcharset", *m_xSearchSet))
+{
+ m_aShowChar.SetCentered(true);
+ m_xFontLB->make_sorted();
+ //lock the size request of this widget to the width of all possible entries
+ fillAllSubsets(*m_xSubsetLB);
+ m_xSubsetLB->set_size_request(m_xSubsetLB->get_preferred_size().Width(), -1);
+ m_xCharName->set_size_request(m_aShowChar.get_preferred_size().Width(), m_xCharName->get_text_height() * 4);
+ //lock the size request of this widget to the width of the original .ui string
+ m_xHexCodeText->set_size_request(m_xHexCodeText->get_preferred_size().Width(), -1);
+ //so things don't jump around if all the children are hidden
+ m_xRecentGrid->set_size_request(-1, m_aRecentCharView[0].get_preferred_size().Height());
+ m_xFavGrid->set_size_request(-1, m_aFavCharView[0].get_preferred_size().Height());
+
+ init();
+
+ const SfxInt32Item* pCharItem = SfxItemSet::GetItem<SfxInt32Item>(pSet, SID_ATTR_CHAR, false);
+ if ( pCharItem )
+ SetChar( pCharItem->GetValue() );
+
+ const SfxBoolItem* pDisableItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, FN_PARAM_2, false);
+ if ( pDisableItem && pDisableItem->GetValue() )
+ DisableFontSelection();
+
+ const SvxFontItem* pFontItem = SfxItemSet::GetItem<SvxFontItem>(pSet, SID_ATTR_CHAR_FONT, false);
+ const SfxStringItem* pFontNameItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_FONT_NAME, false);
+ if ( pFontItem )
+ {
+ vcl::Font aTmpFont( pFontItem->GetFamilyName(), pFontItem->GetStyleName(), GetCharFont().GetFontSize() );
+ aTmpFont.SetCharSet( pFontItem->GetCharSet() );
+ aTmpFont.SetPitch( pFontItem->GetPitch() );
+ SetCharFont( aTmpFont );
+ }
+ else if ( pFontNameItem )
+ {
+ vcl::Font aTmpFont( GetCharFont() );
+ aTmpFont.SetFamilyName( pFontNameItem->GetValue() );
+ SetCharFont( aTmpFont );
+ }
+
+ m_xOutputSet.reset(new SfxAllItemSet(pSet ? *pSet->GetPool() : SfxGetpApp()->GetPool()));
+ m_xShowSet->Show();
+ m_xSearchSet->Hide();
+}
+
+short SvxCharacterMap::run()
+{
+ if( SvxShowCharSet::getSelectedChar() == ' ')
+ {
+ m_xOKBtn->set_sensitive(false);
+ setFavButtonState(u"", u"");
+ }
+ else
+ {
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ m_aShowChar.SetText(aOUStr);
+
+ setFavButtonState(aOUStr, m_aShowChar.GetFont().GetFamilyName());
+ m_xOKBtn->set_sensitive(true);
+ }
+
+ return SfxDialogController::run();
+}
+
+void SvxCharacterMap::SetChar( sal_UCS4 c )
+{
+ m_xShowSet->SelectCharacter( c );
+ setFavButtonState(OUString(&c, 1), aFont.GetFamilyName());
+}
+
+sal_UCS4 SvxCharacterMap::GetChar() const
+{
+ return m_aShowChar.GetText().iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+}
+
+void SvxCharacterMap::DisableFontSelection()
+{
+ m_xFontText->set_sensitive(false);
+ m_xFontLB->set_sensitive(false);
+}
+
+
+void SvxCharacterMap::getRecentCharacterList()
+{
+ //retrieve recent character list
+ const css::uno::Sequence< OUString > rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() );
+ for (OUString const & s : rRecentCharList)
+ {
+ maRecentCharList.push_back(s);
+ }
+
+ //retrieve recent character font list
+ const css::uno::Sequence< OUString > rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() );
+ for (OUString const & s : rRecentCharFontList)
+ {
+ maRecentCharFontList.push_back(s);
+ }
+
+ // tdf#135997: make sure that the two lists are same length
+ const auto nCommonLength = std::min(maRecentCharList.size(), maRecentCharFontList.size());
+ maRecentCharList.resize(nCommonLength);
+ maRecentCharFontList.resize(nCommonLength);
+}
+
+
+void SvxCharacterMap::getFavCharacterList()
+{
+ maFavCharList.clear();
+ maFavCharFontList.clear();
+ //retrieve recent character list
+ const css::uno::Sequence< OUString > rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() );
+ for (const OUString& s : rFavCharList)
+ {
+ maFavCharList.push_back(s);
+ }
+
+ //retrieve recent character font list
+ const css::uno::Sequence< OUString > rFavCharFontList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::get() );
+ for (const OUString& s : rFavCharFontList)
+ {
+ maFavCharFontList.push_back(s);
+ }
+
+ // tdf#135997: make sure that the two lists are same length
+ const auto nCommonLength = std::min(maFavCharList.size(), maFavCharFontList.size());
+ maFavCharList.resize(nCommonLength);
+ maFavCharFontList.resize(nCommonLength);
+}
+
+static std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator>
+findInPair(std::u16string_view str1, const std::deque<OUString>& rContainer1,
+ std::u16string_view str2, const std::deque<OUString>& rContainer2)
+{
+ assert(rContainer1.size() == rContainer2.size());
+
+ if (auto it1 = std::find(rContainer1.begin(), rContainer1.end(), str1);
+ it1 != rContainer1.end())
+ {
+ auto it2 = rContainer2.begin() + (it1 - rContainer1.begin());
+ if (*it2 == str2)
+ return { it1, it2 };
+ }
+ return { rContainer1.end(), rContainer2.end() };
+}
+
+std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator>
+SvxCharacterMap::getRecentChar(std::u16string_view sTitle, std::u16string_view rFont) const
+{
+ return findInPair(sTitle, maRecentCharList, rFont, maRecentCharFontList);
+}
+
+std::pair<std::deque<OUString>::const_iterator, std::deque<OUString>::const_iterator>
+SvxCharacterMap::getFavChar(std::u16string_view sTitle, std::u16string_view rFont) const
+{
+ return findInPair(sTitle, maFavCharList, rFont, maFavCharFontList);
+}
+
+
+void SvxCharacterMap::updateRecentCharControl()
+{
+ assert(maRecentCharList.size() == maRecentCharFontList.size());
+
+ int i = 0;
+ for ( std::deque< OUString >::iterator it = maRecentCharList.begin(), it2 = maRecentCharFontList.begin();
+ it != maRecentCharList.end() && it2 != maRecentCharFontList.end();
+ ++it, ++it2, i++)
+ {
+ m_aRecentCharView[i].SetText(*it);
+ vcl::Font rFont = m_aRecentCharView[i].GetFont();
+ rFont.SetFamilyName( *it2 );
+ m_aRecentCharView[i].SetFont(rFont);
+ m_aRecentCharView[i].Show();
+ }
+
+ for(; i < 16 ; i++)
+ {
+ m_aRecentCharView[i].SetText(OUString());
+ m_aRecentCharView[i].Hide();
+ }
+}
+
+void SvxCharacterMap::updateRecentCharacterList(const OUString& sTitle, const OUString& rFont)
+{
+ // if recent char to be added is already in list, remove it
+ if( const auto& [itChar, itChar2] = getRecentChar(sTitle, rFont);
+ itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() )
+ {
+ maRecentCharList.erase( itChar );
+ maRecentCharFontList.erase( itChar2);
+ }
+
+ if (maRecentCharList.size() == 16)
+ {
+ maRecentCharList.pop_back();
+ maRecentCharFontList.pop_back();
+ }
+
+ maRecentCharList.push_front(sTitle);
+ maRecentCharFontList.push_front(rFont);
+
+ css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size());
+ auto aRecentCharListRange = asNonConstRange(aRecentCharList);
+ css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size());
+ auto aRecentCharFontListRange = asNonConstRange(aRecentCharFontList);
+
+ for (size_t i = 0; i < maRecentCharList.size(); ++i)
+ {
+ aRecentCharListRange[i] = maRecentCharList[i];
+ aRecentCharFontListRange[i] = maRecentCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
+ officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
+ batch->commit();
+
+ updateRecentCharControl();
+}
+
+
+void SvxCharacterMap::updateFavCharacterList(const OUString& sTitle, const OUString& rFont)
+{
+ // if Fav char to be added is already in list, remove it
+ if( const auto& [itChar, itChar2] = getFavChar(sTitle, rFont);
+ itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() )
+ {
+ maFavCharList.erase( itChar );
+ maFavCharFontList.erase( itChar2);
+ }
+
+ if (maFavCharList.size() == 16)
+ {
+ maFavCharList.pop_back();
+ maFavCharFontList.pop_back();
+ }
+
+ maFavCharList.push_back(sTitle);
+ maFavCharFontList.push_back(rFont);
+
+ css::uno::Sequence< OUString > aFavCharList(maFavCharList.size());
+ auto aFavCharListRange = asNonConstRange(aFavCharList);
+ css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size());
+ auto aFavCharFontListRange = asNonConstRange(aFavCharFontList);
+
+ for (size_t i = 0; i < maFavCharList.size(); ++i)
+ {
+ aFavCharListRange[i] = maFavCharList[i];
+ aFavCharFontListRange[i] = maFavCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
+ batch->commit();
+}
+
+
+void SvxCharacterMap::updateFavCharControl()
+{
+ assert(maFavCharList.size() == maFavCharFontList.size());
+
+ int i = 0;
+ for ( std::deque< OUString >::iterator it = maFavCharList.begin(), it2 = maFavCharFontList.begin();
+ it != maFavCharList.end() && it2 != maFavCharFontList.end();
+ ++it, ++it2, i++)
+ {
+ m_aFavCharView[i].SetText(*it);
+ vcl::Font rFont = m_aFavCharView[i].GetFont();
+ rFont.SetFamilyName( *it2 );
+ m_aFavCharView[i].SetFont(rFont);
+ m_aFavCharView[i].Show();
+ }
+
+ for(; i < 16 ; i++)
+ {
+ m_aFavCharView[i].SetText(OUString());
+ m_aFavCharView[i].Hide();
+ }
+ m_xShowSet->getFavCharacterList();
+ m_xSearchSet->getFavCharacterList();
+ // tdf#109214 - redraw highlight of the favorite characters
+ m_xShowSet->Invalidate();
+}
+
+void SvxCharacterMap::deleteFavCharacterFromList(std::u16string_view sTitle, std::u16string_view rFont)
+{
+ // if Fav char is found, remove it
+ if( const auto& [itChar, itChar2] = getFavChar(sTitle, rFont);
+ itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() )
+ {
+ maFavCharList.erase( itChar );
+ maFavCharFontList.erase( itChar2);
+ }
+
+ css::uno::Sequence< OUString > aFavCharList(maFavCharList.size());
+ auto aFavCharListRange = asNonConstRange(aFavCharList);
+ css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size());
+ auto aFavCharFontListRange = asNonConstRange(aFavCharFontList);
+
+ for (size_t i = 0; i < maFavCharList.size(); ++i)
+ {
+ aFavCharListRange[i] = maFavCharList[i];
+ aFavCharFontListRange[i] = maFavCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
+ batch->commit();
+}
+
+void SvxCharacterMap::init()
+{
+ aFont = m_xVirDev->GetFont();
+ aFont.SetTransparent( true );
+ aFont.SetFamily( FAMILY_DONTKNOW );
+ aFont.SetPitch( PITCH_DONTKNOW );
+ aFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
+
+ OUString aDefStr( aFont.GetFamilyName() );
+ OUString aLastName;
+ int nCount = m_xVirDev->GetFontFaceCollectionCount();
+ std::vector<weld::ComboBoxEntry> aEntries;
+ aEntries.reserve(nCount);
+ for (int i = 0; i < nCount; ++i)
+ {
+ OUString aFontName( m_xVirDev->GetFontMetricFromCollection( i ).GetFamilyName() );
+ if (aFontName != aLastName)
+ {
+ aLastName = aFontName;
+ aEntries.emplace_back(aFontName, OUString::number(i));
+ }
+ }
+ m_xFontLB->insert_vector(aEntries, true);
+ // the font may not be in the list =>
+ // try to find a font name token in list and select found font,
+ // else select topmost entry
+ bool bFound = (m_xFontLB->find_text(aDefStr) != -1);
+ if (!bFound)
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = aDefStr.getToken(0, ';', nIndex);
+ if (m_xFontLB->find_text(aToken) != -1)
+ {
+ aDefStr = aToken;
+ bFound = true;
+ break;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+
+ if (bFound)
+ m_xFontLB->set_active_text(aDefStr);
+ else if (m_xFontLB->get_count() )
+ m_xFontLB->set_active(0);
+ FontSelectHdl(*m_xFontLB);
+ if (m_xSubsetLB->get_count())
+ m_xSubsetLB->set_active(0);
+
+ m_xFontLB->connect_changed(LINK( this, SvxCharacterMap, FontSelectHdl));
+ m_xSubsetLB->connect_changed(LINK( this, SvxCharacterMap, SubsetSelectHdl));
+ m_xOKBtn->connect_clicked(LINK(this, SvxCharacterMap, InsertClickHdl));
+ m_xOKBtn->show();
+
+ m_xShowSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, CharDoubleClickHdl ) );
+ m_xShowSet->SetSelectHdl( LINK( this, SvxCharacterMap, CharSelectHdl ) );
+ m_xShowSet->SetHighlightHdl( LINK( this, SvxCharacterMap, CharHighlightHdl ) );
+ m_xShowSet->SetPreSelectHdl( LINK( this, SvxCharacterMap, CharPreSelectHdl ) );
+ m_xShowSet->SetFavClickHdl( LINK( this, SvxCharacterMap, FavClickHdl ) );
+
+ m_xSearchSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, SearchCharDoubleClickHdl ) );
+ m_xSearchSet->SetSelectHdl( LINK( this, SvxCharacterMap, SearchCharSelectHdl ) );
+ m_xSearchSet->SetHighlightHdl( LINK( this, SvxCharacterMap, SearchCharHighlightHdl ) );
+ m_xSearchSet->SetPreSelectHdl( LINK( this, SvxCharacterMap, SearchCharPreSelectHdl ) );
+ m_xSearchSet->SetFavClickHdl( LINK( this, SvxCharacterMap, FavClickHdl ) );
+
+ m_xDecimalCodeText->connect_changed( LINK( this, SvxCharacterMap, DecimalCodeChangeHdl ) );
+ m_xHexCodeText->connect_changed( LINK( this, SvxCharacterMap, HexCodeChangeHdl ) );
+ m_xFavouritesBtn->connect_clicked( LINK(this, SvxCharacterMap, FavSelectHdl));
+
+ // tdf#117038 set the buttons width to its max possible width so it doesn't
+ // make layout change when the label changes
+ m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_REMOVE_FAVORITES));
+ auto nMaxWidth = m_xFavouritesBtn->get_preferred_size().Width();
+ m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_ADD_FAVORITES));
+ nMaxWidth = std::max(nMaxWidth, m_xFavouritesBtn->get_preferred_size().Width());
+ m_xFavouritesBtn->set_size_request(nMaxWidth, -1);
+
+ if( SvxShowCharSet::getSelectedChar() == ' ')
+ {
+ m_xOKBtn->set_sensitive(false);
+ }
+ else
+ {
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ m_aShowChar.SetText(aOUStr);
+
+ setFavButtonState(aOUStr, aDefStr);
+ m_xOKBtn->set_sensitive(true);
+ }
+
+ getRecentCharacterList();
+ updateRecentCharControl();
+
+ getFavCharacterList();
+ updateFavCharControl();
+
+ bool bHasInsert = m_xFrame.is();
+
+ for(int i = 0; i < 16; i++)
+ {
+ m_aRecentCharView[i].SetHasInsert(bHasInsert);
+ m_aRecentCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl));
+ m_aRecentCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, RecentClearClickHdl));
+ m_aRecentCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, RecentClearAllClickHdl));
+ m_aFavCharView[i].SetHasInsert(bHasInsert);
+ m_aFavCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl));
+ m_aFavCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, FavClearClickHdl));
+ m_aFavCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, FavClearAllClickHdl));
+ }
+
+ setCharName(90);
+
+ m_xSearchText->connect_focus_in(LINK( this, SvxCharacterMap, SearchFieldGetFocusHdl ));
+ m_xSearchText->connect_changed(LINK(this, SvxCharacterMap, SearchUpdateHdl));
+}
+
+bool SvxCharacterMap::isFavChar(std::u16string_view sTitle, std::u16string_view rFont)
+{
+ const auto& [itChar, itFont] = getFavChar(sTitle, rFont);
+ return itChar != maFavCharList.end() && itFont != maFavCharFontList.end();
+}
+
+
+void SvxCharacterMap::setFavButtonState(std::u16string_view sTitle, std::u16string_view rFont)
+{
+ if(sTitle.empty() || rFont.empty())
+ {
+ m_xFavouritesBtn->set_sensitive(false);
+ return;
+ }
+ else
+ m_xFavouritesBtn->set_sensitive(true);
+
+ if (isFavChar(sTitle, rFont))
+ {
+ m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_REMOVE_FAVORITES));
+ }
+ else
+ {
+ if(maFavCharList.size() == 16)
+ {
+ m_xFavouritesBtn->set_sensitive(false);
+ }
+
+ m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_ADD_FAVORITES));
+ }
+}
+
+
+void SvxCharacterMap::SetCharFont( const vcl::Font& rFont )
+{
+ // first get the underlying info in order to get font names
+ // like "Times New Roman;Times" resolved
+ vcl::Font aTmp(m_xVirDev->GetFontMetric(rFont));
+
+ // tdf#56363 - search font family without the font feature after the colon
+ OUString sFontFamilyName = aTmp.GetFamilyName();
+ if (const sal_Int32 nIndex = sFontFamilyName.indexOf(":"); nIndex != -1)
+ sFontFamilyName = sFontFamilyName.copy(0, nIndex);
+ if (sFontFamilyName == "StarSymbol" && m_xFontLB->find_text(sFontFamilyName) == -1)
+ {
+ //if for some reason, like font in an old document, StarSymbol is requested and it's not available, then
+ //try OpenSymbol instead
+ aTmp.SetFamilyName("OpenSymbol");
+ }
+
+ if (m_xFontLB->find_text(sFontFamilyName) == -1)
+ return;
+
+ m_xFontLB->set_active_text(sFontFamilyName);
+ aFont = aTmp;
+ FontSelectHdl(*m_xFontLB);
+ if (m_xSubsetLB->get_count())
+ m_xSubsetLB->set_active(0);
+}
+
+void SvxCharacterMap::fillAllSubsets(weld::ComboBox& rListBox)
+{
+ SubsetMap aAll(nullptr);
+ std::vector<weld::ComboBoxEntry> aEntries;
+ for (auto & subset : aAll.GetSubsetMap())
+ aEntries.emplace_back(subset.GetName());
+ rListBox.insert_vector(aEntries, true);
+}
+
+void SvxCharacterMap::insertCharToDoc(const OUString& sGlyph)
+{
+ if(sGlyph.isEmpty())
+ return;
+
+ if (m_xFrame.is()) {
+ uno::Sequence<beans::PropertyValue> aArgs{
+ comphelper::makePropertyValue("Symbols", sGlyph),
+ comphelper::makePropertyValue("FontName", aFont.GetFamilyName())
+ };
+ comphelper::dispatchCommand(".uno:InsertSymbol", m_xFrame, aArgs);
+
+ updateRecentCharacterList(sGlyph, aFont.GetFamilyName());
+
+ } else {
+ sal_UCS4 cChar = sGlyph.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+ const SfxItemPool* pPool = m_xOutputSet->GetPool();
+ m_xOutputSet->Put( SfxStringItem( SID_CHARMAP, sGlyph ) );
+ m_xOutputSet->Put( SvxFontItem( aFont.GetFamilyType(), aFont.GetFamilyName(),
+ aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(), pPool->GetWhich(SID_ATTR_CHAR_FONT) ) );
+ m_xOutputSet->Put( SfxStringItem( SID_FONT_NAME, aFont.GetFamilyName() ) );
+ m_xOutputSet->Put( SfxInt32Item( SID_ATTR_CHAR, cChar ) );
+ }
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FontSelectHdl, weld::ComboBox&, void)
+{
+ const sal_uInt32 nFont = m_xFontLB->get_active_id().toUInt32();
+ aFont = m_xVirDev->GetFontMetricFromCollection(nFont);
+ aFont.SetWeight( WEIGHT_DONTKNOW );
+ aFont.SetItalic( ITALIC_NONE );
+ aFont.SetWidthType( WIDTH_DONTKNOW );
+ aFont.SetPitch( PITCH_DONTKNOW );
+ aFont.SetFamily( FAMILY_DONTKNOW );
+
+ // notify children using this font
+ m_xShowSet->SetFont( aFont );
+ m_xSearchSet->SetFont( aFont );
+ m_aShowChar.SetFont( aFont );
+
+ // setup unicode subset listbar with font specific subsets,
+ // hide unicode subset listbar for symbol fonts
+ // TODO: get info from the Font once it provides it
+ pSubsetMap.reset();
+ m_xSubsetLB->clear();
+
+ bool bNeedSubset = (aFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL);
+ if (bNeedSubset)
+ {
+ FontCharMapRef xFontCharMap = m_xShowSet->GetFontCharMap();
+ pSubsetMap.reset(new SubsetMap( xFontCharMap ));
+
+ // update subset listbox for new font's unicode subsets
+ for (auto const& subset : pSubsetMap->GetSubsetMap())
+ {
+ m_xSubsetLB->append(weld::toId(&subset), subset.GetName());
+ // NOTE: subset must live at least as long as the selected font
+ }
+
+ if (m_xSubsetLB->get_count() <= 1)
+ bNeedSubset = false;
+ }
+
+ m_xSubsetText->set_sensitive(bNeedSubset);
+ m_xSubsetLB->set_sensitive(bNeedSubset);
+
+ if (isSearchMode)
+ {
+ // tdf#137294 do this after modifying m_xSubsetLB sensitivity to
+ // restore insensitive for the search case
+ SearchUpdateHdl(*m_xSearchText);
+ SearchCharHighlightHdl(m_xSearchSet.get());
+ }
+
+ // tdf#118304 reselect current glyph to see if it's still there in new font
+ selectCharByCode(Radix::hexadecimal);
+}
+
+void SvxCharacterMap::toggleSearchView(bool state)
+{
+ isSearchMode = state;
+ m_xHexCodeText->set_editable(!state);
+ m_xDecimalCodeText->set_editable(!state);
+ m_xSubsetLB->set_sensitive(!state);
+
+ if(state)
+ {
+ m_xSearchSet->Show();
+ m_xShowSet->Hide();
+ }
+ else
+ {
+ m_xSearchSet->Hide();
+ m_xShowSet->Show();
+ }
+}
+
+void SvxCharacterMap::setCharName(sal_UCS4 nDecimalValue)
+{
+ /* get the character name */
+ UErrorCode errorCode = U_ZERO_ERROR;
+ // icu has a private uprv_getMaxCharNameLength function which returns the max possible
+ // length of this property. Unicode 3.2 max char name length was 83
+ char buffer[100];
+ u_charName(nDecimalValue, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
+ if (U_SUCCESS(errorCode))
+ m_xCharName->set_label(OUString::createFromAscii(buffer));
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SubsetSelectHdl, weld::ComboBox&, void)
+{
+ const sal_Int32 nPos = m_xSubsetLB->get_active();
+ const Subset* pSubset = weld::fromId<const Subset*>(m_xSubsetLB->get_active_id());
+
+ if( pSubset && !isSearchMode)
+ {
+ sal_UCS4 cFirst = pSubset->GetRangeMin();
+ m_xShowSet->SelectCharacter( cFirst );
+
+ setFavButtonState(OUString(&cFirst, 1), aFont.GetFamilyName());
+ m_xSubsetLB->set_active(nPos);
+ }
+ else if( pSubset && isSearchMode)
+ {
+ m_xSearchSet->SelectCharacter( pSubset );
+
+ const Subset* curSubset = nullptr;
+ if( pSubsetMap )
+ curSubset = pSubsetMap->GetSubsetByUnicode( m_xSearchSet->GetSelectCharacter() );
+ if( curSubset )
+ m_xSubsetLB->set_active_text(curSubset->GetName());
+ else
+ m_xSubsetLB->set_active(-1);
+
+ sal_UCS4 sChar = m_xSearchSet->GetSelectCharacter();
+ setFavButtonState(OUString(&sChar, 1), aFont.GetFamilyName());
+ }
+}
+
+IMPL_LINK(SvxCharacterMap, RecentClearClickHdl, SvxCharView*, rView, void)
+{
+ const OUString& sTitle = rView->GetText();
+ OUString sFont = rView->GetFont().GetFamilyName();
+
+ // if recent char to be added is already in list, remove it
+ if( const auto& [itChar, itChar2] = getRecentChar(sTitle, sFont);
+ itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() )
+ {
+ maRecentCharList.erase( itChar );
+ maRecentCharFontList.erase( itChar2);
+ }
+
+ css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size());
+ auto aRecentCharListRange = asNonConstRange(aRecentCharList);
+ css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size());
+ auto aRecentCharFontListRange = asNonConstRange(aRecentCharFontList);
+
+ for (size_t i = 0; i < maRecentCharList.size(); ++i)
+ {
+ aRecentCharListRange[i] = maRecentCharList[i];
+ aRecentCharFontListRange[i] = maRecentCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
+ officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
+ batch->commit();
+
+ updateRecentCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, RecentClearAllClickHdl, SvxCharView*, void)
+{
+ maRecentCharList.clear();
+ maRecentCharFontList.clear();
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::RecentCharacters::RecentCharacterList::set({ }, batch);
+ officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set({ }, batch);
+ batch->commit();
+
+ updateRecentCharControl();
+}
+
+IMPL_LINK(SvxCharacterMap, FavClearClickHdl, SvxCharView*, rView, void)
+{
+ deleteFavCharacterFromList(rView->GetText(), rView->GetFont().GetFamilyName());
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FavClearAllClickHdl, SvxCharView*, void)
+{
+ maFavCharList.clear();
+ maFavCharFontList.clear();
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set({ }, batch);
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set({ }, batch);
+ batch->commit();
+
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchFieldGetFocusHdl, weld::Widget&, void)
+{
+ m_xOKBtn->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchUpdateHdl, weld::Entry&, void)
+{
+ if (!m_xSearchText->get_text().isEmpty())
+ {
+ m_xSearchSet->ClearPreviousData();
+ OUString aKeyword = m_xSearchText->get_text();
+
+ toggleSearchView(true);
+
+ FontCharMapRef xFontCharMap = m_xSearchSet->GetFontCharMap();
+
+ sal_UCS4 sChar = xFontCharMap->GetFirstChar();
+ while(sChar != xFontCharMap->GetLastChar())
+ {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ char buffer[100];
+ u_charName(sChar, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
+ if (U_SUCCESS(errorCode))
+ {
+ OUString sName = OUString::createFromAscii(buffer);
+ if(!sName.isEmpty() && sName.toAsciiLowerCase().indexOf(aKeyword.toAsciiLowerCase()) >= 0)
+ m_xSearchSet->AppendCharToList(sChar);
+ }
+ sChar = xFontCharMap->GetNextChar(sChar);
+ }
+ //for last char
+ UErrorCode errorCode = U_ZERO_ERROR;
+ char buffer[100];
+ u_charName(sChar, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
+ if (U_SUCCESS(errorCode))
+ {
+ OUString sName = OUString::createFromAscii(buffer);
+ if(!sName.isEmpty() && sName.toAsciiLowerCase().indexOf(aKeyword.toAsciiLowerCase()) >= 0)
+ m_xSearchSet->AppendCharToList(sChar);
+ }
+
+ m_xSearchSet->UpdateScrollRange();
+ }
+ else
+ {
+ toggleSearchView(false);
+ }
+}
+
+
+IMPL_LINK(SvxCharacterMap, CharClickHdl, SvxCharView*, rView, void)
+{
+ rView->GrabFocus();
+
+ m_aShowChar.SetText( rView->GetText() );
+ m_aShowChar.SetFont(rView->GetFont());
+ m_aShowChar.Invalidate();
+
+ setFavButtonState(rView->GetText(), rView->GetFont().GetFamilyName());//check state
+
+ // Get the hexadecimal code
+ OUString charValue = rView->GetText();
+ sal_UCS4 cChar = charValue.iterateCodePoints(&o3tl::temporary(sal_Int32(1)), -1);
+ OUString aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
+
+ // Get the decimal code
+ OUString aDecimalText = OUString::number(cChar);
+
+ m_xHexCodeText->set_text(aHexText);
+ m_xDecimalCodeText->set_text(aDecimalText);
+ setCharName(cChar);
+
+ rView->Invalidate();
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharDoubleClickHdl, SvxShowCharSet*, void)
+{
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ setFavButtonState(aOUStr, aFont.GetFamilyName());
+ insertCharToDoc(aOUStr);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharDoubleClickHdl, SvxShowCharSet*, void)
+{
+ sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ setFavButtonState(aOUStr, aFont.GetFamilyName());
+ insertCharToDoc(aOUStr);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharSelectHdl, SvxShowCharSet*, void)
+{
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharSelectHdl, SvxShowCharSet*, void)
+{
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, InsertClickHdl, weld::Button&, void)
+{
+ OUString sChar = m_aShowChar.GetText();
+ insertCharToDoc(sChar);
+ // Need to update recent character list, when OK button does not insert
+ if(!m_xFrame.is())
+ updateRecentCharacterList(sChar, aFont.GetFamilyName());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FavSelectHdl, weld::Button&, void)
+{
+ if (m_xFavouritesBtn->get_label().match(CuiResId(RID_CUISTR_ADD_FAVORITES)))
+ {
+ updateFavCharacterList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
+ setFavButtonState(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
+ }
+ else
+ {
+ deleteFavCharacterFromList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
+ m_xFavouritesBtn->set_label(CuiResId(RID_CUISTR_ADD_FAVORITES));
+ m_xFavouritesBtn->set_sensitive(false);
+ }
+
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FavClickHdl, SvxShowCharSet*, void)
+{
+ getFavCharacterList();
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharHighlightHdl, SvxShowCharSet*, void)
+{
+ OUString aText;
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ bool bSelect = (cChar > 0);
+
+ // show char sample
+ if ( bSelect )
+ {
+ // using the new UCS4 constructor
+ aText = OUString( &cChar, 1 );
+ // Get the hexadecimal code
+ OUString aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
+ // Get the decimal code
+ OUString aDecimalText = OUString::number(cChar);
+ setCharName(cChar);
+
+ // Update the hex and decimal codes only if necessary
+ if (!m_xHexCodeText->get_text().equalsIgnoreAsciiCase(aHexText))
+ m_xHexCodeText->set_text(aHexText);
+ if (m_xDecimalCodeText->get_text() != aDecimalText)
+ m_xDecimalCodeText->set_text( aDecimalText );
+
+ const Subset* pSubset = nullptr;
+ if( pSubsetMap )
+ pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ else
+ m_xSubsetLB->set_active(-1);
+ }
+
+ m_aShowChar.SetText( aText );
+ m_aShowChar.SetFont( aFont );
+ m_aShowChar.Invalidate();
+
+ setFavButtonState(aText, aFont.GetFamilyName());
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharHighlightHdl, SvxShowCharSet*, void)
+{
+ OUString aText;
+ sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
+ bool bSelect = (cChar > 0);
+
+ // show char sample
+ if ( bSelect )
+ {
+ aText = OUString( &cChar, 1 );
+ // Get the hexadecimal code
+ OUString aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
+ // Get the decimal code
+ OUString aDecimalText = OUString::number(cChar);
+ setCharName(cChar);
+
+ // Update the hex and decimal codes only if necessary
+ if (!m_xHexCodeText->get_text().equalsIgnoreAsciiCase(aHexText))
+ m_xHexCodeText->set_text(aHexText);
+ if (m_xDecimalCodeText->get_text() != aDecimalText)
+ m_xDecimalCodeText->set_text( aDecimalText );
+
+ const Subset* pSubset = nullptr;
+ if( pSubsetMap )
+ pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ else
+ m_xSubsetLB->set_active(-1);
+ }
+
+ if(m_xSearchSet->HasFocus())
+ {
+ m_aShowChar.SetText( aText );
+ m_aShowChar.SetFont( aFont );
+ m_aShowChar.Invalidate();
+
+ setFavButtonState(aText, aFont.GetFamilyName());
+ }
+}
+
+void SvxCharacterMap::selectCharByCode(Radix radix)
+{
+ OUString aCodeString;
+ switch(radix)
+ {
+ case Radix::decimal:
+ aCodeString = m_xDecimalCodeText->get_text();
+ break;
+ case Radix::hexadecimal:
+ aCodeString = m_xHexCodeText->get_text();
+ break;
+ }
+ // Convert the code back to a character using the appropriate radix
+ sal_UCS4 cChar = aCodeString.toUInt32(static_cast<sal_Int16> (radix));
+ // Use FontCharMap::HasChar(sal_UCS4 cChar) to see if the desired character is in the font
+ FontCharMapRef xFontCharMap = m_xShowSet->GetFontCharMap();
+ if (xFontCharMap->HasChar(cChar))
+ // Select the corresponding character
+ SetChar(cChar);
+ else {
+ m_xCharName->set_label(CuiResId(RID_CUISTR_MISSING_CHAR));
+ m_aShowChar.SetText(" ");
+ switch(radix)
+ {
+ case Radix::decimal:
+ m_xHexCodeText->set_text(OUString::number(cChar, 16));
+ break;
+ case Radix::hexadecimal:
+ m_xDecimalCodeText->set_text(OUString::number(cChar));
+ break;
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, DecimalCodeChangeHdl, weld::Entry&, void)
+{
+ selectCharByCode(Radix::decimal);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, HexCodeChangeHdl, weld::Entry&, void)
+{
+ selectCharByCode(Radix::hexadecimal);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharPreSelectHdl, SvxShowCharSet*, void)
+{
+ // adjust subset selection
+ if( pSubsetMap )
+ {
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+
+ setFavButtonState(OUString(&cChar, 1), aFont.GetFamilyName());
+ const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ }
+
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharPreSelectHdl, SvxShowCharSet*, void)
+{
+ // adjust subset selection
+ if( pSubsetMap )
+ {
+ sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
+
+ setFavButtonState(OUString(&cChar, 1), aFont.GetFamilyName());
+ const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ }
+
+ m_xOKBtn->set_sensitive(true);
+}
+
+// class SvxShowText =====================================================
+SvxShowText::SvxShowText(const VclPtr<VirtualDevice>& rVirDev)
+ : m_xVirDev(rVirDev)
+ , mnY(0)
+ , mbCenter(false)
+{
+}
+
+void SvxShowText::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ vcl::Font aFont = m_xVirDev->GetFont();
+ Size aFontSize(aFont.GetFontSize().Width() * 5, aFont.GetFontSize().Height() * 5);
+ aFont.SetFontSize(aFontSize);
+ m_xVirDev->Push(PUSH_ALLFONT);
+ m_xVirDev->SetFont(aFont);
+ pDrawingArea->set_size_request(m_xVirDev->approximate_digit_width() + 2 * 12,
+ m_xVirDev->LogicToPixel(aFontSize).Height() * 2);
+ m_xVirDev->Pop();
+}
+
+void SvxShowText::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ rRenderContext.SetFont(m_aFont);
+
+ Color aTextCol = rRenderContext.GetTextColor();
+ Color aFillCol = rRenderContext.GetFillColor();
+ Color aLineCol = rRenderContext.GetLineColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ const Color aWindowTextColor(rStyleSettings.GetDialogTextColor());
+ const Color aWindowColor(rStyleSettings.GetWindowColor());
+ const Color aShadowColor(rStyleSettings.GetShadowColor());
+ rRenderContext.SetTextColor(aWindowTextColor);
+ rRenderContext.SetFillColor(aWindowColor);
+
+ const OUString aText = GetText();
+
+ Size aSize(GetOutputSizePixel());
+ tools::Long nAvailWidth = aSize.Width();
+ tools::Long nWinHeight = aSize.Height();
+
+ bool bGotBoundary = true;
+ bool bShrankFont = false;
+ vcl::Font aOrigFont(rRenderContext.GetFont());
+ Size aFontSize(aOrigFont.GetFontSize());
+ ::tools::Rectangle aBoundRect;
+
+ for (tools::Long nFontHeight = aFontSize.Height(); nFontHeight > 0; nFontHeight -= 5)
+ {
+ if (!rRenderContext.GetTextBoundRect( aBoundRect, aText ) || aBoundRect.IsEmpty())
+ {
+ bGotBoundary = false;
+ break;
+ }
+ if (!mbCenter)
+ break;
+ //only shrink in the single glyph large view mode
+ tools::Long nTextWidth = aBoundRect.GetWidth();
+ if (nAvailWidth > nTextWidth)
+ break;
+ vcl::Font aFont(aOrigFont);
+ aFontSize.setHeight( nFontHeight );
+ aFont.SetFontSize(aFontSize);
+ rRenderContext.SetFont(aFont);
+ mnY = (nWinHeight - rRenderContext.GetTextHeight()) / 2;
+ bShrankFont = true;
+ }
+
+ Point aPoint(2, mnY);
+ // adjust position using ink boundary if possible
+ if (!bGotBoundary)
+ aPoint.setX( (aSize.Width() - rRenderContext.GetTextWidth(aText)) / 2 );
+ else
+ {
+ // adjust position before it gets out of bounds
+ aBoundRect += aPoint;
+
+ // shift back vertically if needed
+ int nYLDelta = aBoundRect.Top();
+ int nYHDelta = aSize.Height() - aBoundRect.Bottom();
+ if( nYLDelta <= 0 )
+ aPoint.AdjustY( -(nYLDelta - 1) );
+ else if( nYHDelta <= 0 )
+ aPoint.AdjustY(nYHDelta - 1 );
+
+ if (mbCenter)
+ {
+ // move glyph to middle of cell
+ aPoint.setX( -aBoundRect.Left() + (aSize.Width() - aBoundRect.GetWidth()) / 2 );
+ }
+ else
+ {
+ // shift back horizontally if needed
+ int nXLDelta = aBoundRect.Left();
+ int nXHDelta = aSize.Width() - aBoundRect.Right();
+ if( nXLDelta <= 0 )
+ aPoint.AdjustX( -(nXLDelta - 1) );
+ else if( nXHDelta <= 0 )
+ aPoint.AdjustX(nXHDelta - 1 );
+ }
+ }
+
+ rRenderContext.SetLineColor(aShadowColor);
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aSize));
+ rRenderContext.DrawText(aPoint, aText);
+ rRenderContext.SetTextColor(aTextCol);
+ rRenderContext.SetFillColor(aFillCol);
+ rRenderContext.SetLineColor(aLineCol);
+ if (bShrankFont)
+ rRenderContext.SetFont(aOrigFont);
+}
+
+void SvxShowText::SetFont( const vcl::Font& rFont )
+{
+ tools::Long nWinHeight = GetOutputSizePixel().Height();
+
+ m_aFont = rFont;
+ m_aFont.SetWeight(WEIGHT_NORMAL);
+ m_aFont.SetAlignment(ALIGN_TOP);
+ m_aFont.SetFontSize(m_xVirDev->PixelToLogic(Size(0, nWinHeight / 2)));
+ m_aFont.SetTransparent(true);
+
+ m_xVirDev->Push(PUSH_ALLFONT);
+ m_xVirDev->SetFont(m_aFont);
+ mnY = (nWinHeight - m_xVirDev->GetTextHeight()) / 2;
+ m_xVirDev->Pop();
+
+ Invalidate();
+}
+
+void SvxShowText::Resize()
+{
+ SetFont(GetFont()); //force recalculation of size
+}
+
+void SvxShowText::SetText(const OUString& rText)
+{
+ m_sText = rText;
+ Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuifmsearch.cxx b/cui/source/dialogs/cuifmsearch.cxx
new file mode 100644
index 000000000..f1af2838c
--- /dev/null
+++ b/cui/source/dialogs/cuifmsearch.cxx
@@ -0,0 +1,759 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/app.hxx>
+#include <svx/fmsrccfg.hxx>
+#include <svx/fmsrcimp.hxx>
+#include <strings.hrc>
+#include <cuifmsearch.hxx>
+#include <svl/cjkoptions.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <svx/svxdlg.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace css::uno;
+using namespace css::i18n;
+using namespace ::svxform;
+using namespace css::sdbc;
+using namespace css::util;
+
+#define MAX_HISTORY_ENTRIES 50
+
+void FmSearchDialog::initCommon( const Reference< XResultSet >& _rxCursor )
+{
+ // init the engine
+ DBG_ASSERT( m_pSearchEngine, "FmSearchDialog::initCommon: have no engine!" );
+ m_pSearchEngine->SetProgressHandler(LINK(this, FmSearchDialog, OnSearchProgress));
+
+ // some layout changes according to available CJK options
+ if (!SvtCJKOptions::IsJapaneseFindEnabled())
+ {
+ // hide the options for the japanese search
+ m_pSoundsLikeCJK->hide();
+ m_pSoundsLikeCJKSettings->hide();
+ }
+
+ if (!SvtCJKOptions::IsCJKFontEnabled())
+ {
+ m_pHalfFullFormsCJK->hide();
+
+ // never ignore the width (ignoring is expensive) if the option is not available at all
+ m_pSearchEngine->SetIgnoreWidthCJK( false );
+ }
+
+ // some initial record texts
+ m_pftRecord->set_label( OUString::number(_rxCursor->getRow()) );
+ m_pbClose->set_tooltip_text(OUString());
+}
+
+FmSearchDialog::FmSearchDialog(weld::Window* pParent, const OUString& sInitialText, const std::vector< OUString >& _rContexts, sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier)
+ : GenericDialogController(pParent, "cui/ui/fmsearchdialog.ui", "RecordSearchDialog")
+ , m_sCancel( GetStandardText( StandardButtonType::Cancel ) )
+ , m_lnkContextSupplier(lnkContextSupplier)
+ , m_prbSearchForText(m_xBuilder->weld_radio_button("rbSearchForText"))
+ , m_prbSearchForNull(m_xBuilder->weld_radio_button("rbSearchForNull"))
+ , m_prbSearchForNotNull(m_xBuilder->weld_radio_button("rbSearchForNotNull"))
+ , m_pcmbSearchText(m_xBuilder->weld_combo_box("cmbSearchText"))
+ , m_pftForm(m_xBuilder->weld_label("ftForm"))
+ , m_plbForm(m_xBuilder->weld_combo_box("lbForm"))
+ , m_prbAllFields(m_xBuilder->weld_radio_button("rbAllFields"))
+ , m_prbSingleField(m_xBuilder->weld_radio_button("rbSingleField"))
+ , m_plbField(m_xBuilder->weld_combo_box("lbField"))
+ , m_pftPosition(m_xBuilder->weld_label("ftPosition"))
+ , m_plbPosition(m_xBuilder->weld_combo_box("lbPosition"))
+ , m_pcbUseFormat(m_xBuilder->weld_check_button("cbUseFormat"))
+ , m_pcbCase(m_xBuilder->weld_check_button("cbCase"))
+ , m_pcbBackwards(m_xBuilder->weld_check_button("cbBackwards"))
+ , m_pcbStartOver(m_xBuilder->weld_check_button("cbStartOver"))
+ , m_pcbWildCard(m_xBuilder->weld_check_button("cbWildCard"))
+ , m_pcbRegular(m_xBuilder->weld_check_button("cbRegular"))
+ , m_pcbApprox(m_xBuilder->weld_check_button("cbApprox"))
+ , m_ppbApproxSettings(m_xBuilder->weld_button("pbApproxSettings"))
+ , m_pHalfFullFormsCJK(m_xBuilder->weld_check_button("HalfFullFormsCJK"))
+ , m_pSoundsLikeCJK(m_xBuilder->weld_check_button("SoundsLikeCJK"))
+ , m_pSoundsLikeCJKSettings(m_xBuilder->weld_button("SoundsLikeCJKSettings"))
+ , m_pftRecord(m_xBuilder->weld_label("ftRecord"))
+ , m_pftHint(m_xBuilder->weld_label("ftHint"))
+ , m_pbSearchAgain(m_xBuilder->weld_button("pbSearchAgain"))
+ , m_pbClose(m_xBuilder->weld_button("close"))
+{
+ m_pcmbSearchText->set_size_request(m_pcmbSearchText->get_approximate_digit_width() * 38, -1);
+ m_plbForm->set_size_request(m_plbForm->get_approximate_digit_width() * 38, -1);
+ m_sSearch = m_pbSearchAgain->get_label();
+
+ DBG_ASSERT(m_lnkContextSupplier.IsSet(), "FmSearchDialog::FmSearchDialog : have no ContextSupplier !");
+
+ FmSearchContext fmscInitial;
+ fmscInitial.nContext = nInitialContext;
+ m_lnkContextSupplier.Call(fmscInitial);
+ DBG_ASSERT(fmscInitial.xCursor.is(), "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplier !");
+ DBG_ASSERT(comphelper::string::getTokenCount(fmscInitial.strUsedFields, ';') == static_cast<sal_Int32>(fmscInitial.arrFields.size()),
+ "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplied !");
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ for (const Reference<XInterface> & arrField : fmscInitial.arrFields)
+ {
+ DBG_ASSERT(arrField.is(), "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplier !");
+ }
+#endif // (OSL_DEBUG_LEVEL > 1) || DBG_UTIL
+
+ for ( std::vector< OUString >::const_iterator context = _rContexts.begin();
+ context != _rContexts.end();
+ ++context
+ )
+ {
+ m_arrContextFields.emplace_back();
+ m_plbForm->append_text(*context);
+ }
+ m_plbForm->set_active(nInitialContext);
+
+ m_plbForm->connect_changed(LINK(this, FmSearchDialog, OnContextSelection));
+
+ if (m_arrContextFields.size() == 1)
+ {
+ // hide dispensable controls
+ m_pftForm->hide();
+ m_plbForm->hide();
+ }
+
+ m_pSearchEngine.reset( new FmSearchEngine(
+ ::comphelper::getProcessComponentContext(), fmscInitial.xCursor, fmscInitial.strUsedFields, fmscInitial.arrFields ) );
+ initCommon( fmscInitial.xCursor );
+
+ if ( !fmscInitial.sFieldDisplayNames.isEmpty() )
+ { // use the display names if supplied
+ DBG_ASSERT(comphelper::string::getTokenCount(fmscInitial.sFieldDisplayNames, ';') == comphelper::string::getTokenCount(fmscInitial.strUsedFields, ';'),
+ "FmSearchDialog::FmSearchDialog : invalid initial context description !");
+ Init(fmscInitial.sFieldDisplayNames, sInitialText);
+ }
+ else
+ Init(fmscInitial.strUsedFields, sInitialText);
+}
+
+FmSearchDialog::~FmSearchDialog()
+{
+ SaveParams();
+
+ m_pConfig.reset();
+ m_pSearchEngine.reset();
+}
+
+void FmSearchDialog::Init(std::u16string_view strVisibleFields, const OUString& sInitialText)
+{
+ //the initialization of all the Controls
+ m_prbSearchForText->connect_toggled(LINK(this, FmSearchDialog, OnToggledSearchRadio));
+ m_prbSearchForNull->connect_toggled(LINK(this, FmSearchDialog, OnToggledSearchRadio));
+ m_prbSearchForNotNull->connect_toggled(LINK(this, FmSearchDialog, OnToggledSearchRadio));
+
+ m_prbAllFields->connect_toggled(LINK(this, FmSearchDialog, OnToggledFieldRadios));
+ m_prbSingleField->connect_toggled(LINK(this, FmSearchDialog, OnToggledFieldRadios));
+
+ m_pbSearchAgain->connect_clicked(LINK(this, FmSearchDialog, OnClickedSearchAgain));
+ m_ppbApproxSettings->connect_clicked(LINK(this, FmSearchDialog, OnClickedSpecialSettings));
+ m_pSoundsLikeCJKSettings->connect_clicked(LINK(this, FmSearchDialog, OnClickedSpecialSettings));
+
+ m_plbPosition->connect_changed(LINK(this, FmSearchDialog, OnPositionSelected));
+ m_plbField->connect_changed(LINK(this, FmSearchDialog, OnFieldSelected));
+
+ m_pcmbSearchText->connect_changed(LINK(this, FmSearchDialog, OnSearchTextModified));
+ m_pcmbSearchText->set_entry_completion(false);
+ m_pcmbSearchText->connect_focus_in(LINK(this, FmSearchDialog, OnFocusGrabbed));
+
+ m_pcbUseFormat->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbBackwards->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbStartOver->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbCase->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbWildCard->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbRegular->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbApprox->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pHalfFullFormsCJK->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pSoundsLikeCJK->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+
+ // fill the listboxes
+ // method of field comparison
+ const TranslateId aResIds[] = {
+ RID_STR_SEARCH_ANYWHERE,
+ RID_STR_SEARCH_BEGINNING,
+ RID_STR_SEARCH_END,
+ RID_STR_SEARCH_WHOLE
+ };
+ for (auto const & pResId : aResIds)
+ m_plbPosition->append_text(CuiResId(pResId));
+ m_plbPosition->set_active(MATCHING_ANYWHERE);
+
+ // the field listbox
+ if (!strVisibleFields.empty())
+ {
+ sal_Int32 nPos {0};
+ do {
+ m_plbField->append_text(OUString(o3tl::getToken(strVisibleFields, 0, ';', nPos)));
+ } while (nPos>=0);
+ }
+
+
+ m_pConfig.reset( new FmSearchConfigItem );
+ LoadParams();
+
+ m_pcmbSearchText->set_entry_text(sInitialText);
+ // if the Edit-line has changed the text (e.g. because it contains
+ // control characters, as can be the case with memo fields), I use
+ // an empty OUString.
+ OUString sRealSetText = m_pcmbSearchText->get_active_text();
+ if (sRealSetText != sInitialText)
+ m_pcmbSearchText->set_entry_text(OUString());
+ OnSearchTextModified(*m_pcmbSearchText);
+
+ // initial
+ EnableSearchUI(true);
+
+ if ( m_prbSearchForText->get_active() )
+ m_pcmbSearchText->grab_focus();
+
+}
+
+short FmSearchDialog::run()
+{
+ short nRet = weld::GenericDialogController::run();
+ m_pSearchEngine->CancelSearch();
+ return nRet;
+}
+
+IMPL_LINK(FmSearchDialog, OnToggledSearchRadio, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ EnableSearchForDependees(true);
+}
+
+IMPL_LINK(FmSearchDialog, OnToggledFieldRadios, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ // en- or disable field list box accordingly
+ if (m_prbSingleField->get_active())
+ {
+ m_plbField->set_sensitive(true);
+ m_pSearchEngine->RebuildUsedFields(m_plbField->get_active());
+ }
+ else
+ {
+ m_plbField->set_sensitive(false);
+ m_pSearchEngine->RebuildUsedFields(-1);
+ }
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnClickedSearchAgain, weld::Button&, void)
+{
+ if (m_pbClose->get_sensitive())
+ { // the button has the function 'search'
+ OUString strThisRoundText = m_pcmbSearchText->get_active_text();
+ // to history
+ m_pcmbSearchText->remove_text(strThisRoundText);
+ m_pcmbSearchText->insert_text(0, strThisRoundText);
+ // the remove/insert makes sure that a) the OUString does not appear twice and
+ // that b) the last searched strings are at the beginning and limit the list length
+ while (m_pcmbSearchText->get_count() > MAX_HISTORY_ENTRIES)
+ m_pcmbSearchText->remove(m_pcmbSearchText->get_count()-1);
+
+ // take out the 'overflow' hint
+ m_pftHint->set_label(OUString());
+
+ if (m_pcbStartOver->get_active())
+ {
+ m_pcbStartOver->set_active(false);
+ EnableSearchUI(false);
+ if (m_prbSearchForText->get_active())
+ m_pSearchEngine->StartOver(strThisRoundText);
+ else
+ m_pSearchEngine->StartOverSpecial(m_prbSearchForNull->get_active());
+ }
+ else
+ {
+ EnableSearchUI(false);
+ if (m_prbSearchForText->get_active())
+ m_pSearchEngine->SearchNext(strThisRoundText);
+ else
+ m_pSearchEngine->SearchNextSpecial(m_prbSearchForNull->get_active());
+ }
+ }
+ else
+ { // the button has the function 'cancel'
+ // the CancelButton is usually only disabled, when working in a thread or with reschedule
+ m_pSearchEngine->CancelSearch();
+ // the ProgressHandler is called when it's really finished, here it's only a demand
+ }
+}
+
+IMPL_LINK(FmSearchDialog, OnClickedSpecialSettings, weld::Button&, rButton, void)
+{
+ if (m_ppbApproxSettings.get() == &rButton)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxSearchSimilarityDialog> pDlg(pFact->CreateSvxSearchSimilarityDialog(m_xDialog.get(), m_pSearchEngine->GetLevRelaxed(), m_pSearchEngine->GetLevOther(),
+ m_pSearchEngine->GetLevShorter(), m_pSearchEngine->GetLevLonger() ));
+ if (pDlg->Execute() == RET_OK)
+ {
+ m_pSearchEngine->SetLevRelaxed( pDlg->IsRelaxed() );
+ m_pSearchEngine->SetLevOther( pDlg->GetOther() );
+ m_pSearchEngine->SetLevShorter(pDlg->GetShorter() );
+ m_pSearchEngine->SetLevLonger( pDlg->GetLonger() );
+ }
+ }
+ else if (m_pSoundsLikeCJKSettings.get() == &rButton)
+ {
+ SfxItemSet aSet( SfxGetpApp()->GetPool() );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxJSearchOptionsDialog> aDlg(pFact->CreateSvxJSearchOptionsDialog(m_xDialog.get(), aSet, m_pSearchEngine->GetTransliterationFlags() ));
+ aDlg->Execute();
+
+ TransliterationFlags nFlags = aDlg->GetTransliterationFlags();
+ m_pSearchEngine->SetTransliterationFlags(nFlags);
+
+ m_pcbCase->set_active(m_pSearchEngine->GetCaseSensitive());
+ OnCheckBoxToggled( *m_pcbCase );
+ m_pHalfFullFormsCJK->set_active( !m_pSearchEngine->GetIgnoreWidthCJK() );
+ OnCheckBoxToggled( *m_pHalfFullFormsCJK );
+ }
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnSearchTextModified, weld::ComboBox&, void)
+{
+ if ((!m_pcmbSearchText->get_active_text().isEmpty()) || !m_prbSearchForText->get_active())
+ m_pbSearchAgain->set_sensitive(true);
+ else
+ m_pbSearchAgain->set_sensitive(false);
+
+ m_pSearchEngine->InvalidatePreviousLoc();
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnFocusGrabbed, weld::Widget&, void)
+{
+ m_pcmbSearchText->select_entry_region(0, -1);
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnPositionSelected, weld::ComboBox&, void)
+{
+ m_pSearchEngine->SetPosition(m_plbPosition->get_active());
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnFieldSelected, weld::ComboBox&, void)
+{
+ m_pSearchEngine->RebuildUsedFields(m_prbAllFields->get_active() ? -1 : m_plbField->get_active());
+ // calls m_pSearchEngine->InvalidatePreviousLoc too
+
+ int nCurrentContext = m_plbForm->get_active();
+ if (nCurrentContext != -1)
+ m_arrContextFields[nCurrentContext] = m_plbField->get_active_text();
+}
+
+IMPL_LINK(FmSearchDialog, OnCheckBoxToggled, weld::Toggleable&, rBox, void)
+{
+ bool bChecked = rBox.get_active();
+
+ // formatter or case -> pass on to the engine
+ if (&rBox == m_pcbUseFormat.get())
+ m_pSearchEngine->SetFormatterUsing(bChecked);
+ else if (&rBox == m_pcbCase.get())
+ m_pSearchEngine->SetCaseSensitive(bChecked);
+ // direction -> pass on and reset the checkbox-text for StartOver
+ else if (&rBox == m_pcbBackwards.get())
+ {
+ m_pcbStartOver->set_label( CuiResId( bChecked ? RID_STR_FROM_BOTTOM : RID_STR_FROM_TOP ) );
+ m_pSearchEngine->SetDirection(!bChecked);
+ }
+ // similarity-search or regular expression
+ else if ((&rBox == m_pcbApprox.get()) || (&rBox == m_pcbRegular.get()) || (&rBox == m_pcbWildCard.get()))
+ {
+ weld::CheckButton* pBoxes[] = { m_pcbWildCard.get(), m_pcbRegular.get(), m_pcbApprox.get() };
+ for (weld::CheckButton* pBoxe : pBoxes)
+ {
+ if (pBoxe != &rBox)
+ {
+ if (bChecked)
+ pBoxe->set_sensitive(false);
+ else
+ pBoxe->set_sensitive(true);
+ }
+ }
+
+ // pass on to the engine
+ m_pSearchEngine->SetWildcard(m_pcbWildCard->get_sensitive() && m_pcbWildCard->get_active());
+ m_pSearchEngine->SetRegular(m_pcbRegular->get_sensitive() && m_pcbRegular->get_active());
+ m_pSearchEngine->SetLevenshtein(m_pcbApprox->get_sensitive() && m_pcbApprox->get_active());
+ // (disabled boxes have to be passed to the engine as sal_False)
+
+ // adjust the Position-Listbox (which is not allowed during Wildcard-search)
+ if (&rBox == m_pcbWildCard.get())
+ {
+ if (bChecked)
+ {
+ m_pftPosition->set_sensitive(false);
+ m_plbPosition->set_sensitive(false);
+ }
+ else
+ {
+ m_pftPosition->set_sensitive(true);
+ m_plbPosition->set_sensitive(true);
+ }
+ }
+
+ // and the button for similarity-search
+ if (&rBox == m_pcbApprox.get())
+ {
+ if (bChecked)
+ m_ppbApproxSettings->set_sensitive(true);
+ else
+ m_ppbApproxSettings->set_sensitive(false);
+ }
+ }
+ else if (&rBox == m_pHalfFullFormsCJK.get())
+ {
+ // forward to the search engine
+ m_pSearchEngine->SetIgnoreWidthCJK( !bChecked );
+ }
+ else if (&rBox == m_pSoundsLikeCJK.get())
+ {
+ m_pSoundsLikeCJKSettings->set_sensitive(bChecked);
+
+ // two other buttons which depend on this one
+ bool bEnable = ( m_prbSearchForText->get_active()
+ && !m_pSoundsLikeCJK->get_active()
+ )
+ || !SvtCJKOptions::IsJapaneseFindEnabled();
+ m_pcbCase->set_sensitive(bEnable);
+ m_pHalfFullFormsCJK->set_sensitive(bEnable);
+
+ // forward to the search engine
+ m_pSearchEngine->SetTransliteration( bChecked );
+ }
+}
+
+void FmSearchDialog::InitContext(sal_Int16 nContext)
+{
+ FmSearchContext fmscContext;
+ fmscContext.nContext = nContext;
+
+ sal_uInt32 nResult = m_lnkContextSupplier.Call(fmscContext);
+ DBG_ASSERT(nResult > 0, "FmSearchDialog::InitContext : ContextSupplier didn't give me any controls !");
+
+ // put the field names into the respective listbox
+ m_plbField->clear();
+
+ if (!fmscContext.sFieldDisplayNames.isEmpty())
+ {
+ // use the display names if supplied
+ DBG_ASSERT(comphelper::string::getTokenCount(fmscContext.sFieldDisplayNames, ';') == comphelper::string::getTokenCount(fmscContext.strUsedFields, ';'),
+ "FmSearchDialog::InitContext : invalid context description supplied !");
+ sal_Int32 nPos {0};
+ do {
+ m_plbField->append_text(fmscContext.sFieldDisplayNames.getToken(0, ';', nPos));
+ } while (nPos>=0);
+ }
+ else if (!fmscContext.strUsedFields.isEmpty())
+ {
+ // else use the field names
+ sal_Int32 nPos {0};
+ do {
+ m_plbField->append_text(fmscContext.strUsedFields.getToken(0, ';', nPos));
+ } while (nPos>=0);
+ }
+
+ if (nContext < static_cast<sal_Int32>(m_arrContextFields.size()) && !m_arrContextFields[nContext].isEmpty())
+ {
+ m_plbField->set_active_text(m_arrContextFields[nContext]);
+ }
+ else
+ {
+ m_plbField->set_active(0);
+ if (m_prbSingleField->get_active() && (m_plbField->get_count() > 1))
+ m_plbField->grab_focus();
+ }
+
+ m_pSearchEngine->SwitchToContext(fmscContext.xCursor, fmscContext.strUsedFields, fmscContext.arrFields,
+ m_prbAllFields->get_active() ? -1 : 0);
+
+ m_pftRecord->set_label(OUString::number(fmscContext.xCursor->getRow()));
+}
+
+IMPL_LINK(FmSearchDialog, OnContextSelection, weld::ComboBox&, rBox, void)
+{
+ InitContext(rBox.get_active());
+}
+
+void FmSearchDialog::EnableSearchUI(bool bEnable)
+{
+ // the search button has two functions -> adjust its text accordingly
+ OUString sButtonText( bEnable ? m_sSearch : m_sCancel );
+ m_pbSearchAgain->set_label(sButtonText);
+
+ m_prbSearchForText->set_sensitive(bEnable);
+ m_prbSearchForNull->set_sensitive(bEnable);
+ m_prbSearchForNotNull->set_sensitive(bEnable);
+ m_plbForm->set_sensitive(bEnable);
+ m_prbAllFields->set_sensitive(bEnable);
+ m_prbSingleField->set_sensitive(bEnable);
+ m_plbField->set_sensitive(bEnable && m_prbSingleField->get_active());
+ m_pcbBackwards->set_sensitive(bEnable);
+ m_pcbStartOver->set_sensitive(bEnable);
+ m_pbClose->set_sensitive(bEnable);
+ EnableSearchForDependees(bEnable);
+
+ if ( !bEnable )
+ { // this means we're preparing for starting a search
+ // In this case, EnableSearchForDependees disabled the search button
+ // But as we're about to use it for cancelling the search, we really need to enable it, again
+ m_pbSearchAgain->set_sensitive(true);
+ }
+}
+
+void FmSearchDialog::EnableSearchForDependees(bool bEnable)
+{
+ bool bSearchingForText = m_prbSearchForText->get_active();
+ m_pbSearchAgain->set_sensitive(bEnable && (!bSearchingForText || (!m_pcmbSearchText->get_active_text().isEmpty())));
+
+ bEnable = bEnable && bSearchingForText;
+
+ bool bEnableRedundants = !m_pSoundsLikeCJK->get_active() || !SvtCJKOptions::IsJapaneseFindEnabled();
+
+ m_pcmbSearchText->set_sensitive(bEnable);
+ m_pftPosition->set_sensitive(bEnable && !m_pcbWildCard->get_active());
+ m_pcbWildCard->set_sensitive(bEnable && !m_pcbRegular->get_active() && !m_pcbApprox->get_active());
+ m_pcbRegular->set_sensitive(bEnable && !m_pcbWildCard->get_active() && !m_pcbApprox->get_active());
+ m_pcbApprox->set_sensitive(bEnable && !m_pcbWildCard->get_active() && !m_pcbRegular->get_active());
+ m_ppbApproxSettings->set_sensitive(bEnable && m_pcbApprox->get_active());
+ m_pHalfFullFormsCJK->set_sensitive(bEnable && bEnableRedundants);
+ m_pSoundsLikeCJK->set_sensitive(bEnable);
+ m_pSoundsLikeCJKSettings->set_sensitive(bEnable && m_pSoundsLikeCJK->get_active());
+ m_plbPosition->set_sensitive(bEnable && !m_pcbWildCard->get_active());
+ m_pcbUseFormat->set_sensitive(bEnable);
+ m_pcbCase->set_sensitive(bEnable && bEnableRedundants);
+}
+
+void FmSearchDialog::OnFound(const css::uno::Any& aCursorPos, sal_Int16 nFieldPos)
+{
+ FmFoundRecordInformation friInfo;
+ friInfo.nContext = m_plbForm->get_active();
+ // if I don't do a search in a context, this has an invalid value - but then it doesn't matter anyway
+ friInfo.aPosition = aCursorPos;
+ if (m_prbAllFields->get_active())
+ friInfo.nFieldPos = nFieldPos;
+ else
+ friInfo.nFieldPos = m_plbField->get_active();
+ // this of course implies that I have really searched in the field that is selected in the listbox,
+ // which is made sure in RebuildUsedFields
+
+ m_lnkFoundHandler.Call(friInfo);
+
+ m_pcmbSearchText->grab_focus();
+}
+
+IMPL_LINK(FmSearchDialog, OnSearchProgress, const FmSearchProgress*, pProgress, void)
+{
+ SolarMutexGuard aGuard;
+ // make this single method thread-safe (it's an overkill to block the whole application for this,
+ // but we don't have another safety concept at the moment)
+
+ switch (pProgress->aSearchState)
+ {
+ case FmSearchProgress::State::Progress:
+ if (pProgress->bOverflow)
+ {
+ OUString sHint( CuiResId( m_pcbBackwards->get_active() ? RID_STR_OVERFLOW_BACKWARD : RID_STR_OVERFLOW_FORWARD ) );
+ m_pftHint->set_label( sHint );
+ }
+
+ m_pftRecord->set_label(OUString::number(1 + pProgress->nCurrentRecord));
+ break;
+
+ case FmSearchProgress::State::ProgressCounting:
+ m_pftHint->set_label(CuiResId(RID_STR_SEARCH_COUNTING));
+ m_pftRecord->set_label(OUString::number(pProgress->nCurrentRecord));
+ break;
+
+ case FmSearchProgress::State::Successful:
+ OnFound(pProgress->aBookmark, static_cast<sal_Int16>(pProgress->nFieldIndex));
+ EnableSearchUI(true);
+ break;
+
+ case FmSearchProgress::State::Error:
+ case FmSearchProgress::State::NothingFound:
+ {
+ TranslateId pErrorId = (FmSearchProgress::State::Error == pProgress->aSearchState)
+ ? RID_STR_SEARCH_GENERAL_ERROR
+ : RID_STR_SEARCH_NORECORD;
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, CuiResId(pErrorId)));
+ xBox->run();
+ [[fallthrough]];
+ }
+ case FmSearchProgress::State::Canceled:
+ EnableSearchUI(true);
+ if (m_lnkCanceledNotFoundHdl.IsSet())
+ {
+ FmFoundRecordInformation friInfo;
+ friInfo.nContext = m_plbForm->get_active();
+ // if I don't do a search in a context, this has an invalid value - but then it doesn't matter anyway
+ friInfo.aPosition = pProgress->aBookmark;
+ m_lnkCanceledNotFoundHdl.Call(friInfo);
+ }
+ break;
+ }
+
+ m_pftRecord->set_label(OUString::number(1 + pProgress->nCurrentRecord));
+}
+
+void FmSearchDialog::LoadParams()
+{
+ FmSearchParams aParams(m_pConfig->getParams());
+
+ const OUString* pHistory = aParams.aHistory.getConstArray();
+ const OUString* pHistoryEnd = pHistory + aParams.aHistory.getLength();
+ for (; pHistory != pHistoryEnd; ++pHistory)
+ m_pcmbSearchText->append_text( *pHistory );
+
+ // I do the settings at my UI-elements and then I simply call the respective change-handler,
+ // that way the data is handed on to the SearchEngine and all dependent settings are done
+
+ // current field
+ int nInitialField = m_plbField->find_text( aParams.sSingleSearchField );
+ if (nInitialField == -1)
+ nInitialField = 0;
+ m_plbField->set_active(nInitialField);
+ OnFieldSelected(*m_plbField);
+ // all fields/single field (AFTER selecting the field because OnToggledFieldRadios expects a valid value there)
+ if (aParams.bAllFields)
+ {
+ m_prbSingleField->set_active(false);
+ m_prbAllFields->set_active(true);
+ OnToggledFieldRadios(*m_prbAllFields);
+ // OnToggledFieldRadios also calls to RebuildUsedFields
+ }
+ else
+ {
+ m_prbAllFields->set_active(false);
+ m_prbSingleField->set_active(true);
+ OnToggledFieldRadios(*m_prbSingleField);
+ }
+
+ m_plbPosition->set_active(aParams.nPosition);
+ OnPositionSelected(*m_plbPosition);
+
+ // field formatting/case sensitivity/direction
+ m_pcbUseFormat->set_active(aParams.bUseFormatter);
+ m_pcbCase->set_active( aParams.isCaseSensitive() );
+ m_pcbBackwards->set_active(aParams.bBackwards);
+ OnCheckBoxToggled(*m_pcbUseFormat);
+ OnCheckBoxToggled(*m_pcbCase);
+ OnCheckBoxToggled(*m_pcbBackwards);
+
+ m_pHalfFullFormsCJK->set_active( !aParams.isIgnoreWidthCJK( ) ); // BEWARE: this checkbox has an inverse semantics!
+ m_pSoundsLikeCJK->set_active( aParams.bSoundsLikeCJK );
+ OnCheckBoxToggled(*m_pHalfFullFormsCJK);
+ OnCheckBoxToggled(*m_pSoundsLikeCJK);
+
+ m_pcbWildCard->set_active(false);
+ m_pcbRegular->set_active(false);
+ m_pcbApprox->set_active(false);
+ OnCheckBoxToggled(*m_pcbWildCard);
+ OnCheckBoxToggled(*m_pcbRegular);
+ OnCheckBoxToggled(*m_pcbApprox);
+
+ weld::CheckButton* pToCheck = nullptr;
+ if (aParams.bWildcard)
+ pToCheck = m_pcbWildCard.get();
+ if (aParams.bRegular)
+ pToCheck = m_pcbRegular.get();
+ if (aParams.bApproxSearch)
+ pToCheck = m_pcbApprox.get();
+ if (aParams.bSoundsLikeCJK)
+ pToCheck = m_pSoundsLikeCJK.get();
+ if (pToCheck)
+ {
+ pToCheck->set_active(true);
+ OnCheckBoxToggled(*pToCheck);
+ }
+
+ // set Levenshtein-parameters directly at the SearchEngine
+ m_pSearchEngine->SetLevRelaxed(aParams.bLevRelaxed);
+ m_pSearchEngine->SetLevOther(aParams.nLevOther);
+ m_pSearchEngine->SetLevShorter(aParams.nLevShorter);
+ m_pSearchEngine->SetLevLonger(aParams.nLevLonger);
+
+ m_pSearchEngine->SetTransliterationFlags( aParams.getTransliterationFlags( ) );
+
+ m_prbSearchForText->set_active(false);
+ m_prbSearchForNull->set_active(false);
+ m_prbSearchForNotNull->set_active(false);
+ switch (aParams.nSearchForType)
+ {
+ case 1: m_prbSearchForNull->set_active(true); break;
+ case 2: m_prbSearchForNotNull->set_active(true); break;
+ default: m_prbSearchForText->set_active(true); break;
+ }
+ OnToggledFieldRadios(*m_prbSearchForText);
+}
+
+void FmSearchDialog::SaveParams() const
+{
+ if (!m_pConfig)
+ return;
+
+ FmSearchParams aCurrentSettings;
+
+ int nCount = m_pcmbSearchText->get_count();
+ aCurrentSettings.aHistory.realloc(nCount);
+ OUString* pHistory = aCurrentSettings.aHistory.getArray();
+ for (int i = 0; i < nCount; ++i, ++pHistory)
+ *pHistory = m_pcmbSearchText->get_text(i);
+
+ aCurrentSettings.sSingleSearchField = m_plbField->get_active_text();
+ aCurrentSettings.bAllFields = m_prbAllFields->get_active();
+ aCurrentSettings.nPosition = m_pSearchEngine->GetPosition();
+ aCurrentSettings.bUseFormatter = m_pSearchEngine->GetFormatterUsing();
+ aCurrentSettings.setCaseSensitive ( m_pSearchEngine->GetCaseSensitive() );
+ aCurrentSettings.bBackwards = !m_pSearchEngine->GetDirection();
+ aCurrentSettings.bWildcard = m_pSearchEngine->GetWildcard();
+ aCurrentSettings.bRegular = m_pSearchEngine->GetRegular();
+ aCurrentSettings.bApproxSearch = m_pSearchEngine->GetLevenshtein();
+ aCurrentSettings.bLevRelaxed = m_pSearchEngine->GetLevRelaxed();
+ aCurrentSettings.nLevOther = m_pSearchEngine->GetLevOther();
+ aCurrentSettings.nLevShorter = m_pSearchEngine->GetLevShorter();
+ aCurrentSettings.nLevLonger = m_pSearchEngine->GetLevLonger();
+
+ aCurrentSettings.bSoundsLikeCJK = m_pSearchEngine->GetTransliteration();
+ aCurrentSettings.setTransliterationFlags ( m_pSearchEngine->GetTransliterationFlags() );
+
+ if (m_prbSearchForNull->get_active())
+ aCurrentSettings.nSearchForType = 1;
+ else if (m_prbSearchForNotNull->get_active())
+ aCurrentSettings.nSearchForType = 2;
+ else
+ aCurrentSettings.nSearchForType = 0;
+
+ m_pConfig->setParams( aCurrentSettings );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuigaldlg.cxx b/cui/source/dialogs/cuigaldlg.cxx
new file mode 100644
index 000000000..e432b4fce
--- /dev/null
+++ b/cui/source/dialogs/cuigaldlg.cxx
@@ -0,0 +1,1009 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <sal/config.h>
+
+#include <algorithm>
+#include <cassert>
+
+#include <utility>
+#include <vcl/errinf.hxx>
+#include <ucbhelper/content.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <avmedia/mediawindow.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/opengrf.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/gallery1.hxx>
+#include <svx/galtheme.hxx>
+#include <cuigaldlg.hxx>
+#include <bitmaps.hlst>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <osl/diagnose.h>
+#include <o3tl/string_view.hxx>
+
+using namespace ::ucbhelper;
+using namespace ::cppu;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+
+SearchThread::SearchThread(SearchProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ INetURLObject aStartURL)
+ : Thread("cuiSearchThread")
+ , mpProgress(pProgress)
+ , mpBrowser(pBrowser)
+ , maStartURL(std::move(aStartURL))
+{
+}
+
+SearchThread::~SearchThread()
+{
+}
+
+void SearchThread::execute()
+{
+ const OUString aFileType(mpBrowser->m_xCbbFileType->get_active_text());
+
+ if (!aFileType.isEmpty())
+ {
+ const int nFileNumber = mpBrowser->m_xCbbFileType->find_text(aFileType);
+ sal_Int32 nBeginFormat, nEndFormat;
+ std::vector< OUString > aFormats;
+
+ if( !nFileNumber || nFileNumber == -1)
+ {
+ nBeginFormat = 1;
+ nEndFormat = mpBrowser->m_xCbbFileType->get_count() - 1;
+ }
+ else
+ nBeginFormat = nEndFormat = nFileNumber;
+
+ for (sal_Int32 i = nBeginFormat; i <= nEndFormat; ++i)
+ aFormats.push_back( mpBrowser->aFilterEntryList[ i ]->aFilterName.toAsciiLowerCase() );
+
+ ImplSearch( maStartURL, aFormats, mpBrowser->bSearchRecursive );
+ }
+
+ Application::PostUserEvent(LINK(mpProgress, SearchProgress, CleanUpHdl));
+}
+
+
+void SearchThread::ImplSearch( const INetURLObject& rStartURL,
+ const std::vector< OUString >& rFormats,
+ bool bRecursive )
+{
+ {
+ SolarMutexGuard aGuard;
+
+ mpProgress->SetDirectory( rStartURL );
+ }
+
+ try
+ {
+ css::uno::Reference< XCommandEnvironment > xEnv;
+ Content aCnt( rStartURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), xEnv, comphelper::getProcessComponentContext() );
+ Sequence< OUString > aProps( 2 );
+
+ aProps.getArray()[ 0 ] = "IsFolder";
+ aProps.getArray()[ 1 ] = "IsDocument";
+ css::uno::Reference< XResultSet > xResultSet(
+ aCnt.createCursor( aProps ) );
+
+ if( xResultSet.is() )
+ {
+ css::uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
+ css::uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
+
+ while( xResultSet->next() && schedule() )
+ {
+ INetURLObject aFoundURL( xContentAccess->queryContentIdentifierString() );
+ DBG_ASSERT( aFoundURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ bool bFolder = xRow->getBoolean( 1 ); // property "IsFolder"
+ if ( xRow->wasNull() )
+ bFolder = false;
+
+ if( bRecursive && bFolder )
+ ImplSearch( aFoundURL, rFormats, true );
+ else
+ {
+ bool bDocument = xRow->getBoolean( 2 ); // property "IsDocument"
+ if ( xRow->wasNull() )
+ bDocument = false;
+
+ if( bDocument )
+ {
+ GraphicDescriptor aDesc( aFoundURL );
+
+ if( ( aDesc.Detect() &&
+ std::find( rFormats.begin(),
+ rFormats.end(),
+ GraphicDescriptor::GetImportFormatShortName(
+ aDesc.GetFileFormat() ).toAsciiLowerCase() )
+ != rFormats.end() ) ||
+ std::find( rFormats.begin(),
+ rFormats.end(),
+ aFoundURL.GetFileExtension().toAsciiLowerCase())
+ != rFormats.end() )
+ {
+ SolarMutexGuard aGuard;
+
+ mpBrowser->aFoundList.push_back(
+ aFoundURL.GetMainURL( INetURLObject::DecodeMechanism::NONE )
+ );
+ mpBrowser->m_xLbxFound->insert_text(
+ mpBrowser->aFoundList.size() - 1,
+ GetReducedString(aFoundURL, 50));
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (const ContentCreationException&)
+ {
+ }
+ catch (const css::uno::RuntimeException&)
+ {
+ }
+ catch (const css::uno::Exception&)
+ {
+ }
+}
+
+SearchProgress::SearchProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage, INetURLObject aStartURL)
+ : GenericDialogController(pParent, "cui/ui/gallerysearchprogress.ui", "GallerySearchProgress")
+ , startUrl_(std::move(aStartURL))
+ , m_pTabPage(pTabPage)
+ , m_xFtSearchDir(m_xBuilder->weld_label("dir"))
+ , m_xFtSearchType(m_xBuilder->weld_label("file"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xFtSearchType->set_size_request(m_xFtSearchType->get_preferred_size().Width(), -1);
+ m_xBtnCancel->connect_clicked(LINK(this, SearchProgress, ClickCancelBtn));
+}
+
+SearchProgress::~SearchProgress()
+{
+}
+
+IMPL_LINK_NOARG(SearchProgress, ClickCancelBtn, weld::Button&, void)
+{
+ if (m_aSearchThread.is())
+ m_aSearchThread->terminate();
+}
+
+IMPL_LINK_NOARG(SearchProgress, CleanUpHdl, void*, void)
+{
+ if (m_aSearchThread.is())
+ m_aSearchThread->join();
+
+ m_xDialog->response(RET_OK);
+}
+
+void SearchProgress::LaunchThread()
+{
+ assert(!m_aSearchThread.is());
+ m_aSearchThread = new SearchThread(this, m_pTabPage, startUrl_);
+ m_aSearchThread->launch();
+}
+
+TakeThread::TakeThread(
+ TakeProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ TokenList_impl& rTakenList
+) :
+ Thread ( "cuiTakeThread" ),
+ mpProgress ( pProgress ),
+ mpBrowser ( pBrowser ),
+ mrTakenList ( rTakenList )
+{
+}
+
+
+TakeThread::~TakeThread()
+{
+}
+
+void TakeThread::execute()
+{
+ sal_Int32 nEntries;
+ GalleryTheme* pThm = mpBrowser->GetXChgData()->pTheme;
+ std::unique_ptr<GalleryProgress> pStatusProgress;
+
+ std::vector<int> aSelectedRows;
+
+ {
+ SolarMutexGuard aGuard;
+ pStatusProgress.reset(new GalleryProgress);
+ if (mpBrowser->bTakeAll)
+ nEntries = mpBrowser->m_xLbxFound->n_children();
+ else
+ {
+ aSelectedRows = mpBrowser->m_xLbxFound->get_selected_rows();
+ nEntries = aSelectedRows.size();
+ }
+ pThm->LockBroadcaster();
+ }
+
+ for( sal_Int32 i = 0; i < nEntries && schedule(); ++i )
+ {
+ const sal_Int32 nPos = mpBrowser->bTakeAll ? i : aSelectedRows[i];
+ const INetURLObject aURL( mpBrowser->aFoundList[ nPos ]);
+
+ mrTakenList.push_back( nPos );
+
+ {
+ SolarMutexGuard aGuard;
+
+ mpProgress->SetFile( aURL );
+ pStatusProgress->Update( i, nEntries - 1 );
+ pThm->InsertURL( aURL );
+ }
+ }
+
+ {
+ SolarMutexGuard aGuard;
+
+ pThm->UnlockBroadcaster();
+ pStatusProgress.reset();
+ }
+
+ Application::PostUserEvent(LINK(mpProgress, TakeProgress, CleanUpHdl));
+}
+
+TakeProgress::TakeProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage)
+ : GenericDialogController(pParent, "cui/ui/galleryapplyprogress.ui",
+ "GalleryApplyProgress")
+ , m_pParent(pParent)
+ , m_pTabPage(pTabPage)
+ , m_xFtTakeFile(m_xBuilder->weld_label("file"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xBtnCancel->connect_clicked(LINK(this, TakeProgress, ClickCancelBtn));
+}
+
+TakeProgress::~TakeProgress()
+{
+}
+
+IMPL_LINK_NOARG(TakeProgress, ClickCancelBtn, weld::Button&, void)
+{
+ if (maTakeThread.is())
+ maTakeThread->terminate();
+}
+
+
+IMPL_LINK_NOARG(TakeProgress, CleanUpHdl, void*, void)
+{
+ if (maTakeThread.is())
+ maTakeThread->join();
+
+ std::vector<bool, std::allocator<bool> > aRemoveEntries(m_pTabPage->aFoundList.size(), false);
+ std::vector< OUString > aRemainingVector;
+ sal_uInt32 i, nCount;
+
+ std::unique_ptr<weld::WaitObject> xWait(new weld::WaitObject(m_pParent));
+
+ m_pTabPage->m_xLbxFound->select(-1);
+ m_pTabPage->m_xLbxFound->freeze();
+
+ // mark all taken positions in aRemoveEntries
+ for( i = 0, nCount = maTakenList.size(); i < nCount; ++i )
+ aRemoveEntries[ maTakenList[ i ] ] = true;
+ maTakenList.clear();
+
+ // refill found list
+ for( i = 0, nCount = aRemoveEntries.size(); i < nCount; ++i )
+ if( !aRemoveEntries[ i ] )
+ aRemainingVector.push_back( m_pTabPage->aFoundList[i] );
+
+ std::swap(m_pTabPage->aFoundList, aRemainingVector);
+ aRemainingVector.clear();
+
+ // refill list box
+ for( i = 0, nCount = aRemoveEntries.size(); i < nCount; ++i )
+ if( !aRemoveEntries[ i ] )
+ aRemainingVector.push_back(m_pTabPage->m_xLbxFound->get_text(i));
+
+ m_pTabPage->m_xLbxFound->clear();
+ for( i = 0, nCount = aRemainingVector.size(); i < nCount; ++i )
+ m_pTabPage->m_xLbxFound->append_text(aRemainingVector[i]);
+ aRemainingVector.clear();
+
+ m_pTabPage->m_xLbxFound->thaw();
+ m_pTabPage->SelectFoundHdl( *m_pTabPage->m_xLbxFound );
+
+ xWait.reset();
+
+ m_xDialog->response(RET_OK);
+}
+
+void TakeProgress::LaunchThread()
+{
+ assert(!maTakeThread.is());
+ maTakeThread = new TakeThread(this, m_pTabPage, maTakenList);
+ maTakeThread->launch();
+}
+
+ActualizeProgress::ActualizeProgress(weld::Widget* pWindow, GalleryTheme* pThm)
+ : GenericDialogController(pWindow, "cui/ui/galleryupdateprogress.ui",
+ "GalleryUpdateProgress")
+ , pIdle(nullptr)
+ , pTheme(pThm)
+ , m_xFtActualizeFile(m_xBuilder->weld_label("file"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xBtnCancel->connect_clicked(LINK(this, ActualizeProgress, ClickCancelBtn));
+}
+
+ActualizeProgress::~ActualizeProgress()
+{
+}
+
+short ActualizeProgress::run()
+{
+ pIdle = new Idle("ActualizeProgressTimeout");
+ pIdle->SetInvokeHandler( LINK( this, ActualizeProgress, TimeoutHdl ) );
+ pIdle->SetPriority( TaskPriority::LOWEST );
+ pIdle->Start();
+
+ return GenericDialogController::run();
+}
+
+IMPL_LINK_NOARG(ActualizeProgress, ClickCancelBtn, weld::Button&, void)
+{
+ pTheme->AbortActualize();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK( ActualizeProgress, TimeoutHdl, Timer*, _pTimer, void)
+{
+ if (_pTimer)
+ {
+ _pTimer->Stop();
+ delete _pTimer;
+ }
+
+ pTheme->Actualize(LINK(this, ActualizeProgress, ActualizeHdl), &aStatusProgress);
+ ClickCancelBtn(*m_xBtnCancel);
+}
+
+IMPL_LINK( ActualizeProgress, ActualizeHdl, const INetURLObject&, rURL, void )
+{
+ Application::Reschedule(true);
+ m_xFtActualizeFile->set_label(GetReducedString(rURL, 30));
+}
+
+TitleDialog::TitleDialog(weld::Widget* pParent, const OUString& rOldTitle)
+ : GenericDialogController(pParent, "cui/ui/gallerytitledialog.ui", "GalleryTitleDialog")
+ , m_xEdit(m_xBuilder->weld_entry("entry"))
+{
+ m_xEdit->set_text(rOldTitle);
+ m_xEdit->grab_focus();
+}
+
+TitleDialog::~TitleDialog()
+{
+}
+
+GalleryIdDialog::GalleryIdDialog(weld::Widget* pParent, GalleryTheme* _pThm)
+ : GenericDialogController(pParent, "cui/ui/gallerythemeiddialog.ui", "GalleryThemeIDDialog")
+ , m_pThm(_pThm)
+ , m_xBtnOk(m_xBuilder->weld_button("ok"))
+ , m_xLbResName(m_xBuilder->weld_combo_box("entry"))
+{
+ m_xLbResName->append_text("!!! No Id !!!");
+
+ GalleryTheme::InsertAllThemes(*m_xLbResName);
+
+ m_xLbResName->set_active(m_pThm->GetId());
+ m_xLbResName->grab_focus();
+
+ m_xBtnOk->connect_clicked(LINK(this, GalleryIdDialog, ClickOkHdl));
+}
+
+GalleryIdDialog::~GalleryIdDialog()
+{
+}
+
+IMPL_LINK_NOARG(GalleryIdDialog, ClickOkHdl, weld::Button&, void)
+{
+ Gallery* pGal = m_pThm->GetParent();
+ const sal_uInt32 nId = GetId();
+ bool bDifferentThemeExists = false;
+
+ for( size_t i = 0, nCount = pGal->GetThemeCount(); i < nCount && !bDifferentThemeExists; i++ )
+ {
+ const GalleryThemeEntry* pInfo = pGal->GetThemeInfo( i );
+
+ if ((pInfo->GetId() == nId) && (pInfo->GetThemeName() != m_pThm->GetName()))
+ {
+ OUString aStr = CuiResId( RID_CUISTR_GALLERY_ID_EXISTS ) +
+ " (" + pInfo->GetThemeName() + ")";
+
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ aStr));
+ xInfoBox->run();
+ m_xLbResName->grab_focus();
+ bDifferentThemeExists = true;
+ }
+ }
+
+ if (!bDifferentThemeExists)
+ m_xDialog->response(RET_OK);
+}
+
+GalleryThemeProperties::GalleryThemeProperties(weld::Widget* pParent,
+ ExchangeData* _pData, SfxItemSet const * pItemSet)
+ : SfxTabDialogController(pParent, "cui/ui/gallerythemedialog.ui",
+ "GalleryThemeDialog", pItemSet)
+ , pData(_pData)
+{
+ AddTabPage("general", TPGalleryThemeGeneral::Create, nullptr);
+ AddTabPage("files", TPGalleryThemeProperties::Create, nullptr);
+ if (pData->pTheme->IsReadOnly())
+ RemoveTabPage("files");
+
+ OUString aText = m_xDialog->get_title().replaceFirst( "%1", pData->pTheme->GetName() );
+
+ if (pData->pTheme->IsReadOnly())
+ aText += " " + CuiResId( RID_CUISTR_GALLERY_READONLY );
+
+ m_xDialog->set_title(aText);
+}
+
+void GalleryThemeProperties::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "general")
+ static_cast<TPGalleryThemeGeneral&>( rPage ).SetXChgData( pData );
+ else
+ static_cast<TPGalleryThemeProperties&>( rPage ).SetXChgData( pData );
+}
+
+TPGalleryThemeGeneral::TPGalleryThemeGeneral(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/gallerygeneralpage.ui", "GalleryGeneralPage", &rSet)
+ , pData(nullptr)
+ , m_xFiMSImage(m_xBuilder->weld_image("image"))
+ , m_xEdtMSName(m_xBuilder->weld_entry("name"))
+ , m_xFtMSShowType(m_xBuilder->weld_label("type"))
+ , m_xFtMSShowPath(m_xBuilder->weld_label("location"))
+ , m_xFtMSShowContent(m_xBuilder->weld_label("contents"))
+ , m_xFtMSShowChangeDate(m_xBuilder->weld_label("modified"))
+{
+}
+
+void TPGalleryThemeGeneral::SetXChgData( ExchangeData* _pData )
+{
+ pData = _pData;
+
+ GalleryTheme* pThm = pData->pTheme;
+ OUString aOutStr( OUString::number(pThm->GetObjectCount()) );
+ OUString aObjStr( CuiResId( RID_CUISTR_GALLERYPROPS_OBJECT ) );
+ OUString aAccess;
+ OUString aType( SvxResId( RID_SVXSTR_GALLERYPROPS_GALTHEME ) );
+ bool bReadOnly = pThm->IsReadOnly();
+
+ m_xEdtMSName->set_text(pThm->GetName());
+ m_xEdtMSName->set_editable(!bReadOnly);
+ m_xEdtMSName->set_sensitive(!bReadOnly);
+
+ if( pThm->IsReadOnly() )
+ aType += CuiResId( RID_CUISTR_GALLERY_READONLY );
+
+ m_xFtMSShowType->set_label(aType);
+ m_xFtMSShowPath->set_label(pThm->getThemeURL().GetMainURL(INetURLObject::DecodeMechanism::Unambiguous));
+
+ // singular or plural?
+ if ( 1 == pThm->GetObjectCount() )
+ aObjStr = aObjStr.getToken( 0, ';' );
+ else
+ aObjStr = aObjStr.getToken( 1, ';' );
+
+ aOutStr += " " + aObjStr;
+
+ m_xFtMSShowContent->set_label(aOutStr);
+
+ // get locale wrapper (singleton)
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& aLocaleData = aSysLocale.GetLocaleData();
+
+ // ChangeDate/Time
+ aAccess = aLocaleData.getDate( pData->aThemeChangeDate ) + ", " + aLocaleData.getTime( pData->aThemeChangeTime );
+ m_xFtMSShowChangeDate->set_label(aAccess);
+
+ // set image
+ OUString sId;
+
+ if( pThm->IsReadOnly() )
+ sId = RID_SVXBMP_THEME_READONLY_BIG;
+ else if( pThm->IsDefault() )
+ sId = RID_SVXBMP_THEME_DEFAULT_BIG;
+ else
+ sId = RID_SVXBMP_THEME_NORMAL_BIG;
+
+ m_xFiMSImage->set_from_icon_name(sId);
+}
+
+bool TPGalleryThemeGeneral::FillItemSet( SfxItemSet* /*rSet*/ )
+{
+ pData->aEditedTitle = m_xEdtMSName->get_text();
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> TPGalleryThemeGeneral::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<TPGalleryThemeGeneral>(pPage, pController, *rSet);
+}
+
+TPGalleryThemeProperties::TPGalleryThemeProperties(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/galleryfilespage.ui", "GalleryFilesPage", &rSet)
+ , pData(nullptr)
+ , aPreviewTimer("cui TPGalleryThemeProperties aPreviewTimer")
+ , bEntriesFound(false)
+ , bInputAllowed(true)
+ , bTakeAll(false)
+ , bSearchRecursive(false)
+ , xDialogListener(new ::svt::DialogClosedListener())
+ , m_xCbbFileType(m_xBuilder->weld_combo_box("filetype"))
+ , m_xLbxFound(m_xBuilder->weld_tree_view("files"))
+ , m_xBtnSearch(m_xBuilder->weld_button("findfiles"))
+ , m_xBtnTake(m_xBuilder->weld_button("add"))
+ , m_xBtnTakeAll(m_xBuilder->weld_button("addall"))
+ , m_xCbxPreview(m_xBuilder->weld_check_button("preview"))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "image", m_aWndPreview))
+{
+ m_xLbxFound->set_size_request(m_xLbxFound->get_approximate_digit_width() * 35,
+ m_xLbxFound->get_height_rows(15));
+ m_xLbxFound->set_selection_mode(SelectionMode::Multiple);
+ xDialogListener->SetDialogClosedLink( LINK( this, TPGalleryThemeProperties, DialogClosedHdl ) );
+}
+
+void TPGalleryThemeProperties::SetXChgData( ExchangeData* _pData )
+{
+ pData = _pData;
+
+ aPreviewTimer.SetInvokeHandler( LINK( this, TPGalleryThemeProperties, PreviewTimerHdl ) );
+ aPreviewTimer.SetTimeout( 500 );
+ m_xBtnSearch->connect_clicked(LINK(this, TPGalleryThemeProperties, ClickSearchHdl));
+ m_xBtnTake->connect_clicked(LINK(this, TPGalleryThemeProperties, ClickTakeHdl));
+ m_xBtnTakeAll->connect_clicked(LINK(this, TPGalleryThemeProperties, ClickTakeAllHdl));
+ m_xCbxPreview->connect_toggled(LINK(this, TPGalleryThemeProperties, ClickPreviewHdl));
+ m_xCbbFileType->connect_changed(LINK(this, TPGalleryThemeProperties, SelectFileTypeHdl));
+ m_xLbxFound->connect_row_activated(LINK(this, TPGalleryThemeProperties, DClickFoundHdl));
+ m_xLbxFound->connect_changed(LINK(this, TPGalleryThemeProperties, SelectFoundHdl));
+ m_xLbxFound->append_text(CuiResId(RID_CUISTR_GALLERY_NOFILES));
+ m_xLbxFound->show();
+
+ FillFilterList();
+
+ m_xBtnTake->set_sensitive(true);
+ m_xBtnTakeAll->set_sensitive(false);
+ m_xCbxPreview->set_sensitive(false);
+}
+
+void TPGalleryThemeProperties::StartSearchFiles( std::u16string_view _rFolderURL, short _nDlgResult )
+{
+ if ( RET_OK == _nDlgResult )
+ {
+ aURL = INetURLObject( _rFolderURL );
+ bSearchRecursive = true; // UI choice no longer possible, windows file picker allows no user controls
+ SearchFiles();
+ }
+}
+
+TPGalleryThemeProperties::~TPGalleryThemeProperties()
+{
+ xMediaPlayer.clear();
+ xDialogListener.clear();
+ aFilterEntryList.clear();
+}
+
+std::unique_ptr<SfxTabPage> TPGalleryThemeProperties::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<TPGalleryThemeProperties>(pPage, pController, *rSet);
+}
+
+OUString TPGalleryThemeProperties::addExtension( const OUString& _rDisplayText, std::u16string_view _rExtension )
+{
+ OUString sRet = _rDisplayText;
+ if ( sRet.indexOf( "(*.*)" ) == -1 )
+ {
+ sRet += OUString::Concat(" (") + _rExtension + ")";
+ }
+ return sRet;
+}
+
+void TPGalleryThemeProperties::FillFilterList()
+{
+ GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
+ OUString aExt;
+ OUString aName;
+ sal_uInt16 i, nKeyCount;
+
+ // graphic filters
+ for( i = 0, nKeyCount = rFilter.GetImportFormatCount(); i < nKeyCount; i++ )
+ {
+ aExt = rFilter.GetImportFormatShortName( i );
+ aName = rFilter.GetImportFormatName( i );
+ size_t entryIndex = 0;
+ FilterEntry* pTestEntry = aFilterEntryList.empty() ? nullptr : aFilterEntryList[ entryIndex ].get();
+ bool bInList = false;
+
+ OUString aExtensions;
+ int j = 0;
+ OUString sWildcard;
+ while( true )
+ {
+ sWildcard = rFilter.GetImportWildcard( i, j++ );
+ if ( sWildcard.isEmpty() )
+ break;
+ if ( aExtensions.indexOf( sWildcard ) == -1 )
+ {
+ if ( !aExtensions.isEmpty() )
+ aExtensions += ";";
+ aExtensions += sWildcard;
+ }
+ }
+ aName = addExtension( aName, aExtensions );
+
+ while( pTestEntry )
+ {
+ if ( pTestEntry->aFilterName == aExt )
+ {
+ bInList = true;
+ break;
+ }
+ pTestEntry = ( ++entryIndex < aFilterEntryList.size() )
+ ? aFilterEntryList[ entryIndex ].get() : nullptr;
+ }
+ if ( !bInList )
+ {
+ std::unique_ptr<FilterEntry> pFilterEntry(new FilterEntry);
+ pFilterEntry->aFilterName = aExt;
+ m_xCbbFileType->append_text(aName);
+ aFilterEntryList.push_back(std::move(pFilterEntry));
+ }
+ }
+
+#if HAVE_FEATURE_AVMEDIA
+ // media filters
+ static constexpr OUStringLiteral aWildcard = u"*.";
+ ::avmedia::FilterNameVector aFilters= ::avmedia::MediaWindow::getMediaFilters();
+
+ for(const std::pair<OUString,OUString> & aFilter : aFilters)
+ {
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ OUString aFilterWildcard( aWildcard );
+
+ std::unique_ptr<FilterEntry> pFilterEntry(new FilterEntry);
+ pFilterEntry->aFilterName = aFilter.second.getToken( 0, ';', nIndex );
+ aFilterWildcard += pFilterEntry->aFilterName;
+ m_xCbbFileType->append_text(addExtension(aFilter.first, aFilterWildcard));
+ aFilterEntryList.push_back( std::move(pFilterEntry) );
+ }
+ }
+#endif
+
+ // 'All' filters
+ OUString aExtensions;
+
+ // graphic filters
+ for ( i = 0; i < nKeyCount; ++i )
+ {
+ int j = 0;
+ OUString sWildcard;
+ while( true )
+ {
+ sWildcard = rFilter.GetImportWildcard( i, j++ );
+ if ( sWildcard.isEmpty() )
+ break;
+ if ( aExtensions.indexOf( sWildcard ) == -1 )
+ {
+ if ( !aExtensions.isEmpty() )
+ aExtensions += ";";
+
+ aExtensions += sWildcard;
+ }
+ }
+ }
+
+#if HAVE_FEATURE_AVMEDIA
+ // media filters
+ for(const std::pair<OUString,OUString> & aFilter : aFilters)
+ {
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ if ( !aExtensions.isEmpty() )
+ aExtensions += ";";
+ aExtensions += OUString::Concat(aWildcard) + o3tl::getToken(aFilter.second, 0, ';', nIndex );
+ }
+ }
+#endif
+
+#if defined(_WIN32)
+ if (aExtensions.getLength() > 240)
+ aExtensions = "*.*";
+#endif
+
+ std::unique_ptr<FilterEntry> pFilterEntry(new FilterEntry);
+ pFilterEntry->aFilterName = CuiResId(RID_CUISTR_GALLERY_ALLFILES);
+ pFilterEntry->aFilterName = addExtension(pFilterEntry->aFilterName, aExtensions);
+ m_xCbbFileType->insert_text(0, pFilterEntry->aFilterName);
+ m_xCbbFileType->set_active(0);
+ aFilterEntryList.insert(aFilterEntryList.begin(), std::move(pFilterEntry));
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, SelectFileTypeHdl, weld::ComboBox&, void)
+{
+ OUString aText(m_xCbbFileType->get_active_text());
+
+ if( bInputAllowed && ( aLastFilterName != aText ) )
+ {
+ aLastFilterName = aText;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryupdategalleryfilelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryUpdateFileListDialog"));
+ if (xQuery->run() == RET_YES)
+ SearchFiles();
+ }
+}
+
+void TPGalleryThemeProperties::SearchFiles()
+{
+ auto xProgress = std::make_shared<SearchProgress>(GetFrameWeld(), this, aURL);
+
+ aFoundList.clear();
+ m_xLbxFound->clear();
+
+ xProgress->SetFileType( m_xCbbFileType->get_active_text() );
+ xProgress->SetDirectory( INetURLObject() );
+
+ xProgress->LaunchThread();
+ weld::DialogController::runAsync(xProgress, [this](sal_Int32 nResult) {
+ EndSearchProgressHdl(nResult);
+ });
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickSearchHdl, weld::Button&, void)
+{
+ if( !bInputAllowed )
+ return;
+
+ try
+ {
+ // setup folder picker
+ css::uno::Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ OUString aDlgPathName( SvtPathOptions().GetGraphicPath() );
+ xFolderPicker->setDisplayDirectory(aDlgPathName);
+
+ aPreviewTimer.Stop();
+
+ css::uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else
+ {
+ if( xFolderPicker->execute() == RET_OK )
+ {
+ aURL = INetURLObject( xFolderPicker->getDirectory() );
+ bSearchRecursive = true; // UI choice no longer possible, windows file picker allows no user controls
+ SearchFiles();
+ }
+ }
+ }
+ catch (const IllegalArgumentException&)
+ {
+ OSL_FAIL( "Folder picker failed with illegal arguments" );
+ }
+}
+
+void TPGalleryThemeProperties::TakeFiles()
+{
+ if (m_xLbxFound->count_selected_rows() || (bTakeAll && bEntriesFound))
+ {
+ auto xTakeProgress = std::make_shared<TakeProgress>(GetFrameWeld(), this);
+ xTakeProgress->LaunchThread();
+ weld::DialogController::runAsync(xTakeProgress, [](sal_Int32 /*nResult*/) {
+ /* no postprocessing needed, pTakeProgress
+ will be disposed in TakeProgress::CleanupHdl */
+ });
+
+ }
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickPreviewHdl, weld::Toggleable&, void)
+{
+ if ( !bInputAllowed )
+ return;
+
+ aPreviewTimer.Stop();
+ aPreviewString.clear();
+
+ if (!m_xCbxPreview->get_active())
+ {
+ xMediaPlayer.clear();
+ m_aWndPreview.SetGraphic(Graphic());
+ m_aWndPreview.Invalidate();
+ }
+ else
+ DoPreview();
+}
+
+void TPGalleryThemeProperties::DoPreview()
+{
+ int nIndex = m_xLbxFound->get_selected_index();
+ OUString aString(m_xLbxFound->get_text(nIndex));
+
+ if (aString == aPreviewString)
+ return;
+
+ INetURLObject _aURL(aFoundList[nIndex]);
+ bInputAllowed = false;
+
+ if (!m_aWndPreview.SetGraphic(_aURL))
+ {
+ weld::WaitObject aWaitObject(GetFrameWeld());
+ ErrorHandler::HandleError(ERRCODE_IO_NOTEXISTSPATH, GetFrameWeld());
+ }
+#if HAVE_FEATURE_AVMEDIA
+ else if( ::avmedia::MediaWindow::isMediaURL( _aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), "" ) )
+ {
+ xMediaPlayer = ::avmedia::MediaWindow::createPlayer( _aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), "" );
+ if( xMediaPlayer.is() )
+ xMediaPlayer->start();
+ }
+#endif
+ bInputAllowed = true;
+ aPreviewString = aString;
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickTakeHdl, weld::Button&, void)
+{
+ if( !bInputAllowed )
+ return;
+
+ aPreviewTimer.Stop();
+
+ if (!m_xLbxFound->count_selected_rows() || !bEntriesFound)
+ {
+ SvxOpenGraphicDialog aDlg(CuiResId(RID_CUISTR_KEY_GALLERY_DIR), GetFrameWeld());
+ aDlg.EnableLink(false);
+ aDlg.AsLink(false);
+
+ if( !aDlg.Execute() )
+ pData->pTheme->InsertURL( INetURLObject( aDlg.GetPath() ) );
+ }
+ else
+ {
+ bTakeAll = false;
+ TakeFiles();
+ }
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickTakeAllHdl, weld::Button&, void)
+{
+ if( bInputAllowed )
+ {
+ aPreviewTimer.Stop();
+ bTakeAll = true;
+ TakeFiles();
+ }
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, SelectFoundHdl, weld::TreeView&, void)
+{
+ if (!bInputAllowed)
+ return;
+
+ bool bPreviewPossible = false;
+
+ aPreviewTimer.Stop();
+
+ if( bEntriesFound )
+ {
+ if (m_xLbxFound->count_selected_rows() == 1)
+ {
+ m_xCbxPreview->set_sensitive(true);
+ bPreviewPossible = true;
+ }
+ else
+ m_xCbxPreview->set_sensitive(false);
+
+ if( !aFoundList.empty() )
+ m_xBtnTakeAll->set_sensitive(true);
+ else
+ m_xBtnTakeAll->set_sensitive(false);
+ }
+
+ if (bPreviewPossible && m_xCbxPreview->get_active())
+ aPreviewTimer.Start();
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, DClickFoundHdl, weld::TreeView&, bool)
+{
+ if( bInputAllowed )
+ {
+ aPreviewTimer.Stop();
+
+ if (m_xLbxFound->count_selected_rows() == 1 && bEntriesFound)
+ ClickTakeHdl(*m_xBtnTake);
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, PreviewTimerHdl, Timer *, void)
+{
+ aPreviewTimer.Stop();
+ DoPreview();
+}
+
+void TPGalleryThemeProperties::EndSearchProgressHdl(sal_Int32 /*nResult*/)
+{
+ if( !aFoundList.empty() )
+ {
+ m_xLbxFound->select(0);
+ m_xBtnTakeAll->set_sensitive(true);
+ m_xCbxPreview->set_sensitive(true);
+ bEntriesFound = true;
+ }
+ else
+ {
+ m_xLbxFound->append_text(CuiResId(RID_CUISTR_GALLERY_NOFILES));
+ m_xBtnTakeAll->set_sensitive(false);
+ m_xCbxPreview->set_sensitive(false);
+ bEntriesFound = false;
+ }
+}
+
+IMPL_LINK( TPGalleryThemeProperties, DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, pEvt, void )
+{
+ DBG_ASSERT( xFolderPicker.is(), "TPGalleryThemeProperties::DialogClosedHdl(): no folder picker" );
+
+ OUString sURL = xFolderPicker->getDirectory();
+ StartSearchFiles( sURL, pEvt->DialogResult );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuigrfflt.cxx b/cui/source/dialogs/cuigrfflt.cxx
new file mode 100644
index 000000000..c67ee92d1
--- /dev/null
+++ b/cui/source/dialogs/cuigrfflt.cxx
@@ -0,0 +1,469 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/BitmapMosaicFilter.hxx>
+#include <vcl/BitmapSharpenFilter.hxx>
+#include <vcl/BitmapEmbossGreyFilter.hxx>
+#include <vcl/BitmapSepiaFilter.hxx>
+#include <vcl/BitmapSmoothenFilter.hxx>
+#include <vcl/BitmapSolarizeFilter.hxx>
+#include <vcl/BitmapColorQuantizationFilter.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/diagnose.h>
+#include <tools/helpers.hxx>
+#include <cuigrfflt.hxx>
+
+CuiGraphicPreviewWindow::CuiGraphicPreviewWindow()
+ : mpOrigGraphic(nullptr)
+ , mfScaleX(0.0)
+ , mfScaleY(0.0)
+{
+}
+
+void CuiGraphicPreviewWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ OutputDevice &rDevice = pDrawingArea->get_ref_device();
+ maOutputSizePixel = rDevice.LogicToPixel(Size(81, 73), MapMode(MapUnit::MapAppFont));
+ pDrawingArea->set_size_request(maOutputSizePixel.Width(), maOutputSizePixel.Height());
+}
+
+void CuiGraphicPreviewWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetDialogColor()));
+ rRenderContext.Erase();
+
+ const Size aOutputSize(GetOutputSizePixel());
+
+ if (maPreview.IsAnimated())
+ {
+ const Size aGraphicSize(rRenderContext.LogicToPixel(maPreview.GetPrefSize(), maPreview.GetPrefMapMode()));
+ const Point aGraphicPosition((aOutputSize.Width() - aGraphicSize.Width() ) >> 1,
+ (aOutputSize.Height() - aGraphicSize.Height() ) >> 1);
+ maPreview.StartAnimation(rRenderContext, aGraphicPosition, aGraphicSize);
+ }
+ else
+ {
+ const Size aGraphicSize(maPreview.GetSizePixel());
+ const Point aGraphicPosition((aOutputSize.Width() - aGraphicSize.Width()) >> 1,
+ (aOutputSize.Height() - aGraphicSize.Height()) >> 1);
+ maPreview.Draw(rRenderContext, aGraphicPosition, aGraphicSize);
+ }
+}
+
+void CuiGraphicPreviewWindow::SetPreview(const Graphic& rGraphic)
+{
+ maPreview = rGraphic;
+ Invalidate();
+}
+
+void CuiGraphicPreviewWindow::ScaleImageToFit()
+{
+ if (!mpOrigGraphic)
+ return;
+
+ maScaledOrig = *mpOrigGraphic;
+
+ const Size aPreviewSize(GetOutputSizePixel());
+ Size aGrfSize(maOrigGraphicSizePixel);
+
+ if( mpOrigGraphic->GetType() == GraphicType::Bitmap &&
+ aPreviewSize.Width() && aPreviewSize.Height() &&
+ aGrfSize.Width() && aGrfSize.Height() )
+ {
+ const double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
+ const double fPreWH = static_cast<double>(aPreviewSize.Width()) / aPreviewSize.Height();
+
+ if( fGrfWH < fPreWH )
+ {
+ aGrfSize.setWidth( static_cast<tools::Long>( aPreviewSize.Height() * fGrfWH ) );
+ aGrfSize.setHeight( aPreviewSize.Height() );
+ }
+ else
+ {
+ aGrfSize.setWidth( aPreviewSize.Width() );
+ aGrfSize.setHeight( static_cast<tools::Long>( aPreviewSize.Width() / fGrfWH ) );
+ }
+
+ mfScaleX = static_cast<double>(aGrfSize.Width()) / maOrigGraphicSizePixel.Width();
+ mfScaleY = static_cast<double>(aGrfSize.Height()) / maOrigGraphicSizePixel.Height();
+
+ if( !mpOrigGraphic->IsAnimated() )
+ {
+ BitmapEx aBmpEx( mpOrigGraphic->GetBitmapEx() );
+
+ if( aBmpEx.Scale( aGrfSize ) )
+ maScaledOrig = aBmpEx;
+ }
+ }
+
+ maModifyHdl.Call(nullptr);
+}
+
+void CuiGraphicPreviewWindow::Resize()
+{
+ maOutputSizePixel = GetOutputSizePixel();
+ ScaleImageToFit();
+}
+
+GraphicFilterDialog::GraphicFilterDialog(weld::Window* pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ const Graphic& rGraphic)
+ : GenericDialogController(pParent, rUIXMLDescription, rID)
+ , maTimer("cui GraphicFilterDialog maTimer")
+ , maModifyHdl(LINK(this, GraphicFilterDialog, ImplModifyHdl))
+ , mxPreview(new weld::CustomWeld(*m_xBuilder, "preview", maPreview))
+{
+ bIsBitmap = rGraphic.GetType() == GraphicType::Bitmap;
+
+ maTimer.SetInvokeHandler(LINK(this, GraphicFilterDialog, ImplPreviewTimeoutHdl));
+ maTimer.SetTimeout(5);
+
+ maPreview.init(&rGraphic, maModifyHdl);
+}
+
+IMPL_LINK_NOARG(GraphicFilterDialog, ImplPreviewTimeoutHdl, Timer *, void)
+{
+ maTimer.Stop();
+ maPreview.SetPreview(GetFilteredGraphic(maPreview.GetScaledOriginal(),
+ maPreview.GetScaleX(), maPreview.GetScaleY()));
+}
+
+IMPL_LINK_NOARG(GraphicFilterDialog, ImplModifyHdl, LinkParamNone*, void)
+{
+ if (bIsBitmap)
+ {
+ maTimer.Stop();
+ maTimer.Start();
+ }
+}
+
+GraphicFilterMosaic::GraphicFilterMosaic(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges)
+ : GraphicFilterDialog(pParent, "cui/ui/mosaicdialog.ui", "MosaicDialog", rGraphic)
+ , mxMtrWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PIXEL))
+ , mxMtrHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PIXEL))
+ , mxCbxEdges(m_xBuilder->weld_check_button("edges"))
+{
+ mxMtrWidth->set_value(nTileWidth, FieldUnit::PIXEL);
+ mxMtrWidth->set_max(GetGraphicSizePixel().Width(), FieldUnit::PIXEL);
+ mxMtrWidth->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
+
+ mxMtrHeight->set_value(nTileHeight, FieldUnit::PIXEL);
+ mxMtrHeight->set_max(GetGraphicSizePixel().Height(), FieldUnit::PIXEL);
+ mxMtrHeight->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
+
+ mxCbxEdges->set_active(bEnhanceEdges);
+ mxCbxEdges->connect_toggled(LINK(this, GraphicFilterMosaic, CheckBoxModifyHdl));
+
+ mxMtrWidth->grab_focus();
+}
+
+IMPL_LINK_NOARG(GraphicFilterMosaic, CheckBoxModifyHdl, weld::Toggleable&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+IMPL_LINK_NOARG(GraphicFilterMosaic, EditModifyHdl, weld::MetricSpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterMosaic::GetFilteredGraphic( const Graphic& rGraphic,
+ double fScaleX, double fScaleY )
+{
+ Graphic aRet;
+ tools::Long nTileWidth = static_cast<tools::Long>(mxMtrWidth->get_value(FieldUnit::PIXEL));
+ tools::Long nTileHeight = static_cast<tools::Long>(mxMtrHeight->get_value(FieldUnit::PIXEL));
+ const Size aSize( std::max( FRound( nTileWidth * fScaleX ), tools::Long(1) ),
+ std::max( FRound( nTileHeight * fScaleY ), tools::Long(1) ) );
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
+ {
+ if( IsEnhanceEdges() )
+ (void)BitmapFilter::Filter(aAnim, BitmapSharpenFilter());
+
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
+ {
+ if( IsEnhanceEdges() )
+ BitmapFilter::Filter(aBmpEx, BitmapSharpenFilter());
+
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+GraphicFilterSmooth::GraphicFilterSmooth(weld::Window* pParent, const Graphic& rGraphic, double nRadius)
+ : GraphicFilterDialog(pParent, "cui/ui/smoothdialog.ui", "SmoothDialog", rGraphic)
+ , mxMtrRadius(m_xBuilder->weld_spin_button("radius"))
+{
+ mxMtrRadius->set_value(nRadius * 10);
+ mxMtrRadius->connect_value_changed(LINK(this, GraphicFilterSmooth, EditModifyHdl));
+ mxMtrRadius->grab_focus();
+}
+
+IMPL_LINK_NOARG(GraphicFilterSmooth, EditModifyHdl, weld::SpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterSmooth::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ double nRadius = mxMtrRadius->get_value() / 10.0;
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapSmoothenFilter(nRadius)))
+ {
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapSmoothenFilter(nRadius)))
+ {
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+GraphicFilterSolarize::GraphicFilterSolarize(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt8 cGreyThreshold, bool bInvert)
+ : GraphicFilterDialog(pParent, "cui/ui/solarizedialog.ui", "SolarizeDialog", rGraphic)
+ , mxMtrThreshold(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
+ , mxCbxInvert(m_xBuilder->weld_check_button("invert"))
+{
+ mxMtrThreshold->set_value(FRound(cGreyThreshold / 2.55), FieldUnit::PERCENT);
+ mxMtrThreshold->connect_value_changed(LINK(this, GraphicFilterSolarize, EditModifyHdl));
+
+ mxCbxInvert->set_active(bInvert);
+ mxCbxInvert->connect_toggled(LINK(this, GraphicFilterSolarize, CheckBoxModifyHdl));
+}
+
+IMPL_LINK_NOARG(GraphicFilterSolarize, CheckBoxModifyHdl, weld::Toggleable&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+IMPL_LINK_NOARG(GraphicFilterSolarize, EditModifyHdl, weld::MetricSpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterSolarize::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ sal_uInt8 nGreyThreshold = static_cast<sal_uInt8>(FRound(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 2.55));
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapSolarizeFilter(nGreyThreshold)))
+ {
+ if( IsInvert() )
+ aAnim.Invert();
+
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapSolarizeFilter(nGreyThreshold)))
+ {
+ if( IsInvert() )
+ aBmpEx.Invert();
+
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+GraphicFilterSepia::GraphicFilterSepia(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nSepiaPercent)
+ : GraphicFilterDialog(pParent, "cui/ui/agingdialog.ui", "AgingDialog", rGraphic)
+ , mxMtrSepia(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
+{
+ mxMtrSepia->set_value(nSepiaPercent, FieldUnit::PERCENT);
+ mxMtrSepia->connect_value_changed(LINK(this, GraphicFilterSepia, EditModifyHdl));
+}
+
+IMPL_LINK_NOARG(GraphicFilterSepia, EditModifyHdl, weld::MetricSpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterSepia::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ sal_uInt16 nSepiaPct = sal::static_int_cast< sal_uInt16 >(mxMtrSepia->get_value(FieldUnit::PERCENT));
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapSepiaFilter(nSepiaPct)))
+ aRet = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapSepiaFilter(nSepiaPct)))
+ aRet = aBmpEx;
+ }
+
+ return aRet;
+}
+
+GraphicFilterPoster::GraphicFilterPoster(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nPosterCount)
+ : GraphicFilterDialog(pParent, "cui/ui/posterdialog.ui", "PosterDialog", rGraphic)
+ , mxNumPoster(m_xBuilder->weld_spin_button("value"))
+{
+ mxNumPoster->set_range(2, vcl::pixelFormatBitCount(rGraphic.GetBitmapEx().getPixelFormat()));
+ mxNumPoster->set_value(nPosterCount);
+ mxNumPoster->connect_value_changed(LINK(this, GraphicFilterPoster, EditModifyHdl));
+}
+
+IMPL_LINK_NOARG(GraphicFilterPoster, EditModifyHdl, weld::SpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterPoster::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ const sal_uInt16 nPosterCount = static_cast<sal_uInt16>(mxNumPoster->get_value());
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if( aAnim.ReduceColors( nPosterCount ) )
+ aRet = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapColorQuantizationFilter(nPosterCount)))
+ aRet = aBmpEx;
+ }
+
+ return aRet;
+}
+
+bool EmbossControl::MouseButtonDown( const MouseEvent& rEvt )
+{
+ const RectPoint eOldRP = GetActualRP();
+
+ SvxRectCtl::MouseButtonDown( rEvt );
+
+ if( GetActualRP() != eOldRP )
+ maModifyHdl.Call( nullptr );
+
+ return true;
+}
+
+void EmbossControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ SvxRectCtl::SetDrawingArea(pDrawingArea);
+ Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(77, 60), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+}
+
+GraphicFilterEmboss::GraphicFilterEmboss(weld::Window* pParent,
+ const Graphic& rGraphic, RectPoint eLightSource)
+ : GraphicFilterDialog(pParent, "cui/ui/embossdialog.ui", "EmbossDialog", rGraphic)
+ , mxCtlLight(new weld::CustomWeld(*m_xBuilder, "lightsource", maCtlLight))
+{
+ maCtlLight.SetActualRP(eLightSource);
+ maCtlLight.SetModifyHdl( GetModifyHdl() );
+ maCtlLight.GrabFocus();
+}
+
+GraphicFilterEmboss::~GraphicFilterEmboss()
+{
+}
+
+Graphic GraphicFilterEmboss::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ sal_uInt16 nAzim, nElev;
+
+ switch (maCtlLight.GetActualRP())
+ {
+ default: OSL_FAIL("svx::GraphicFilterEmboss::GetFilteredGraphic(), unknown Reference Point!" );
+ [[fallthrough]];
+ case RectPoint::LT: nAzim = 4500; nElev = 4500; break;
+ case RectPoint::MT: nAzim = 9000; nElev = 4500; break;
+ case RectPoint::RT: nAzim = 13500; nElev = 4500; break;
+ case RectPoint::LM: nAzim = 0; nElev = 4500; break;
+ case RectPoint::MM: nAzim = 0; nElev = 9000; break;
+ case RectPoint::RM: nAzim = 18000; nElev = 4500; break;
+ case RectPoint::LB: nAzim = 31500; nElev = 4500; break;
+ case RectPoint::MB: nAzim = 27000; nElev = 4500; break;
+ case RectPoint::RB: nAzim = 22500; nElev = 4500; break;
+ }
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapEmbossGreyFilter(nAzim, nElev)))
+ aRet = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapEmbossGreyFilter(nAzim, nElev)))
+ aRet = aBmpEx;
+ }
+
+ return aRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuihyperdlg.cxx b/cui/source/dialogs/cuihyperdlg.cxx
new file mode 100644
index 000000000..20c1b1e26
--- /dev/null
+++ b/cui/source/dialogs/cuihyperdlg.cxx
@@ -0,0 +1,294 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <osl/diagnose.h>
+#include <comphelper/lok.hxx>
+#include <unotools/viewoptions.hxx>
+#include <cuihyperdlg.hxx>
+#include <hlinettp.hxx>
+#include <hlmailtp.hxx>
+#include <hldoctp.hxx>
+#include <hldocntp.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/eitem.hxx>
+#include <svx/svxids.hrc>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <vector>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::frame::XFrame;
+
+
+//# #
+//# Childwindow-Wrapper-Class #
+//# #
+
+
+SvxHlinkCtrl::SvxHlinkCtrl( sal_uInt16 _nId, SfxBindings & rBindings, SvxHpLinkDlg* pDlg )
+ : SfxControllerItem ( _nId, rBindings )
+ , aRdOnlyForwarder ( SID_READONLY_MODE, *this )
+{
+ pParent = pDlg;
+}
+
+void SvxHlinkCtrl::dispose()
+{
+ pParent = nullptr;
+ aRdOnlyForwarder.dispose();
+ ::SfxControllerItem::dispose();
+}
+
+void SvxHlinkCtrl::StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ if (!(eState == SfxItemState::DEFAULT && pParent))
+ return;
+
+ switch ( nSID )
+ {
+ case SID_HYPERLINK_GETLINK :
+ {
+ pParent->SetPage( static_cast<const SvxHyperlinkItem*>(pState) );
+ }
+ break;
+ case SID_READONLY_MODE :
+ {
+ pParent->SetReadOnlyMode( static_cast<const SfxBoolItem*>(pState)->GetValue() );
+ }
+ break;
+ }
+}
+
+//# #
+//# Hyperlink - Dialog #
+//# #
+SvxHpLinkDlg::SvxHpLinkDlg(SfxBindings* pBindings, SfxChildWindow* pChild, weld::Window* pParent)
+ : SfxModelessDialogController(pBindings, pChild, pParent, "cui/ui/hyperlinkdialog.ui", "HyperlinkDialog")
+ , pSet ( nullptr )
+ , maCtrl ( SID_HYPERLINK_GETLINK, *pBindings, this )
+ , mbIsHTMLDoc ( false )
+ , m_xIconCtrl(m_xBuilder->weld_notebook("tabcontrol"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xApplyBtn(m_xBuilder->weld_button("apply"))
+ , m_xCancelBtn(m_xBuilder->weld_button("cancel"))
+ , m_xHelpBtn(m_xBuilder->weld_button("help"))
+ , m_xResetBtn(m_xBuilder->weld_button("reset"))
+{
+ m_xIconCtrl->connect_enter_page( LINK ( this, SvxHpLinkDlg, ChosePageHdl_Impl ) );
+ m_xIconCtrl->show();
+
+ // ItemSet
+ if ( pSet )
+ {
+ pExampleSet.reset(new SfxItemSet( *pSet ));
+ pOutSet.reset(new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ));
+ }
+
+ // Buttons
+ m_xOKBtn->show();
+ m_xApplyBtn->show();
+ m_xCancelBtn->show();
+ m_xHelpBtn->show();
+ m_xResetBtn->show();
+
+ mbGrabFocus = true;
+
+ // set OK/Cancel - button
+ m_xCancelBtn->set_label(CuiResId(RID_CUISTR_HYPDLG_CLOSEBUT));
+
+ // create itemset for tabpages
+ mpItemSet = std::make_unique<SfxItemSetFixed<SID_HYPERLINK_GETLINK,
+ SID_HYPERLINK_SETLINK>>( SfxGetpApp()->GetPool());
+
+ SvxHyperlinkItem aItem(SID_HYPERLINK_GETLINK);
+ mpItemSet->Put(aItem);
+
+ SetInputSet (mpItemSet.get());
+
+ // insert pages
+ AddTabPage("internet", SvxHyperlinkInternetTp::Create);
+ AddTabPage("mail", SvxHyperlinkMailTp::Create);
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ AddTabPage("document", SvxHyperlinkDocTp::Create);
+ AddTabPage("newdocument", SvxHyperlinkNewDocTp::Create);
+ }
+
+ SetCurPageId("internet");
+
+ // Init Dialog
+ Start();
+
+ GetBindings().Update(SID_HYPERLINK_GETLINK);
+ GetBindings().Update(SID_READONLY_MODE);
+
+ m_xResetBtn->connect_clicked( LINK( this, SvxHpLinkDlg, ResetHdl ) );
+ m_xOKBtn->connect_clicked( LINK ( this, SvxHpLinkDlg, ClickOkHdl_Impl ) );
+ m_xApplyBtn->connect_clicked ( LINK ( this, SvxHpLinkDlg, ClickApplyHdl_Impl ) );
+}
+
+SvxHpLinkDlg::~SvxHpLinkDlg()
+{
+ mbGrabFocus = false; // don't do any grab if tear-down moves focus around during destruction
+
+ // delete config item, so the base class (SfxModelessDialogController) can not load it on the next start
+ SvtViewOptions aViewOpt( EViewType::TabDialog, OUString::number(SID_HYPERLINK_DIALOG) );
+ aViewOpt.Delete();
+
+ mpItemSet.reset();
+
+ maCtrl.dispose();
+
+ maPageList.clear();
+
+ pRanges.reset();
+ pOutSet.reset();
+}
+
+void SvxHpLinkDlg::Activate() {
+ if (mbGrabFocus) {
+ static_cast<SvxHyperlinkTabPageBase *>(GetTabPage(GetCurPageId()))->SetInitFocus();
+ mbGrabFocus = false;
+ }
+ SfxModelessDialogController::Activate();
+}
+
+void SvxHpLinkDlg::Close()
+{
+ if (IsClosing())
+ return;
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if (pViewFrame)
+ pViewFrame->ToggleChildWindow(SID_HYPERLINK_DIALOG);
+}
+
+void SvxHpLinkDlg::Apply()
+{
+ SfxItemSetFixed<SID_HYPERLINK_GETLINK, SID_HYPERLINK_SETLINK> aItemSet( SfxGetpApp()->GetPool() );
+
+ SvxHyperlinkTabPageBase* pCurrentPage = static_cast<SvxHyperlinkTabPageBase*>(
+ GetTabPage( GetCurPageId() ) );
+
+ pCurrentPage->FillItemSet( &aItemSet );
+
+ const SvxHyperlinkItem *aItem = aItemSet.GetItem(SID_HYPERLINK_SETLINK);
+ if ( !aItem->GetURL().isEmpty() )
+ GetDispatcher()->ExecuteList(SID_HYPERLINK_SETLINK,
+ SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { aItem });
+
+ static_cast<SvxHyperlinkTabPageBase*>( GetTabPage( GetCurPageId() ) )->DoApply();
+}
+
+/// Click on OK button
+IMPL_LINK_NOARG(SvxHpLinkDlg, ClickOkHdl_Impl, weld::Button&, void)
+{
+ Apply();
+ m_xDialog->response(RET_OK);
+}
+
+/*************************************************************************
+|*
+|* Click on Apply-button
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHpLinkDlg, ClickApplyHdl_Impl, weld::Button&, void)
+{
+ Apply();
+}
+
+/*************************************************************************
+|*
+|* Set Page
+|*
+|************************************************************************/
+void SvxHpLinkDlg::SetPage ( SvxHyperlinkItem const * pItem )
+{
+ OString sPageId("internet");
+
+ OUString aStrURL(pItem->GetURL());
+ INetURLObject aURL(aStrURL);
+ INetProtocol eProtocolTyp = aURL.GetProtocol();
+
+ switch ( eProtocolTyp )
+ {
+ case INetProtocol::Http :
+ case INetProtocol::Ftp :
+ sPageId = "internet";
+ break;
+ case INetProtocol::File :
+ sPageId = "document";
+ break;
+ case INetProtocol::Mailto :
+ sPageId = "mail";
+ break;
+ default :
+ if (aStrURL.startsWith("#"))
+ sPageId = "document";
+ else
+ {
+ // not valid
+ sPageId = GetCurPageId();
+ }
+ break;
+ }
+
+ ShowPage (sPageId);
+
+ SvxHyperlinkTabPageBase* pCurrentPage = static_cast<SvxHyperlinkTabPageBase*>(GetTabPage( sPageId ));
+
+ mbIsHTMLDoc = (pItem->GetInsertMode() & HLINK_HTMLMODE) != 0;
+
+ IconChoicePage* pPage = GetTabPage (sPageId);
+ if(pPage)
+ {
+ SfxItemSet& aPageSet = const_cast<SfxItemSet&>(pPage->GetItemSet ());
+ aPageSet.Put ( *pItem );
+
+ pCurrentPage->Reset( aPageSet );
+ }
+}
+
+/*************************************************************************
+|*
+|* Enable/Disable ReadOnly mode
+|*
+|************************************************************************/
+void SvxHpLinkDlg::SetReadOnlyMode( bool bRdOnly )
+{
+ m_xOKBtn->set_sensitive(!bRdOnly);
+}
+
+/*************************************************************************
+|*
+|* late-initialization of newly created pages
+|*
+|************************************************************************/
+void SvxHpLinkDlg::PageCreated(IconChoicePage& rPage)
+{
+ SvxHyperlinkTabPageBase& rHyperlinkPage = dynamic_cast< SvxHyperlinkTabPageBase& >( rPage );
+ Reference< XFrame > xDocumentFrame = GetBindings().GetActiveFrame();
+ OSL_ENSURE( xDocumentFrame.is(), "SvxHpLinkDlg::PageCreated: macro assignment functionality won't work with a proper frame!" );
+ rHyperlinkPage.SetDocumentFrame( xDocumentFrame );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuiimapwnd.cxx b/cui/source/dialogs/cuiimapwnd.cxx
new file mode 100644
index 000000000..d613e1a80
--- /dev/null
+++ b/cui/source/dialogs/cuiimapwnd.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cuiimapwnd.hxx>
+
+/*************************************************************************
+|*
+|* URLDlg
+|*
+\************************************************************************/
+
+URLDlg::URLDlg(weld::Widget* pWindow, const OUString& rURL, const OUString& rAlternativeText,
+ const OUString& rDescription, const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList)
+ : GenericDialogController(pWindow, "cui/ui/cuiimapdlg.ui", "IMapDialog")
+ , m_xEdtURL(m_xBuilder->weld_entry("urlentry"))
+ , m_xCbbTargets(m_xBuilder->weld_combo_box("frameCB"))
+ , m_xEdtName(m_xBuilder->weld_entry("nameentry"))
+ , m_xEdtAlternativeText(m_xBuilder->weld_entry("textentry"))
+ , m_xEdtDescription(m_xBuilder->weld_text_view("descTV"))
+{
+ m_xEdtDescription->set_size_request(m_xEdtDescription->get_approximate_digit_width() * 51,
+ m_xEdtDescription->get_height_rows(5));
+
+ m_xEdtURL->set_text(rURL);
+ m_xEdtAlternativeText->set_text(rAlternativeText);
+ m_xEdtDescription->set_text(rDescription);
+ m_xEdtName->set_text(rName);
+
+ for (const OUString& a : rTargetList)
+ m_xCbbTargets->append_text(a);
+
+ if (rTarget.isEmpty())
+ m_xCbbTargets->set_entry_text("_self");
+ else
+ m_xCbbTargets->set_entry_text(rTarget);
+}
+
+URLDlg::~URLDlg() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuitbxform.cxx b/cui/source/dialogs/cuitbxform.cxx
new file mode 100644
index 000000000..55d21325d
--- /dev/null
+++ b/cui/source/dialogs/cuitbxform.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cuitbxform.hxx>
+
+FmInputRecordNoDialog::FmInputRecordNoDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/recordnumberdialog.ui", "RecordNumberDialog")
+ , m_xRecordNo(m_xBuilder->weld_spin_button("entry"))
+{
+ m_xRecordNo->set_range(1, 0x7FFFFFFF);
+}
+
+FmInputRecordNoDialog::~FmInputRecordNoDialog() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/dlgname.cxx b/cui/source/dialogs/dlgname.cxx
new file mode 100644
index 000000000..ffa540bbc
--- /dev/null
+++ b/cui/source/dialogs/dlgname.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dlgname.hxx>
+
+/*************************************************************************
+|*
+|* Dialog for editing a name
+|*
+\************************************************************************/
+
+SvxNameDialog::SvxNameDialog(weld::Window* pParent, const OUString& rName, const OUString& rDesc)
+ : GenericDialogController(pParent, "cui/ui/namedialog.ui", "NameDialog")
+ , m_xEdtName(m_xBuilder->weld_entry("name_entry"))
+ , m_xFtDescription(m_xBuilder->weld_label("description_label"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+{
+ m_xFtDescription->set_label(rDesc);
+ m_xEdtName->set_text(rName);
+ m_xEdtName->select_region(0, -1);
+ ModifyHdl(*m_xEdtName);
+ m_xEdtName->connect_changed(LINK(this, SvxNameDialog, ModifyHdl));
+}
+
+IMPL_LINK_NOARG(SvxNameDialog, ModifyHdl, weld::Entry&, void)
+{
+ // Do not allow empty names
+ bool bEnable;
+ if (m_aCheckNameHdl.IsSet())
+ bEnable = !m_xEdtName->get_text().isEmpty() && m_aCheckNameHdl.Call(*this);
+ else
+ bEnable = !m_xEdtName->get_text().isEmpty();
+ m_xBtnOK->set_sensitive(bEnable);
+ // tdf#129032: feedback on reason to disabled controls
+ m_xEdtName->set_message_type(bEnable ? weld::EntryMessageType::Normal
+ : weld::EntryMessageType::Error);
+ OUString rTip = "";
+ if (!bEnable && m_aCheckNameTooltipHdl.IsSet())
+ rTip = m_aCheckNameTooltipHdl.Call(*this);
+ m_xBtnOK->set_tooltip_text(rTip);
+ m_xEdtName->set_tooltip_text(rTip);
+}
+
+// #i68101#
+// Dialog for editing Object Name
+// plus uniqueness-callback-linkHandler
+
+SvxObjectNameDialog::SvxObjectNameDialog(weld::Window* pParent, const OUString& rName)
+ : GenericDialogController(pParent, "cui/ui/objectnamedialog.ui", "ObjectNameDialog")
+ , m_xEdtName(m_xBuilder->weld_entry("object_name_entry"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+{
+ // set name
+ m_xEdtName->set_text(rName);
+ m_xEdtName->select_region(0, -1);
+
+ // activate name
+ ModifyHdl(*m_xEdtName);
+ m_xEdtName->connect_changed(LINK(this, SvxObjectNameDialog, ModifyHdl));
+}
+
+IMPL_LINK_NOARG(SvxObjectNameDialog, ModifyHdl, weld::Entry&, void)
+{
+ if (aCheckNameHdl.IsSet())
+ {
+ m_xBtnOK->set_sensitive(aCheckNameHdl.Call(*this));
+ }
+}
+
+// #i68101#
+// Dialog for editing Object Title and Description
+
+SvxObjectTitleDescDialog::SvxObjectTitleDescDialog(weld::Window* pParent, const OUString& rTitle,
+ const OUString& rDescription)
+ : GenericDialogController(pParent, "cui/ui/objecttitledescdialog.ui", "ObjectTitleDescDialog")
+ , m_xEdtTitle(m_xBuilder->weld_entry("object_title_entry"))
+ , m_xEdtDescription(m_xBuilder->weld_text_view("desc_entry"))
+{
+ //lock height to initial height
+ m_xEdtDescription->set_size_request(-1, m_xEdtDescription->get_text_height() * 5);
+ // set title & desc
+ m_xEdtTitle->set_text(rTitle);
+ m_xEdtDescription->set_text(rDescription);
+
+ // activate title
+ m_xEdtTitle->select_region(0, -1);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/fileextcheckdlg.cxx b/cui/source/dialogs/fileextcheckdlg.cxx
new file mode 100644
index 000000000..732f83674
--- /dev/null
+++ b/cui/source/dialogs/fileextcheckdlg.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <officecfg/Office/Common.hxx>
+#include <vcl/fileregistration.hxx>
+
+#include <fileextcheckdlg.hxx>
+
+FileExtCheckDialog::FileExtCheckDialog(weld::Window* pParent, const OUString& sTitle,
+ const OUString& sMsg)
+ : GenericDialogController(pParent, "cui/ui/fileextcheckdialog.ui", "FileExtCheckDialog")
+ , m_pText(m_xBuilder->weld_label("lbText"))
+ , m_pPerformCheck(m_xBuilder->weld_check_button("cbPerformCheck"))
+ , m_pOk(m_xBuilder->weld_button("btnOk"))
+{
+ m_pPerformCheck->set_active(true);
+ m_pOk->connect_clicked(LINK(this, FileExtCheckDialog, OnOkClick));
+ m_xDialog->set_title(sTitle);
+ m_pText->set_label(sMsg);
+}
+
+FileExtCheckDialog::~FileExtCheckDialog()
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::PerformFileExtCheck::set(m_pPerformCheck->get_active(),
+ xChanges);
+ xChanges->commit();
+}
+
+IMPL_LINK_NOARG(FileExtCheckDialog, OnOkClick, weld::Button&, void)
+{
+ vcl::fileregistration::LaunchRegistrationUI();
+ FileExtCheckDialog::response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/hangulhanjadlg.cxx b/cui/source/dialogs/hangulhanjadlg.cxx
new file mode 100644
index 000000000..fb25df938
--- /dev/null
+++ b/cui/source/dialogs/hangulhanjadlg.cxx
@@ -0,0 +1,1508 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hangulhanjadlg.hxx>
+#include <dialmgr.hxx>
+
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <algorithm>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weldutils.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
+#include <com/sun/star/linguistic2/ConversionDirection.hpp>
+#include <com/sun/star/linguistic2/ConversionDictionaryList.hpp>
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#define HHC editeng::HangulHanjaConversion
+#define LINE_CNT static_cast< sal_uInt16 >(2)
+#define MAXNUM_SUGGESTIONS 50
+
+
+namespace svx
+{
+
+ using namespace ::com::sun::star;
+ using namespace css::uno;
+ using namespace css::linguistic2;
+ using namespace css::lang;
+ using namespace css::container;
+
+
+ namespace
+ {
+ class FontSwitch
+ {
+ private:
+ OutputDevice& m_rDev;
+
+ public:
+ FontSwitch( OutputDevice& _rDev, const vcl::Font& _rTemporaryFont )
+ :m_rDev( _rDev )
+ {
+ m_rDev.Push( vcl::PushFlags::FONT );
+ m_rDev.SetFont( _rTemporaryFont );
+ }
+ ~FontSwitch() COVERITY_NOEXCEPT_FALSE
+ {
+ m_rDev.Pop();
+ }
+ };
+
+ /** a class which allows to draw two texts in a pseudo-ruby way (which basically
+ means one text above or below the other, and a little bit smaller)
+ */
+ class PseudoRubyText
+ {
+ public:
+ enum RubyPosition
+ {
+ eAbove, eBelow
+ };
+
+ protected:
+ OUString m_sPrimaryText;
+ OUString m_sSecondaryText;
+ RubyPosition m_ePosition;
+
+ public:
+ PseudoRubyText();
+ void init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition );
+ const OUString& getPrimaryText() const { return m_sPrimaryText; }
+ const OUString& getSecondaryText() const { return m_sSecondaryText; }
+
+ public:
+ void Paint( vcl::RenderContext& _rDevice, const ::tools::Rectangle& _rRect,
+ ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation );
+ };
+
+ }
+
+ PseudoRubyText::PseudoRubyText()
+ : m_ePosition(eAbove)
+ {
+ }
+
+ void PseudoRubyText::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition )
+ {
+ m_sPrimaryText = rPrimaryText;
+ m_sSecondaryText = rSecondaryText;
+ m_ePosition = rPosition;
+ }
+
+
+ void PseudoRubyText::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& _rRect,
+ ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation )
+ {
+ // calculate the text flags for the painting
+ constexpr DrawTextFlags nTextStyle = DrawTextFlags::Mnemonic |
+ DrawTextFlags::Left |
+ DrawTextFlags::VCenter;
+
+ Size aPlaygroundSize(_rRect.GetSize());
+
+ // the font for the secondary text:
+ vcl::Font aSmallerFont(rRenderContext.GetFont());
+ // heuristic: 80% of the original size
+ aSmallerFont.SetFontHeight( static_cast<tools::Long>( 0.8 * aSmallerFont.GetFontHeight() ) );
+
+ // let's calculate the size of our two texts
+ ::tools::Rectangle aPrimaryRect = rRenderContext.GetTextRect( _rRect, m_sPrimaryText, nTextStyle );
+ ::tools::Rectangle aSecondaryRect;
+ {
+ FontSwitch aFontRestore(rRenderContext, aSmallerFont);
+ aSecondaryRect = rRenderContext.GetTextRect(_rRect, m_sSecondaryText, nTextStyle);
+ }
+
+ // position these rectangles properly
+ // x-axis:
+ sal_Int32 nCombinedWidth = std::max( aSecondaryRect.GetWidth(), aPrimaryRect.GetWidth() );
+ // the rectangle where both texts will reside is as high as possible, and as wide as the
+ // widest of both text rects
+ aPrimaryRect.SetLeft( _rRect.Left() );
+ aSecondaryRect.SetLeft( aPrimaryRect.Left() );
+ aPrimaryRect.SetRight( _rRect.Left() + nCombinedWidth );
+ aSecondaryRect.SetRight( aPrimaryRect.Right() );
+
+ // y-axis:
+ sal_Int32 nCombinedHeight = aPrimaryRect.GetHeight() + aSecondaryRect.GetHeight();
+ // align to the top, for the moment
+ aPrimaryRect.Move( 0, _rRect.Top() - aPrimaryRect.Top() );
+ aSecondaryRect.Move( 0, aPrimaryRect.Top() + aPrimaryRect.GetHeight() - aSecondaryRect.Top() );
+ // move the rects to the bottom
+ aPrimaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
+ aSecondaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
+
+ // 'til here, everything we did assumes that the secondary text is painted _below_ the primary
+ // text. If this isn't the case, we need to correct the rectangles
+ if (eAbove == m_ePosition)
+ {
+ sal_Int32 nVertDistance = aSecondaryRect.Top() - aPrimaryRect.Top();
+ aSecondaryRect.Move( 0, -nVertDistance );
+ aPrimaryRect.Move( 0, nCombinedHeight - nVertDistance );
+ }
+
+ // now draw the texts
+ // as we already calculated the precise rectangles for the texts, we don't want to
+ // use the alignment flags given - within its rect, every text is centered
+ DrawTextFlags nDrawTextStyle( nTextStyle );
+ nDrawTextStyle &= ~DrawTextFlags( DrawTextFlags::Right | DrawTextFlags::Left | DrawTextFlags::Bottom | DrawTextFlags::Top );
+ nDrawTextStyle |= DrawTextFlags::Center | DrawTextFlags::VCenter;
+
+ rRenderContext.DrawText( aPrimaryRect, m_sPrimaryText, nDrawTextStyle );
+ {
+ FontSwitch aFontRestore(rRenderContext, aSmallerFont);
+ rRenderContext.DrawText( aSecondaryRect, m_sSecondaryText, nDrawTextStyle );
+ }
+
+ // outta here
+ if (_pPrimaryLocation)
+ *_pPrimaryLocation = aPrimaryRect;
+ if (_pSecondaryLocation)
+ *_pSecondaryLocation = aSecondaryRect;
+ }
+
+ class RubyRadioButton
+ {
+ public:
+ RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl, std::unique_ptr<weld::Image> xImage);
+ void init(const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition);
+
+ void set_sensitive(bool sensitive)
+ {
+ m_xControl->set_sensitive(sensitive);
+ m_xImage->set_sensitive(sensitive);
+ }
+ void set_active(bool active) { m_xControl->set_active(active); }
+ bool get_active() const { return m_xControl->get_active(); }
+
+ void connect_toggled(const Link<weld::Toggleable&, void>& rLink) { m_xControl->connect_toggled(rLink); }
+
+ private:
+ Size GetOptimalSize() const;
+ void Paint(vcl::RenderContext& rRenderContext);
+
+ ScopedVclPtr<VirtualDevice> m_xVirDev;
+ std::unique_ptr<weld::RadioButton> m_xControl;
+ std::unique_ptr<weld::Image> m_xImage;
+ PseudoRubyText m_aRubyText;
+ };
+
+ RubyRadioButton::RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl, std::unique_ptr<weld::Image> xImage)
+ : m_xVirDev(xControl->create_virtual_device())
+ , m_xControl(std::move(xControl))
+ , m_xImage(std::move(xImage))
+ {
+ // expand the point size of the desired font to the equivalent pixel size
+ weld::SetPointFont(*m_xVirDev, m_xControl->get_font());
+ }
+
+ void RubyRadioButton::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition )
+ {
+ m_aRubyText.init(rPrimaryText, rSecondaryText, rPosition);
+
+ m_xVirDev->SetOutputSizePixel(GetOptimalSize());
+
+ Paint(*m_xVirDev);
+
+ m_xImage->set_image(m_xVirDev.get());
+ }
+
+ void RubyRadioButton::Paint(vcl::RenderContext& rRenderContext)
+ {
+ ::tools::Rectangle aOverallRect(Point(0, 0), rRenderContext.GetOutputSizePixel());
+ // inflate the rect a little bit (because the VCL radio button does the same)
+ ::tools::Rectangle aTextRect( aOverallRect );
+ aTextRect.AdjustLeft( 1 ); aTextRect.AdjustRight( -1 );
+ aTextRect.AdjustTop( 1 ); aTextRect.AdjustBottom( -1 );
+
+ // paint the ruby text
+ ::tools::Rectangle aPrimaryTextLocation;
+ ::tools::Rectangle aSecondaryTextLocation;
+
+ m_aRubyText.Paint(rRenderContext, aTextRect, &aPrimaryTextLocation, &aSecondaryTextLocation);
+ }
+
+ Size RubyRadioButton::GetOptimalSize() const
+ {
+ vcl::Font aSmallerFont(m_xVirDev->GetFont());
+ aSmallerFont.SetFontHeight( static_cast<tools::Long>( 0.8 * aSmallerFont.GetFontHeight() ) );
+ ::tools::Rectangle rect( Point(), Size( SAL_MAX_INT32, SAL_MAX_INT32 ) );
+
+ Size aPrimarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getPrimaryText() ).GetSize();
+ Size aSecondarySize;
+ {
+ FontSwitch aFontRestore(*m_xVirDev, aSmallerFont);
+ aSecondarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getSecondaryText() ).GetSize();
+ }
+
+ Size minimumSize;
+ minimumSize.setHeight( aPrimarySize.Height() + aSecondarySize.Height() + 5 );
+ minimumSize.setWidth(std::max(aPrimarySize.Width(), aSecondarySize.Width()) + 5 );
+ return minimumSize;
+ }
+
+ SuggestionSet::SuggestionSet(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow)
+ : ValueSet(std::move(xScrolledWindow))
+
+ {
+ }
+
+ void SuggestionSet::UserDraw( const UserDrawEvent& rUDEvt )
+ {
+ vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
+ ::tools::Rectangle aRect = rUDEvt.GetRect();
+ sal_uInt16 nItemId = rUDEvt.GetItemId();
+
+ OUString sText = *static_cast< OUString* >( GetItemData( nItemId ) );
+ pDev->DrawText( aRect, sText, DrawTextFlags::Center | DrawTextFlags::VCenter );
+ }
+
+ SuggestionDisplay::SuggestionDisplay(weld::Builder& rBuilder)
+ : m_bDisplayListBox( true )
+ , m_bInSelectionUpdate( false )
+ , m_xValueSet(new SuggestionSet(rBuilder.weld_scrolled_window("scrollwin", true)))
+ , m_xValueSetWin(new weld::CustomWeld(rBuilder, "valueset", *m_xValueSet))
+ , m_xListBox(rBuilder.weld_tree_view("listbox"))
+ {
+ m_xValueSet->SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionValueSetHdl ) );
+ m_xListBox->connect_changed( LINK( this, SuggestionDisplay, SelectSuggestionListBoxHdl ) );
+
+ m_xValueSet->SetLineCount( LINE_CNT );
+ m_xValueSet->SetStyle( m_xValueSet->GetStyle() | WB_ITEMBORDER | WB_VSCROLL );
+
+ auto nItemWidth = 2 * m_xListBox->get_pixel_size("AU").Width();
+ m_xValueSet->SetItemWidth( nItemWidth );
+
+ Size aSize(m_xListBox->get_approximate_digit_width() * 42, m_xListBox->get_text_height() * 5);
+ m_xValueSet->set_size_request(aSize.Width(), aSize.Height());
+ m_xListBox->set_size_request(aSize.Width(), aSize.Height());
+
+ implUpdateDisplay();
+ }
+
+ void SuggestionDisplay::implUpdateDisplay()
+ {
+ m_xListBox->set_visible(m_bDisplayListBox);
+ if (!m_bDisplayListBox)
+ m_xValueSetWin->show();
+ else
+ m_xValueSetWin->hide();
+ }
+
+ weld::Widget& SuggestionDisplay::implGetCurrentControl()
+ {
+ if (m_bDisplayListBox)
+ return *m_xListBox;
+ return *m_xValueSet->GetDrawingArea();
+ }
+
+ void SuggestionDisplay::DisplayListBox( bool bDisplayListBox )
+ {
+ if( m_bDisplayListBox == bDisplayListBox )
+ return;
+
+ weld::Widget& rOldControl = implGetCurrentControl();
+ bool bHasFocus = rOldControl.has_focus();
+
+ m_bDisplayListBox = bDisplayListBox;
+
+ if( bHasFocus )
+ {
+ weld::Widget& rNewControl = implGetCurrentControl();
+ rNewControl.grab_focus();
+ }
+
+ implUpdateDisplay();
+ }
+
+ IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet*, void)
+ {
+ SelectSuggestionHdl(false);
+ }
+
+ IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionListBoxHdl, weld::TreeView&, void)
+ {
+ SelectSuggestionHdl(true);
+ }
+
+ void SuggestionDisplay::SelectSuggestionHdl(bool bListBox)
+ {
+ if( m_bInSelectionUpdate )
+ return;
+
+ m_bInSelectionUpdate = true;
+ if (bListBox)
+ {
+ sal_uInt16 nPos = m_xListBox->get_selected_index();
+ m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
+ }
+ else
+ {
+ sal_uInt16 nPos = m_xValueSet->GetSelectedItemId()-1; //itemid == pos+1 (id 0 has special meaning)
+ m_xListBox->select(nPos);
+ }
+ m_bInSelectionUpdate = false;
+ m_aSelectLink.Call( *this );
+ }
+
+ void SuggestionDisplay::SetSelectHdl( const Link<SuggestionDisplay&,void>& rLink )
+ {
+ m_aSelectLink = rLink;
+ }
+
+ void SuggestionDisplay::Clear()
+ {
+ m_xListBox->clear();
+ m_xValueSet->Clear();
+ }
+
+ void SuggestionDisplay::InsertEntry( const OUString& rStr )
+ {
+ m_xListBox->append_text(rStr);
+ sal_uInt16 nItemId = m_xListBox->n_children(); //itemid == pos+1 (id 0 has special meaning)
+ m_xValueSet->InsertItem( nItemId );
+ OUString* pItemData = new OUString( rStr );
+ m_xValueSet->SetItemData( nItemId, pItemData );
+ }
+
+ void SuggestionDisplay::SelectEntryPos( sal_uInt16 nPos )
+ {
+ m_xListBox->select(nPos);
+ m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
+ }
+
+ sal_uInt16 SuggestionDisplay::GetEntryCount() const
+ {
+ return m_xListBox->n_children();
+ }
+
+ OUString SuggestionDisplay::GetEntry( sal_uInt16 nPos ) const
+ {
+ return m_xListBox->get_text( nPos );
+ }
+
+ OUString SuggestionDisplay::GetSelectedEntry() const
+ {
+ return m_xListBox->get_selected_text();
+ }
+
+ void SuggestionDisplay::SetHelpIds()
+ {
+ m_xValueSet->SetHelpId(HID_HANGULDLG_SUGGESTIONS_GRID);
+ m_xListBox->set_help_id(HID_HANGULDLG_SUGGESTIONS_LIST);
+ }
+
+ HangulHanjaConversionDialog::HangulHanjaConversionDialog(weld::Widget* pParent)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaconversiondialog.ui", "HangulHanjaConversionDialog")
+ , m_bDocumentMode( true )
+ , m_xFind(m_xBuilder->weld_button("find"))
+ , m_xIgnore(m_xBuilder->weld_button("ignore"))
+ , m_xIgnoreAll(m_xBuilder->weld_button("ignoreall"))
+ , m_xReplace(m_xBuilder->weld_button("replace"))
+ , m_xReplaceAll(m_xBuilder->weld_button("replaceall"))
+ , m_xOptions(m_xBuilder->weld_button("options"))
+ , m_xSuggestions(new SuggestionDisplay(*m_xBuilder))
+ , m_xSimpleConversion(m_xBuilder->weld_radio_button("simpleconversion"))
+ , m_xHangulBracketed(m_xBuilder->weld_radio_button("hangulbracket"))
+ , m_xHanjaBracketed(m_xBuilder->weld_radio_button("hanjabracket"))
+ , m_xWordInput(m_xBuilder->weld_entry("wordinput"))
+ , m_xOriginalWord(m_xBuilder->weld_label("originalword"))
+ , m_xHanjaAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_above"),
+ m_xBuilder->weld_image("hanja_above_img")))
+ , m_xHanjaBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_below"),
+ m_xBuilder->weld_image("hanja_below_img")))
+ , m_xHangulAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_above"),
+ m_xBuilder->weld_image("hangul_above_img")))
+ , m_xHangulBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_below"),
+ m_xBuilder->weld_image("hangul_below_img")))
+ , m_xHangulOnly(m_xBuilder->weld_check_button("hangulonly"))
+ , m_xHanjaOnly(m_xBuilder->weld_check_button("hanjaonly"))
+ , m_xReplaceByChar(m_xBuilder->weld_check_button("replacebychar"))
+ {
+ m_xSuggestions->set_size_request(m_xOriginalWord->get_approximate_digit_width() * 42,
+ m_xOriginalWord->get_text_height() * 5);
+
+ const OUString sHangul(CuiResId(RID_CUISTR_HANGUL));
+ const OUString sHanja(CuiResId(RID_CUISTR_HANJA));
+ m_xHanjaAbove->init( sHangul, sHanja, PseudoRubyText::eAbove );
+ m_xHanjaBelow->init( sHangul, sHanja, PseudoRubyText::eBelow );
+ m_xHangulAbove->init( sHanja, sHangul, PseudoRubyText::eAbove );
+ m_xHangulBelow->init( sHanja, sHangul, PseudoRubyText::eBelow );
+
+ m_xWordInput->connect_changed( LINK( this, HangulHanjaConversionDialog, OnSuggestionModified ) );
+ m_xSuggestions->SetSelectHdl( LINK( this, HangulHanjaConversionDialog, OnSuggestionSelected ) );
+ m_xReplaceByChar->connect_toggled( LINK( this, HangulHanjaConversionDialog, ClickByCharacterHdl ) );
+ m_xHangulOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
+ m_xHanjaOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
+ m_xOptions->connect_clicked(LINK(this, HangulHanjaConversionDialog, OnOption));
+
+ // initial focus
+ FocusSuggestion( );
+
+ // initial control values
+ m_xSimpleConversion->set_active(true);
+
+ m_xSuggestions->SetHelpIds();
+ }
+
+ HangulHanjaConversionDialog::~HangulHanjaConversionDialog()
+ {
+ }
+
+ void HangulHanjaConversionDialog::FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions )
+ {
+ m_xSuggestions->Clear();
+ for ( auto const & suggestion : _rSuggestions )
+ m_xSuggestions->InsertEntry( suggestion );
+
+ // select the first suggestion, and fill in the suggestion edit field
+ OUString sFirstSuggestion;
+ if ( m_xSuggestions->GetEntryCount() )
+ {
+ sFirstSuggestion = m_xSuggestions->GetEntry( 0 );
+ m_xSuggestions->SelectEntryPos( 0 );
+ }
+ m_xWordInput->set_text( sFirstSuggestion );
+ m_xWordInput->save_value();
+ OnSuggestionModified( *m_xWordInput );
+ }
+
+ void HangulHanjaConversionDialog::SetOptionsChangedHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aOptionsChangedLink = rHdl;
+ }
+
+ void HangulHanjaConversionDialog::SetIgnoreHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xIgnore->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetIgnoreAllHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xIgnoreAll->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetChangeHdl(const Link<weld::Button&,void>& rHdl )
+ {
+ m_xReplace->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetChangeAllHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xReplaceAll->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetFindHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xFind->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetConversionFormatChangedHdl( const Link<weld::Toggleable&,void>& rHdl )
+ {
+ m_xSimpleConversion->connect_toggled( rHdl );
+ m_xHangulBracketed->connect_toggled( rHdl );
+ m_xHanjaBracketed->connect_toggled( rHdl );
+ m_xHanjaAbove->connect_toggled( rHdl );
+ m_xHanjaBelow->connect_toggled( rHdl );
+ m_xHangulAbove->connect_toggled( rHdl );
+ m_xHangulBelow->connect_toggled( rHdl );
+ }
+
+ void HangulHanjaConversionDialog::SetClickByCharacterHdl( const Link<weld::Toggleable&,void>& _rHdl )
+ {
+ m_aClickByCharacterLink = _rHdl;
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionSelected, SuggestionDisplay&, void )
+ {
+ m_xWordInput->set_text(m_xSuggestions->GetSelectedEntry());
+ OnSuggestionModified( *m_xWordInput );
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionModified, weld::Entry&, void )
+ {
+ m_xFind->set_sensitive(m_xWordInput->get_value_changed_from_saved());
+
+ bool bSameLen = m_xWordInput->get_text().getLength() == m_xOriginalWord->get_label().getLength();
+ m_xReplace->set_sensitive( m_bDocumentMode && bSameLen );
+ m_xReplaceAll->set_sensitive( m_bDocumentMode && bSameLen );
+ }
+
+ IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::Toggleable&, rBox, void)
+ {
+ m_aClickByCharacterLink.Call(rBox);
+ bool bByCharacter = rBox.get_active();
+ m_xSuggestions->DisplayListBox( !bByCharacter );
+ }
+
+ IMPL_LINK(HangulHanjaConversionDialog, OnConversionDirectionClicked, weld::Toggleable&, rBox, void)
+ {
+ weld::CheckButton* pOtherBox = nullptr;
+ if (&rBox == m_xHangulOnly.get())
+ pOtherBox = m_xHanjaOnly.get();
+ else
+ pOtherBox = m_xHangulOnly.get();
+ bool bBoxChecked = rBox.get_active();
+ if (bBoxChecked)
+ pOtherBox->set_active(false);
+ pOtherBox->set_sensitive(!bBoxChecked);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaConversionDialog, OnOption, weld::Button&, void)
+ {
+ HangulHanjaOptionsDialog aOptDlg(m_xDialog.get());
+ aOptDlg.run();
+ m_aOptionsChangedLink.Call( nullptr );
+ }
+
+ OUString HangulHanjaConversionDialog::GetCurrentString( ) const
+ {
+ return m_xOriginalWord->get_label();
+ }
+
+ void HangulHanjaConversionDialog::FocusSuggestion( )
+ {
+ m_xWordInput->grab_focus();
+ }
+
+ void HangulHanjaConversionDialog::SetCurrentString( const OUString& _rNewString,
+ const Sequence< OUString >& _rSuggestions, bool _bOriginatesFromDocument )
+ {
+ m_xOriginalWord->set_label(_rNewString);
+
+ bool bOldDocumentMode = m_bDocumentMode;
+ m_bDocumentMode = _bOriginatesFromDocument; // before FillSuggestions!
+ FillSuggestions( _rSuggestions );
+
+ m_xIgnoreAll->set_sensitive( m_bDocumentMode );
+
+ // switch the def button depending if we're working for document text
+ if (bOldDocumentMode == m_bDocumentMode)
+ return;
+
+ weld::Widget* pOldDefButton = nullptr;
+ weld::Widget* pNewDefButton = nullptr;
+ if (m_bDocumentMode)
+ {
+ pOldDefButton = m_xFind.get();
+ pNewDefButton = m_xReplace.get();
+ }
+ else
+ {
+ pOldDefButton = m_xReplace.get();
+ pNewDefButton = m_xFind.get();
+ }
+
+ m_xDialog->change_default_widget(pOldDefButton, pNewDefButton);
+ }
+
+ OUString HangulHanjaConversionDialog::GetCurrentSuggestion( ) const
+ {
+ return m_xWordInput->get_text();
+ }
+
+ void HangulHanjaConversionDialog::SetByCharacter( bool _bByCharacter )
+ {
+ m_xReplaceByChar->set_active( _bByCharacter );
+ m_xSuggestions->DisplayListBox( !_bByCharacter );
+ }
+
+ void HangulHanjaConversionDialog::SetConversionDirectionState(
+ bool _bTryBothDirections,
+ HHC::ConversionDirection ePrimaryConversionDirection )
+ {
+ // default state: try both direction
+ m_xHangulOnly->set_active( false );
+ m_xHangulOnly->set_sensitive(true);
+ m_xHanjaOnly->set_active( false );
+ m_xHanjaOnly->set_sensitive(true);
+
+ if (!_bTryBothDirections)
+ {
+ weld::CheckButton* pBox = ePrimaryConversionDirection == HHC::eHangulToHanja ?
+ m_xHangulOnly.get() : m_xHanjaOnly.get();
+ pBox->set_active(true);
+ OnConversionDirectionClicked(*pBox);
+ }
+ }
+
+ bool HangulHanjaConversionDialog::GetUseBothDirections( ) const
+ {
+ return !m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active();
+ }
+
+ HHC::ConversionDirection HangulHanjaConversionDialog::GetDirection(
+ HHC::ConversionDirection eDefaultDirection ) const
+ {
+ HHC::ConversionDirection eDirection = eDefaultDirection;
+ if (m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active())
+ eDirection = HHC::eHangulToHanja;
+ else if (!m_xHangulOnly->get_active() && m_xHanjaOnly->get_active())
+ eDirection = HHC::eHanjaToHangul;
+ return eDirection;
+ }
+
+ void HangulHanjaConversionDialog::SetConversionFormat( HHC::ConversionFormat _eType )
+ {
+ switch ( _eType )
+ {
+ case HHC::eSimpleConversion: m_xSimpleConversion->set_active(true); break;
+ case HHC::eHangulBracketed: m_xHangulBracketed->set_active(true); break;
+ case HHC::eHanjaBracketed: m_xHanjaBracketed->set_active(true); break;
+ case HHC::eRubyHanjaAbove: m_xHanjaAbove->set_active(true); break;
+ case HHC::eRubyHanjaBelow: m_xHanjaBelow->set_active(true); break;
+ case HHC::eRubyHangulAbove: m_xHangulAbove->set_active(true); break;
+ case HHC::eRubyHangulBelow: m_xHangulBelow->set_active(true); break;
+ default:
+ OSL_FAIL( "HangulHanjaConversionDialog::SetConversionFormat: unknown type!" );
+ }
+ }
+
+ HHC::ConversionFormat HangulHanjaConversionDialog::GetConversionFormat( ) const
+ {
+ if ( m_xSimpleConversion->get_active() )
+ return HHC::eSimpleConversion;
+ if ( m_xHangulBracketed->get_active() )
+ return HHC::eHangulBracketed;
+ if ( m_xHanjaBracketed->get_active() )
+ return HHC::eHanjaBracketed;
+ if ( m_xHanjaAbove->get_active() )
+ return HHC::eRubyHanjaAbove;
+ if ( m_xHanjaBelow->get_active() )
+ return HHC::eRubyHanjaBelow;
+ if ( m_xHangulAbove->get_active() )
+ return HHC::eRubyHangulAbove;
+ if ( m_xHangulBelow->get_active() )
+ return HHC::eRubyHangulBelow;
+
+ OSL_FAIL( "HangulHanjaConversionDialog::GetConversionFormat: no radio checked?" );
+ return HHC::eSimpleConversion;
+ }
+
+ void HangulHanjaConversionDialog::EnableRubySupport( bool bVal )
+ {
+ m_xHanjaAbove->set_sensitive( bVal );
+ m_xHanjaBelow->set_sensitive( bVal );
+ m_xHangulAbove->set_sensitive( bVal );
+ m_xHangulBelow->set_sensitive( bVal );
+ }
+
+ void HangulHanjaOptionsDialog::Init()
+ {
+ if( !m_xConversionDictionaryList.is() )
+ {
+ m_xConversionDictionaryList = ConversionDictionaryList::create( ::comphelper::getProcessComponentContext() );
+ }
+
+ m_aDictList.clear();
+ m_xDictsLB->clear();
+
+ Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
+ if( xNameCont.is() )
+ {
+ Sequence< OUString > aDictNames( xNameCont->getElementNames() );
+
+ const OUString* pDic = aDictNames.getConstArray();
+ sal_Int32 nCount = aDictNames.getLength();
+
+ sal_Int32 i;
+ for( i = 0 ; i < nCount ; ++i )
+ {
+ Any aAny( xNameCont->getByName( pDic[ i ] ) );
+ Reference< XConversionDictionary > xDic;
+ if( ( aAny >>= xDic ) && xDic.is() )
+ {
+ if( LANGUAGE_KOREAN == LanguageTag( xDic->getLocale() ).getLanguageType() )
+ {
+ m_aDictList.push_back( xDic );
+ AddDict( xDic->getName(), xDic->isActive() );
+ }
+ }
+ }
+ }
+ if (m_xDictsLB->n_children())
+ m_xDictsLB->select(0);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, OkHdl, weld::Button&, void)
+ {
+ sal_uInt32 nCnt = m_aDictList.size();
+ sal_uInt32 n = 0;
+ sal_uInt32 nActiveDics = 0;
+ Sequence< OUString > aActiveDics;
+
+ aActiveDics.realloc( nCnt );
+ OUString* pActActiveDic = aActiveDics.getArray();
+
+ while( nCnt )
+ {
+ Reference< XConversionDictionary > xDict = m_aDictList[ n ];
+
+ DBG_ASSERT( xDict.is(), "-HangulHanjaOptionsDialog::OkHdl(): someone is evaporated..." );
+
+ bool bActive = m_xDictsLB->get_toggle(n) == TRISTATE_TRUE;
+ xDict->setActive( bActive );
+ Reference< util::XFlushable > xFlush( xDict, uno::UNO_QUERY );
+ if( xFlush.is() )
+ xFlush->flush();
+
+ if( bActive )
+ {
+ pActActiveDic[ nActiveDics ] = xDict->getName();
+ ++nActiveDics;
+ }
+
+ ++n;
+ --nCnt;
+ }
+
+ // save configuration
+ aActiveDics.realloc( nActiveDics );
+ Any aTmp;
+ SvtLinguConfig aLngCfg;
+ aTmp <<= aActiveDics;
+ aLngCfg.SetProperty( UPH_ACTIVE_CONVERSION_DICTIONARIES, aTmp );
+
+ aTmp <<= m_xIgnorepostCB->get_active();
+ aLngCfg.SetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD, aTmp );
+
+ aTmp <<= m_xShowrecentlyfirstCB->get_active();
+ aLngCfg.SetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, aTmp );
+
+ aTmp <<= m_xAutoreplaceuniqueCB->get_active();
+ aLngCfg.SetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES, aTmp );
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DictsLB_SelectHdl, weld::TreeView&, void)
+ {
+ bool bSel = m_xDictsLB->get_selected_index() != -1;
+
+ m_xEditPB->set_sensitive(bSel);
+ m_xDeletePB->set_sensitive(bSel);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, NewDictHdl, weld::Button&, void)
+ {
+ OUString aName;
+ HangulHanjaNewDictDialog aNewDlg(m_xDialog.get());
+ aNewDlg.run();
+ if (!aNewDlg.GetName(aName))
+ return;
+
+ if( !m_xConversionDictionaryList.is() )
+ return;
+
+ try
+ {
+ Reference< XConversionDictionary > xDic =
+ m_xConversionDictionaryList->addNewDictionary( aName, LanguageTag::convertToLocale( LANGUAGE_KOREAN ), ConversionDictionaryType::HANGUL_HANJA );
+
+ if( xDic.is() )
+ {
+ //adapt local caches:
+ m_aDictList.push_back( xDic );
+ AddDict( xDic->getName(), xDic->isActive() );
+ }
+ }
+ catch( const ElementExistException& )
+ {
+ }
+ catch( const NoSupportException& )
+ {
+ }
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, EditDictHdl, weld::Button&, void)
+ {
+ int nEntry = m_xDictsLB->get_selected_index();
+ DBG_ASSERT(nEntry != -1, "+HangulHanjaEditDictDialog::EditDictHdl(): call of edit should not be possible with no selection!");
+ if (nEntry != -1)
+ {
+ HangulHanjaEditDictDialog aEdDlg(m_xDialog.get(), m_aDictList, nEntry);
+ aEdDlg.run();
+ }
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DeleteDictHdl, weld::Button&, void)
+ {
+ int nSelPos = m_xDictsLB->get_selected_index();
+ if (nSelPos == -1)
+ return;
+
+ Reference< XConversionDictionary > xDic( m_aDictList[ nSelPos ] );
+ if( !(m_xConversionDictionaryList.is() && xDic.is()) )
+ return;
+
+ Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
+ if( !xNameCont.is() )
+ return;
+
+ try
+ {
+ xNameCont->removeByName( xDic->getName() );
+
+ //adapt local caches:
+ m_aDictList.erase(m_aDictList.begin()+nSelPos );
+ m_xDictsLB->remove(nSelPos);
+ }
+ catch( const ElementExistException& )
+ {
+ }
+ catch( const NoSupportException& )
+ {
+ }
+ }
+
+ HangulHanjaOptionsDialog::HangulHanjaOptionsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaoptdialog.ui", "HangulHanjaOptDialog")
+ , m_xDictsLB(m_xBuilder->weld_tree_view("dicts"))
+ , m_xIgnorepostCB(m_xBuilder->weld_check_button("ignorepost"))
+ , m_xShowrecentlyfirstCB(m_xBuilder->weld_check_button("showrecentfirst"))
+ , m_xAutoreplaceuniqueCB(m_xBuilder->weld_check_button("autoreplaceunique"))
+ , m_xNewPB(m_xBuilder->weld_button("new"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ , m_xOkPB(m_xBuilder->weld_button("ok"))
+ {
+ m_xDictsLB->set_size_request(m_xDictsLB->get_approximate_digit_width() * 32,
+ m_xDictsLB->get_height_rows(5));
+
+ m_xDictsLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ m_xDictsLB->connect_changed( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
+
+ m_xOkPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, OkHdl ) );
+ m_xNewPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, NewDictHdl ) );
+ m_xEditPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, EditDictHdl ) );
+ m_xDeletePB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, DeleteDictHdl ) );
+
+ SvtLinguConfig aLngCfg;
+ Any aTmp;
+ bool bVal = bool();
+ aTmp = aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD );
+ if( aTmp >>= bVal )
+ m_xIgnorepostCB->set_active( bVal );
+
+ aTmp = aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST );
+ if( aTmp >>= bVal )
+ m_xShowrecentlyfirstCB->set_active( bVal );
+
+ aTmp = aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES );
+ if( aTmp >>= bVal )
+ m_xAutoreplaceuniqueCB->set_active( bVal );
+
+ Init();
+ }
+
+ HangulHanjaOptionsDialog::~HangulHanjaOptionsDialog()
+ {
+ }
+
+ void HangulHanjaOptionsDialog::AddDict(const OUString& rName, bool bChecked)
+ {
+ m_xDictsLB->append();
+ int nRow = m_xDictsLB->n_children() - 1;
+ m_xDictsLB->set_toggle(nRow, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xDictsLB->set_text(nRow, rName, 0);
+ m_xDictsLB->set_id(nRow, rName);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaNewDictDialog, OKHdl, weld::Button&, void)
+ {
+ OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
+
+ m_bEntered = !aName.isEmpty();
+ if (m_bEntered)
+ m_xDictNameED->set_text(aName); // do this in case of trailing chars have been deleted
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaNewDictDialog, ModifyHdl, weld::Entry&, void)
+ {
+ OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
+
+ m_xOkBtn->set_sensitive(!aName.isEmpty());
+ }
+
+ HangulHanjaNewDictDialog::HangulHanjaNewDictDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaadddialog.ui", "HangulHanjaAddDialog")
+ , m_bEntered(false)
+ , m_xOkBtn(m_xBuilder->weld_button("ok"))
+ , m_xDictNameED(m_xBuilder->weld_entry("entry"))
+ {
+ m_xOkBtn->connect_clicked( LINK( this, HangulHanjaNewDictDialog, OKHdl ) );
+ m_xDictNameED->connect_changed( LINK( this, HangulHanjaNewDictDialog, ModifyHdl ) );
+ }
+
+ HangulHanjaNewDictDialog::~HangulHanjaNewDictDialog()
+ {
+ }
+
+ bool HangulHanjaNewDictDialog::GetName( OUString& _rRetName ) const
+ {
+ if( m_bEntered )
+ _rRetName = comphelper::string::stripEnd(m_xDictNameED->get_text(), ' ');
+
+ return m_bEntered;
+ }
+
+ class SuggestionList
+ {
+ private:
+ protected:
+ std::vector<OUString> m_vElements;
+ sal_uInt16 m_nNumOfEntries;
+ // index of the internal iterator, used for First() and Next() methods
+ sal_uInt16 m_nAct;
+
+ const OUString* Next_();
+ public:
+ SuggestionList();
+ ~SuggestionList();
+
+ void Set( const OUString& _rElement, sal_uInt16 _nNumOfElement );
+ void Reset( sal_uInt16 _nNumOfElement );
+ const OUString & Get( sal_uInt16 _nNumOfElement ) const;
+ void Clear();
+
+ const OUString* First();
+ const OUString* Next();
+
+ sal_uInt16 GetCount() const { return m_nNumOfEntries; }
+ };
+
+ SuggestionList::SuggestionList() :
+ m_vElements(MAXNUM_SUGGESTIONS)
+ {
+ m_nAct = m_nNumOfEntries = 0;
+ }
+
+ SuggestionList::~SuggestionList()
+ {
+ Clear();
+ }
+
+ void SuggestionList::Set( const OUString& _rElement, sal_uInt16 _nNumOfElement )
+ {
+ m_vElements[_nNumOfElement] = _rElement;
+ ++m_nNumOfEntries;
+ }
+
+ void SuggestionList::Reset( sal_uInt16 _nNumOfElement )
+ {
+ m_vElements[_nNumOfElement].clear();
+ --m_nNumOfEntries;
+ }
+
+ const OUString& SuggestionList::Get( sal_uInt16 _nNumOfElement ) const
+ {
+ return m_vElements[_nNumOfElement];
+ }
+
+ void SuggestionList::Clear()
+ {
+ if( m_nNumOfEntries )
+ {
+ for (auto & vElement : m_vElements)
+ vElement.clear();
+ m_nNumOfEntries = m_nAct = 0;
+ }
+ }
+
+ const OUString* SuggestionList::Next_()
+ {
+ while( m_nAct < m_vElements.size() )
+ {
+ auto & s = m_vElements[ m_nAct ];
+ if (!s.isEmpty())
+ return &s;
+ ++m_nAct;
+ }
+
+ return nullptr;
+ }
+
+ const OUString* SuggestionList::First()
+ {
+ m_nAct = 0;
+ return Next_();
+ }
+
+ const OUString* SuggestionList::Next()
+ {
+ const OUString* pRet;
+
+ if( m_nAct < m_nNumOfEntries )
+ {
+ ++m_nAct;
+ pRet = Next_();
+ }
+ else
+ pRet = nullptr;
+
+ return pRet;
+ }
+
+
+ bool SuggestionEdit::ShouldScroll( bool _bUp ) const
+ {
+ bool bRet = false;
+
+ if( _bUp )
+ {
+ if( !m_pPrev )
+ bRet = m_pScrollBar->vadjustment_get_value() > m_pScrollBar->vadjustment_get_lower();
+ }
+ else
+ {
+ if( !m_pNext )
+ bRet = m_pScrollBar->vadjustment_get_value() < ( m_pScrollBar->vadjustment_get_upper() - 4 );
+ }
+
+ return bRet;
+ }
+
+ void SuggestionEdit::DoJump( bool _bUp )
+ {
+ m_pScrollBar->vadjustment_set_value( m_pScrollBar->vadjustment_get_value() + ( _bUp? -1 : 1 ) );
+ m_pParent->UpdateScrollbar();
+ }
+
+ SuggestionEdit::SuggestionEdit(std::unique_ptr<weld::Entry> xEntry, HangulHanjaEditDictDialog* pParent)
+ : m_pParent(pParent)
+ , m_pPrev(nullptr)
+ , m_pNext(nullptr)
+ , m_pScrollBar(nullptr)
+ , m_xEntry(std::move(xEntry))
+ {
+ m_xEntry->connect_key_press(LINK(this, SuggestionEdit, KeyInputHdl));
+ }
+
+ IMPL_LINK(SuggestionEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+ {
+ bool bHandled = false;
+
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ sal_uInt16 nMod = rKeyCode.GetModifier();
+ sal_uInt16 nCode = rKeyCode.GetCode();
+ if( nCode == KEY_TAB && ( !nMod || KEY_SHIFT == nMod ) )
+ {
+ bool bUp = KEY_SHIFT == nMod;
+ if( ShouldScroll( bUp ) )
+ {
+ DoJump( bUp );
+ m_xEntry->select_region(0, -1);
+ // Tab-travel doesn't really happen, so emulate it by setting a selection manually
+ bHandled = true;
+ }
+ }
+ else if( KEY_UP == nCode || KEY_DOWN == nCode )
+ {
+ bool bUp = KEY_UP == nCode;
+ if( ShouldScroll( bUp ) )
+ {
+ DoJump( bUp );
+ bHandled = true;
+ }
+ else if( bUp )
+ {
+ if( m_pPrev )
+ {
+ m_pPrev->grab_focus();
+ bHandled = true;
+ }
+ }
+ else if( m_pNext )
+ {
+ m_pNext->grab_focus();
+ bHandled = true;
+ }
+ }
+
+ return bHandled;
+ }
+
+ void SuggestionEdit::init(weld::ScrolledWindow* pScrollBar, SuggestionEdit* pPrev, SuggestionEdit* pNext)
+ {
+ m_pScrollBar = pScrollBar;
+ m_pPrev = pPrev;
+ m_pNext = pNext;
+ }
+
+ namespace
+ {
+ bool GetConversions( const Reference< XConversionDictionary >& _xDict,
+ const OUString& _rOrg,
+ Sequence< OUString >& _rEntries )
+ {
+ bool bRet = false;
+ if( _xDict.is() && !_rOrg.isEmpty() )
+ {
+ try
+ {
+ _rEntries = _xDict->getConversions( _rOrg,
+ 0,
+ _rOrg.getLength(),
+ ConversionDirection_FROM_LEFT,
+ css::i18n::TextConversionOption::NONE );
+ bRet = _rEntries.hasElements();
+ }
+ catch( const IllegalArgumentException& )
+ {
+ }
+ }
+
+ return bRet;
+ }
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, ScrollHdl, weld::ScrolledWindow&, void )
+ {
+ UpdateScrollbar();
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, OriginalModifyHdl, weld::ComboBox&, void )
+ {
+ m_bModifiedOriginal = true;
+ m_aOriginal = comphelper::string::stripEnd( m_xOriginalLB->get_active_text(), ' ' );
+
+ UpdateSuggestions();
+ UpdateButtonStates();
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl1, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 0 );
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl2, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 1 );
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl3, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 2 );
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl4, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 3 );
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, BookLBSelectHdl, weld::ComboBox&, void )
+ {
+ InitEditDictDialog( m_xBookLB->get_active() );
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, NewPBPushHdl, weld::Button&, void )
+ {
+ DBG_ASSERT( m_xSuggestions, "-HangulHanjaEditDictDialog::NewPBPushHdl(): no suggestions... search in hell..." );
+ Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
+ if( xDict.is() && m_xSuggestions )
+ {
+ //delete old entry
+ bool bRemovedSomething = DeleteEntryFromDictionary( xDict );
+
+ OUString aLeft( m_aOriginal );
+ const OUString* pRight = m_xSuggestions->First();
+ bool bAddedSomething = false;
+ while( pRight )
+ {
+ try
+ {
+ //add new entry
+ xDict->addEntry( aLeft, *pRight );
+ bAddedSomething = true;
+ }
+ catch( const IllegalArgumentException& )
+ {
+ }
+ catch( const ElementExistException& )
+ {
+ }
+
+ pRight = m_xSuggestions->Next();
+ }
+
+ if( bAddedSomething || bRemovedSomething )
+ InitEditDictDialog( m_nCurrentDict );
+ }
+ else
+ {
+ SAL_INFO( "cui.dialogs", "dictionary faded away..." );
+ }
+ }
+
+ bool HangulHanjaEditDictDialog::DeleteEntryFromDictionary( const Reference< XConversionDictionary >& xDict )
+ {
+ bool bRemovedSomething = false;
+ if( xDict.is() )
+ {
+ OUString aOrg( m_aOriginal );
+ Sequence< OUString > aEntries;
+ GetConversions( xDict, m_aOriginal, aEntries );
+
+ sal_uInt32 n = aEntries.getLength();
+ OUString* pEntry = aEntries.getArray();
+ while( n )
+ {
+ try
+ {
+ xDict->removeEntry( aOrg, *pEntry );
+ bRemovedSomething = true;
+ }
+ catch( const NoSuchElementException& )
+ { // can not be...
+ }
+
+ ++pEntry;
+ --n;
+ }
+ }
+ return bRemovedSomething;
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, DeletePBPushHdl, weld::Button&, void )
+ {
+ if( DeleteEntryFromDictionary( m_rDictList[ m_nCurrentDict ] ) )
+ {
+ m_aOriginal.clear();
+ m_bModifiedOriginal = true;
+ InitEditDictDialog( m_nCurrentDict );
+ }
+ }
+
+ void HangulHanjaEditDictDialog::InitEditDictDialog( sal_uInt32 nSelDict )
+ {
+ if( m_xSuggestions )
+ m_xSuggestions->Clear();
+
+ if( m_nCurrentDict != nSelDict )
+ {
+ m_nCurrentDict = nSelDict;
+ m_aOriginal.clear();
+ m_bModifiedOriginal = true;
+ }
+
+ UpdateOriginalLB();
+
+ m_xOriginalLB->set_entry_text( !m_aOriginal.isEmpty() ? m_aOriginal : m_aEditHintText);
+ m_xOriginalLB->select_entry_region(0, -1);
+ m_xOriginalLB->grab_focus();
+
+ UpdateSuggestions();
+ UpdateButtonStates();
+ }
+
+ void HangulHanjaEditDictDialog::UpdateOriginalLB()
+ {
+ m_xOriginalLB->clear();
+ Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
+ if( xDict.is() )
+ {
+ Sequence< OUString > aEntries = xDict->getConversionEntries( ConversionDirection_FROM_LEFT );
+ sal_uInt32 n = aEntries.getLength();
+ OUString* pEntry = aEntries.getArray();
+ while( n )
+ {
+ m_xOriginalLB->append_text( *pEntry );
+
+ ++pEntry;
+ --n;
+ }
+ }
+ else
+ {
+ SAL_INFO( "cui.dialogs", "dictionary faded away..." );
+ }
+ }
+
+ void HangulHanjaEditDictDialog::UpdateButtonStates()
+ {
+ bool bHaveValidOriginalString = !m_aOriginal.isEmpty() && m_aOriginal != m_aEditHintText;
+ bool bNew = bHaveValidOriginalString && m_xSuggestions && m_xSuggestions->GetCount() > 0;
+ bNew = bNew && ( m_bModifiedSuggestions || m_bModifiedOriginal );
+
+ m_xNewPB->set_sensitive( bNew );
+ m_xDeletePB->set_sensitive(!m_bModifiedOriginal && bHaveValidOriginalString);
+ }
+
+ void HangulHanjaEditDictDialog::UpdateSuggestions()
+ {
+ Sequence< OUString > aEntries;
+ bool bFound = GetConversions( m_rDictList[ m_nCurrentDict ], m_aOriginal, aEntries );
+ if( bFound )
+ {
+ m_bModifiedOriginal = false;
+
+ if( m_xSuggestions )
+ m_xSuggestions->Clear();
+
+ //fill found entries into boxes
+ sal_uInt32 nCnt = aEntries.getLength();
+ if( nCnt )
+ {
+ if( !m_xSuggestions )
+ m_xSuggestions.reset(new SuggestionList);
+
+ const OUString* pSugg = aEntries.getConstArray();
+ sal_uInt32 n = 0;
+ while( nCnt )
+ {
+ m_xSuggestions->Set( pSugg[ n ], sal_uInt16( n ) );
+ ++n;
+ --nCnt;
+ }
+ }
+ m_bModifiedSuggestions = false;
+ }
+
+ m_xScrollSB->vadjustment_set_value( 0 );
+ UpdateScrollbar(); // will force edits to be filled new
+ }
+
+ void HangulHanjaEditDictDialog::SetEditText(SuggestionEdit& rEdit, sal_uInt16 nEntryNum)
+ {
+ OUString aStr;
+ if( m_xSuggestions )
+ {
+ aStr = m_xSuggestions->Get(nEntryNum);
+ }
+
+ rEdit.set_text(aStr);
+ }
+
+ void HangulHanjaEditDictDialog::EditModify(const weld::Entry* pEdit, sal_uInt8 _nEntryOffset)
+ {
+ m_bModifiedSuggestions = true;
+
+ OUString aTxt( pEdit->get_text() );
+ sal_uInt16 nEntryNum = m_nTopPos + _nEntryOffset;
+ if( aTxt.isEmpty() )
+ {
+ //reset suggestion
+ if( m_xSuggestions )
+ m_xSuggestions->Reset( nEntryNum );
+ }
+ else
+ {
+ //set suggestion
+ if( !m_xSuggestions )
+ m_xSuggestions.reset(new SuggestionList);
+ m_xSuggestions->Set( aTxt, nEntryNum );
+ }
+
+ UpdateButtonStates();
+ }
+
+ HangulHanjaEditDictDialog::HangulHanjaEditDictDialog(weld::Window* pParent, HHDictList& _rDictList, sal_uInt32 nSelDict)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaeditdictdialog.ui", "HangulHanjaEditDictDialog")
+ , m_aEditHintText ( CuiResId(RID_CUISTR_EDITHINT) )
+ , m_rDictList ( _rDictList )
+ , m_nCurrentDict ( 0xFFFFFFFF )
+ , m_nTopPos ( 0 )
+ , m_bModifiedSuggestions ( false )
+ , m_bModifiedOriginal ( false )
+ , m_xBookLB(m_xBuilder->weld_combo_box("book"))
+ , m_xOriginalLB(m_xBuilder->weld_combo_box("original"))
+ , m_xEdit1(new SuggestionEdit(m_xBuilder->weld_entry("edit1"), this))
+ , m_xEdit2(new SuggestionEdit(m_xBuilder->weld_entry("edit2"), this))
+ , m_xEdit3(new SuggestionEdit(m_xBuilder->weld_entry("edit3"), this))
+ , m_xEdit4(new SuggestionEdit(m_xBuilder->weld_entry("edit4"), this))
+ , m_xContents(m_xBuilder->weld_widget("box"))
+ , m_xScrollSB(m_xBuilder->weld_scrolled_window("scrollbar", true))
+ , m_xNewPB(m_xBuilder->weld_button("new"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ {
+ Size aSize(m_xContents->get_preferred_size());
+ m_xScrollSB->set_size_request(-1, aSize.Height());
+
+ m_xEdit1->init( m_xScrollSB.get(), nullptr, m_xEdit2.get() );
+ m_xEdit2->init( m_xScrollSB.get(), m_xEdit1.get(), m_xEdit3.get() );
+ m_xEdit3->init( m_xScrollSB.get(), m_xEdit2.get(), m_xEdit4.get() );
+ m_xEdit4->init( m_xScrollSB.get(), m_xEdit3.get(), nullptr );
+
+ m_xOriginalLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, OriginalModifyHdl ) );
+
+ m_xNewPB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, NewPBPushHdl ) );
+ m_xNewPB->set_sensitive( false );
+
+ m_xDeletePB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, DeletePBPushHdl ) );
+ m_xDeletePB->set_sensitive( false );
+
+ static_assert(MAXNUM_SUGGESTIONS >= 5, "number of suggestions should not under-run the value of 5");
+
+ // 4 here, because we have 4 edits / page
+ m_xScrollSB->vadjustment_configure(0, 0, MAXNUM_SUGGESTIONS, 1, 4, 4);
+ m_xScrollSB->connect_vadjustment_changed(LINK(this, HangulHanjaEditDictDialog, ScrollHdl));
+
+ m_xEdit1->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl1 ) );
+ m_xEdit2->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl2 ) );
+ m_xEdit3->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl3 ) );
+ m_xEdit4->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl4 ) );
+
+ m_xBookLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, BookLBSelectHdl ) );
+ sal_uInt32 nDictCnt = m_rDictList.size();
+ for( sal_uInt32 n = 0 ; n < nDictCnt ; ++n )
+ {
+ Reference< XConversionDictionary > xDic( m_rDictList[n] );
+ OUString aName;
+ if( xDic.is() )
+ aName = xDic->getName();
+ m_xBookLB->append_text( aName );
+ }
+ m_xBookLB->set_active(nSelDict);
+
+ InitEditDictDialog(nSelDict);
+ }
+
+ HangulHanjaEditDictDialog::~HangulHanjaEditDictDialog()
+ {
+ }
+
+ void HangulHanjaEditDictDialog::UpdateScrollbar()
+ {
+ sal_uInt16 nPos = m_xScrollSB->vadjustment_get_value();
+ m_nTopPos = nPos;
+
+ SetEditText( *m_xEdit1, nPos++ );
+ SetEditText( *m_xEdit2, nPos++ );
+ SetEditText( *m_xEdit3, nPos++ );
+ SetEditText( *m_xEdit4, nPos );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hldocntp.cxx b/cui/source/dialogs/hldocntp.cxx
new file mode 100644
index 000000000..1c3b850b4
--- /dev/null
+++ b/cui/source/dialogs/hldocntp.cxx
@@ -0,0 +1,450 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hldocntp.hxx>
+#include <osl/file.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfilt.hxx>
+#include <svl/stritem.hxx>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Exception.hpp>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/dynamicmenuoptions.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/ucbhelper.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <cuihyperdlg.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+|*
+|* Data-struct for documenttypes in listbox
+|*
+|************************************************************************/
+
+namespace {
+
+struct DocumentTypeData
+{
+ OUString aStrURL;
+ OUString aStrExt;
+ DocumentTypeData (OUString aURL, OUString aExt) : aStrURL(std::move(aURL)), aStrExt(std::move(aExt))
+ {}
+};
+
+}
+
+bool SvxHyperlinkNewDocTp::ImplGetURLObject( const OUString& rPath, std::u16string_view rBase, INetURLObject& aURLObject ) const
+{
+ bool bIsValidURL = !rPath.isEmpty();
+ if ( bIsValidURL )
+ {
+ aURLObject.SetURL( rPath );
+ if ( aURLObject.GetProtocol() == INetProtocol::NotValid ) // test if the source is already a valid url
+ { // if not we have to create a url from a physical file name
+ bool wasAbs;
+ INetURLObject base(rBase);
+ base.setFinalSlash();
+ aURLObject = base.smartRel2Abs(
+ rPath, wasAbs, true, INetURLObject::EncodeMechanism::All,
+ RTL_TEXTENCODING_UTF8, true);
+ }
+ bIsValidURL = aURLObject.GetProtocol() != INetProtocol::NotValid;
+ if ( bIsValidURL )
+ {
+ OUString aBase( aURLObject.getName( INetURLObject::LAST_SEGMENT, false ) );
+ if ( aBase.isEmpty() || ( aBase[0] == '.' ) )
+ bIsValidURL = false;
+ }
+ if ( bIsValidURL )
+ {
+ sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
+ if (nPos != -1)
+ aURLObject.SetExtension(weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos))->aStrExt);
+ }
+
+ }
+ return bIsValidURL;
+}
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+
+SvxHyperlinkNewDocTp::SvxHyperlinkNewDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinknewdocpage.ui", "HyperlinkNewDocPage", pItemSet)
+ , m_xRbtEditNow(xBuilder->weld_radio_button("editnow"))
+ , m_xRbtEditLater(xBuilder->weld_radio_button("editlater"))
+ , m_xCbbPath(new SvxHyperURLBox(xBuilder->weld_combo_box("path")))
+ , m_xBtCreate(xBuilder->weld_button("create"))
+ , m_xLbDocTypes(xBuilder->weld_tree_view("types"))
+{
+ m_xCbbPath->SetSmartProtocol(INetProtocol::File);
+ m_xLbDocTypes->set_size_request(-1, m_xLbDocTypes->get_height_rows(5));
+
+ InitStdControls();
+
+ SetExchangeSupport ();
+
+ m_xCbbPath->show();
+ m_xCbbPath->SetBaseURL(SvtPathOptions().GetWorkPath());
+
+ // set defaults
+ m_xRbtEditNow->set_active(true);
+
+ m_xBtCreate->connect_clicked(LINK(this, SvxHyperlinkNewDocTp, ClickNewHdl_Impl));
+
+ FillDocumentList ();
+}
+
+SvxHyperlinkNewDocTp::~SvxHyperlinkNewDocTp ()
+{
+ if (m_xLbDocTypes)
+ {
+ for (sal_Int32 n = 0, nEntryCount = m_xLbDocTypes->n_children(); n < nEntryCount; ++n)
+ delete weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(n));
+ m_xLbDocTypes = nullptr;
+ }
+}
+
+/*************************************************************************
+|*
+|* Fill the all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+
+
+void SvxHyperlinkNewDocTp::FillDlgFields(const OUString& /*rStrURL*/)
+{
+}
+
+void SvxHyperlinkNewDocTp::FillDocumentList()
+{
+ weld::WaitObject aWaitObj(mpDialog->getDialog());
+
+ std::vector<SvtDynMenuEntry> aDynamicMenuEntries( SvtDynamicMenuOptions::GetMenu( EDynamicMenuType::NewMenu ) );
+
+ for ( const SvtDynMenuEntry & rDynamicMenuEntry : aDynamicMenuEntries )
+ {
+ OUString aDocumentUrl = rDynamicMenuEntry.sURL;
+ OUString aTitle = rDynamicMenuEntry.sTitle;
+
+ //#i96822# business cards, labels and database should not be inserted here
+ if( aDocumentUrl == "private:factory/swriter?slot=21051" ||
+ aDocumentUrl == "private:factory/swriter?slot=21052" ||
+ aDocumentUrl == "private:factory/sdatabase?Interactive" )
+ continue;
+
+ // Insert into listbox
+ if ( !aDocumentUrl.isEmpty() )
+ {
+ if ( aDocumentUrl == "private:factory/simpress?slot=6686" ) // SJ: #106216# do not start
+ aDocumentUrl = "private:factory/simpress"; // the AutoPilot for impress
+
+ // insert private-url and default-extension as user-data
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl );
+ if ( pFilter )
+ {
+ // insert doc-name and image
+ OUString aTitleName = aTitle.replaceFirst( "~", "" );
+
+ OUString aStrDefExt(pFilter->GetDefaultExtension());
+ DocumentTypeData *pTypeData = new DocumentTypeData(aDocumentUrl, aStrDefExt.copy(2));
+ OUString sId(weld::toId(pTypeData));
+ m_xLbDocTypes->append(sId, aTitleName);
+ }
+ }
+ }
+ m_xLbDocTypes->select(0);
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+
+void SvxHyperlinkNewDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ // get data from dialog-controls
+ rStrURL = m_xCbbPath->get_active_text();
+ INetURLObject aURL;
+ if ( ImplGetURLObject( rStrURL, m_xCbbPath->GetBaseURL(), aURL ) )
+ {
+ rStrURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+
+std::unique_ptr<IconChoicePage> SvxHyperlinkNewDocTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkNewDocTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkNewDocTp::SetInitFocus()
+{
+ m_xCbbPath->grab_focus();
+}
+
+namespace
+{
+ struct ExecuteInfo
+ {
+ bool bRbtEditLater;
+ bool bRbtEditNow;
+ INetURLObject aURL;
+ OUString aStrDocName;
+ // current document
+ css::uno::Reference<css::frame::XFrame> xFrame;
+ SfxDispatcher* pDispatcher;
+ };
+}
+
+IMPL_STATIC_LINK(SvxHyperlinkNewDocTp, DispatchDocument, void*, p, void)
+{
+ std::unique_ptr<ExecuteInfo> xExecuteInfo(static_cast<ExecuteInfo*>(p));
+ if (!xExecuteInfo->xFrame.is())
+ return;
+ try
+ {
+ //if it throws dispatcher is invalid
+ css::uno::Reference<css::awt::XTopWindow>(xExecuteInfo->xFrame->getContainerWindow(), css::uno::UNO_QUERY_THROW);
+
+ SfxViewFrame *pViewFrame = nullptr;
+
+ // create items
+ SfxStringItem aName( SID_FILE_NAME, xExecuteInfo->aStrDocName );
+ SfxStringItem aReferer( SID_REFERER, "private:user" );
+ SfxStringItem aFrame( SID_TARGETNAME, "_blank");
+
+ OUString aStrFlags('S');
+ if (xExecuteInfo->bRbtEditLater)
+ {
+ aStrFlags += "H";
+ }
+ SfxStringItem aFlags (SID_OPTIONS, aStrFlags);
+
+ // open url
+ const SfxPoolItem* pReturn = xExecuteInfo->pDispatcher->ExecuteList(
+ SID_OPENDOC, SfxCallMode::SYNCHRON,
+ { &aName, &aFlags, &aFrame, &aReferer });
+
+ // save new doc
+ const SfxViewFrameItem *pItem = dynamic_cast<const SfxViewFrameItem*>( pReturn ); // SJ: pReturn is NULL if the Hyperlink
+ if ( pItem ) // creation is cancelled #106216#
+ {
+ pViewFrame = pItem->GetFrame();
+ if (pViewFrame)
+ {
+ SfxStringItem aNewName( SID_FILE_NAME, xExecuteInfo->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ SfxUnoFrameItem aDocFrame( SID_FILLFRAME, pViewFrame->GetFrame().GetFrameInterface() );
+ fprintf(stderr, "is there a frame int %p\n", pViewFrame->GetFrame().GetFrameInterface().get() );
+ pViewFrame->GetDispatcher()->ExecuteList(
+ SID_SAVEASDOC, SfxCallMode::SYNCHRON,
+ { &aNewName }, { &aDocFrame });
+ }
+ }
+
+ if (xExecuteInfo->bRbtEditNow)
+ {
+ css::uno::Reference<css::awt::XTopWindow> xWindow(xExecuteInfo->xFrame->getContainerWindow(), css::uno::UNO_QUERY);
+ if (xWindow.is()) //will be false if the frame was exited while the document was loading (e.g. we waited for warning dialogs)
+ xWindow->toFront();
+ }
+
+ if (pViewFrame && xExecuteInfo->bRbtEditLater)
+ {
+ SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
+ pObjShell->DoClose();
+ }
+ }
+ catch (...)
+ {
+ }
+}
+
+/*************************************************************************
+|*
+|* Any action to do after apply-button is pressed
+|*
+\************************************************************************/
+void SvxHyperlinkNewDocTp::DoApply()
+{
+ weld::WaitObject aWait(mpDialog->getDialog());
+
+ // get data from dialog-controls
+ OUString aStrNewName = m_xCbbPath->get_active_text();
+
+ if ( aStrNewName.isEmpty() )
+ aStrNewName = maStrInitURL;
+
+ // create a real URL-String
+ INetURLObject aURL;
+ if ( !ImplGetURLObject( aStrNewName, m_xCbbPath->GetBaseURL(), aURL ) )
+ return;
+
+ // create Document
+ aStrNewName = aURL.GetURLPath( INetURLObject::DecodeMechanism::NONE );
+ bool bCreate = true;
+ try
+ {
+ // check if file exists, warn before we overwrite it
+ std::unique_ptr<SvStream> pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ );
+
+ bool bOk = pIStm && ( pIStm->GetError() == ERRCODE_NONE);
+
+ pIStm.reset();
+
+ if( bOk )
+ {
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(mpDialog->getDialog(),
+ VclMessageType::Warning, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_HYPERDLG_QUERYOVERWRITE)));
+ bCreate = xWarn->run() == RET_YES;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ if (!bCreate || aStrNewName.isEmpty())
+ return;
+
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+
+ pExecuteInfo->bRbtEditLater = m_xRbtEditLater->get_active();
+ pExecuteInfo->bRbtEditNow = m_xRbtEditNow->get_active();
+ // get private-url
+ sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
+ if (nPos == -1)
+ nPos = 0;
+ pExecuteInfo->aURL = aURL;
+ pExecuteInfo->aStrDocName = weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos))->aStrURL;
+
+ // current document
+ pExecuteInfo->xFrame = GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface();
+ pExecuteInfo->pDispatcher = GetDispatcher();
+
+ Application::PostUserEvent(LINK(nullptr, SvxHyperlinkNewDocTp, DispatchDocument), pExecuteInfo);
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : new
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkNewDocTp, ClickNewHdl_Impl, weld::Button&, void)
+{
+ DisableClose( true );
+ uno::Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference < XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, mpDialog->getDialog());
+
+ OUString aStrURL;
+ OUString aTempStrURL( m_xCbbPath->get_active_text() );
+ osl::FileBase::getFileURLFromSystemPath( aTempStrURL, aStrURL );
+
+ OUString aStrPath = aStrURL;
+ bool bZeroPath = aStrPath.isEmpty();
+ bool bHandleFileName = bZeroPath; // when path has length of 0, then the rest should always be handled
+ // as file name, otherwise we do not yet know
+
+ if( bZeroPath )
+ aStrPath = SvtPathOptions().GetWorkPath();
+ else if( !::utl::UCBContentHelper::IsFolder( aStrURL ) )
+ bHandleFileName = true;
+
+ xFolderPicker->setDisplayDirectory( aStrPath );
+ sal_Int16 nResult = xFolderPicker->execute();
+ DisableClose( false );
+ if( ExecutableDialogResults::OK != nResult )
+ return;
+
+ char const sSlash[] = "/";
+
+ INetURLObject aURL( aStrURL, INetProtocol::File );
+ OUString aStrName;
+ if( bHandleFileName )
+ aStrName = bZeroPath? aTempStrURL : aURL.getName();
+
+ m_xCbbPath->SetBaseURL( xFolderPicker->getDirectory() );
+ OUString aStrTmp( xFolderPicker->getDirectory() );
+
+ if( aStrTmp[ aStrTmp.getLength() - 1 ] != sSlash[0] )
+ aStrTmp += sSlash;
+
+ // append old file name
+ if( bHandleFileName )
+ aStrTmp += aStrName;
+
+ INetURLObject aNewURL( aStrTmp );
+
+ if (!aStrName.isEmpty() && !aNewURL.getExtension().isEmpty() &&
+ m_xLbDocTypes->get_selected_index() != -1)
+ {
+ // get private-url
+ const sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
+ aNewURL.setExtension(weld::fromId<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos))->aStrExt);
+ }
+
+ if( aNewURL.GetProtocol() == INetProtocol::File )
+ {
+ osl::FileBase::getSystemPathFromFileURL(aNewURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aStrTmp);
+ }
+ else
+ {
+ aStrTmp = aNewURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
+ }
+
+ m_xCbbPath->set_entry_text( aStrTmp );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hldoctp.cxx b/cui/source/dialogs/hldoctp.cxx
new file mode 100644
index 000000000..5da741202
--- /dev/null
+++ b/cui/source/dialogs/hldoctp.cxx
@@ -0,0 +1,317 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cuihyperdlg.hxx>
+#include <osl/file.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <hldoctp.hxx>
+#include <hlmarkwn_def.hxx>
+
+char const sHash[] = "#";
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+
+SvxHyperlinkDocTp::SvxHyperlinkDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinkdocpage.ui", "HyperlinkDocPage", pItemSet)
+ , m_xCbbPath(new SvxHyperURLBox(xBuilder->weld_combo_box("path")))
+ , m_xBtFileopen(xBuilder->weld_button("fileopen"))
+ , m_xEdTarget(xBuilder->weld_entry("target"))
+ , m_xFtFullURL(xBuilder->weld_label("url"))
+ , m_xBtBrowse(xBuilder->weld_button("browse"))
+ , m_bMarkWndOpen(false)
+{
+ m_xCbbPath->SetSmartProtocol(INetProtocol::File);
+
+ InitStdControls();
+
+ m_xCbbPath->show();
+ m_xCbbPath->SetBaseURL(INET_FILE_SCHEME);
+
+ SetExchangeSupport();
+
+ // set handlers
+ m_xBtFileopen->connect_clicked( LINK ( this, SvxHyperlinkDocTp, ClickFileopenHdl_Impl ) );
+ m_xBtBrowse->connect_clicked( LINK ( this, SvxHyperlinkDocTp, ClickTargetHdl_Impl ) );
+ m_xCbbPath->connect_changed( LINK ( this, SvxHyperlinkDocTp, ModifiedPathHdl_Impl ) );
+ m_xEdTarget->connect_changed( LINK ( this, SvxHyperlinkDocTp, ModifiedTargetHdl_Impl ) );
+
+ m_xCbbPath->connect_focus_out( LINK ( this, SvxHyperlinkDocTp, LostFocusPathHdl_Impl ) );
+
+ maTimer.SetInvokeHandler ( LINK ( this, SvxHyperlinkDocTp, TimeoutHdl_Impl ) );
+}
+
+SvxHyperlinkDocTp::~SvxHyperlinkDocTp()
+{
+}
+
+/*************************************************************************
+|*
+|* Fill all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::FillDlgFields(const OUString& rStrURL)
+{
+ sal_Int32 nPos = rStrURL.indexOf(sHash);
+ // path
+ m_xCbbPath->set_entry_text( rStrURL.copy( 0, ( nPos == -1 ? rStrURL.getLength() : nPos ) ) );
+
+ // set target in document at editfield
+ OUString aStrMark;
+ if ( nPos != -1 && nPos < rStrURL.getLength()-1 )
+ aStrMark = rStrURL.copy( nPos+1 );
+ m_xEdTarget->set_text( aStrMark );
+
+ ModifiedPathHdl_Impl(*m_xCbbPath->getWidget());
+}
+
+/*************************************************************************
+|*
+|* retrieve current url-string
+|*
+|************************************************************************/
+OUString SvxHyperlinkDocTp::GetCurrentURL () const
+{
+ // get data from dialog-controls
+ OUString aStrURL;
+ OUString aStrPath( m_xCbbPath->get_active_text() );
+ OUString aStrMark( m_xEdTarget->get_text() );
+
+ if ( !aStrPath.isEmpty() )
+ {
+ INetURLObject aURL( aStrPath );
+ if ( aURL.GetProtocol() != INetProtocol::NotValid ) // maybe the path is already a valid
+ aStrURL = aStrPath; // hyperlink, then we can use this path directly
+ else
+ {
+ osl::FileBase::getFileURLFromSystemPath( aStrPath, aStrURL );
+ aStrURL = INetURLObject::decode(aStrURL, INetURLObject::DecodeMechanism::ToIUri, RTL_TEXTENCODING_UTF8);
+ }
+
+ //#105788# always create a URL even if it is not valid
+ if( aStrURL.isEmpty() )
+ aStrURL = aStrPath;
+ }
+
+ if( !aStrMark.isEmpty() )
+ {
+ aStrURL += sHash + aStrMark;
+ }
+
+ return aStrURL;
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ // get data from standard-fields
+ rStrURL = GetCurrentURL();
+
+ if( rStrURL.equalsIgnoreAsciiCase( INET_FILE_SCHEME ) )
+ rStrURL.clear();
+
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+std::unique_ptr<IconChoicePage> SvxHyperlinkDocTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkDocTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::SetInitFocus()
+{
+ m_xCbbPath->grab_focus();
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : fileopen
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ClickFileopenHdl_Impl, weld::Button&, void)
+{
+ DisableClose( true );
+ // Open Fileopen-Dialog
+ sfx2::FileDialogHelper aDlg(
+ css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE,
+ mpDialog->getDialog() );
+ OUString aOldURL( GetCurrentURL() );
+ if( aOldURL.startsWithIgnoreAsciiCase( INET_FILE_SCHEME ) )
+ {
+ OUString aPath;
+ osl::FileBase::getSystemPathFromFileURL(aOldURL, aPath);
+ aDlg.SetDisplayFolder( aPath );
+ }
+
+ ErrCode nError = aDlg.Execute();
+ DisableClose( false );
+
+ if ( ERRCODE_NONE != nError )
+ return;
+
+ OUString aURL( aDlg.GetPath() );
+ OUString aPath;
+
+ osl::FileBase::getSystemPathFromFileURL(aURL, aPath);
+
+ m_xCbbPath->SetBaseURL( aURL );
+ m_xCbbPath->set_entry_text(aPath);
+
+ if ( aOldURL != GetCurrentURL() )
+ ModifiedPathHdl_Impl(*m_xCbbPath->getWidget());
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : target
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ClickTargetHdl_Impl, weld::Button&, void)
+{
+ ShowMarkWnd();
+
+ if ( GetPathType ( maStrURL ) == EPathType::ExistsFile ||
+ maStrURL.isEmpty() ||
+ maStrURL.equalsIgnoreAsciiCase( INET_FILE_SCHEME ) ||
+ maStrURL.startsWith( sHash ) )
+ {
+ mxMarkWnd->SetError( LERR_NOERROR );
+
+ weld::WaitObject aWait(mpDialog->getDialog());
+
+ if ( maStrURL.equalsIgnoreAsciiCase( INET_FILE_SCHEME ) )
+ mxMarkWnd->RefreshTree ( "" );
+ else
+ mxMarkWnd->RefreshTree ( maStrURL );
+ }
+ else
+ mxMarkWnd->SetError( LERR_DOCNOTOPEN );
+}
+
+/*************************************************************************
+|*
+|* Contents of combobox "Path" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ModifiedPathHdl_Impl, weld::ComboBox&, void)
+{
+ maStrURL = GetCurrentURL();
+
+ maTimer.SetTimeout( 2500 );
+ maTimer.Start();
+
+ m_xFtFullURL->set_label( maStrURL );
+}
+
+/*************************************************************************
+|*
+|* If path-field was modify, to browse the new doc after timeout
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, TimeoutHdl_Impl, Timer *, void)
+{
+ if ( IsMarkWndVisible() && ( GetPathType( maStrURL )== EPathType::ExistsFile ||
+ maStrURL.isEmpty() ||
+ maStrURL.equalsIgnoreAsciiCase( INET_FILE_SCHEME ) ) )
+ {
+ weld::WaitObject aWait(mpDialog->getDialog());
+
+ if ( maStrURL.equalsIgnoreAsciiCase( INET_FILE_SCHEME ) )
+ mxMarkWnd->RefreshTree ( "" );
+ else
+ mxMarkWnd->RefreshTree ( maStrURL );
+ }
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "Target" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ModifiedTargetHdl_Impl, weld::Entry&, void)
+{
+ maStrURL = GetCurrentURL();
+
+ if (IsMarkWndVisible())
+ mxMarkWnd->SelectEntry(m_xEdTarget->get_text());
+
+ m_xFtFullURL->set_label( maStrURL );
+}
+
+/*************************************************************************
+|*
+|* editfield "Target" lost focus
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, LostFocusPathHdl_Impl, weld::Widget&, void)
+{
+ maStrURL = GetCurrentURL();
+
+ m_xFtFullURL->set_label( maStrURL );
+}
+
+/*************************************************************************
+|*
+|* Get String from Bookmark-Wnd
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::SetMarkStr ( const OUString& aStrMark )
+{
+ m_xEdTarget->set_text(aStrMark);
+
+ ModifiedTargetHdl_Impl ( *m_xEdTarget );
+}
+
+/*************************************************************************
+|*
+|* retrieve kind of pathstr
+|*
+|************************************************************************/
+SvxHyperlinkDocTp::EPathType SvxHyperlinkDocTp::GetPathType ( std::u16string_view rStrPath )
+{
+ INetURLObject aURL( rStrPath, INetProtocol::File );
+
+ if( aURL.HasError() )
+ return EPathType::Invalid;
+ else
+ return EPathType::ExistsFile;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hlinettp.cxx b/cui/source/dialogs/hlinettp.cxx
new file mode 100644
index 000000000..3a0f431ac
--- /dev/null
+++ b/cui/source/dialogs/hlinettp.cxx
@@ -0,0 +1,389 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/string_view.hxx>
+#include <unotools/useroptions.hxx>
+#include <svl/adrparse.hxx>
+
+#include <hlinettp.hxx>
+#include <hlmarkwn_def.hxx>
+
+constexpr OUStringLiteral sAnonymous = u"anonymous";
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+SvxHyperlinkInternetTp::SvxHyperlinkInternetTp(weld::Container* pParent,
+ SvxHpLinkDlg* pDlg,
+ const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinkinternetpage.ui", "HyperlinkInternetPage",
+ pItemSet)
+ , m_bMarkWndOpen(false)
+ , m_xRbtLinktypInternet(xBuilder->weld_radio_button("linktyp_internet"))
+ , m_xRbtLinktypFTP(xBuilder->weld_radio_button("linktyp_ftp"))
+ , m_xCbbTarget(new SvxHyperURLBox(xBuilder->weld_combo_box("target")))
+ , m_xFtTarget(xBuilder->weld_label("target_label"))
+ , m_xFtLogin(xBuilder->weld_label("login_label"))
+ , m_xEdLogin(xBuilder->weld_entry("login"))
+ , m_xFtPassword(xBuilder->weld_label("password_label"))
+ , m_xEdPassword(xBuilder->weld_entry("password"))
+ , m_xCbAnonymous(xBuilder->weld_check_button("anonymous"))
+{
+ // gtk_size_group_set_ignore_hidden, "Measuring the size of hidden widgets
+ // ... they will report a size of 0 nowadays, and thus, their size will
+ // not affect the other size group members", which is unfortunate. So here
+ // before we hide the labels, take the size group width and set it as
+ // explicit preferred size on a label that won't be hidden
+ auto nLabelWidth = m_xFtTarget->get_preferred_size().Width();
+ m_xFtTarget->set_size_request(nLabelWidth, -1);
+
+ m_xCbbTarget->SetSmartProtocol(INetProtocol::Http);
+
+ InitStdControls();
+
+ m_xCbbTarget->show();
+
+ SetExchangeSupport ();
+
+ // set defaults
+ m_xRbtLinktypInternet->set_active(true);
+
+ // set handlers
+ Link<weld::Toggleable&, void> aLink( LINK ( this, SvxHyperlinkInternetTp, Click_SmartProtocol_Impl ) );
+ m_xRbtLinktypInternet->connect_toggled( aLink );
+ m_xRbtLinktypFTP->connect_toggled( aLink );
+ m_xCbAnonymous->connect_toggled( LINK ( this, SvxHyperlinkInternetTp, ClickAnonymousHdl_Impl ) );
+ m_xEdLogin->connect_changed( LINK ( this, SvxHyperlinkInternetTp, ModifiedLoginHdl_Impl ) );
+ m_xCbbTarget->connect_focus_out( LINK ( this, SvxHyperlinkInternetTp, LostFocusTargetHdl_Impl ) );
+ m_xCbbTarget->connect_changed( LINK ( this, SvxHyperlinkInternetTp, ModifiedTargetHdl_Impl ) );
+ maTimer.SetInvokeHandler ( LINK ( this, SvxHyperlinkInternetTp, TimeoutHdl_Impl ) );
+}
+
+SvxHyperlinkInternetTp::~SvxHyperlinkInternetTp()
+{
+}
+
+/*************************************************************************
+|*
+|* Fill the all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+void SvxHyperlinkInternetTp::FillDlgFields(const OUString& rStrURL)
+{
+ INetURLObject aURL(rStrURL);
+ OUString aStrScheme(GetSchemeFromURL(rStrURL));
+
+ // set additional controls for FTP: Username / Password
+ if (aStrScheme.startsWith(INET_FTP_SCHEME))
+ {
+ if ( aURL.GetUser().toAsciiLowerCase().startsWith( sAnonymous ) )
+ setAnonymousFTPUser();
+ else
+ setFTPUser(aURL.GetUser(), aURL.GetPass());
+
+ //do not show password and user in url
+ if(!aURL.GetUser().isEmpty() || !aURL.GetPass().isEmpty() )
+ aURL.SetUserAndPass(u"", u"");
+ }
+
+ // set URL-field
+ // Show the scheme, #72740
+ if ( aURL.GetProtocol() != INetProtocol::NotValid )
+ m_xCbbTarget->set_entry_text( aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ) );
+ else
+ m_xCbbTarget->set_entry_text(rStrURL);
+
+ SetScheme(aStrScheme);
+}
+
+void SvxHyperlinkInternetTp::setAnonymousFTPUser()
+{
+ m_xEdLogin->set_text(sAnonymous);
+ SvAddressParser aAddress(SvtUserOptions().GetEmail());
+ m_xEdPassword->set_text(aAddress.Count() ? aAddress.GetEmailAddress(0) : OUString());
+
+ m_xFtLogin->set_sensitive(false);
+ m_xFtPassword->set_sensitive(false);
+ m_xEdLogin->set_sensitive(false);
+ m_xEdPassword->set_sensitive(false);
+ m_xCbAnonymous->set_active(true);
+}
+
+void SvxHyperlinkInternetTp::setFTPUser(const OUString& rUser, const OUString& rPassword)
+{
+ m_xEdLogin->set_text(rUser);
+ m_xEdPassword->set_text(rPassword);
+
+ m_xFtLogin->set_sensitive(true);
+ m_xFtPassword->set_sensitive(true);
+ m_xEdLogin->set_sensitive(true);
+ m_xEdPassword->set_sensitive(true);
+ m_xCbAnonymous->set_active(false);
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+
+void SvxHyperlinkInternetTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ rStrURL = CreateAbsoluteURL();
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+OUString SvxHyperlinkInternetTp::CreateAbsoluteURL() const
+{
+ // erase leading and trailing whitespaces
+ OUString aStrURL(m_xCbbTarget->get_active_text().trim());
+
+ INetURLObject aURL(aStrURL, GetSmartProtocolFromButtons());
+
+ // username and password for ftp-url
+ if( aURL.GetProtocol() == INetProtocol::Ftp && !m_xEdLogin->get_text().isEmpty() )
+ aURL.SetUserAndPass ( m_xEdLogin->get_text(), m_xEdPassword->get_text() );
+
+ if ( aURL.GetProtocol() != INetProtocol::NotValid )
+ return aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+ else //#105788# always create a URL even if it is not valid
+ return aStrURL;
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+
+std::unique_ptr<IconChoicePage> SvxHyperlinkInternetTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkInternetTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkInternetTp::SetInitFocus()
+{
+ m_xCbbTarget->grab_focus();
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "Target" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, ModifiedTargetHdl_Impl, weld::ComboBox&, void)
+{
+ OUString aScheme = GetSchemeFromURL( m_xCbbTarget->get_active_text() );
+ if( !aScheme.isEmpty() )
+ SetScheme( aScheme );
+
+ // start timer
+ maTimer.SetTimeout( 2500 );
+ maTimer.Start();
+}
+
+/*************************************************************************
+|*
+|* If target-field was modify, to browse the new doc after timeout
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, TimeoutHdl_Impl, Timer *, void)
+{
+ RefreshMarkWindow();
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "Login" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, ModifiedLoginHdl_Impl, weld::Entry&, void)
+{
+ OUString aStrLogin ( m_xEdLogin->get_text() );
+ if ( aStrLogin.equalsIgnoreAsciiCase( sAnonymous ) )
+ {
+ m_xCbAnonymous->set_active(true);
+ ClickAnonymousHdl_Impl(*m_xCbAnonymous);
+ }
+}
+
+void SvxHyperlinkInternetTp::SetScheme(std::u16string_view rScheme)
+{
+ //if rScheme is empty or unknown the default behaviour is like it where HTTP
+ bool bFTP = o3tl::starts_with(rScheme, INET_FTP_SCHEME);
+ bool bInternet = !bFTP;
+
+ //update protocol button selection:
+ m_xRbtLinktypFTP->set_active(bFTP);
+ m_xRbtLinktypInternet->set_active(bInternet);
+
+ //update target:
+ RemoveImproperProtocol(rScheme);
+ m_xCbbTarget->SetSmartProtocol( GetSmartProtocolFromButtons() );
+
+ //show/hide special fields for FTP:
+ m_xFtLogin->set_visible( bFTP );
+ m_xFtPassword->set_visible( bFTP );
+ m_xEdLogin->set_visible( bFTP );
+ m_xEdPassword->set_visible( bFTP );
+ m_xCbAnonymous->set_visible( bFTP );
+
+ //update 'link target in document'-window and opening-button
+ if (o3tl::starts_with(rScheme, INET_HTTP_SCHEME) || rScheme.empty())
+ {
+ if ( m_bMarkWndOpen )
+ ShowMarkWnd ();
+ }
+ else
+ {
+ //disable for https and ftp
+ if ( m_bMarkWndOpen )
+ HideMarkWnd ();
+ }
+}
+
+/*************************************************************************
+|*
+|* Remove protocol if it does not fit to the current button selection
+|*
+|************************************************************************/
+
+void SvxHyperlinkInternetTp::RemoveImproperProtocol(std::u16string_view aProperScheme)
+{
+ OUString aStrURL ( m_xCbbTarget->get_active_text() );
+ if ( !aStrURL.isEmpty() )
+ {
+ OUString aStrScheme(GetSchemeFromURL(aStrURL));
+ if ( !aStrScheme.isEmpty() && aStrScheme != aProperScheme )
+ {
+ aStrURL = aStrURL.copy( aStrScheme.getLength() );
+ m_xCbbTarget->set_entry_text( aStrURL );
+ }
+ }
+}
+
+OUString SvxHyperlinkInternetTp::GetSchemeFromButtons() const
+{
+ if( m_xRbtLinktypFTP->get_active() )
+ return INET_FTP_SCHEME;
+ return INET_HTTP_SCHEME;
+}
+
+INetProtocol SvxHyperlinkInternetTp::GetSmartProtocolFromButtons() const
+{
+ if( m_xRbtLinktypFTP->get_active() )
+ {
+ return INetProtocol::Ftp;
+ }
+ return INetProtocol::Http;
+}
+
+/*************************************************************************
+|*
+|* Click on Radiobutton : Internet or FTP
+|*
+|************************************************************************/
+IMPL_LINK(SvxHyperlinkInternetTp, Click_SmartProtocol_Impl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ OUString aScheme = GetSchemeFromButtons();
+ SetScheme(aScheme);
+}
+
+/*************************************************************************
+|*
+|* Click on Checkbox : Anonymous user
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, ClickAnonymousHdl_Impl, weld::Toggleable&, void)
+{
+ // disable login-editfields if checked
+ if ( m_xCbAnonymous->get_active() )
+ {
+ if ( m_xEdLogin->get_text().toAsciiLowerCase().startsWith( sAnonymous ) )
+ {
+ maStrOldUser.clear();
+ maStrOldPassword.clear();
+ }
+ else
+ {
+ maStrOldUser = m_xEdLogin->get_text();
+ maStrOldPassword = m_xEdPassword->get_text();
+ }
+
+ setAnonymousFTPUser();
+ }
+ else
+ setFTPUser(maStrOldUser, maStrOldPassword);
+}
+
+/*************************************************************************
+|*
+|* Combobox Target lost the focus
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, LostFocusTargetHdl_Impl, weld::Widget&, void)
+{
+ RefreshMarkWindow();
+}
+
+void SvxHyperlinkInternetTp::RefreshMarkWindow()
+{
+ if (m_xRbtLinktypInternet->get_active() && IsMarkWndVisible())
+ {
+ weld::WaitObject aWait(mpDialog->getDialog());
+ OUString aStrURL( CreateAbsoluteURL() );
+ if ( !aStrURL.isEmpty() )
+ mxMarkWnd->RefreshTree ( aStrURL );
+ else
+ mxMarkWnd->SetError( LERR_DOCNOTOPEN );
+ }
+}
+
+/*************************************************************************
+|*
+|* Get String from Bookmark-Wnd
+|*
+|************************************************************************/
+void SvxHyperlinkInternetTp::SetMarkStr ( const OUString& aStrMark )
+{
+ OUString aStrURL(m_xCbbTarget->get_active_text());
+
+ const sal_Unicode sUHash = '#';
+ sal_Int32 nPos = aStrURL.lastIndexOf( sUHash );
+
+ if( nPos != -1 )
+ aStrURL = aStrURL.copy(0, nPos);
+
+ aStrURL += OUStringChar(sUHash) + aStrMark;
+
+ m_xCbbTarget->set_entry_text(aStrURL);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hlmailtp.cxx b/cui/source/dialogs/hlmailtp.cxx
new file mode 100644
index 000000000..f02a8f765
--- /dev/null
+++ b/cui/source/dialogs/hlmailtp.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/request.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <hlmailtp.hxx>
+
+#include <comphelper/lok.hxx>
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+SvxHyperlinkMailTp::SvxHyperlinkMailTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinkmailpage.ui", "HyperlinkMailPage", pItemSet)
+ , m_xCbbReceiver(new SvxHyperURLBox(xBuilder->weld_combo_box("receiver")))
+ , m_xBtAdrBook(xBuilder->weld_button("addressbook"))
+ , m_xFtSubject(xBuilder->weld_label("subject_label"))
+ , m_xEdSubject(xBuilder->weld_entry("subject"))
+{
+ m_xCbbReceiver->SetSmartProtocol(INetProtocol::Mailto);
+
+ InitStdControls();
+
+ m_xCbbReceiver->show();
+
+ SetExchangeSupport ();
+
+ // set handlers
+ m_xBtAdrBook->connect_clicked( LINK ( this, SvxHyperlinkMailTp, ClickAdrBookHdl_Impl ) );
+ m_xCbbReceiver->connect_changed( LINK ( this, SvxHyperlinkMailTp, ModifiedReceiverHdl_Impl) );
+
+ if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) ||
+ comphelper::LibreOfficeKit::isActive() )
+ m_xBtAdrBook->hide();
+}
+
+SvxHyperlinkMailTp::~SvxHyperlinkMailTp()
+{
+}
+
+/*************************************************************************
+|*
+|* Fill the all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+
+void SvxHyperlinkMailTp::FillDlgFields(const OUString& rStrURL)
+{
+ OUString aStrScheme = GetSchemeFromURL(rStrURL);
+
+ // set URL-field and additional controls
+ OUString aStrURLc (rStrURL);
+ // set additional controls for EMail:
+ if ( aStrScheme.startsWith( INET_MAILTO_SCHEME ) )
+ {
+ // Find mail-subject
+ OUString aStrSubject, aStrTmp( aStrURLc );
+
+ sal_Int32 nPos = aStrTmp.toAsciiLowerCase().indexOf( "subject" );
+
+ if ( nPos != -1 )
+ nPos = aStrTmp.indexOf( '=', nPos );
+
+ if ( nPos != -1 )
+ aStrSubject = aStrURLc.copy( nPos+1 );
+
+ nPos = aStrURLc.indexOf( '?' );
+
+ if ( nPos != -1 )
+ aStrURLc = aStrURLc.copy( 0, nPos );
+
+ m_xEdSubject->set_text( aStrSubject );
+ }
+ else
+ {
+ m_xEdSubject->set_text("");
+ }
+
+ m_xCbbReceiver->set_entry_text(aStrURLc);
+
+ SetScheme( aStrScheme );
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+void SvxHyperlinkMailTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ rStrURL = CreateAbsoluteURL();
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+OUString SvxHyperlinkMailTp::CreateAbsoluteURL() const
+{
+ OUString aStrURL = m_xCbbReceiver->get_active_text();
+ INetURLObject aURL(aStrURL, INetProtocol::Mailto);
+
+ // subject for EMail-url
+ if( aURL.GetProtocol() == INetProtocol::Mailto )
+ {
+ if (!m_xEdSubject->get_text().isEmpty())
+ {
+ OUString aQuery = "subject=" + m_xEdSubject->get_text();
+ aURL.SetParam(aQuery);
+ }
+ }
+
+ if ( aURL.GetProtocol() != INetProtocol::NotValid )
+ return aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
+ else //#105788# always create a URL even if it is not valid
+ return aStrURL;
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+
+std::unique_ptr<IconChoicePage> SvxHyperlinkMailTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkMailTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkMailTp::SetInitFocus()
+{
+ m_xCbbReceiver->grab_focus();
+}
+
+/*************************************************************************
+|************************************************************************/
+void SvxHyperlinkMailTp::SetScheme(std::u16string_view rScheme)
+{
+ //update target:
+ RemoveImproperProtocol(rScheme);
+ m_xCbbReceiver->SetSmartProtocol( INetProtocol::Mailto );
+
+ //show/hide special fields for MAIL:
+ m_xBtAdrBook->set_sensitive(true);
+ m_xEdSubject->set_sensitive(true);
+}
+
+/*************************************************************************
+|*
+|* Remove protocol if it does not fit to the current button selection
+|*
+|************************************************************************/
+void SvxHyperlinkMailTp::RemoveImproperProtocol(std::u16string_view aProperScheme)
+{
+ OUString aStrURL(m_xCbbReceiver->get_active_text());
+ if ( !aStrURL.isEmpty() )
+ {
+ OUString aStrScheme = GetSchemeFromURL( aStrURL );
+ if ( !aStrScheme.isEmpty() && aStrScheme != aProperScheme )
+ {
+ aStrURL = aStrURL.copy( aStrScheme.getLength() );
+ m_xCbbReceiver->set_entry_text(aStrURL);
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "receiver" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkMailTp, ModifiedReceiverHdl_Impl, weld::ComboBox&, void)
+{
+ OUString aScheme = GetSchemeFromURL( m_xCbbReceiver->get_active_text() );
+ if(!aScheme.isEmpty())
+ SetScheme( aScheme );
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : addressbook
+|*
+|************************************************************************/
+IMPL_STATIC_LINK_NOARG(SvxHyperlinkMailTp, ClickAdrBookHdl_Impl, weld::Button&, void)
+{
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if( pViewFrame )
+ {
+ SfxItemPool &rPool = pViewFrame->GetPool();
+ SfxRequest aReq(SID_VIEW_DATA_SOURCE_BROWSER, SfxCallMode::SLOT, rPool);
+ pViewFrame->ExecuteSlot( aReq, true );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hlmarkwn.cxx b/cui/source/dialogs/hlmarkwn.cxx
new file mode 100644
index 000000000..ff7730db5
--- /dev/null
+++ b/cui/source/dialogs/hlmarkwn.cxx
@@ -0,0 +1,520 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dialmgr.hxx>
+#include <o3tl/any.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <unotools/viewoptions.hxx>
+#include <vcl/graph.hxx>
+
+// UNO-Stuff
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/document/XLinkTargetSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/io/IOException.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <strings.hrc>
+#include <hlmarkwn.hxx>
+#include <hltpbase.hxx>
+#include <hlmarkwn_def.hxx>
+
+#include <stack>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+// Userdata-struct for tree-entries
+struct TargetData
+{
+ OUString aUStrLinkname;
+ bool bIsTarget;
+
+ TargetData (const OUString& aUStrLName, bool bTarget)
+ : bIsTarget(bTarget)
+ {
+ if (bIsTarget)
+ aUStrLinkname = aUStrLName;
+ }
+};
+
+}
+
+//*** Window-Class ***
+// Constructor / Destructor
+SvxHlinkDlgMarkWnd::SvxHlinkDlgMarkWnd(weld::Window* pParentDialog, SvxHyperlinkTabPageBase *pParentPage)
+ : GenericDialogController(pParentDialog, "cui/ui/hyperlinkmarkdialog.ui", "HyperlinkMark")
+ , mpParent(pParentPage)
+ , mnError(LERR_NOERROR)
+ , mxBtApply(m_xBuilder->weld_button("ok"))
+ , mxBtClose(m_xBuilder->weld_button("close"))
+ , mxLbTree(m_xBuilder->weld_tree_view("TreeListBox"))
+ , mxError(m_xBuilder->weld_label("error"))
+{
+ mxLbTree->set_size_request(mxLbTree->get_approximate_digit_width() * 25,
+ mxLbTree->get_height_rows(12));
+ mxBtApply->connect_clicked( LINK ( this, SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl ) );
+ mxBtClose->connect_clicked( LINK ( this, SvxHlinkDlgMarkWnd, ClickCloseHdl_Impl ) );
+ mxLbTree->connect_row_activated( LINK ( this, SvxHlinkDlgMarkWnd, DoubleClickApplyHdl_Impl ) );
+}
+
+SvxHlinkDlgMarkWnd::~SvxHlinkDlgMarkWnd()
+{
+ ClearTree();
+}
+
+void SvxHlinkDlgMarkWnd::ErrorChanged()
+{
+ if (mnError == LERR_NOENTRIES)
+ {
+ OUString aStrMessage = CuiResId( RID_CUISTR_HYPDLG_ERR_LERR_NOENTRIES );
+ mxError->set_label(aStrMessage);
+ mxError->show();
+ mxLbTree->hide();
+ }
+ else if (mnError == LERR_DOCNOTOPEN)
+ {
+ OUString aStrMessage = CuiResId( RID_CUISTR_HYPDLG_ERR_LERR_DOCNOTOPEN );
+ mxError->set_label(aStrMessage);
+ mxError->show();
+ mxLbTree->hide();
+ }
+ else
+ {
+ mxLbTree->show();
+ mxError->hide();
+ }
+}
+
+// Set an errorstatus
+sal_uInt16 SvxHlinkDlgMarkWnd::SetError( sal_uInt16 nError)
+{
+ sal_uInt16 nOldError = mnError;
+ mnError = nError;
+
+ if( mnError != LERR_NOERROR )
+ ClearTree();
+
+ ErrorChanged();
+
+ return nOldError;
+}
+
+// Move window
+void SvxHlinkDlgMarkWnd::MoveTo(const Point& rNewPos)
+{
+ m_xDialog->window_move(rNewPos.X(), rNewPos.Y());
+}
+
+namespace
+{
+ void SelectPath(weld::TreeIter* pEntry, weld::TreeView& rLbTree,
+ std::deque<OUString> &rLastSelectedPath)
+ {
+ OUString sTitle(rLastSelectedPath.front());
+ rLastSelectedPath.pop_front();
+ if (sTitle.isEmpty())
+ return;
+ while (pEntry)
+ {
+ if (sTitle == rLbTree.get_text(*pEntry))
+ {
+ rLbTree.select(*pEntry);
+ rLbTree.scroll_to_row(*pEntry);
+ if (!rLastSelectedPath.empty())
+ {
+ rLbTree.expand_row(*pEntry);
+ if (!rLbTree.iter_children(*pEntry))
+ pEntry = nullptr;
+ SelectPath(pEntry, rLbTree, rLastSelectedPath);
+ }
+ break;
+ }
+ if (!rLbTree.iter_next_sibling(*pEntry))
+ pEntry = nullptr;
+ }
+ }
+}
+
+constexpr OUStringLiteral TG_SETTING_MANAGER = u"TargetInDocument";
+constexpr OUStringLiteral TG_SETTING_LASTMARK = u"LastSelectedMark";
+constexpr OUStringLiteral TG_SETTING_LASTPATH = u"LastSelectedPath";
+
+void SvxHlinkDlgMarkWnd::RestoreLastSelection()
+{
+ bool bSelectedEntry = false;
+
+ OUString sLastSelectedMark;
+ std::deque<OUString> aLastSelectedPath;
+ SvtViewOptions aViewSettings( EViewType::Dialog, TG_SETTING_MANAGER );
+ if (aViewSettings.Exists())
+ {
+ //Maybe we might want to have some sort of mru list and keep a mapping
+ //per document, rather than the current reuse of "the last thing
+ //selected, regardless of the document"
+ aViewSettings.GetUserItem(TG_SETTING_LASTMARK) >>= sLastSelectedMark;
+ uno::Sequence<OUString> aTmp;
+ aViewSettings.GetUserItem(TG_SETTING_LASTPATH) >>= aTmp;
+ aLastSelectedPath = comphelper::sequenceToContainer< std::deque<OUString> >(aTmp);
+ }
+ //fallback to previous entry selected the last time we executed this dialog.
+ //First see if the exact mark exists and re-use that
+ if (!sLastSelectedMark.isEmpty())
+ bSelectedEntry = SelectEntry(sLastSelectedMark);
+ //Otherwise just select the closest path available
+ //now to what was available at dialog close time
+ if (!bSelectedEntry && !aLastSelectedPath.empty())
+ {
+ std::deque<OUString> aTmpSelectedPath(aLastSelectedPath);
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ if (!mxLbTree->get_iter_first(*xEntry))
+ xEntry.reset();
+ SelectPath(xEntry.get(), *mxLbTree, aTmpSelectedPath);
+ }
+}
+
+// Interface to refresh tree
+void SvxHlinkDlgMarkWnd::RefreshTree (const OUString& aStrURL)
+{
+ OUString aUStrURL;
+
+ weld::WaitObject aWait(m_xDialog.get());
+
+ ClearTree();
+
+ sal_Int32 nPos = aStrURL.indexOf('#');
+
+ if (nPos != 0)
+ aUStrURL = aStrURL;
+
+ if (!RefreshFromDoc(aUStrURL))
+ ErrorChanged();
+
+ bool bSelectedEntry = false;
+
+ if ( nPos != -1 )
+ {
+ OUString aStrMark = aStrURL.copy(nPos+1);
+ bSelectedEntry = SelectEntry(aStrMark);
+ }
+
+ if (!bSelectedEntry)
+ RestoreLastSelection();
+}
+
+// get links from document
+bool SvxHlinkDlgMarkWnd::RefreshFromDoc(const OUString& aURL)
+{
+ mnError = LERR_NOERROR;
+
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( ::comphelper::getProcessComponentContext() );
+ uno::Reference< lang::XComponent > xComp;
+
+ if( !aURL.isEmpty() )
+ {
+ // load from url
+ if( xDesktop.is() )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aArg { comphelper::makePropertyValue("Hidden", true) };
+ xComp = xDesktop->loadComponentFromURL( aURL, "_blank", 0, aArg );
+ }
+ catch( const io::IOException& )
+ {
+
+ }
+ catch( const lang::IllegalArgumentException& )
+ {
+
+ }
+ }
+ }
+ else
+ {
+ // the component with user focus ( current document )
+ xComp = xDesktop->getCurrentComponent();
+ }
+
+ if( xComp.is() )
+ {
+ uno::Reference< document::XLinkTargetSupplier > xLTS( xComp, uno::UNO_QUERY );
+
+ if( xLTS.is() )
+ {
+ if( FillTree( xLTS->getLinks() ) == 0 )
+ mnError = LERR_NOENTRIES;
+ }
+ else
+ mnError = LERR_DOCNOTOPEN;
+
+ if ( !aURL.isEmpty() )
+ xComp->dispose();
+ }
+ else
+ {
+ if( !aURL.isEmpty() )
+ mnError=LERR_DOCNOTOPEN;
+ }
+ return (mnError==0);
+}
+
+// Fill Tree-Control
+int SvxHlinkDlgMarkWnd::FillTree( const uno::Reference< container::XNameAccess >& xLinks, const weld::TreeIter* pParentEntry )
+{
+ // used to create the Headings outline parent children tree view relation
+ std::stack<std::pair<std::unique_ptr<weld::TreeIter>, const sal_Int32>> aHeadingsParentEntryStack;
+
+ int nEntries=0;
+ const uno::Sequence< OUString > aNames( xLinks->getElementNames() );
+ const sal_Int32 nLinks = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+
+ static const OUStringLiteral aProp_LinkDisplayName( u"LinkDisplayName" );
+ static const OUStringLiteral aProp_LinkTarget( u"com.sun.star.document.LinkTarget" );
+ static const OUStringLiteral aProp_LinkDisplayBitmap( u"LinkDisplayBitmap" );
+ for( sal_Int32 i = 0; i < nLinks; i++ )
+ {
+ uno::Any aAny;
+ OUString aLink( *pNames++ );
+
+ bool bError = false;
+ try
+ {
+ aAny = xLinks->getByName( aLink );
+ }
+ catch(const uno::Exception&)
+ {
+ // if the name of the target was invalid (like empty headings)
+ // no object can be provided
+ bError = true;
+ }
+ if(bError)
+ continue;
+
+ uno::Reference< beans::XPropertySet > xTarget;
+
+ if( aAny >>= xTarget )
+ {
+ try
+ {
+ // get name to display
+ aAny = xTarget->getPropertyValue( aProp_LinkDisplayName );
+ OUString aDisplayName;
+ aAny >>= aDisplayName;
+ OUString aStrDisplayname ( aDisplayName );
+
+ // is it a target ?
+ uno::Reference< lang::XServiceInfo > xSI( xTarget, uno::UNO_QUERY );
+ bool bIsTarget = xSI->supportsService( aProp_LinkTarget );
+
+ // create userdata
+ TargetData *pData = new TargetData ( aLink, bIsTarget );
+ OUString sId(weld::toId(pData));
+
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ if (pParentEntry)
+ {
+ OUString sContentType = mxLbTree->get_text(*pParentEntry);
+ if (sContentType == "Headings")
+ {
+ if (aHeadingsParentEntryStack.empty())
+ aHeadingsParentEntryStack.push(
+ std::pair(mxLbTree->make_iterator(pParentEntry), -1));
+
+ // get the headings name to display
+ aAny = xTarget->getPropertyValue("ActualOutlineName");
+ OUString sActualOutlineName;
+ aAny >>= sActualOutlineName;
+
+ // get the headings outline level
+ aAny = xTarget->getPropertyValue("OutlineLevel");
+ sal_Int32 nOutlineLevel = *o3tl::doAccess<sal_Int32>(aAny);
+
+ // pop until the top of stack entry has an outline level less than
+ // the to be inserted heading outline level
+ while (nOutlineLevel <= aHeadingsParentEntryStack.top().second)
+ aHeadingsParentEntryStack.pop();
+
+ mxLbTree->insert(aHeadingsParentEntryStack.top().first.get(), -1,
+ &sActualOutlineName, &sId, nullptr, nullptr, false,
+ xEntry.get());
+
+ // push if the inserted entry is a child
+ if (nOutlineLevel > aHeadingsParentEntryStack.top().second)
+ aHeadingsParentEntryStack.push(
+ std::pair(mxLbTree->make_iterator(xEntry.get()), nOutlineLevel));
+ }
+ else
+ {
+ mxLbTree->insert(pParentEntry, -1, &aStrDisplayname, &sId, nullptr,
+ nullptr, false, xEntry.get());
+ }
+ }
+ else
+ {
+ mxLbTree->insert(pParentEntry, -1, &aStrDisplayname, &sId, nullptr, nullptr,
+ false, xEntry.get());
+ }
+
+ try
+ {
+ // get bitmap for the tree-entry
+ uno::Reference< awt::XBitmap >
+ aXBitmap( xTarget->getPropertyValue( aProp_LinkDisplayBitmap ), uno::UNO_QUERY );
+ if (aXBitmap.is())
+ {
+ Graphic aBmp(Graphic(VCLUnoHelper::GetBitmap(aXBitmap)));
+ // insert Displayname into treelist with bitmaps
+ mxLbTree->set_image(*xEntry, aBmp.GetXGraphic(), -1);
+ }
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+
+ nEntries++;
+
+ uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, uno::UNO_QUERY );
+ if( xLTS.is() )
+ nEntries += FillTree( xLTS->getLinks(), xEntry.get() );
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+ }
+ }
+
+ return nEntries;
+}
+
+// Clear Tree
+void SvxHlinkDlgMarkWnd::ClearTree()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = mxLbTree->make_iterator();
+ bool bEntry = mxLbTree->get_iter_first(*xEntry);
+
+ while (bEntry)
+ {
+ TargetData* pUserData = weld::fromId<TargetData*>(mxLbTree->get_id(*xEntry));
+ delete pUserData;
+
+ bEntry = mxLbTree->iter_next(*xEntry);
+ }
+
+ mxLbTree->clear();
+}
+
+// Find Entry for String
+std::unique_ptr<weld::TreeIter> SvxHlinkDlgMarkWnd::FindEntry (std::u16string_view aStrName)
+{
+ bool bFound=false;
+ std::unique_ptr<weld::TreeIter> xEntry = mxLbTree->make_iterator();
+ bool bEntry = mxLbTree->get_iter_first(*xEntry);
+
+ while (bEntry && !bFound)
+ {
+ TargetData* pUserData = weld::fromId<TargetData*>(mxLbTree->get_id(*xEntry));
+ if (aStrName == pUserData->aUStrLinkname)
+ bFound = true;
+ else
+ bEntry = mxLbTree->iter_next(*xEntry);
+ }
+
+ if (!bFound)
+ xEntry.reset();
+
+ return xEntry;
+}
+
+// Select Entry
+bool SvxHlinkDlgMarkWnd::SelectEntry(std::u16string_view aStrMark)
+{
+ std::unique_ptr<weld::TreeIter> xEntry = FindEntry(aStrMark);
+ if (!xEntry)
+ return false;
+ mxLbTree->select(*xEntry);
+ mxLbTree->scroll_to_row(*xEntry);
+ return true;
+}
+
+// Click on Apply-Button / Double-click on item in tree
+IMPL_LINK_NOARG(SvxHlinkDlgMarkWnd, DoubleClickApplyHdl_Impl, weld::TreeView&, bool)
+{
+ ClickApplyHdl_Impl(*mxBtApply);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl, weld::Button&, void)
+{
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ bool bEntry = mxLbTree->get_cursor(xEntry.get());
+ if (bEntry)
+ {
+ TargetData* pData = weld::fromId<TargetData*>(mxLbTree->get_id(*xEntry));
+ if (pData->bIsTarget)
+ {
+ mpParent->SetMarkStr(pData->aUStrLinkname);
+ }
+ }
+}
+
+// Click on Close-Button
+IMPL_LINK_NOARG(SvxHlinkDlgMarkWnd, ClickCloseHdl_Impl, weld::Button&, void)
+{
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ bool bEntry = mxLbTree->get_cursor(xEntry.get());
+ if (bEntry)
+ {
+ TargetData* pUserData = weld::fromId<TargetData*>(mxLbTree->get_id(*xEntry));
+ OUString sLastSelectedMark = pUserData->aUStrLinkname;
+
+ std::deque<OUString> aLastSelectedPath;
+ //If the bottommost entry is expanded but nothing
+ //underneath it is selected leave a dummy entry
+ if (mxLbTree->get_row_expanded(*xEntry))
+ aLastSelectedPath.push_front(OUString());
+ while (bEntry)
+ {
+ aLastSelectedPath.push_front(mxLbTree->get_text(*xEntry));
+ bEntry = mxLbTree->iter_parent(*xEntry);
+ }
+
+ uno::Sequence< beans::NamedValue > aSettings
+ {
+ { TG_SETTING_LASTMARK, css::uno::Any(sLastSelectedMark) },
+ { TG_SETTING_LASTPATH, css::uno::Any(comphelper::containerToSequence(aLastSelectedPath)) }
+ };
+
+ // write
+ SvtViewOptions aViewSettings( EViewType::Dialog, TG_SETTING_MANAGER );
+ aViewSettings.SetUserData( aSettings );
+ }
+
+ m_xDialog->response(RET_CANCEL);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hltpbase.cxx b/cui/source/dialogs/hltpbase.cxx
new file mode 100644
index 000000000..77d335f10
--- /dev/null
+++ b/cui/source/dialogs/hltpbase.cxx
@@ -0,0 +1,537 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <sal/config.h>
+
+#include <comphelper/lok.hxx>
+#include <osl/file.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/formats.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/macitem.hxx>
+#include <ucbhelper/content.hxx>
+#include <cuihyperdlg.hxx>
+#include <hltpbase.hxx>
+#include <macroass.hxx>
+#include <svx/svxdlg.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+#include <bitmaps.hlst>
+
+using namespace ::ucbhelper;
+
+namespace {
+
+OUString CreateUiNameFromURL( const OUString& aStrURL )
+{
+ OUString aStrUiURL;
+ INetURLObject aURLObj( aStrURL );
+
+ switch(aURLObj.GetProtocol())
+ {
+ case INetProtocol::File:
+ osl::FileBase::getSystemPathFromFileURL(aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE), aStrUiURL);
+ break;
+ case INetProtocol::Ftp :
+ {
+ //remove password from name
+ INetURLObject aTmpURL(aURLObj);
+ aTmpURL.SetPass(u"");
+ aStrUiURL = aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
+ }
+ break;
+ default :
+ {
+ aStrUiURL = aURLObj.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ }
+ if(aStrUiURL.isEmpty())
+ return aStrURL;
+ return aStrUiURL;
+}
+
+}
+
+// ComboBox-Control for URL's with History and Autocompletion
+SvxHyperURLBox::SvxHyperURLBox(std::unique_ptr<weld::ComboBox> xControl)
+ : SvtURLBox(std::move(xControl))
+ , DropTargetHelper(getWidget()->get_drop_target())
+{
+ SetSmartProtocol(INetProtocol::Http);
+}
+
+sal_Int8 SvxHyperURLBox::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
+{
+ return IsDropFormatSupported( SotClipboardFormatId::STRING ) ? DND_ACTION_COPY : DND_ACTION_NONE;
+}
+
+sal_Int8 SvxHyperURLBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable );
+ OUString aString;
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ if( aDataHelper.GetString( SotClipboardFormatId::STRING, aString ) )
+ {
+ set_entry_text(aString);
+ nRet = DND_ACTION_COPY;
+ }
+
+ return nRet;
+}
+
+//# Hyperlink-Dialog: Tabpages-Baseclass #
+
+SvxHyperlinkTabPageBase::SvxHyperlinkTabPageBase(weld::Container* pParent,
+ SvxHpLinkDlg* pDlg,
+ const OUString& rUIXMLDescription,
+ const OString& rID,
+ const SfxItemSet* pItemSet)
+ : IconChoicePage(pParent, rUIXMLDescription, rID, pItemSet)
+ , mxCbbFrame(xBuilder->weld_combo_box("frame"))
+ , mxLbForm(xBuilder->weld_combo_box("form"))
+ , mxEdIndication(xBuilder->weld_entry("indication"))
+ , mxEdText(xBuilder->weld_entry("name"))
+ , mxBtScript(xBuilder->weld_button("script"))
+ , mxFormLabel(xBuilder->weld_label("form_label"))
+ , mxFrameLabel(xBuilder->weld_label("frame_label"))
+ , mbIsCloseDisabled( false )
+ , mpDialog( pDlg )
+ , mbStdControlsInit( false )
+ , maTimer("cui SvxHyperlinkTabPageBase maTimer")
+{
+ // create bookmark-window
+}
+
+SvxHyperlinkTabPageBase::~SvxHyperlinkTabPageBase()
+{
+ maTimer.Stop();
+
+ HideMarkWnd();
+}
+
+bool SvxHyperlinkTabPageBase::QueryClose()
+{
+ return !mbIsCloseDisabled;
+}
+
+void SvxHyperlinkTabPageBase::InitStdControls ()
+{
+ if ( !mbStdControlsInit )
+ {
+ SfxDispatcher* pDispatch = GetDispatcher();
+ SfxViewFrame* pViewFrame = pDispatch ? pDispatch->GetFrame() : nullptr;
+ SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
+ if ( pFrame )
+ {
+ TargetList aList;
+ SfxFrame::GetDefaultTargetList(aList);
+ if( !aList.empty() )
+ {
+ size_t nCount = aList.size();
+ size_t i;
+ for ( i = 0; i < nCount; i++ )
+ {
+ mxCbbFrame->append_text( aList.at( i ) );
+ }
+ }
+ }
+
+ mxBtScript->set_from_icon_name(RID_SVXBMP_SCRIPT);
+
+ mxBtScript->connect_clicked ( LINK ( this, SvxHyperlinkTabPageBase, ClickScriptHdl_Impl ) );
+ }
+
+ mbStdControlsInit = true;
+}
+
+// Move Extra-Window
+void SvxHyperlinkTabPageBase::MoveToExtraWnd( Point aNewPos )
+{
+ mxMarkWnd->MoveTo(aNewPos);
+}
+
+// Show Extra-Window
+void SvxHyperlinkTabPageBase::ShowMarkWnd()
+{
+ if (mxMarkWnd)
+ {
+ mxMarkWnd->getDialog()->present();
+ return;
+ }
+
+ weld::Dialog* pDialog = mpDialog->getDialog();
+
+ mxMarkWnd = std::make_shared<SvxHlinkDlgMarkWnd>(pDialog, this);
+
+ // Size of dialog-window in screen pixels
+ Point aDlgPos(pDialog->get_position());
+ Size aDlgSize(pDialog->get_size());
+
+ // Absolute size of the screen
+ ::tools::Rectangle aScreen(pDialog->get_monitor_workarea());
+
+ // Size of Extrawindow
+ Size aExtraWndSize(mxMarkWnd->getDialog()->get_preferred_size());
+
+ // mxMarkWnd is a child of mpDialog, so coordinates for positioning must be relative to mpDialog
+ if( aDlgPos.X()+(1.05*aDlgSize.Width())+aExtraWndSize.Width() > aScreen.Right() )
+ {
+ if( aDlgPos.X() - ( 0.05*aDlgSize.Width() ) - aExtraWndSize.Width() < 0 )
+ {
+ // Pos Extrawindow anywhere
+ MoveToExtraWnd( Point(10,10) ); // very unlikely
+ }
+ else
+ {
+ // Pos Extrawindow on the left side of Dialog
+ MoveToExtraWnd( Point(0,0) - Point( tools::Long(0.05*aDlgSize.Width()), 0 ) - Point( aExtraWndSize.Width(), 0 ) );
+ }
+ }
+ else
+ {
+ // Pos Extrawindow on the right side of Dialog
+ MoveToExtraWnd ( Point( tools::Long(1.05*aDlgSize.getWidth()), 0 ) );
+ }
+
+ // Set size of Extra-Window
+ mxMarkWnd->getDialog()->set_size_request(aExtraWndSize.Width(), aDlgSize.Height());
+
+ weld::DialogController::runAsync(mxMarkWnd, [this](sal_Int32 /*nResult*/) { mxMarkWnd.reset(); } );
+}
+
+void SvxHyperlinkTabPageBase::HideMarkWnd()
+{
+ if (mxMarkWnd)
+ {
+ mxMarkWnd->response(RET_CANCEL);
+ mxMarkWnd.reset();
+ }
+}
+
+// Fill Dialogfields
+void SvxHyperlinkTabPageBase::FillStandardDlgFields ( const SvxHyperlinkItem* pHyperlinkItem )
+{
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ // Frame
+ sal_Int32 nPos = mxCbbFrame->find_text(pHyperlinkItem->GetTargetFrame());
+ if (nPos != -1)
+ mxCbbFrame->set_active(nPos);
+
+ // Form
+ OUString aStrFormText = CuiResId( RID_CUISTR_HYPERDLG_FROM_TEXT );
+
+ OUString aStrFormButton = CuiResId( RID_CUISTR_HYPERDLG_FORM_BUTTON );
+
+ if( pHyperlinkItem->GetInsertMode() & HLINK_HTMLMODE )
+ {
+ mxLbForm->clear();
+ mxLbForm->append_text( aStrFormText );
+ mxLbForm->set_active( 0 );
+ }
+ else
+ {
+ mxLbForm->clear();
+ mxLbForm->append_text( aStrFormText );
+ mxLbForm->append_text( aStrFormButton );
+ mxLbForm->set_active( pHyperlinkItem->GetInsertMode() == HLINK_BUTTON ? 1 : 0 );
+ }
+ }
+ else
+ {
+ mxCbbFrame->hide();
+ mxLbForm->hide();
+ mxFormLabel->hide();
+ mxFrameLabel->hide();
+ }
+
+ // URL
+ mxEdIndication->set_text( pHyperlinkItem->GetName() );
+
+ // Name
+ mxEdText->set_text( pHyperlinkItem->GetIntName() );
+
+ // Script-button
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ if ( pHyperlinkItem->GetMacroEvents() == HyperDialogEvent::NONE )
+ mxBtScript->set_sensitive(false);
+ else
+ mxBtScript->set_sensitive(true);
+ }
+ else
+ {
+ mxBtScript->hide();
+ }
+}
+
+// Any action to do after apply-button is pressed
+void SvxHyperlinkTabPageBase::DoApply ()
+{
+ // default-implementation : do nothing
+}
+
+// This method would be called from bookmark-window to set new mark-string
+void SvxHyperlinkTabPageBase::SetMarkStr ( const OUString& /*aStrMark*/ )
+{
+ // default-implementation : do nothing
+}
+
+// Set initial focus
+void SvxHyperlinkTabPageBase::SetInitFocus()
+{
+ xContainer->grab_focus();
+}
+
+// retrieve dispatcher
+SfxDispatcher* SvxHyperlinkTabPageBase::GetDispatcher() const
+{
+ return mpDialog->GetDispatcher();
+}
+
+void SvxHyperlinkTabPageBase::DisableClose(bool _bDisable)
+{
+ mbIsCloseDisabled = _bDisable;
+ if (mbIsCloseDisabled)
+ maBusy.incBusy(mpDialog->getDialog());
+ else
+ maBusy.decBusy();
+}
+
+// Click on imagebutton : Script
+IMPL_LINK_NOARG(SvxHyperlinkTabPageBase, ClickScriptHdl_Impl, weld::Button&, void)
+{
+ SvxHyperlinkItem *pHyperlinkItem = const_cast<SvxHyperlinkItem*>(
+ GetItemSet().GetItem (SID_HYPERLINK_GETLINK));
+
+ if (!pHyperlinkItem || pHyperlinkItem->GetMacroEvents() == HyperDialogEvent::NONE)
+ return;
+
+ // get macros from itemset
+ const SvxMacroTableDtor* pMacroTbl = pHyperlinkItem->GetMacroTable();
+ SvxMacroItem aItem ( SID_ATTR_MACROITEM );
+ if( pMacroTbl )
+ aItem.SetMacroTable( *pMacroTbl );
+
+ // create empty itemset for macro-dlg
+ SfxItemSetFixed<SID_ATTR_MACROITEM, SID_ATTR_MACROITEM> aItemSet( SfxGetpApp()->GetPool() );
+ aItemSet.Put ( aItem );
+
+ DisableClose( true );
+
+ SfxMacroAssignDlg aDlg(mpDialog->getDialog(), mxDocumentFrame, aItemSet);
+
+ // add events
+ SfxMacroTabPage *pMacroPage = aDlg.GetTabPage();
+
+ if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseOverObject )
+ pMacroPage->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT1),
+ SvMacroItemId::OnMouseOver );
+ if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseClickObject )
+ pMacroPage->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT2),
+ SvMacroItemId::OnClick);
+ if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseOutObject )
+ pMacroPage->AddEvent( CuiResId(RID_CUISTR_HYPDLG_MACROACT3),
+ SvMacroItemId::OnMouseOut);
+ // execute dlg
+ short nRet = aDlg.run();
+ DisableClose( false );
+ if ( RET_OK == nRet )
+ {
+ const SfxItemSet* pOutSet = aDlg.GetOutputItemSet();
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == pOutSet->GetItemState( SID_ATTR_MACROITEM, false, &pItem ))
+ {
+ pHyperlinkItem->SetMacroTable( static_cast<const SvxMacroItem*>(pItem)->GetMacroTable() );
+ }
+ }
+}
+
+// Get Macro-Infos
+HyperDialogEvent SvxHyperlinkTabPageBase::GetMacroEvents() const
+{
+ const SvxHyperlinkItem *pHyperlinkItem =
+ GetItemSet().GetItem (SID_HYPERLINK_GETLINK);
+
+ return pHyperlinkItem ? pHyperlinkItem->GetMacroEvents() : HyperDialogEvent();
+}
+
+SvxMacroTableDtor* SvxHyperlinkTabPageBase::GetMacroTable()
+{
+ const SvxHyperlinkItem *pHyperlinkItem =
+ GetItemSet().GetItem (SID_HYPERLINK_GETLINK);
+
+ return const_cast<SvxMacroTableDtor*>(pHyperlinkItem->GetMacroTable());
+}
+
+// try to detect the current protocol that is used in rStrURL
+OUString SvxHyperlinkTabPageBase::GetSchemeFromURL( const OUString& rStrURL )
+{
+ OUString aStrScheme;
+
+ INetURLObject aURL( rStrURL );
+ INetProtocol aProtocol = aURL.GetProtocol();
+
+ // our new INetUrlObject now has the ability
+ // to detect if a Url is valid or not :-(
+ if ( aProtocol == INetProtocol::NotValid )
+ {
+ if ( rStrURL.startsWithIgnoreAsciiCase( INET_HTTP_SCHEME ) )
+ {
+ aStrScheme = INET_HTTP_SCHEME;
+ }
+ else if ( rStrURL.startsWithIgnoreAsciiCase( INET_HTTPS_SCHEME ) )
+ {
+ aStrScheme = INET_HTTPS_SCHEME;
+ }
+ else if ( rStrURL.startsWithIgnoreAsciiCase( INET_FTP_SCHEME ) )
+ {
+ aStrScheme = INET_FTP_SCHEME;
+ }
+ else if ( rStrURL.startsWithIgnoreAsciiCase( INET_MAILTO_SCHEME ) )
+ {
+ aStrScheme = INET_MAILTO_SCHEME;
+ }
+ }
+ else
+ aStrScheme = INetURLObject::GetScheme( aProtocol );
+ return aStrScheme;
+}
+
+void SvxHyperlinkTabPageBase::GetDataFromCommonFields( OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ aStrIntName = mxEdText->get_text();
+ aStrName = mxEdIndication->get_text();
+ aStrFrame = mxCbbFrame->get_active_text();
+
+ sal_Int32 nPos = mxLbForm->get_active();
+ if (nPos == -1)
+ // This happens when FillStandardDlgFields() hides mpLbForm.
+ nPos = 0;
+ eMode = static_cast<SvxLinkInsertMode>(nPos + 1);
+
+ // Ask dialog whether the current doc is a HTML-doc
+ if (mpDialog->IsHTMLDoc())
+ eMode = static_cast<SvxLinkInsertMode>( sal_uInt16(eMode) | HLINK_HTMLMODE );
+}
+
+// reset dialog-fields
+void SvxHyperlinkTabPageBase::Reset( const SfxItemSet& rItemSet)
+{
+
+ // Set dialog-fields from create-itemset
+ maStrInitURL.clear();
+
+ const SvxHyperlinkItem *pHyperlinkItem =
+ rItemSet.GetItem (SID_HYPERLINK_GETLINK);
+
+ if ( pHyperlinkItem )
+ {
+ // set dialog-fields
+ FillStandardDlgFields (pHyperlinkItem);
+
+ // set all other fields
+ FillDlgFields ( pHyperlinkItem->GetURL() );
+
+ // Store initial URL
+ maStrInitURL = pHyperlinkItem->GetURL();
+ }
+}
+
+// Fill output-ItemSet
+bool SvxHyperlinkTabPageBase::FillItemSet( SfxItemSet* rOut)
+{
+ OUString aStrURL, aStrName, aStrIntName, aStrFrame;
+ SvxLinkInsertMode eMode;
+
+ GetCurentItemData ( aStrURL, aStrName, aStrIntName, aStrFrame, eMode);
+ if ( aStrName.isEmpty() ) //automatically create a visible name if the link is created without name
+ aStrName = CreateUiNameFromURL(aStrURL);
+
+ HyperDialogEvent nEvents = GetMacroEvents();
+ SvxMacroTableDtor* pTable = GetMacroTable();
+
+ SvxHyperlinkItem aItem( SID_HYPERLINK_SETLINK, aStrName, aStrURL, aStrFrame,
+ aStrIntName, eMode, nEvents, pTable );
+ rOut->Put (aItem);
+
+ return true;
+}
+
+// Activate / Deactivate Tabpage
+void SvxHyperlinkTabPageBase::ActivatePage( const SfxItemSet& rItemSet )
+{
+
+ // Set dialog-fields from input-itemset
+ const SvxHyperlinkItem *pHyperlinkItem =
+ rItemSet.GetItem (SID_HYPERLINK_GETLINK);
+
+ if ( pHyperlinkItem )
+ {
+ // standard-fields
+ FillStandardDlgFields (pHyperlinkItem);
+ }
+
+ // show mark-window if it was open before
+ if ( ShouldOpenMarkWnd () )
+ ShowMarkWnd ();
+}
+
+DeactivateRC SvxHyperlinkTabPageBase::DeactivatePage( SfxItemSet* _pSet)
+{
+ // hide mark-wnd
+ SetMarkWndShouldOpen( IsMarkWndVisible () );
+ HideMarkWnd ();
+
+ // retrieve data of dialog
+ OUString aStrURL, aStrName, aStrIntName, aStrFrame;
+ SvxLinkInsertMode eMode;
+
+ GetCurentItemData ( aStrURL, aStrName, aStrIntName, aStrFrame, eMode);
+
+ HyperDialogEvent nEvents = GetMacroEvents();
+ SvxMacroTableDtor* pTable = GetMacroTable();
+
+ if( _pSet )
+ {
+ SvxHyperlinkItem aItem( SID_HYPERLINK_GETLINK, aStrName, aStrURL, aStrFrame,
+ aStrIntName, eMode, nEvents, pTable );
+ _pSet->Put( aItem );
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxHyperlinkTabPageBase::ShouldOpenMarkWnd()
+{
+ return false;
+}
+
+void SvxHyperlinkTabPageBase::SetMarkWndShouldOpen(bool)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hyphen.cxx b/cui/source/dialogs/hyphen.cxx
new file mode 100644
index 000000000..259ec5d03
--- /dev/null
+++ b/cui/source/dialogs/hyphen.cxx
@@ -0,0 +1,472 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hyphen.hxx>
+
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+
+#include <editeng/splwrap.hxx>
+#include <editeng/unolingu.hxx>
+#include <svtools/langtab.hxx>
+#include <sal/log.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <tools/debug.hxx>
+#include <utility>
+
+#define HYPH_POS_CHAR '='
+
+#define CUR_HYPH_POS_CHAR '-'
+
+using namespace css;
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, CursorChangeHdl_Impl, weld::Entry&, void)
+{
+ int nStart, nEnd;
+ m_xWordEdit->get_selection_bounds(nStart, nEnd);
+ if (nStart == m_nOldPos && nEnd == m_nOldPos + 1)
+ return;
+ bool bReSelect;
+ if (nStart <= m_nOldPos)
+ bReSelect = !SelLeft();
+ else
+ bReSelect = !SelRight();
+ if (bReSelect)
+ select_region(m_nOldPos, m_nOldPos + 1);
+}
+
+void SvxHyphenWordDialog::EnableLRBtn_Impl()
+{
+ const sal_Int32 nLen = m_aEditWord.getLength();
+
+ m_xRightBtn->set_sensitive(false);
+ for ( sal_Int32 i = m_nOldPos + 2; i < nLen; ++i )
+ {
+ if ( m_aEditWord[ i ] == sal_Unicode( HYPH_POS_CHAR ) )
+ {
+ m_xRightBtn->set_sensitive(true);
+ break;
+ }
+ }
+
+ DBG_ASSERT(m_nOldPos < nLen, "nOldPos out of range");
+ if (m_nOldPos >= nLen)
+ m_nOldPos = nLen - 1;
+ m_xLeftBtn->set_sensitive(false);
+ for ( sal_Int32 i = m_nOldPos; i-- > 0; )
+ {
+ if ( m_aEditWord[ i ] == sal_Unicode( HYPH_POS_CHAR ) )
+ {
+ m_xLeftBtn->set_sensitive(true);
+ break;
+ }
+ }
+}
+
+OUString SvxHyphenWordDialog::EraseUnusableHyphens_Impl()
+{
+ // returns a String showing only those hyphen positions which will result
+ // in a line break if hyphenation is done there
+ // 1) we will need to discard all hyphenation positions at the end that
+ // will not result in a line break where the text to the left still fits
+ // on the line.
+ // 2) since as from OOo 3.2 '-' are part of a word and thus text like
+ // 'multi-line-editor' is regarded as single word we also need to discard those
+ // hyphenation positions to the left of the rightmost '-' that is still left of
+ // the rightmost valid hyphenation position according to 1)
+
+ // Example:
+ // If the possible hyphenation position in 'multi-line-editor' are to be marked
+ // by '=' then the text will look like this: 'mul=ti-line-ed=it=or'.
+ // If now the first line is only large enough for 'multi-line-edi' we need to discard
+ // the last possible hyphenation point because of 1). The right most valid
+ // hyphenation position is "ed=itor". The first '-' left of this position is
+ // "line-ed", thus because of 2) we now need to discard all possible hyphenation
+ // positions to the left of that as well. Thus in the end leaving us with just
+ // 'multi-line-ed=itor' as return value for this function. (Just one valid hyphenation
+ // position for the user to choose from. However ALL the '-' characters in the word
+ // will ALWAYS be valid implicit hyphenation positions for the core to choose from!
+ // And thus even if this word is skipped in the hyphenation dialog it will still be broken
+ // right after 'multi-line-' (actually it might already be broken up that way before
+ // the hyphenation dialog is called!).
+ // Thus rule 2) just eliminates those positions which will not be used by the core at all
+ // even if the user were to select one of them.
+
+ OUString aTxt;
+ DBG_ASSERT(m_xPossHyph.is(), "missing possible hyphens");
+ if (m_xPossHyph.is())
+ {
+ DBG_ASSERT( m_aActWord == m_xPossHyph->getWord(), "word mismatch" );
+
+ aTxt = m_xPossHyph->getPossibleHyphens();
+
+ m_nHyphenationPositionsOffset = 0;
+ uno::Sequence< sal_Int16 > aHyphenationPositions(
+ m_xPossHyph->getHyphenationPositions() );
+ sal_Int32 nLen = aHyphenationPositions.getLength();
+ const sal_Int16 *pHyphenationPos = aHyphenationPositions.getConstArray();
+
+ // find position nIdx after which all hyphen positions are unusable
+ sal_Int32 nIdx = -1;
+ sal_Int32 nPos = 0, nPos1 = 0;
+ if (nLen)
+ {
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ if (pHyphenationPos[i] > m_nMaxHyphenationPos)
+ break;
+ else
+ {
+ // find corresponding hyphen positions in string
+ nPos = aTxt.indexOf( sal_Unicode( HYPH_POS_CHAR ), nStart );
+
+ if (nPos == -1)
+ break;
+ else
+ {
+ nIdx = nPos;
+ nStart = nPos + 1;
+ }
+ }
+ }
+ }
+ DBG_ASSERT(nIdx != -1, "no usable hyphenation position");
+
+ // 1) remove all not usable hyphenation positions from the end of the string
+ nPos = nIdx == -1 ? 0 : nIdx + 1;
+ nPos1 = nPos; //save for later use in 2) below
+ const OUString aTmp( sal_Unicode( HYPH_POS_CHAR ) );
+ while (nPos != -1)
+ {
+ nPos++;
+ aTxt = aTxt.replaceFirst( aTmp, "", &nPos);
+ }
+
+ // 2) remove all hyphenation positions from the start that are not considered by the core
+ const std::u16string_view aSearchRange( aTxt.subView( 0, nPos1 ) );
+ size_t nPos2 = aSearchRange.rfind( '-' ); // the '-' position the core will use by default
+ if (nPos2 != std::u16string_view::npos && nPos2 != 0)
+ {
+ OUString aLeft( aSearchRange.substr( 0, nPos2 ) );
+ nPos = 0;
+ while (nPos != -1)
+ {
+ nPos++;
+ aLeft = aLeft.replaceFirst( aTmp, "", &nPos );
+ if (nPos != -1)
+ ++m_nHyphenationPositionsOffset;
+ }
+ aTxt = aTxt.replaceAt( 0, nPos2, aLeft );
+ }
+ }
+ return aTxt;
+}
+
+void SvxHyphenWordDialog::InitControls_Impl()
+{
+ m_xPossHyph = nullptr;
+ if (m_xHyphenator.is())
+ {
+ lang::Locale aLocale( LanguageTag::convertToLocale(m_nActLanguage) );
+ m_xPossHyph = m_xHyphenator->createPossibleHyphens( m_aActWord, aLocale,
+ uno::Sequence< beans::PropertyValue >() );
+ if (m_xPossHyph.is())
+ m_aEditWord = EraseUnusableHyphens_Impl();
+ }
+ m_xWordEdit->set_text(m_aEditWord);
+
+ m_nOldPos = m_aEditWord.getLength();
+ SelLeft();
+ EnableLRBtn_Impl();
+}
+
+void SvxHyphenWordDialog::ContinueHyph_Impl( sal_Int32 nInsPos )
+{
+ if ( nInsPos >= 0 && m_xPossHyph.is() )
+ {
+ if (nInsPos)
+ {
+ DBG_ASSERT(nInsPos <= m_aEditWord.getLength() - 2, "wrong hyphen position");
+
+ sal_Int32 nIdxPos = -1;
+ for (sal_Int32 i = 0; i <= nInsPos; ++i)
+ {
+ if (HYPH_POS_CHAR == m_aEditWord[ i ])
+ nIdxPos++;
+ }
+ // take the possible hyphenation positions that got removed from the
+ // start of the word into account:
+ nIdxPos += m_nHyphenationPositionsOffset;
+
+ uno::Sequence< sal_Int16 > aSeq = m_xPossHyph->getHyphenationPositions();
+ sal_Int32 nLen = aSeq.getLength();
+ DBG_ASSERT(nLen, "empty sequence");
+ DBG_ASSERT(0 <= nIdxPos && nIdxPos < nLen, "index out of range");
+ if (nLen && 0 <= nIdxPos && nIdxPos < nLen)
+ {
+ nInsPos = aSeq.getConstArray()[ nIdxPos ];
+ m_pHyphWrapper->InsertHyphen( nInsPos );
+ }
+ }
+ else
+ {
+ //! calling with 0 as argument will remove hyphens!
+ m_pHyphWrapper->InsertHyphen( nInsPos );
+ }
+ }
+
+ if ( m_pHyphWrapper->FindSpellError() )
+ {
+ uno::Reference< linguistic2::XHyphenatedWord > xHyphWord( m_pHyphWrapper->GetLast(), uno::UNO_QUERY );
+
+ // adapt actual word and language to new found hyphenation result
+ if(xHyphWord.is())
+ {
+ m_aActWord = xHyphWord->getWord();
+ m_nActLanguage = LanguageTag( xHyphWord->getLocale() ).getLanguageType();
+ m_nMaxHyphenationPos = xHyphWord->getHyphenationPos();
+ InitControls_Impl();
+ SetWindowTitle( m_nActLanguage );
+ }
+ }
+ else
+ {
+ m_xCloseBtn->set_sensitive(false);
+ m_xDialog->response(RET_OK);
+ }
+}
+
+bool SvxHyphenWordDialog::SelLeft()
+{
+ bool bRet = false;
+ DBG_ASSERT( m_nOldPos > 0, "invalid hyphenation position" );
+ if (m_nOldPos > 0)
+ {
+ OUString aTxt( m_aEditWord );
+ for( sal_Int32 i = m_nOldPos - 1; i > 0; --i )
+ {
+ DBG_ASSERT(i <= aTxt.getLength(), "index out of range");
+ if (aTxt[ i ] == sal_Unicode( HYPH_POS_CHAR ))
+ {
+ aTxt = aTxt.replaceAt( i, 1, rtl::OUStringChar( CUR_HYPH_POS_CHAR ) );
+
+ m_nOldPos = i;
+ m_xWordEdit->set_text(aTxt);
+ select_region(i, i + 1);
+ m_xWordEdit->grab_focus();
+ bRet = true;
+ break;
+ }
+ }
+ EnableLRBtn_Impl();
+ }
+ return bRet;
+}
+
+bool SvxHyphenWordDialog::SelRight()
+{
+ bool bRet = false;
+ OUString aTxt( m_aEditWord );
+ for ( sal_Int32 i = m_nOldPos + 1; i < aTxt.getLength(); ++i )
+ {
+ if (aTxt[ i ] == sal_Unicode( HYPH_POS_CHAR ))
+ {
+ aTxt = aTxt.replaceAt( i, 1, rtl::OUStringChar( CUR_HYPH_POS_CHAR ) );
+
+ m_nOldPos = i;
+ m_xWordEdit->set_text(aTxt);
+ select_region(i, i + 1);
+ m_xWordEdit->grab_focus();
+ bRet = true;
+ break;
+ }
+ }
+ EnableLRBtn_Impl();
+ return bRet;
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, CutHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ ContinueHyph_Impl( /*m_nHyphPos*/m_nOldPos );
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, HyphenateAllHdl_Impl, weld::Button&, void)
+{
+ if( m_bBusy )
+ return;
+
+ try
+ {
+ uno::Reference< linguistic2::XLinguProperties > xProp( LinguMgr::GetLinguPropertySet() );
+
+ xProp->setIsHyphAuto( true );
+
+ m_bBusy = true;
+ ContinueHyph_Impl( /*m_nHyphPos*/m_nOldPos );
+ m_bBusy = false;
+
+ xProp->setIsHyphAuto( false );
+ }
+ catch (uno::Exception &)
+ {
+ SAL_WARN( "cui.dialogs", "Hyphenate All failed" );
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ ContinueHyph_Impl( 0 );
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, ContinueHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ ContinueHyph_Impl();
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, CancelHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ m_xDialog->response(RET_CANCEL);
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, Left_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ SelLeft();
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, Right_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ SelRight();
+ m_bBusy = false;
+ }
+}
+
+void SvxHyphenWordDialog::select_region(int nStart, int nEnd)
+{
+ int nScrollPos = nStart + m_nWordEditWidth/2;
+ if (nScrollPos > m_aEditWord.getLength())
+ nScrollPos = m_aEditWord.getLength() - m_nWordEditWidth/2;
+ if (nScrollPos < 0)
+ nScrollPos = 0;
+ m_xWordEdit->set_position(nScrollPos);
+ m_xWordEdit->select_region(nStart, nEnd);
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, GetFocusHdl_Impl, weld::Widget&, void)
+{
+ select_region(m_nOldPos, m_nOldPos + 1);
+}
+
+// class SvxHyphenWordDialog ---------------------------------------------
+
+SvxHyphenWordDialog::SvxHyphenWordDialog(
+ OUString aWord, LanguageType nLang,
+ weld::Widget* pParent,
+ uno::Reference< linguistic2::XHyphenator > const &xHyphen,
+ SvxSpellWrapper* pWrapper)
+ : SfxDialogController(pParent, "cui/ui/hyphenate.ui", "HyphenateDialog")
+ , m_pHyphWrapper(pWrapper)
+ , m_aActWord(std::move(aWord))
+ , m_nActLanguage(nLang)
+ , m_nMaxHyphenationPos(0)
+ , m_nOldPos(0)
+ , m_nHyphenationPositionsOffset(0)
+ , m_bBusy(false)
+ , m_xWordEdit(m_xBuilder->weld_entry("worded"))
+ , m_xLeftBtn(m_xBuilder->weld_button("left"))
+ , m_xRightBtn(m_xBuilder->weld_button("right"))
+ , m_xOkBtn(m_xBuilder->weld_button("ok"))
+ , m_xContBtn(m_xBuilder->weld_button("continue"))
+ , m_xDelBtn(m_xBuilder->weld_button("delete"))
+ , m_xHyphAll(m_xBuilder->weld_button("hyphall"))
+ , m_xCloseBtn(m_xBuilder->weld_button("close"))
+{
+ m_nWordEditWidth = m_xWordEdit->get_width_chars();
+ m_aLabel = m_xDialog->get_title();
+ m_xHyphenator = xHyphen;
+
+ uno::Reference< linguistic2::XHyphenatedWord > xHyphWord( m_pHyphWrapper ?
+ m_pHyphWrapper->GetLast() : nullptr, uno::UNO_QUERY );
+ DBG_ASSERT( xHyphWord.is(), "hyphenation result missing" );
+ if (xHyphWord.is())
+ {
+ DBG_ASSERT( m_aActWord == xHyphWord->getWord(), "word mismatch" );
+ DBG_ASSERT( m_nActLanguage == LanguageTag( xHyphWord->getLocale() ).getLanguageType(), "language mismatch" );
+ m_nMaxHyphenationPos = xHyphWord->getHyphenationPos();
+ }
+
+ InitControls_Impl();
+ m_xWordEdit->grab_focus();
+
+ m_xLeftBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, Left_Impl ) );
+ m_xRightBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, Right_Impl ) );
+ m_xOkBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, CutHdl_Impl ) );
+ m_xContBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, ContinueHdl_Impl ) );
+ m_xDelBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, DeleteHdl_Impl ) );
+ m_xHyphAll->connect_clicked( LINK( this, SvxHyphenWordDialog, HyphenateAllHdl_Impl ) );
+ m_xCloseBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, CancelHdl_Impl ) );
+ m_xWordEdit->connect_focus_in( LINK( this, SvxHyphenWordDialog, GetFocusHdl_Impl ) );
+ m_xWordEdit->connect_cursor_position( LINK( this, SvxHyphenWordDialog, CursorChangeHdl_Impl ) );
+
+ SetWindowTitle( nLang );
+
+ // disable controls if service is not available
+ if (!m_xHyphenator.is())
+ m_xDialog->set_sensitive(false);
+}
+
+SvxHyphenWordDialog::~SvxHyphenWordDialog()
+{
+ if (m_xCloseBtn->get_sensitive())
+ m_pHyphWrapper->SpellEnd();
+}
+
+void SvxHyphenWordDialog::SetWindowTitle(LanguageType nLang)
+{
+ m_xDialog->set_title(m_aLabel + " (" + SvtLanguageTable::GetLanguageString(nLang) + ")");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/iconcdlg.cxx b/cui/source/dialogs/iconcdlg.cxx
new file mode 100644
index 000000000..6e6ffaf5c
--- /dev/null
+++ b/cui/source/dialogs/iconcdlg.cxx
@@ -0,0 +1,308 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <iconcdlg.hxx>
+#include <cuihyperdlg.hxx>
+
+#include <cassert>
+#include <sal/log.hxx>
+#include <vcl/svapp.hxx>
+
+/**********************************************************************
+|
+| Ctor / Dtor
+|
+\**********************************************************************/
+
+IconChoicePage::IconChoicePage(weld::Container* pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ const SfxItemSet* pItemSet)
+ : xBuilder(Application::CreateBuilder(pParent, rUIXMLDescription))
+ , xContainer(xBuilder->weld_container(rID))
+ , pSet(pItemSet)
+ , bHasExchangeSupport(false)
+{
+}
+
+IconChoicePage::~IconChoicePage()
+{
+}
+
+/**********************************************************************
+|
+| Activate / Deactivate
+|
+\**********************************************************************/
+
+void IconChoicePage::ActivatePage( const SfxItemSet& )
+{
+}
+
+
+DeactivateRC IconChoicePage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool IconChoicePage::QueryClose()
+{
+ return true;
+}
+
+/**********************************************************************
+|
+| add new page
+|
+\**********************************************************************/
+void SvxHpLinkDlg::AddTabPage(const OString& rId, CreatePage pCreateFunc /* != 0 */)
+{
+ weld::Container* pPage = m_xIconCtrl->get_page(rId);
+ maPageList.emplace_back(new IconChoicePageData(rId, pCreateFunc(pPage, this, pSet)));
+ maPageList.back()->xPage->Reset(*pSet);
+ PageCreated(*maPageList.back()->xPage);
+}
+
+/**********************************************************************
+|
+| Show / Hide page or button
+|
+\**********************************************************************/
+void SvxHpLinkDlg::ShowPage(const OString& rId)
+{
+ OString sOldPageId = GetCurPageId();
+ bool bInvalidate = sOldPageId != rId;
+ if (bInvalidate)
+ {
+ IconChoicePageData* pOldData = GetPageData(sOldPageId);
+ if (pOldData && pOldData->xPage)
+ {
+ DeActivatePageImpl();
+ }
+ }
+ SetCurPageId(rId);
+ ActivatePageImpl();
+}
+
+/**********************************************************************
+|
+| select a page
+|
+\**********************************************************************/
+IMPL_LINK(SvxHpLinkDlg, ChosePageHdl_Impl, const OString&, rId, void)
+{
+ if (rId != msCurrentPageId)
+ {
+ ShowPage(rId);
+ }
+}
+
+/**********************************************************************
+|
+| Button-handler
+|
+\**********************************************************************/
+IMPL_LINK_NOARG(SvxHpLinkDlg, ResetHdl, weld::Button&, void)
+{
+ ResetPageImpl ();
+
+ IconChoicePageData* pData = GetPageData ( msCurrentPageId );
+ assert( pData && "ID not known " );
+
+ pData->xPage->Reset( *pSet );
+}
+
+/**********************************************************************
+|
+| call page
+|
+\**********************************************************************/
+void SvxHpLinkDlg::ActivatePageImpl()
+{
+ assert( !maPageList.empty() && "no Pages registered " );
+ IconChoicePageData* pData = GetPageData ( msCurrentPageId );
+ assert( pData && "ID not known " );
+
+ if ( pData->bRefresh )
+ {
+ pData->xPage->Reset( *pSet );
+ pData->bRefresh = false;
+ }
+
+ if ( pExampleSet )
+ pData->xPage->ActivatePage( *pExampleSet );
+ m_xDialog->set_help_id(pData->xPage->GetHelpId());
+
+ m_xResetBtn->show();
+}
+
+void SvxHpLinkDlg::DeActivatePageImpl ()
+{
+ IconChoicePageData *pData = GetPageData ( msCurrentPageId );
+
+ DeactivateRC nRet = DeactivateRC::LeavePage;
+
+ if ( !pData )
+ return;
+
+ IconChoicePage * pPage = pData->xPage.get();
+
+ if ( !pExampleSet && pPage->HasExchangeSupport() && pSet )
+ pExampleSet.reset(new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ));
+
+ if ( pSet )
+ {
+ SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
+
+ if ( pPage->HasExchangeSupport() )
+ nRet = pPage->DeactivatePage( &aTmp );
+
+ if ( ( DeactivateRC::LeavePage & nRet ) &&
+ aTmp.Count() )
+ {
+ if (pExampleSet)
+ pExampleSet->Put(aTmp);
+ pOutSet->Put( aTmp );
+ }
+ }
+ else
+ {
+ if ( pPage->HasExchangeSupport() ) //!!!
+ {
+ if ( !pExampleSet )
+ {
+ SfxItemPool* pPool = pPage->GetItemSet().GetPool();
+ pExampleSet.reset(
+ new SfxItemSet( *pPool, GetInputRanges( *pPool ) ) );
+ }
+ nRet = pPage->DeactivatePage( pExampleSet.get() );
+ }
+ else
+ nRet = pPage->DeactivatePage( nullptr );
+ }
+
+ if ( nRet & DeactivateRC::RefreshSet )
+ {
+ // TODO refresh input set
+ // flag all pages to be newly initialized
+ for (auto & pObj : maPageList)
+ {
+ if ( pObj->xPage.get() != pPage )
+ pObj->bRefresh = true;
+ else
+ pObj->bRefresh = false;
+ }
+ }
+}
+
+
+void SvxHpLinkDlg::ResetPageImpl ()
+{
+ IconChoicePageData *pData = GetPageData ( msCurrentPageId );
+
+ assert( pData && "ID not known " );
+
+ pData->xPage->Reset( *pSet );
+}
+
+/**********************************************************************
+|
+| handling itemsets
+|
+\**********************************************************************/
+
+WhichRangesContainer SvxHpLinkDlg::GetInputRanges( const SfxItemPool& )
+{
+ if ( pSet )
+ {
+ SAL_WARN( "cui.dialogs", "Set does already exist!" );
+ return pSet->GetRanges();
+ }
+
+ if ( !pRanges.empty() )
+ return pRanges;
+
+ return WhichRangesContainer();
+}
+
+
+void SvxHpLinkDlg::SetInputSet( const SfxItemSet* pInSet )
+{
+ bool bSet = ( pSet != nullptr );
+
+ pSet = pInSet;
+
+ if ( !bSet && !pExampleSet && !pOutSet )
+ {
+ pExampleSet.reset(new SfxItemSet( *pSet ));
+ pOutSet.reset(new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ));
+ }
+}
+
+bool SvxHpLinkDlg::QueryClose()
+{
+ bool bRet = true;
+ for (auto & pData : maPageList)
+ {
+ if ( pData->xPage && !pData->xPage->QueryClose() )
+ {
+ bRet = false;
+ break;
+ }
+ }
+ return bRet;
+}
+
+void SvxHpLinkDlg::Start()
+{
+ SwitchPage(msCurrentPageId);
+ ActivatePageImpl();
+}
+
+/**********************************************************************
+|
+| tool-methods
+|
+\**********************************************************************/
+
+IconChoicePageData* SvxHpLinkDlg::GetPageData ( std::string_view rId )
+{
+ IconChoicePageData *pRet = nullptr;
+ for (const auto & pData : maPageList)
+ {
+ if ( pData->sId == rId )
+ {
+ pRet = pData.get();
+ break;
+ }
+ }
+ return pRet;
+}
+
+/**********************************************************************
+|
+| OK-Status
+|
+\**********************************************************************/
+
+void SvxHpLinkDlg::SwitchPage( const OString& rId )
+{
+ m_xIconCtrl->set_current_page(rId);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/insdlg.cxx b/cui/source/dialogs/insdlg.cxx
new file mode 100644
index 000000000..3806c4dc2
--- /dev/null
+++ b/cui/source/dialogs/insdlg.cxx
@@ -0,0 +1,635 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XInsertObjectDialog.hpp>
+#include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+#include <insdlg.hxx>
+#include <dialmgr.hxx>
+#include <osl/diagnose.h>
+#include <svtools/imagemgr.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/diagnose_ex.h>
+#include <utility>
+#include <vcl/image.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/classids.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/frmdescr.hxx>
+#include <sfx2/viewsh.hxx>
+#include <comphelper/seqstream.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ui::dialogs;
+
+bool InsertObjectDialog_Impl::IsCreateNew() const
+{
+ return false;
+}
+
+uno::Reference< io::XInputStream > InsertObjectDialog_Impl::GetIconIfIconified( OUString* /*pGraphicMediaType*/ )
+{
+ return uno::Reference< io::XInputStream >();
+}
+
+InsertObjectDialog_Impl::InsertObjectDialog_Impl(weld::Window* pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ css::uno::Reference < css::embed::XStorage > xStorage)
+ : GenericDialogController(pParent, rUIXMLDescription, rID)
+ , m_xStorage(std::move( xStorage ))
+ , aCnt( m_xStorage )
+{
+}
+
+IMPL_LINK_NOARG(SvInsertOleDlg, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvInsertOleDlg, BrowseHdl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_xDialog.get());
+ aHelper.SetContext(sfx2::FileDialogHelper::InsertOLE);
+ const Reference< XFilePicker3 >& xFilePicker = aHelper.GetFilePicker();
+
+ // add filter
+ try
+ {
+ xFilePicker->appendFilter(CuiResId(RID_CUISTR_FILTER_ALL), "*.*");
+ }
+ catch( const IllegalArgumentException& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "caught IllegalArgumentException when registering filter" );
+ }
+
+ if( xFilePicker->execute() == ExecutableDialogResults::OK )
+ {
+ Sequence< OUString > aPathSeq( xFilePicker->getSelectedFiles() );
+ INetURLObject aObj( aPathSeq[0] );
+ m_xEdFilepath->set_text(aObj.PathToFileName());
+ }
+}
+
+IMPL_LINK(SvInsertOleDlg, RadioHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ if (m_xRbNewObject->get_active())
+ {
+ m_xObjectTypeFrame->show();
+ m_xFileFrame->hide();
+ }
+ else
+ {
+ m_xFileFrame->show();
+ m_xObjectTypeFrame->hide();
+ }
+}
+
+SvInsertOleDlg::SvInsertOleDlg(weld::Window* pParent, const Reference<embed::XStorage>& xStorage,
+ const SvObjectServerList* pServers)
+ : InsertObjectDialog_Impl( pParent, "cui/ui/insertoleobject.ui", "InsertOLEObjectDialog", xStorage)
+ , m_pServers( pServers )
+ , m_xRbNewObject(m_xBuilder->weld_radio_button("createnew"))
+ , m_xRbObjectFromfile(m_xBuilder->weld_radio_button("createfromfile"))
+ , m_xObjectTypeFrame(m_xBuilder->weld_frame("objecttypeframe"))
+ , m_xLbObjecttype(m_xBuilder->weld_tree_view("types"))
+ , m_xFileFrame(m_xBuilder->weld_frame("fileframe"))
+ , m_xEdFilepath(m_xBuilder->weld_entry("urled"))
+ , m_xBtnFilepath(m_xBuilder->weld_button("urlbtn"))
+ , m_xCbFilelink(m_xBuilder->weld_check_button("linktofile"))
+ , m_xCbAsIcon(m_xBuilder->weld_check_button("asicon"))
+{
+ m_xLbObjecttype->set_size_request(m_xLbObjecttype->get_approximate_digit_width() * 32,
+ m_xLbObjecttype->get_height_rows(6));
+ m_xLbObjecttype->connect_row_activated(LINK(this, SvInsertOleDlg, DoubleClickHdl));
+ m_xBtnFilepath->connect_clicked(LINK( this, SvInsertOleDlg, BrowseHdl));
+ Link<weld::Toggleable&,void> aLink( LINK( this, SvInsertOleDlg, RadioHdl ) );
+ m_xRbNewObject->connect_toggled( aLink );
+ m_xRbObjectFromfile->connect_toggled( aLink );
+ m_xRbNewObject->set_active(true);
+}
+
+short SvInsertOleDlg::run()
+{
+ short nRet = RET_OK;
+ SvObjectServerList aObjS;
+ if ( !m_pServers )
+ {
+ // if no list was provided, take the complete one
+ aObjS.FillInsertObjects();
+ m_pServers = &aObjS;
+ }
+
+ // fill listbox and select default
+ m_xLbObjecttype->freeze();
+ for ( size_t i = 0; i < m_pServers->Count(); i++ )
+ m_xLbObjecttype->append_text((*m_pServers)[i].GetHumanName());
+ m_xLbObjecttype->thaw();
+ m_xLbObjecttype->select(0);
+
+ DBG_ASSERT( m_xStorage.is(), "No storage!");
+ if ( m_xStorage.is() && ( nRet = InsertObjectDialog_Impl::run() ) == RET_OK )
+ {
+ OUString aFileName;
+ OUString aName;
+ bool bCreateNew = IsCreateNew();
+ if ( bCreateNew )
+ {
+ // create and insert new embedded object
+ OUString aServerName = m_xLbObjecttype->get_selected_text();
+ const SvObjectServer* pS = m_pServers->Get( aServerName );
+ if ( pS )
+ {
+ if( pS->GetClassName() == SvGlobalName( SO3_OUT_CLASSID ) )
+ {
+ try
+ {
+ uno::Reference < embed::XInsertObjectDialog > xDialogCreator(
+ embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() ),
+ uno::UNO_QUERY );
+
+ if ( xDialogCreator.is() )
+ {
+ aName = aCnt.CreateUniqueObjectName();
+
+ uno::Reference<task::XStatusIndicator> xProgress;
+ OUString aProgressText;
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ if (pFrame)
+ {
+ // Have a current frame, create a matching progressbar, but don't start it yet.
+ uno::Reference<frame::XFrame> xFrame
+ = pFrame->GetFrame().GetFrameInterface();
+ uno::Reference<task::XStatusIndicatorFactory> xProgressFactory(
+ xFrame, uno::UNO_QUERY);
+ if (xProgressFactory.is())
+ {
+ xProgress = xProgressFactory->createStatusIndicator();
+ if (xProgress)
+ {
+ aProgressText = CuiResId(RID_CUISTR_OLE_INSERT);
+ }
+ }
+ }
+
+ const embed::InsertedObjectInfo aNewInf = xDialogCreator->createInstanceByDialog(
+ m_xStorage,
+ aName,
+ {comphelper::makePropertyValue("StatusIndicator", xProgress),
+ comphelper::makePropertyValue("StatusIndicatorText", aProgressText)} );
+
+ OSL_ENSURE( aNewInf.Object.is(), "The object must be created or an exception must be thrown!" );
+ m_xObj = aNewInf.Object;
+ for ( const auto& opt : aNewInf.Options )
+ if ( opt.Name == "Icon" )
+ {
+ opt.Value >>= m_aIconMetaFile;
+ }
+ else if ( opt.Name == "IconFormat" )
+ {
+ datatransfer::DataFlavor aFlavor;
+ if ( opt.Value >>= aFlavor )
+ m_aIconMediaType = aFlavor.MimeType;
+ }
+
+ }
+ }
+ catch( ucb::CommandAbortedException& )
+ {
+ // the user has pressed cancel
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: Error handling
+ }
+ }
+ else
+ {
+ // create object with desired ClassId
+ m_xObj = aCnt.CreateEmbeddedObject( pS->GetClassName().GetByteSequence(), aName );
+ }
+
+ if ( !m_xObj.is() )
+ {
+ if( !aFileName.isEmpty() ) // from OLE Dialog
+ {
+ // object couldn't be created from file
+ // global Resource from svtools (former so3 resource)
+ OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE));
+ aErr = aErr.replaceFirst( "%", aFileName );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aErr));
+ xBox->run();
+ }
+ else
+ {
+ // object couldn't be created
+ // global Resource from svtools (former so3 resource)
+ OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE));
+ aErr = aErr.replaceFirst( "%", aServerName );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aErr));
+ xBox->run();
+ }
+ }
+ }
+ }
+ else
+ {
+ aFileName = m_xEdFilepath->get_text();
+ INetURLObject aURL;
+ aURL.SetSmartProtocol( INetProtocol::File );
+ aURL.SetSmartURL( aFileName );
+ aFileName = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ bool bLink = m_xCbFilelink->get_active();
+
+ if ( !aFileName.isEmpty() )
+ {
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< task::XInteractionHandler2 > xInteraction(
+ task::InteractionHandler::createWithParent(xContext, nullptr) );
+
+ // create MediaDescriptor for file to create object from
+ uno::Sequence < beans::PropertyValue > aMedium{
+ comphelper::makePropertyValue("URL", aFileName),
+ comphelper::makePropertyValue("InteractionHandler", xInteraction)
+ };
+
+ // create object from media descriptor
+
+ uno::Reference<task::XStatusIndicator> xProgress;
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ if (pFrame)
+ {
+ // Have a current frame, create visual indication that insert is in progress.
+ uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface();
+ uno::Reference<task::XStatusIndicatorFactory> xProgressFactory(xFrame, uno::UNO_QUERY);
+ if (xProgressFactory.is())
+ {
+ xProgress = xProgressFactory->createStatusIndicator();
+ if (xProgress)
+ {
+ OUString aOleInsert(CuiResId(RID_CUISTR_OLE_INSERT));
+ xProgress->start(aOleInsert, 100);
+ }
+ }
+ }
+
+ if ( bLink )
+ m_xObj = aCnt.InsertEmbeddedLink( aMedium, aName );
+ else
+ m_xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
+
+ if (xProgress.is())
+ {
+ xProgress->end();
+ }
+ }
+
+ if ( !m_xObj.is() )
+ {
+ // object couldn't be created from file
+ // global Resource from svtools (former so3 resource)
+ OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE));
+ aErr = aErr.replaceFirst( "%", aFileName );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aErr));
+ xBox->run();
+ }
+ else
+ {
+ if (m_xCbAsIcon->get_active())
+ {
+ //something nice here I guess would be to write the filename into
+ //the image with this icon above it
+ Image aImage = SvFileInformationManager::GetImage(aURL, true);
+ SvMemoryStream aTemp;
+ WriteDIBBitmapEx(aImage.GetBitmapEx(), aTemp);
+ m_aIconMetaFile = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aTemp.GetData()), aTemp.TellEnd());
+ m_aIconMediaType = "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
+ }
+ }
+ }
+ }
+
+ m_pServers = nullptr;
+ return nRet;
+}
+
+uno::Reference< io::XInputStream > SvInsertOleDlg::GetIconIfIconified( OUString* pGraphicMediaType )
+{
+ if ( m_aIconMetaFile.hasElements() )
+ {
+ if ( pGraphicMediaType )
+ *pGraphicMediaType = m_aIconMediaType;
+
+ return uno::Reference< io::XInputStream >( new ::comphelper::SequenceInputStream( m_aIconMetaFile ) );
+ }
+
+ return uno::Reference< io::XInputStream >();
+}
+
+
+SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window *pParent,
+ const css::uno::Reference < css::embed::XStorage >& xStorage)
+ : InsertObjectDialog_Impl(pParent, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
+ xStorage)
+{
+ Init();
+}
+
+SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window *pParent,
+ const uno::Reference < embed::XEmbeddedObject >& xObj)
+ : InsertObjectDialog_Impl(pParent, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
+ uno::Reference<embed::XStorage>())
+{
+ m_xObj = xObj;
+
+ Init();
+}
+
+void SfxInsertFloatingFrameDialog::Init()
+{
+ m_xEDName = m_xBuilder->weld_entry("edname");
+ m_xEDURL = m_xBuilder->weld_entry("edurl");
+ m_xBTOpen = m_xBuilder->weld_button("buttonbrowse");
+ m_xRBScrollingOn = m_xBuilder->weld_radio_button("scrollbaron");
+ m_xRBScrollingOff = m_xBuilder->weld_radio_button("scrollbaroff");
+ m_xRBScrollingAuto = m_xBuilder->weld_radio_button("scrollbarauto");
+ m_xRBFrameBorderOn = m_xBuilder->weld_radio_button("borderon");
+ m_xRBFrameBorderOff = m_xBuilder->weld_radio_button("borderoff");
+ m_xFTMarginWidth = m_xBuilder->weld_label("widthlabel");
+ m_xNMMarginWidth = m_xBuilder->weld_spin_button("width");
+ m_xCBMarginWidthDefault = m_xBuilder->weld_check_button("defaultwidth");
+ m_xFTMarginHeight = m_xBuilder->weld_label("heightlabel");
+ m_xNMMarginHeight = m_xBuilder->weld_spin_button("height");
+ m_xCBMarginHeightDefault = m_xBuilder->weld_check_button("defaultheight");
+
+ Link<weld::Toggleable&, void> aLink(LINK(this, SfxInsertFloatingFrameDialog, CheckHdl));
+ m_xCBMarginWidthDefault->connect_toggled(aLink);
+ m_xCBMarginHeightDefault->connect_toggled(aLink);
+
+ m_xCBMarginWidthDefault->set_active(true);
+ m_xCBMarginHeightDefault->set_active(true);
+ m_xRBScrollingAuto->set_active(true);
+ m_xRBFrameBorderOn->set_active(true);
+
+ m_xBTOpen->connect_clicked(LINK(this, SfxInsertFloatingFrameDialog, OpenHdl));
+}
+
+short SfxInsertFloatingFrameDialog::run()
+{
+ short nRet = RET_OK;
+ bool bOK = false;
+ uno::Reference < beans::XPropertySet > xSet;
+ if ( m_xObj.is() )
+ {
+ try
+ {
+ if ( m_xObj->getCurrentState() == embed::EmbedStates::LOADED )
+ m_xObj->changeState( embed::EmbedStates::RUNNING );
+ xSet.set( m_xObj->getComponent(), uno::UNO_QUERY );
+ OUString aStr;
+ uno::Any aAny = xSet->getPropertyValue( "FrameURL" );
+ if ( aAny >>= aStr )
+ m_xEDURL->set_text( aStr );
+ aAny = xSet->getPropertyValue( "FrameName" );
+ if ( aAny >>= aStr )
+ m_xEDName->set_text(aStr);
+
+ sal_Int32 nSize = SIZE_NOT_SET;
+ aAny = xSet->getPropertyValue( "FrameMarginWidth" );
+ aAny >>= nSize;
+
+ if ( nSize == SIZE_NOT_SET )
+ {
+ m_xCBMarginWidthDefault->set_active(true);
+ m_xNMMarginWidth->set_text(OUString::number(DEFAULT_MARGIN_WIDTH));
+ m_xFTMarginWidth->set_sensitive(false);
+ m_xNMMarginWidth->set_sensitive(false);
+ }
+ else
+ m_xNMMarginWidth->set_text(OUString::number(nSize));
+
+ aAny = xSet->getPropertyValue( "FrameMarginHeight" );
+ aAny >>= nSize;
+
+ if ( nSize == SIZE_NOT_SET )
+ {
+ m_xCBMarginHeightDefault->set_active(true);
+ m_xNMMarginHeight->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT));
+ m_xFTMarginHeight->set_sensitive(false);
+ m_xNMMarginHeight->set_sensitive(false);
+ }
+ else
+ m_xNMMarginHeight->set_text(OUString::number(nSize));
+
+ bool bScrollOn = false;
+ bool bScrollOff = false;
+ bool bScrollAuto = false;
+
+ bool bSet = false;
+ aAny = xSet->getPropertyValue( "FrameIsAutoScroll" );
+ aAny >>= bSet;
+ if ( !bSet )
+ {
+ aAny = xSet->getPropertyValue( "FrameIsScrollingMode" );
+ aAny >>= bSet;
+ bScrollOn = bSet;
+ bScrollOff = !bSet;
+ }
+ else
+ bScrollAuto = true;
+
+ m_xRBScrollingOn->set_sensitive(bScrollOn);
+ m_xRBScrollingOff->set_sensitive(bScrollOff);
+ m_xRBScrollingAuto->set_sensitive(bScrollAuto);
+
+ bSet = false;
+ aAny = xSet->getPropertyValue( "FrameIsAutoBorder" );
+ aAny >>= bSet;
+ if ( !bSet )
+ {
+ aAny = xSet->getPropertyValue( "FrameIsBorder" );
+ aAny >>= bSet;
+ m_xRBFrameBorderOn->set_active(bSet);
+ m_xRBFrameBorderOff->set_active(!bSet);
+ }
+
+ bOK = true;
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL( "No IFrame!" );
+ }
+ }
+ else
+ {
+ DBG_ASSERT( m_xStorage.is(), "No storage!");
+ bOK = m_xStorage.is();
+ }
+
+ if (!bOK)
+ return RET_OK;
+
+ nRet = InsertObjectDialog_Impl::run();
+ if ( nRet == RET_OK )
+ {
+ OUString aURL;
+ if (!m_xEDURL->get_text().isEmpty())
+ {
+ // URL can be a valid and absolute URL or a system file name
+ INetURLObject aObj;
+ aObj.SetSmartProtocol( INetProtocol::File );
+ if ( aObj.SetSmartURL( m_xEDURL->get_text() ) )
+ aURL = aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+
+ if ( !m_xObj.is() && !aURL.isEmpty() )
+ {
+ // create the object
+ OUString aName;
+ SvGlobalName aClassId( SO3_IFRAME_CLASSID );
+ m_xObj = aCnt.CreateEmbeddedObject( aClassId.GetByteSequence(), aName );
+ if ( m_xObj->getCurrentState() == embed::EmbedStates::LOADED )
+ m_xObj->changeState( embed::EmbedStates::RUNNING );
+ xSet.set( m_xObj->getComponent(), uno::UNO_QUERY );
+ }
+
+ if ( m_xObj.is() )
+ {
+ try
+ {
+ bool bIPActive = m_xObj->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE;
+ if ( bIPActive )
+ m_xObj->changeState( embed::EmbedStates::RUNNING );
+
+ OUString aName = m_xEDName->get_text();
+ ScrollingMode eScroll = ScrollingMode::No;
+ if (m_xRBScrollingOn->get_active())
+ eScroll = ScrollingMode::Yes;
+ if (m_xRBScrollingOff->get_active())
+ eScroll = ScrollingMode::No;
+ if (m_xRBScrollingAuto->get_active())
+ eScroll = ScrollingMode::Auto;
+
+ bool bHasBorder = m_xRBFrameBorderOn->get_active();
+
+ tools::Long lMarginWidth;
+ if (!m_xCBMarginWidthDefault->get_active())
+ lMarginWidth = static_cast<tools::Long>(m_xNMMarginWidth->get_text().toInt32());
+ else
+ lMarginWidth = SIZE_NOT_SET;
+
+ tools::Long lMarginHeight;
+ if (!m_xCBMarginHeightDefault->get_active())
+ lMarginHeight = static_cast<tools::Long>(m_xNMMarginHeight->get_text().toInt32());
+ else
+ lMarginHeight = SIZE_NOT_SET;
+
+ xSet->setPropertyValue( "FrameURL", Any( aURL ) );
+ xSet->setPropertyValue( "FrameName", Any( aName ) );
+
+ if ( eScroll == ScrollingMode::Auto )
+ xSet->setPropertyValue( "FrameIsAutoScroll", Any( true ) );
+ else
+ xSet->setPropertyValue( "FrameIsScrollingMode", Any( eScroll == ScrollingMode::Yes ) );
+
+ xSet->setPropertyValue( "FrameIsBorder", Any( bHasBorder ) );
+ xSet->setPropertyValue( "FrameMarginWidth", Any( sal_Int32( lMarginWidth ) ) );
+ xSet->setPropertyValue( "FrameMarginHeight", Any( sal_Int32( lMarginHeight ) ) );
+
+ if ( bIPActive )
+ m_xObj->changeState( embed::EmbedStates::INPLACE_ACTIVE );
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL( "No IFrame!" );
+ }
+ }
+ }
+
+ return nRet;
+}
+
+IMPL_LINK(SfxInsertFloatingFrameDialog, CheckHdl, weld::Toggleable&, rButton, void)
+{
+ weld::CheckButton& rCB = dynamic_cast<weld::CheckButton&>(rButton);
+ if (&rCB == m_xCBMarginWidthDefault.get())
+ {
+ if (rCB.get_active())
+ m_xNMMarginWidth->set_text(OUString::number(DEFAULT_MARGIN_WIDTH));
+ m_xFTMarginWidth->set_sensitive(!rCB.get_active());
+ m_xNMMarginWidth->set_sensitive(!rCB.get_active());
+ }
+
+ if (&rCB == m_xCBMarginHeightDefault.get())
+ {
+ if (rCB.get_active())
+ m_xNMMarginHeight->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT));
+ m_xFTMarginHeight->set_sensitive(!rCB.get_active());
+ m_xNMMarginHeight->set_sensitive(!rCB.get_active());
+ }
+}
+
+IMPL_LINK_NOARG( SfxInsertFloatingFrameDialog, OpenHdl, weld::Button&, void)
+{
+ // create the file dialog
+ sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, OUString(),
+ SfxFilterFlags::NONE, SfxFilterFlags::NONE, m_xDialog.get());
+
+ // set the title
+ aFileDlg.SetTitle(CuiResId(RID_CUISTR_SELECT_FILE_IFRAME));
+
+ // show the dialog
+ if ( aFileDlg.Execute() == ERRCODE_NONE )
+ m_xEDURL->set_text(INetURLObject(aFileDlg.GetPath()).GetMainURL(INetURLObject::DecodeMechanism::WithCharset));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/insrc.cxx b/cui/source/dialogs/insrc.cxx
new file mode 100644
index 000000000..bec311442
--- /dev/null
+++ b/cui/source/dialogs/insrc.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <insrc.hxx>
+
+bool SvxInsRowColDlg::isInsertBefore() const
+{
+ return !m_xAfterBtn->get_active();
+}
+
+sal_uInt16 SvxInsRowColDlg::getInsertCount() const
+{
+ return m_xCountEdit->get_value();
+}
+
+SvxInsRowColDlg::SvxInsRowColDlg(weld::Window* pParent, bool bColumn, const OString& rHelpId)
+ : GenericDialogController(pParent, "cui/ui/insertrowcolumn.ui", "InsertRowColumnDialog")
+ , m_xCountEdit(m_xBuilder->weld_spin_button("insert_number"))
+ , m_xBeforeBtn(m_xBuilder->weld_radio_button("insert_before"))
+ , m_xAfterBtn(m_xBuilder->weld_radio_button("insert_after"))
+{
+ m_xDialog->set_title(bColumn ? CuiResId(RID_CUISTR_COL) : CuiResId(RID_CUISTR_ROW));
+
+ // tdf#119293
+ if (bColumn) {
+ m_xBeforeBtn->set_label(CuiResId(RID_CUISTR_INSERTCOL_BEFORE));
+ m_xAfterBtn->set_label(CuiResId(RID_CUISTR_INSERTCOL_AFTER));
+ } else {
+ m_xBeforeBtn->set_label(CuiResId(RID_CUISTR_INSERTROW_BEFORE));
+ m_xAfterBtn->set_label(CuiResId(RID_CUISTR_INSERTROW_AFTER));
+ }
+
+ m_xDialog->set_help_id(rHelpId);
+}
+
+short SvxInsRowColDlg::Execute()
+{
+ return run();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/linkdlg.cxx b/cui/source/dialogs/linkdlg.cxx
new file mode 100644
index 000000000..055721d73
--- /dev/null
+++ b/cui/source/dialogs/linkdlg.cxx
@@ -0,0 +1,644 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <linkdlg.hxx>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+
+#include <tools/diagnose_ex.h>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/weldutils.hxx>
+
+#include <strings.hrc>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/linksrc.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <sfx2/objsh.hxx>
+
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <dialmgr.hxx>
+
+
+using namespace sfx2;
+using namespace ::com::sun::star;
+
+namespace {
+
+class SvBaseLinkMemberList {
+private:
+ std::vector<SvBaseLink*> mLinks;
+
+public:
+ ~SvBaseLinkMemberList()
+ {
+ for (auto const& link : mLinks)
+ {
+ if( link )
+ link->ReleaseRef();
+ }
+ }
+
+ size_t size() const { return mLinks.size(); }
+
+ SvBaseLink *operator[](size_t i) const { return mLinks[i]; }
+
+ void push_back(SvBaseLink* p)
+ {
+ mLinks.push_back(p);
+ p->AddFirstRef();
+ }
+};
+
+}
+
+SvBaseLinksDlg::SvBaseLinksDlg(weld::Window * pParent, LinkManager* pMgr, bool bHtmlMode)
+ : GenericDialogController(pParent, "cui/ui/baselinksdialog.ui", "BaseLinksDialog")
+ , aStrAutolink( CuiResId( STR_AUTOLINK ) )
+ , aStrManuallink( CuiResId( STR_MANUALLINK ) )
+ , aStrBrokenlink( CuiResId( STR_BROKENLINK ) )
+ , aStrCloselinkmsg( CuiResId( STR_CLOSELINKMSG ) )
+ , aStrCloselinkmsgMulti( CuiResId( STR_CLOSELINKMSG_MULTI ) )
+ , aStrWaitinglink( CuiResId( STR_WAITINGLINK ) )
+ , pLinkMgr( nullptr )
+ , aUpdateIdle("cui SvBaseLinksDlg UpdateIdle")
+ , m_xTbLinks(m_xBuilder->weld_tree_view("TB_LINKS"))
+ , m_xFtFullFileName(m_xBuilder->weld_link_button("FULL_FILE_NAME"))
+ , m_xFtFullSourceName(m_xBuilder->weld_label("FULL_SOURCE_NAME"))
+ , m_xFtFullTypeName(m_xBuilder->weld_label("FULL_TYPE_NAME"))
+ , m_xRbAutomatic(m_xBuilder->weld_radio_button("AUTOMATIC"))
+ , m_xRbManual(m_xBuilder->weld_radio_button("MANUAL"))
+ , m_xPbUpdateNow(m_xBuilder->weld_button("UPDATE_NOW"))
+ , m_xPbChangeSource(m_xBuilder->weld_button("CHANGE_SOURCE"))
+ , m_xPbBreakLink(m_xBuilder->weld_button("BREAK_LINK"))
+ , m_xVirDev(VclPtr<VirtualDevice>::Create())
+{
+ // expand the point size of the desired font to the equivalent pixel size
+ weld::SetPointFont(*m_xVirDev, m_xTbLinks->get_font());
+ m_xTbLinks->set_size_request(m_xTbLinks->get_approximate_digit_width() * 90,
+ m_xTbLinks->get_height_rows(12));
+
+ m_xTbLinks->set_selection_mode(SelectionMode::Multiple);
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 30),
+ o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 20),
+ o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 20)
+ };
+ m_xTbLinks->set_column_fixed_widths(aWidths);
+
+ // UpdateTimer for DDE-/Grf-links, which are waited for
+ aUpdateIdle.SetInvokeHandler( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
+ aUpdateIdle.SetPriority( TaskPriority::LOWEST );
+
+ m_xTbLinks->connect_changed( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
+ m_xTbLinks->connect_row_activated( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
+ m_xRbAutomatic->connect_toggled( LINK( this, SvBaseLinksDlg, ToggleHdl ) );
+ m_xRbManual->connect_toggled( LINK( this, SvBaseLinksDlg, ToggleHdl ) );
+ m_xPbUpdateNow->connect_clicked( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
+ m_xPbChangeSource->connect_clicked( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
+ if(!bHtmlMode)
+ m_xPbBreakLink->connect_clicked( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
+ else
+ m_xPbBreakLink->hide();
+
+ SetManager( pMgr );
+}
+
+SvBaseLinksDlg::~SvBaseLinksDlg()
+{
+}
+
+/*************************************************************************
+|* SvBaseLinksDlg::Handler()
+*************************************************************************/
+IMPL_LINK(SvBaseLinksDlg, LinksSelectHdl, weld::TreeView&, rTreeView, void)
+{
+ LinksSelectHdl(&rTreeView);
+}
+
+void SvBaseLinksDlg::LinksSelectHdl(weld::TreeView* pSvTabListBox)
+{
+ const int nSelectionCount = pSvTabListBox ?
+ pSvTabListBox->count_selected_rows() : 0;
+ if (nSelectionCount > 1)
+ {
+ // possibly deselect old entries in case of multi-selection
+ int nSelEntry = pSvTabListBox->get_selected_index();
+ SvBaseLink* pLink = weld::fromId<SvBaseLink*>(pSvTabListBox->get_id(nSelEntry));
+ SvBaseLinkObjectType nObjectType = pLink->GetObjType();
+ if(!isClientFileType(nObjectType))
+ {
+ pSvTabListBox->unselect_all();
+ pSvTabListBox->select(nSelEntry);
+ }
+ else
+ {
+ std::vector<int> aRows = pSvTabListBox->get_selected_rows();
+ for (auto nEntry : aRows)
+ {
+ pLink = weld::fromId<SvBaseLink*>(pSvTabListBox->get_id(nEntry));
+ DBG_ASSERT(pLink, "Where is the Link?");
+ if (!pLink)
+ continue;
+ if( !isClientFileType(pLink->GetObjType()) )
+ pSvTabListBox->unselect(nEntry);
+ }
+ }
+
+ m_xPbUpdateNow->set_sensitive(true);
+ m_xRbAutomatic->set_sensitive(false);
+ m_xRbManual->set_active(true);
+ m_xRbManual->set_sensitive(false);
+ }
+ else
+ {
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+ if( !pLink )
+ return;
+
+ m_xPbUpdateNow->set_sensitive(true);
+
+ OUString sType, sLink;
+ OUString *pLinkNm = &sLink, *pFilter = nullptr;
+
+ if( isClientFileType(pLink->GetObjType()) )
+ {
+ m_xRbAutomatic->set_sensitive(false);
+ m_xRbManual->set_active(true);
+ m_xRbManual->set_sensitive(false);
+ if( SvBaseLinkObjectType::ClientGraphic == pLink->GetObjType() )
+ {
+ pLinkNm = nullptr;
+ pFilter = &sLink;
+ }
+ }
+ else
+ {
+ m_xRbAutomatic->set_sensitive(true);
+ m_xRbManual->set_sensitive(true);
+
+ if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
+ m_xRbAutomatic->set_active(true);
+ else
+ m_xRbManual->set_active(true);
+ }
+
+ OUString aFileName;
+ sfx2::LinkManager::GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
+ aFileName = INetURLObject::decode(aFileName, INetURLObject::DecodeMechanism::Unambiguous);
+ m_xFtFullFileName->set_label( aFileName );
+ m_xFtFullFileName->set_uri( aFileName );
+ m_xFtFullSourceName->set_label( sLink );
+ m_xFtFullTypeName->set_label( sType );
+ }
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, weld::TreeView&, bool )
+{
+ ChangeSourceClickHdl(*m_xPbChangeSource);
+ return true;
+}
+
+IMPL_LINK(SvBaseLinksDlg, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+
+ if (m_xRbAutomatic->get_active())
+ {
+ if( pLink && !isClientFileType( pLink->GetObjType() ) &&
+ SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
+ SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
+ }
+ else
+ {
+ if( pLink && !isClientFileType( pLink->GetObjType() ) &&
+ SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
+ SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
+ }
+}
+
+IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, weld::Button&, void)
+{
+ std::vector< SvBaseLink* > aLnkArr;
+ std::vector< sal_Int16 > aPosArr;
+
+ std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+ for (int nFndPos : aRows)
+ {
+ aLnkArr.push_back( weld::fromId<SvBaseLink*>( m_xTbLinks->get_id(nFndPos) ) );
+ aPosArr.push_back( nFndPos );
+ }
+
+ if( aLnkArr.empty() )
+ return;
+
+ for( size_t n = 0; n < aLnkArr.size(); ++n )
+ {
+ tools::SvRef<SvBaseLink> xLink = aLnkArr[ n ];
+
+ // first look for the entry in the array
+ for(const auto & i : pLinkMgr->GetLinks())
+ if( xLink == i )
+ {
+ SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
+ break;
+ }
+ }
+
+ // if somebody is of the opinion to swap his links (SD)
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+
+
+ OUString sId = weld::toId(aLnkArr[0]);
+ int nE = m_xTbLinks->find_id(sId);
+ if (nE == -1)
+ nE = m_xTbLinks->get_selected_index();
+ int nSelEntry = m_xTbLinks->get_selected_index();
+ if (nE != nSelEntry)
+ m_xTbLinks->unselect(nSelEntry);
+ m_xTbLinks->select(nE);
+ m_xTbLinks->scroll_to_row(nE);
+
+ pNewMgr->CloseCachedComps();
+}
+
+IMPL_LINK_NOARG(SvBaseLinksDlg, ChangeSourceClickHdl, weld::Button&, void)
+{
+ std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+ if (aRows.size() > 1)
+ {
+ try
+ {
+ uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
+ comphelper::getProcessComponentContext(), m_xDialog.get());
+
+ OUString sType, sFile, sLinkName;
+ OUString sFilter;
+ SvBaseLink* pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(aRows[0]));
+ sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile );
+ INetURLObject aUrl(sFile);
+ if(aUrl.GetProtocol() == INetProtocol::File)
+ {
+ OUString sOldPath(aUrl.PathToFileName());
+ sal_Int32 nLen = aUrl.GetLastName().getLength();
+ sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
+ xFolderPicker->setDisplayDirectory(sOldPath);
+ }
+ if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ OUString aPath = xFolderPicker->getDirectory();
+
+ for (auto nRow : aRows)
+ {
+ pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nRow));
+ DBG_ASSERT(pLink,"Where is the link?");
+ if (!pLink)
+ continue;
+ sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
+ INetURLObject aUrl_(sFile);
+ INetURLObject aUrl2(aPath, INetProtocol::File);
+ aUrl2.insertName( aUrl_.getName() );
+ OUString sNewLinkName;
+ MakeLnkName( sNewLinkName, nullptr ,
+ aUrl2.GetMainURL(INetURLObject::DecodeMechanism::ToIUri), sLinkName, &sFilter);
+ pLink->SetLinkSourceName( sNewLinkName );
+ pLink->Update();
+ }
+ if( pLinkMgr->GetPersist() )
+ pLinkMgr->GetPersist()->SetModified();
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "SvBaseLinksDlg");
+ }
+ }
+ else
+ {
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+ if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
+ pLink->Edit(m_xDialog.get(), LINK(this, SvBaseLinksDlg, EndEditHdl));
+ }
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, weld::Button&, void )
+{
+ bool bModified = false;
+ if (m_xTbLinks->count_selected_rows() <= 1)
+ {
+ int nPos;
+ tools::SvRef<SvBaseLink> xLink = GetSelEntry( &nPos );
+ if( !xLink.is() )
+ return;
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ aStrCloselinkmsg));
+ xQueryBox->set_default_response(RET_YES);
+
+ if (RET_YES == xQueryBox->run())
+ {
+ m_xTbLinks->remove(nPos);
+
+ // close object, if it's still existing
+ bool bNewLnkMgr = SvBaseLinkObjectType::ClientFile == xLink->GetObjType();
+
+ // tell the link that it will be resolved!
+ xLink->Closed();
+
+ // if somebody has forgotten to deregister himself
+ if( xLink.is() )
+ pLinkMgr->Remove( xLink.get() );
+
+ if( bNewLnkMgr )
+ {
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+ m_xTbLinks->set_cursor(nPos ? --nPos : 0);
+ }
+ bModified = true;
+ }
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ aStrCloselinkmsgMulti));
+ xQueryBox->set_default_response(RET_YES);
+
+ if (RET_YES == xQueryBox->run())
+ {
+ std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+ SvBaseLinkMemberList aLinkList;
+ for (auto nRow : aRows)
+ {
+ SvBaseLink* pLink = weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nRow));
+ if (pLink)
+ aLinkList.push_back(pLink);
+ }
+ std::sort(aRows.begin(), aRows.end());
+ for (auto it = aRows.rbegin(); it != aRows.rend(); ++it)
+ m_xTbLinks->remove(*it);
+ for (size_t i = 0; i < aLinkList.size(); ++i)
+ {
+ tools::SvRef<SvBaseLink> xLink = aLinkList[i];
+ // tell the link that it will be resolved!
+ xLink->Closed();
+
+ // if somebody has forgotten to deregister himself
+ pLinkMgr->Remove( xLink.get() );
+ bModified = true;
+ }
+ // then remove all selected entries
+ }
+ }
+ if(!bModified)
+ return;
+
+ if (!m_xTbLinks->n_children())
+ {
+ m_xRbAutomatic->set_sensitive(false);
+ m_xRbManual->set_sensitive(false);
+ m_xPbUpdateNow->set_sensitive(false);
+ m_xPbChangeSource->set_sensitive(false);
+ m_xPbBreakLink->set_sensitive(false);
+
+ m_xFtFullSourceName->set_label( "" );
+ m_xFtFullTypeName->set_label( "" );
+ }
+ if( pLinkMgr && pLinkMgr->GetPersist() )
+ pLinkMgr->GetPersist()->SetModified();
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, void )
+{
+ m_xTbLinks->freeze();
+ for (int nPos = m_xTbLinks->n_children(); nPos; --nPos)
+ {
+ tools::SvRef<SvBaseLink> xLink( weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nPos)) );
+ if( xLink.is() )
+ {
+ OUString sCur( ImplGetStateStr( *xLink ) ),
+ sOld( m_xTbLinks->get_text(nPos, 3) );
+ if( sCur != sOld )
+ m_xTbLinks->set_text(nPos, sCur, 3);
+ }
+ }
+ m_xTbLinks->thaw();
+}
+
+IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
+{
+ int nPos;
+ GetSelEntry( &nPos );
+
+ if( !_rLink.WasLastEditOK() )
+ return;
+
+ // StarImpress/Draw swap the LinkObjects themselves!
+ // So search for the link in the manager; if it does not exist
+ // anymore, fill the list completely new. Otherwise only the
+ // edited link needs to be refreshed.
+ bool bLinkFnd = false;
+ for( size_t n = pLinkMgr->GetLinks().size(); n; )
+ if( &_rLink == &(*pLinkMgr->GetLinks()[ --n ]) )
+ {
+ bLinkFnd = true;
+ break;
+ }
+
+ if( bLinkFnd )
+ {
+ m_xTbLinks->remove(nPos);
+ int nToUnselect = m_xTbLinks->get_selected_index();
+ InsertEntry(_rLink, nPos, true);
+ if (nToUnselect != -1)
+ m_xTbLinks->unselect(nToUnselect);
+ }
+ else
+ {
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+ }
+ if (pLinkMgr && pLinkMgr->GetPersist())
+ pLinkMgr->GetPersist()->SetModified();
+}
+
+OUString SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
+{
+ OUString sRet;
+ if( !rLnk.GetObj() )
+ sRet = aStrBrokenlink;
+ else if( rLnk.GetObj()->IsPending() )
+ {
+ sRet = aStrWaitinglink;
+ aUpdateIdle.Start();
+ }
+ else if( SfxLinkUpdateMode::ALWAYS == rLnk.GetUpdateMode() )
+ sRet = aStrAutolink;
+ else
+ sRet = aStrManuallink;
+
+ return sRet;
+}
+
+void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
+{
+ if( pLinkMgr == pNewMgr )
+ return;
+
+ if (pNewMgr)
+ {
+ // update has to be stopped before clear
+ m_xTbLinks->freeze();
+ }
+
+ m_xTbLinks->clear();
+ pLinkMgr = pNewMgr;
+
+ if( !pLinkMgr )
+ return;
+
+ SvBaseLinks& rLnks = const_cast<SvBaseLinks&>(pLinkMgr->GetLinks());
+ for( size_t n = 0; n < rLnks.size(); ++n )
+ {
+ tools::SvRef<SvBaseLink>& rLinkRef = rLnks[ n ];
+ if( !rLinkRef.is() )
+ {
+ rLnks.erase( rLnks.begin() + n );
+ --n;
+ continue;
+ }
+ if( rLinkRef->IsVisible() )
+ InsertEntry( *rLinkRef );
+ }
+
+ m_xTbLinks->thaw();
+
+ if( !rLnks.empty() )
+ {
+ m_xTbLinks->set_cursor(0);
+ m_xTbLinks->select(0);
+ LinksSelectHdl( nullptr );
+ }
+}
+
+void SvBaseLinksDlg::InsertEntry(const SvBaseLink& rLink, int nPos, bool bSelect)
+{
+ OUString sFileNm, sLinkNm, sTypeNm, sFilter;
+
+ sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
+
+ auto nWidthPixel = m_xTbLinks->get_column_width(0);
+ OUString aTxt = m_xVirDev->GetEllipsisString(sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis);
+ INetURLObject aPath( sFileNm, INetProtocol::File );
+ OUString aFileName = aPath.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::Unambiguous);
+
+ if( aFileName.getLength() > aTxt.getLength() )
+ aTxt = aFileName;
+ else if (!aFileName.isEmpty() && aTxt.indexOf(aFileName, aTxt.getLength() - aFileName.getLength()) == -1)
+ // filename not in string
+ aTxt = aFileName;
+
+ if (nPos == -1)
+ nPos = m_xTbLinks->n_children();
+ m_xTbLinks->insert(nPos);
+ m_xTbLinks->set_text(nPos, aTxt, 0);
+ m_xTbLinks->set_id(nPos, weld::toId(&rLink));
+ if( SvBaseLinkObjectType::ClientGraphic == rLink.GetObjType() )
+ m_xTbLinks->set_text(nPos, sFilter, 1);
+ else
+ m_xTbLinks->set_text(nPos, sLinkNm, 1);
+ m_xTbLinks->set_text(nPos, sTypeNm, 2);
+ m_xTbLinks->set_text(nPos, ImplGetStateStr(rLink), 3);
+ if (bSelect)
+ m_xTbLinks->select(nPos);
+}
+
+SvBaseLink* SvBaseLinksDlg::GetSelEntry(int* pPos)
+{
+ int nPos = m_xTbLinks->get_selected_index();
+ if (nPos != -1)
+ {
+ if (pPos)
+ *pPos = nPos;
+ return weld::fromId<SvBaseLink*>(m_xTbLinks->get_id(nPos));
+ }
+ return nullptr;
+}
+
+void SvBaseLinksDlg::SetType(SvBaseLink& rLink,
+ int nSelPos,
+ SfxLinkUpdateMode nType)
+{
+ rLink.SetUpdateMode( nType );
+ rLink.Update();
+ m_xTbLinks->set_text(nSelPos, ImplGetStateStr(rLink), 3);
+ if (pLinkMgr->GetPersist())
+ pLinkMgr->GetPersist()->SetModified();
+}
+
+void SvBaseLinksDlg::SetActLink( SvBaseLink const * pLink )
+{
+ if( !pLinkMgr )
+ return;
+
+ const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
+ int nSelect = 0;
+ for(const auto & rLinkRef : rLnks)
+ {
+ // #109573# only visible links have been inserted into the TreeListBox,
+ // invisible ones have to be skipped here
+ if( rLinkRef->IsVisible() )
+ {
+ if( pLink == rLinkRef.get() )
+ {
+ m_xTbLinks->select(nSelect);
+ LinksSelectHdl( nullptr );
+ return ;
+ }
+ ++nSelect;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/multipat.cxx b/cui/source/dialogs/multipat.cxx
new file mode 100644
index 000000000..085d21f99
--- /dev/null
+++ b/cui/source/dialogs/multipat.cxx
@@ -0,0 +1,316 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <osl/file.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <multipat.hxx>
+#include <dialmgr.hxx>
+
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <unotools/pathoptions.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+IMPL_LINK_NOARG(SvxMultiPathDialog, SelectHdl_Impl, weld::TreeView&, void)
+{
+ auto nCount = m_xRadioLB->n_children();
+ bool bIsSelected = m_xRadioLB->get_selected_index() != -1;
+ bool bEnable = nCount > 1;
+ m_xDelBtn->set_sensitive(bEnable && bIsSelected);
+}
+
+IMPL_LINK_NOARG(SvxPathSelectDialog, SelectHdl_Impl, weld::TreeView&, void)
+{
+ auto nCount = m_xPathLB->n_children();
+ bool bIsSelected = m_xPathLB->get_selected_index() != -1;
+ bool bEnable = nCount > 1;
+ m_xDelBtn->set_sensitive(bEnable && bIsSelected);
+}
+
+void SvxMultiPathDialog::HandleEntryChecked(int nRow)
+{
+ m_xRadioLB->select(nRow);
+ bool bChecked = m_xRadioLB->get_toggle(nRow) == TRISTATE_TRUE;
+ if (bChecked)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ int nCount = m_xRadioLB->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (i != nRow)
+ m_xRadioLB->set_toggle(i, TRISTATE_FALSE);
+ }
+ }
+}
+
+IMPL_LINK(SvxMultiPathDialog, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ HandleEntryChecked(m_xRadioLB->get_iter_index_in_parent(rRowCol.first));
+}
+
+void SvxMultiPathDialog::AppendEntry(const OUString& rText, const OUString& rId)
+{
+ m_xRadioLB->append();
+ const int nRow = m_xRadioLB->n_children() - 1;
+ m_xRadioLB->set_toggle(nRow, TRISTATE_FALSE);
+ m_xRadioLB->set_text(nRow, rText, 0);
+ m_xRadioLB->set_id(nRow, rId);
+}
+
+IMPL_LINK_NOARG(SvxMultiPathDialog, AddHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_xDialog.get());
+
+ if ( xFolderPicker->execute() != ExecutableDialogResults::OK )
+ return;
+
+ INetURLObject aPath( xFolderPicker->getDirectory() );
+ aPath.removeFinalSlash();
+ OUString aURL = aPath.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ OUString sInsPath;
+ osl::FileBase::getSystemPathFromFileURL(aURL, sInsPath);
+
+ if (m_xRadioLB->find_text(sInsPath) != -1)
+ {
+ OUString sMsg( CuiResId( RID_MULTIPATH_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sInsPath );
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xInfoBox->run();
+ }
+ else
+ {
+ AppendEntry(sInsPath, aURL);
+ }
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+IMPL_LINK_NOARG(SvxPathSelectDialog, AddHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_xDialog.get());
+
+ if ( xFolderPicker->execute() != ExecutableDialogResults::OK )
+ return;
+
+ INetURLObject aPath( xFolderPicker->getDirectory() );
+ aPath.removeFinalSlash();
+ OUString aURL = aPath.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ OUString sInsPath;
+ osl::FileBase::getSystemPathFromFileURL(aURL, sInsPath);
+
+ if (m_xPathLB->find_text(sInsPath) != -1)
+ {
+ OUString sMsg( CuiResId( RID_MULTIPATH_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sInsPath );
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xInfoBox->run();
+ }
+ else
+ {
+ m_xPathLB->append(aURL, sInsPath);
+ }
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+IMPL_LINK_NOARG(SvxMultiPathDialog, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xRadioLB->get_selected_index();
+ bool bChecked = m_xRadioLB->get_toggle(nPos) == TRISTATE_TRUE;
+ m_xRadioLB->remove(nPos);
+ int nCnt = m_xRadioLB->n_children();
+ if (nCnt)
+ {
+ --nCnt;
+
+ if ( nPos > nCnt )
+ nPos = nCnt;
+ if (bChecked)
+ {
+ m_xRadioLB->set_toggle(nPos, TRISTATE_TRUE);
+ HandleEntryChecked(nPos);
+ }
+ m_xRadioLB->select(nPos);
+ }
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+IMPL_LINK_NOARG(SvxPathSelectDialog, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xPathLB->get_selected_index();
+ m_xPathLB->remove(nPos);
+ int nCnt = m_xPathLB->n_children();
+
+ if (nCnt)
+ {
+ --nCnt;
+
+ if ( nPos > nCnt )
+ nPos = nCnt;
+ m_xPathLB->select(nPos);
+ }
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+SvxMultiPathDialog::SvxMultiPathDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/multipathdialog.ui", "MultiPathDialog")
+ , m_xRadioLB(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDelBtn(m_xBuilder->weld_button("delete"))
+{
+ m_xRadioLB->set_size_request(m_xRadioLB->get_approximate_digit_width() * 60,
+ m_xRadioLB->get_text_height() * 10);
+ m_xRadioLB->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ m_xRadioLB->connect_toggled(LINK(this, SvxMultiPathDialog, CheckHdl_Impl));
+ m_xRadioLB->connect_changed(LINK(this, SvxMultiPathDialog, SelectHdl_Impl));
+
+ m_xAddBtn->connect_clicked(LINK(this, SvxMultiPathDialog, AddHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this, SvxMultiPathDialog, DelHdl_Impl));
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+SvxPathSelectDialog::SvxPathSelectDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/selectpathdialog.ui", "SelectPathDialog")
+ , m_xPathLB(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDelBtn(m_xBuilder->weld_button("delete"))
+{
+ m_xPathLB->set_size_request(m_xPathLB->get_approximate_digit_width() * 60,
+ m_xPathLB->get_text_height() * 10);
+
+ m_xPathLB->connect_changed(LINK(this, SvxPathSelectDialog, SelectHdl_Impl));
+ m_xAddBtn->connect_clicked(LINK(this, SvxPathSelectDialog, AddHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this, SvxPathSelectDialog, DelHdl_Impl));
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+SvxMultiPathDialog::~SvxMultiPathDialog()
+{
+}
+
+OUString SvxMultiPathDialog::GetPath() const
+{
+ OUStringBuffer sNewPath;
+ sal_Unicode cDelim = SVT_SEARCHPATH_DELIMITER;
+
+ OUString sWritable;
+ for (int i = 0, nCount = m_xRadioLB->n_children(); i < nCount; ++i)
+ {
+ if (m_xRadioLB->get_toggle(i) == TRISTATE_TRUE)
+ sWritable = m_xRadioLB->get_id(i);
+ else
+ {
+ if (!sNewPath.isEmpty())
+ sNewPath.append(cDelim);
+ sNewPath.append(m_xRadioLB->get_id(i));
+ }
+ }
+ if (!sNewPath.isEmpty())
+ sNewPath.append(cDelim);
+ sNewPath.append(sWritable);
+
+ return sNewPath.makeStringAndClear();
+}
+
+OUString SvxPathSelectDialog::GetPath() const
+{
+ OUStringBuffer sNewPath;
+
+ for (int i = 0; i < m_xPathLB->n_children(); ++i)
+ {
+ if ( !sNewPath.isEmpty() )
+ sNewPath.append(SVT_SEARCHPATH_DELIMITER);
+ sNewPath.append( m_xPathLB->get_id(i));
+ }
+
+ return sNewPath.makeStringAndClear();
+}
+
+void SvxMultiPathDialog::SetPath( std::u16string_view rPath )
+{
+ if ( !rPath.empty() )
+ {
+ const sal_Unicode cDelim = SVT_SEARCHPATH_DELIMITER;
+ int nCount = 0;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ const OUString sPath( o3tl::getToken(rPath, 0, cDelim, nIndex ) );
+ OUString sSystemPath;
+ bool bIsSystemPath =
+ osl::FileBase::getSystemPathFromFileURL(sPath, sSystemPath) == osl::FileBase::E_None;
+
+ const OUString sEntry((bIsSystemPath ? sSystemPath : sPath));
+ AppendEntry(sEntry, sPath);
+ ++nCount;
+ }
+ while (nIndex >= 0);
+
+ if (nCount)
+ {
+ m_xRadioLB->set_toggle(nCount - 1, TRISTATE_TRUE);
+ HandleEntryChecked(nCount - 1);
+ }
+ }
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+void SvxPathSelectDialog::SetPath(std::u16string_view rPath)
+{
+ if ( !rPath.empty() )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ const OUString sPath( o3tl::getToken(rPath, 0, SVT_SEARCHPATH_DELIMITER, nIndex ) );
+ OUString sSystemPath;
+ bool bIsSystemPath =
+ osl::FileBase::getSystemPathFromFileURL(sPath, sSystemPath) == osl::FileBase::E_None;
+
+ m_xPathLB->append(sPath, bIsSystemPath ? sSystemPath : sPath);
+ }
+ while (nIndex >= 0);
+ }
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/newtabledlg.cxx b/cui/source/dialogs/newtabledlg.cxx
new file mode 100644
index 000000000..9eb50987e
--- /dev/null
+++ b/cui/source/dialogs/newtabledlg.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <newtabledlg.hxx>
+
+SvxNewTableDialog::SvxNewTableDialog(weld::Window* pWindow)
+ : GenericDialogController(pWindow, "cui/ui/newtabledialog.ui", "NewTableDialog")
+ , mxNumColumns(m_xBuilder->weld_spin_button("columns"))
+ , mxNumRows(m_xBuilder->weld_spin_button("rows"))
+{
+}
+
+sal_Int32 SvxNewTableDialog::getRows() const
+{
+ return sal::static_int_cast<sal_Int32>(mxNumRows->get_value());
+}
+
+sal_Int32 SvxNewTableDialog::getColumns() const
+{
+ return sal::static_int_cast<sal_Int32>(mxNumColumns->get_value());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/passwdomdlg.cxx b/cui/source/dialogs/passwdomdlg.cxx
new file mode 100644
index 000000000..8a8fcb358
--- /dev/null
+++ b/cui/source/dialogs/passwdomdlg.cxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <passwdomdlg.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+IMPL_LINK_NOARG(PasswordToOpenModifyDialog, OkBtnClickHdl, weld::Button&, void)
+{
+ bool bInvalidState = !m_xOpenReadonlyCB->get_active() &&
+ m_xPasswdToOpenED->get_text().isEmpty() &&
+ m_xPasswdToModifyED->get_text().isEmpty();
+ if (bInvalidState)
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ m_bIsPasswordToModify? m_aInvalidStateForOkButton : m_aInvalidStateForOkButton_v2));
+ xErrorBox->run();
+ }
+ else // check for mismatched passwords...
+ {
+ const bool bToOpenMatch = m_xPasswdToOpenED->get_text() == m_xReenterPasswdToOpenED->get_text();
+ const bool bToModifyMatch = m_xPasswdToModifyED->get_text() == m_xReenterPasswdToModifyED->get_text();
+ const int nMismatch = (bToOpenMatch? 0 : 1) + (bToModifyMatch? 0 : 1);
+ if (nMismatch > 0)
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ nMismatch == 1 ? m_aOneMismatch : m_aTwoMismatch));
+ xErrorBox->run();
+
+ weld::Entry* pEdit = !bToOpenMatch ? m_xPasswdToOpenED.get() : m_xPasswdToModifyED.get();
+ weld::Entry* pRepeatEdit = !bToOpenMatch? m_xReenterPasswdToOpenED.get() : m_xReenterPasswdToModifyED.get();
+ if (nMismatch == 1)
+ {
+ pEdit->set_text( "" );
+ pRepeatEdit->set_text( "" );
+ }
+ else if (nMismatch == 2)
+ {
+ m_xPasswdToOpenED->set_text( "" );
+ m_xReenterPasswdToOpenED->set_text( "" );
+ m_xPasswdToModifyED->set_text( "" );
+ m_xReenterPasswdToModifyED->set_text( "" );
+ }
+ pEdit->grab_focus();
+ }
+ else
+ {
+ m_xDialog->response(RET_OK);
+ }
+ }
+}
+
+IMPL_LINK(PasswordToOpenModifyDialog, ChangeHdl, weld::Entry&, rEntry, void)
+{
+ weld::Label* pIndicator = nullptr;
+ int nLength = rEntry.get_text().getLength();
+ if (&rEntry == m_xPasswdToOpenED.get())
+ pIndicator = m_xPasswdToOpenInd.get();
+ else if (&rEntry == m_xReenterPasswdToOpenED.get())
+ pIndicator = m_xReenterPasswdToOpenInd.get();
+ else if (&rEntry == m_xPasswdToModifyED.get())
+ pIndicator = m_xPasswdToModifyInd.get();
+ else if (&rEntry == m_xReenterPasswdToModifyED.get())
+ pIndicator = m_xReenterPasswdToModifyInd.get();
+ assert(pIndicator);
+ pIndicator->set_visible(nLength >= m_nMaxPasswdLen);
+}
+
+PasswordToOpenModifyDialog::PasswordToOpenModifyDialog(weld::Window * pParent, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify)
+ : SfxDialogController(pParent, "cui/ui/password.ui", "PasswordDialog")
+ , m_xPasswdToOpenED(m_xBuilder->weld_entry("newpassEntry"))
+ , m_xPasswdToOpenInd(m_xBuilder->weld_label("newpassIndicator"))
+ , m_xReenterPasswdToOpenED(m_xBuilder->weld_entry("confirmpassEntry"))
+ , m_xReenterPasswdToOpenInd(m_xBuilder->weld_label("confirmpassIndicator"))
+ , m_xOptionsExpander(m_xBuilder->weld_expander("expander"))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+ , m_xOpenReadonlyCB(m_xBuilder->weld_check_button("readonly"))
+ , m_xPasswdToModifyFT(m_xBuilder->weld_label("label7"))
+ , m_xPasswdToModifyED(m_xBuilder->weld_entry("newpassroEntry"))
+ , m_xPasswdToModifyInd(m_xBuilder->weld_label("newpassroIndicator"))
+ , m_xReenterPasswdToModifyFT(m_xBuilder->weld_label("label8"))
+ , m_xReenterPasswdToModifyED(m_xBuilder->weld_entry("confirmropassEntry"))
+ , m_xReenterPasswdToModifyInd(m_xBuilder->weld_label("confirmropassIndicator"))
+ , m_aOneMismatch( CuiResId( RID_CUISTR_ONE_PASSWORD_MISMATCH ) )
+ , m_aTwoMismatch( CuiResId( RID_CUISTR_TWO_PASSWORDS_MISMATCH ) )
+ , m_aInvalidStateForOkButton( CuiResId( RID_CUISTR_INVALID_STATE_FOR_OK_BUTTON ) )
+ , m_aInvalidStateForOkButton_v2( CuiResId( RID_CUISTR_INVALID_STATE_FOR_OK_BUTTON_V2 ) )
+ , m_nMaxPasswdLen(nMaxPasswdLen)
+ , m_bIsPasswordToModify( bIsPasswordToModify )
+{
+ m_xOk->connect_clicked(LINK(this, PasswordToOpenModifyDialog, OkBtnClickHdl));
+
+ if (nMaxPasswdLen)
+ {
+ OUString aIndicatorTemplate(CuiResId(RID_CUISTR_PASSWORD_LEN_INDICATOR).replaceFirst("%1", OUString::number(nMaxPasswdLen)));
+ m_xPasswdToOpenED->set_max_length( nMaxPasswdLen );
+ m_xPasswdToOpenED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xPasswdToOpenInd->set_label(aIndicatorTemplate);
+ m_xReenterPasswdToOpenED->set_max_length( nMaxPasswdLen );
+ m_xReenterPasswdToOpenED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xReenterPasswdToOpenInd->set_label(aIndicatorTemplate);
+ m_xPasswdToModifyED->set_max_length( nMaxPasswdLen );
+ m_xPasswdToModifyED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xPasswdToModifyInd->set_label(aIndicatorTemplate);
+ m_xReenterPasswdToModifyED->set_max_length( nMaxPasswdLen );
+ m_xReenterPasswdToModifyED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xReenterPasswdToModifyInd->set_label(aIndicatorTemplate);
+ }
+
+ m_xPasswdToOpenED->grab_focus();
+
+ m_xOptionsExpander->set_sensitive(bIsPasswordToModify);
+ if (!bIsPasswordToModify)
+ m_xOptionsExpander->hide();
+
+ m_xOpenReadonlyCB->connect_toggled(LINK(this, PasswordToOpenModifyDialog, ReadonlyOnOffHdl));
+ ReadonlyOnOffHdl(*m_xOpenReadonlyCB);
+}
+
+OUString PasswordToOpenModifyDialog::GetPasswordToOpen() const
+{
+ const bool bPasswdOk =
+ !m_xPasswdToOpenED->get_text().isEmpty() &&
+ m_xPasswdToOpenED->get_text() == m_xReenterPasswdToOpenED->get_text();
+ return bPasswdOk ? m_xPasswdToOpenED->get_text() : OUString();
+}
+
+
+OUString PasswordToOpenModifyDialog::GetPasswordToModify() const
+{
+ const bool bPasswdOk =
+ !m_xPasswdToModifyED->get_text().isEmpty() &&
+ m_xPasswdToModifyED->get_text() == m_xReenterPasswdToModifyED->get_text();
+ return bPasswdOk ? m_xPasswdToModifyED->get_text() : OUString();
+}
+
+
+bool PasswordToOpenModifyDialog::IsRecommendToOpenReadonly() const
+{
+ return m_xOpenReadonlyCB->get_active();
+}
+
+IMPL_LINK_NOARG(PasswordToOpenModifyDialog, ReadonlyOnOffHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xOpenReadonlyCB->get_active();
+ m_xPasswdToModifyED->set_sensitive(bEnable);
+ m_xPasswdToModifyFT->set_sensitive(bEnable);
+ m_xReenterPasswdToModifyED->set_sensitive(bEnable);
+ m_xReenterPasswdToModifyFT->set_sensitive(bEnable);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/pastedlg.cxx b/cui/source/dialogs/pastedlg.cxx
new file mode 100644
index 000000000..d86d277cc
--- /dev/null
+++ b/cui/source/dialogs/pastedlg.cxx
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+
+#include <pastedlg.hxx>
+#include <svtools/insdlg.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+#include <tools/lineend.hxx>
+#include <comphelper/dispatchcommand.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+SvPasteObjectDialog::SvPasteObjectDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/pastespecial.ui", "PasteSpecialDialog")
+ , m_xFtObjectSource(m_xBuilder->weld_label("source"))
+ , m_xLbInsertList(m_xBuilder->weld_tree_view("list"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+{
+ m_xLbInsertList->set_size_request(m_xLbInsertList->get_approximate_digit_width() * 40,
+ m_xLbInsertList->get_height_rows(6));
+ m_xOKButton->set_sensitive(false);
+
+ ObjectLB().connect_changed(LINK(this, SvPasteObjectDialog, SelectHdl));
+ ObjectLB().connect_row_activated(LINK( this, SvPasteObjectDialog, DoubleClickHdl));
+}
+
+void SvPasteObjectDialog::SelectObject()
+{
+ if (m_xLbInsertList->n_children())
+ {
+ m_xLbInsertList->select(0);
+ SelectHdl(*m_xLbInsertList);
+ }
+}
+
+IMPL_LINK_NOARG(SvPasteObjectDialog, SelectHdl, weld::TreeView&, void)
+{
+ if (!m_xOKButton->get_sensitive())
+ m_xOKButton->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvPasteObjectDialog, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+/*************************************************************************
+|* SvPasteObjectDialog::Insert()
+*************************************************************************/
+void SvPasteObjectDialog::Insert( SotClipboardFormatId nFormat, const OUString& rFormatName )
+{
+ aSupplementMap.insert( std::make_pair( nFormat, rFormatName ) );
+}
+
+void SvPasteObjectDialog::InsertUno(const OUString& sCmd, const OUString& sLabel)
+{
+ aExtraCommand.first = sCmd;
+ aExtraCommand.second = sLabel;
+}
+
+
+void SvPasteObjectDialog::PreGetFormat( const TransferableDataHelper &rHelper )
+{
+ //TODO/LATER: why is the Descriptor never used?!
+ TransferableObjectDescriptor aDesc;
+ if (rHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
+ {
+ (void)const_cast<TransferableDataHelper&>(rHelper).GetTransferableObjectDescriptor(
+ SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
+ }
+ const DataFlavorExVector* pFormats = &rHelper.GetDataFlavorExVector();
+
+ // create and fill dialog box
+ OUString aSourceName, aTypeName;
+ SvGlobalName aEmptyNm;
+
+ //ObjectLB().SetUpdateMode( false );
+ ObjectLB().freeze();
+
+ DataFlavorExVector::iterator aIter( const_cast<DataFlavorExVector&>(*pFormats).begin() ),
+ aEnd( const_cast<DataFlavorExVector&>(*pFormats).end() );
+ while( aIter != aEnd )
+ {
+ SotClipboardFormatId nFormat = (*aIter++).mnSotId;
+
+ std::map< SotClipboardFormatId, OUString >::iterator itName =
+ aSupplementMap.find( nFormat );
+
+ // if there is an "Embed Source" or and "Embedded Object" on the
+ // Clipboard we read the Description and the Source of this object
+ // from an accompanied "Object Descriptor" format on the clipboard
+ // Remember: these formats mostly appear together on the clipboard
+ OUString aName;
+ const OUString* pName = nullptr;
+ if ( itName == aSupplementMap.end() )
+ {
+ SvPasteObjectHelper::GetEmbeddedName(rHelper,aName,aSourceName,nFormat);
+ if ( !aName.isEmpty() )
+ pName = &aName;
+ }
+ else
+ {
+ pName = &(itName->second);
+ }
+
+ if( pName )
+ {
+ aName = *pName;
+
+ if( SotClipboardFormatId::EMBED_SOURCE == nFormat )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+
+ if( aDesc.maClassName == aObjClassName )
+ aName = aObjName;
+ else
+ aName = aTypeName = aDesc.maTypeName;
+ }
+ }
+ else if( SotClipboardFormatId::LINK_SOURCE == nFormat )
+ {
+ continue;
+ }
+ else if( aName.isEmpty() )
+ aName = SvPasteObjectHelper::GetSotFormatUIName( nFormat );
+
+ // Show RICHTEXT only in case RTF is not present.
+ if (nFormat == SotClipboardFormatId::RICHTEXT &&
+ std::any_of(pFormats->begin(), pFormats->end(),
+ [](const DataFlavorEx& rFlavor) {
+ return rFlavor.mnSotId == SotClipboardFormatId::RTF;
+ }))
+ {
+ continue;
+ }
+
+ if (ObjectLB().find_text(aName) == -1)
+ {
+ ObjectLB().append(OUString::number(static_cast<sal_uInt32>(nFormat)), aName);
+ }
+ }
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+ aTypeName = aDesc.maTypeName;
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ // global resource from svtools (former so3 resource)
+ aSourceName = SvtResId(STR_UNKNOWN_SOURCE);
+ }
+ }
+
+ ObjectLB().thaw();
+ SelectObject();
+
+ if( !aSourceName.isEmpty() )
+ {
+ if( !aTypeName.isEmpty() )
+ aTypeName += "\n";
+
+ aTypeName += aSourceName;
+ aTypeName = convertLineEnd(aTypeName, GetSystemLineEnd());
+ }
+
+ m_xFtObjectSource->set_label(aTypeName);
+}
+
+SotClipboardFormatId SvPasteObjectDialog::GetFormatOnly()
+{
+ return static_cast<SotClipboardFormatId>(ObjectLB().get_selected_id().toUInt32());
+}
+
+SotClipboardFormatId SvPasteObjectDialog::GetFormat( const TransferableDataHelper& rHelper)
+{
+ //TODO/LATER: why is the Descriptor never used?!
+ TransferableObjectDescriptor aDesc;
+ if (rHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
+ {
+ (void)const_cast<TransferableDataHelper&>(rHelper).GetTransferableObjectDescriptor(
+ SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
+ }
+ const DataFlavorExVector* pFormats = &rHelper.GetDataFlavorExVector();
+
+ // create and fill dialog box
+ OUString aSourceName, aTypeName;
+ SotClipboardFormatId nSelFormat = SotClipboardFormatId::NONE;
+ SvGlobalName aEmptyNm;
+
+ ObjectLB().freeze();
+
+ for (auto const& format : *pFormats)
+ {
+ SotClipboardFormatId nFormat = format.mnSotId;
+
+ std::map< SotClipboardFormatId, OUString >::iterator itName =
+ aSupplementMap.find( nFormat );
+
+ // if there is an "Embed Source" or and "Embedded Object" on the
+ // Clipboard we read the Description and the Source of this object
+ // from an accompanied "Object Descriptor" format on the clipboard
+ // Remember: these formats mostly appear together on the clipboard
+ OUString aName;
+ const OUString* pName = nullptr;
+ if ( itName == aSupplementMap.end() )
+ {
+ SvPasteObjectHelper::GetEmbeddedName(rHelper,aName,aSourceName,nFormat);
+ if ( !aName.isEmpty() )
+ pName = &aName;
+ }
+ else
+ {
+ pName = &(itName->second);
+ }
+
+ if( pName )
+ {
+ aName = *pName;
+
+ if( SotClipboardFormatId::EMBED_SOURCE == nFormat )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+
+ if( aDesc.maClassName == aObjClassName )
+ aName = aObjName;
+ else
+ aName = aTypeName = aDesc.maTypeName;
+ }
+ }
+ else if( SotClipboardFormatId::LINK_SOURCE == nFormat )
+ {
+ continue;
+ }
+ else if( aName.isEmpty() )
+ aName = SvPasteObjectHelper::GetSotFormatUIName( nFormat );
+
+ // Show RICHTEXT only in case RTF is not present.
+ if (nFormat == SotClipboardFormatId::RICHTEXT &&
+ std::any_of(pFormats->begin(), pFormats->end(),
+ [](const DataFlavorEx& rFlavor) {
+ return rFlavor.mnSotId == SotClipboardFormatId::RTF;
+ }))
+ {
+ continue;
+ }
+
+ if (ObjectLB().find_text(aName) == -1)
+ {
+ ObjectLB().append(OUString::number(static_cast<sal_uInt32>(nFormat)), aName);
+ }
+ }
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+ aTypeName = aDesc.maTypeName;
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ // global resource from svtools (former so3 resource)
+ aSourceName = SvtResId(STR_UNKNOWN_SOURCE);
+ }
+ }
+
+ if (!aExtraCommand.first.isEmpty())
+ {
+ ObjectLB().append(aExtraCommand.first, aExtraCommand.second);
+ }
+
+ ObjectLB().thaw();
+ SelectObject();
+
+ if( !aSourceName.isEmpty() )
+ {
+ if( !aTypeName.isEmpty() )
+ aTypeName += "\n";
+
+ aTypeName += aSourceName;
+ aTypeName = convertLineEnd(aTypeName, GetSystemLineEnd());
+ }
+
+ m_xFtObjectSource->set_label(aTypeName);
+
+ if (run() == RET_OK)
+ {
+ if (ObjectLB().get_selected_id().startsWithIgnoreAsciiCase(".uno"))
+ {
+ comphelper::dispatchCommand(aExtraCommand.first, {});
+ nSelFormat = SotClipboardFormatId::NONE;
+ }
+ else
+ {
+ nSelFormat = static_cast<SotClipboardFormatId>(ObjectLB().get_selected_id().toUInt32());
+ }
+ }
+
+ return nSelFormat;
+}
+
+void SvPasteObjectDialog::SetObjName( const SvGlobalName & rClass, const OUString & rObjName )
+{
+ aObjClassName = rClass;
+ aObjName = rObjName;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/postdlg.cxx b/cui/source/dialogs/postdlg.cxx
new file mode 100644
index 000000000..1bcb6b7a0
--- /dev/null
+++ b/cui/source/dialogs/postdlg.cxx
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/date.hxx>
+#include <tools/lineend.hxx>
+#include <tools/time.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <unotools/useroptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <svx/svxids.hrc>
+
+#include <svx/postattr.hxx>
+#include <postdlg.hxx>
+
+// class SvxPostItDialog -------------------------------------------------
+
+SvxPostItDialog::SvxPostItDialog(weld::Widget* pParent, const SfxItemSet& rCoreSet,
+ bool bPrevNext)
+ : SfxDialogController(pParent, "cui/ui/comment.ui", "CommentDialog")
+ , m_rSet(rCoreSet)
+ , m_xLastEditFT(m_xBuilder->weld_label("lastedit"))
+ , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
+ , m_xEditED(m_xBuilder->weld_text_view("edit"))
+ , m_xInsertAuthor(m_xBuilder->weld_widget("insertauthor"))
+ , m_xAuthorBtn(m_xBuilder->weld_button("author"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xPrevBtn(m_xBuilder->weld_button("previous"))
+ , m_xNextBtn(m_xBuilder->weld_button("next"))
+{
+ m_xPrevBtn->connect_clicked( LINK( this, SvxPostItDialog, PrevHdl ) );
+ m_xNextBtn->connect_clicked( LINK( this, SvxPostItDialog, NextHdl ) );
+ m_xAuthorBtn->connect_clicked( LINK( this, SvxPostItDialog, Stamp ) );
+ m_xOKBtn->connect_clicked( LINK( this, SvxPostItDialog, OKHdl ) );
+
+ bool bNew = true;
+
+ m_xPrevBtn->set_visible(bPrevNext);
+ m_xNextBtn->set_visible(bPrevNext);
+
+ OUString aAuthorStr, aDateStr;
+
+ if (m_rSet.GetItemState( SID_ATTR_POSTIT_AUTHOR ) >= SfxItemState::DEFAULT)
+ {
+ bNew = false;
+ const SvxPostItAuthorItem& rAuthor = m_rSet.Get(SID_ATTR_POSTIT_AUTHOR);
+ aAuthorStr = rAuthor.GetValue();
+ }
+ else
+ aAuthorStr = SvtUserOptions().GetID();
+
+ if (m_rSet.GetItemState( SID_ATTR_POSTIT_DATE ) >= SfxItemState::DEFAULT)
+ {
+ const SvxPostItDateItem& rDate = m_rSet.Get( SID_ATTR_POSTIT_DATE );
+ aDateStr = rDate.GetValue();
+ }
+ else
+ {
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aDateStr = rLocaleWrapper.getDate( Date( Date::SYSTEM ) );
+ }
+
+ OUString aTextStr;
+ if (m_rSet.GetItemState( SID_ATTR_POSTIT_TEXT ) >= SfxItemState::DEFAULT)
+ {
+ const SvxPostItTextItem& rText = m_rSet.Get( SID_ATTR_POSTIT_TEXT );
+ aTextStr = rText.GetValue();
+ }
+
+ ShowLastAuthor(aAuthorStr, aDateStr);
+
+ //lock to an initial size before replacing contents
+ m_xEditED->set_size_request(m_xEditED->get_approximate_digit_width() * 32,
+ m_xEditED->get_height_rows(10));
+ m_xEditED->set_text(convertLineEnd(aTextStr, GetSystemLineEnd()));
+
+ if (!bNew)
+ m_xDialog->set_title(m_xAltTitle->get_label());
+}
+
+
+SvxPostItDialog::~SvxPostItDialog()
+{
+}
+
+void SvxPostItDialog::ShowLastAuthor(std::u16string_view rAuthor, std::u16string_view rDate)
+{
+ OUString sTxt = OUString::Concat(rAuthor) + ", " + rDate;
+ m_xLastEditFT->set_label( sTxt );
+}
+
+WhichRangesContainer SvxPostItDialog::GetRanges()
+{
+ return WhichRangesContainer(svl::Items<SID_ATTR_POSTIT_AUTHOR, SID_ATTR_POSTIT_TEXT>);
+}
+
+void SvxPostItDialog::EnableTravel(bool bNext, bool bPrev)
+{
+ m_xPrevBtn->set_sensitive(bPrev);
+ m_xNextBtn->set_sensitive(bNext);
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, PrevHdl, weld::Button&, void)
+{
+ m_aPrevHdlLink.Call( *this );
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, NextHdl, weld::Button&, void)
+{
+ m_aNextHdlLink.Call( *this );
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, Stamp, weld::Button&, void)
+{
+ Date aDate( Date::SYSTEM );
+ tools::Time aTime( tools::Time::SYSTEM );
+ OUString aTmp( SvtUserOptions().GetID() );
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ OUString aStr( m_xEditED->get_text() + "\n---- " );
+
+ if ( !aTmp.isEmpty() )
+ {
+ aStr += aTmp + ", ";
+ }
+ aStr += rLocaleWrapper.getDate(aDate) + ", " + rLocaleWrapper.getTime(aTime, false) + " ----\n";
+ aStr = convertLineEnd(aStr, GetSystemLineEnd());
+
+ m_xEditED->set_text(aStr);
+ sal_Int32 nLen = aStr.getLength();
+ m_xEditED->grab_focus();
+ m_xEditED->select_region(nLen, nLen);
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, OKHdl, weld::Button&, void)
+{
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ m_xOutSet.reset(new SfxItemSet(m_rSet));
+ m_xOutSet->Put( SvxPostItAuthorItem(SvtUserOptions().GetID(), SID_ATTR_POSTIT_AUTHOR ) );
+ m_xOutSet->Put( SvxPostItDateItem(rLocaleWrapper.getDate( Date( Date::SYSTEM ) ), SID_ATTR_POSTIT_DATE ) );
+ m_xOutSet->Put( SvxPostItTextItem(m_xEditED->get_text(), SID_ATTR_POSTIT_TEXT ) );
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/screenshotannotationdlg.cxx b/cui/source/dialogs/screenshotannotationdlg.cxx
new file mode 100644
index 000000000..1f21c5278
--- /dev/null
+++ b/cui/source/dialogs/screenshotannotationdlg.cxx
@@ -0,0 +1,581 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <screenshotannotationdlg.hxx>
+
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <basegfx/range/b2irange.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+
+#include <comphelper/random.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <tools/stream.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/event.hxx>
+#include <vcl/pngwrite.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/salgtype.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <set>
+#include <string_view>
+
+using namespace com::sun::star;
+
+namespace
+{
+ OUString lcl_genRandom( std::u16string_view rId )
+ {
+ //FIXME: plus timestamp
+ unsigned int nRand = comphelper::rng::uniform_uint_distribution(0, 0xFFFF);
+ return OUString( rId + OUString::number( nRand ) );
+ }
+
+
+ OUString lcl_AltDescr()
+ {
+ OUString aTempl("<alt id=\"%1\">"
+ " " //FIXME real dialog title or something
+ "</alt>");
+ aTempl = aTempl.replaceFirst( "%1", lcl_genRandom(u"alt_id") );
+
+ return aTempl;
+ }
+
+ OUString lcl_Image( std::u16string_view rScreenshotId, const Size& rSize )
+ {
+ OUString aTempl("<image id=\"%1\" src=\"media/screenshots/%2.png\""
+ " width=\"%3cm\" height=\"%4cm\">"
+ "%5"
+ "</image>");
+ aTempl = aTempl.replaceFirst( "%1", lcl_genRandom(u"img_id") );
+ aTempl = aTempl.replaceFirst( "%2", rScreenshotId );
+ aTempl = aTempl.replaceFirst( "%3", OUString::number( rSize.Width() ) );
+ aTempl = aTempl.replaceFirst( "%4", OUString::number( rSize.Height() ) );
+ aTempl = aTempl.replaceFirst( "%5", lcl_AltDescr() );
+
+ return aTempl;
+ }
+
+ OUString lcl_ParagraphWithImage( std::u16string_view rScreenshotId, const Size& rSize )
+ {
+ OUString aTempl( "<paragraph id=\"%1\" role=\"paragraph\">%2"
+ "</paragraph>" SAL_NEWLINE_STRING );
+ aTempl = aTempl.replaceFirst( "%1", lcl_genRandom(u"par_id") );
+ aTempl = aTempl.replaceFirst( "%2", lcl_Image(rScreenshotId, rSize) );
+
+ return aTempl;
+ }
+
+ OUString lcl_Bookmark( std::u16string_view rWidgetId )
+ {
+ OUString aTempl = "<!-- Bookmark for widget %1 -->" SAL_NEWLINE_STRING
+ "<bookmark branch=\"hid/%2\" id=\"%3\" localize=\"false\"/>" SAL_NEWLINE_STRING;
+ aTempl = aTempl.replaceFirst( "%1", rWidgetId );
+ aTempl = aTempl.replaceFirst( "%2", rWidgetId );
+ aTempl = aTempl.replaceFirst( "%3", lcl_genRandom(u"bm_id") );
+
+ return aTempl;
+ }
+}
+
+namespace
+{
+ class Picture : public weld::CustomWidgetController
+ {
+ private:
+ ScreenshotAnnotationDlg_Impl *m_pDialog;
+ bool m_bMouseOver;
+ private:
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual bool MouseMove(const MouseEvent& rMouseEvent) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMouseEvent) override;
+ public:
+ Picture(ScreenshotAnnotationDlg_Impl* pDialog)
+ : m_pDialog(pDialog)
+ , m_bMouseOver(false)
+ {
+ }
+
+ bool IsMouseOver() const
+ {
+ return m_bMouseOver;
+ }
+ };
+}
+
+class ScreenshotAnnotationDlg_Impl
+{
+public:
+ ScreenshotAnnotationDlg_Impl(
+ weld::Window* pParent,
+ weld::Builder& rParent,
+ weld::Dialog& rParentDialog);
+ ~ScreenshotAnnotationDlg_Impl();
+
+private:
+ // Handler for click on save
+ DECL_LINK(saveButtonHandler, weld::Button&, void);
+
+ // helper methods
+ weld::ScreenShotEntry* CheckHit(const basegfx::B2IPoint& rPosition);
+ void PaintScreenShotEntry(
+ const weld::ScreenShotEntry& rEntry,
+ const Color& rColor,
+ double fLineWidth,
+ double fTransparency);
+ void RepaintToBuffer(
+ bool bUseDimmed = false,
+ bool bPaintHilight = false);
+ void RepaintPictureElement();
+ Point GetOffsetInPicture() const;
+
+ // local variables
+ weld::Window* mpParentWindow;
+ weld::Dialog& mrParentDialog;
+ BitmapEx maParentDialogBitmap;
+ BitmapEx maDimmedDialogBitmap;
+ Size maParentDialogSize;
+
+ // VirtualDevice for buffered interaction paints
+ VclPtr<VirtualDevice> mxVirtualBufferDevice;
+
+ // all detected children
+ weld::ScreenShotCollection maAllChildren;
+
+ // highlighted/selected children
+ weld::ScreenShotEntry* mpHilighted;
+ std::set< weld::ScreenShotEntry* >
+ maSelected;
+
+ // list of detected controls
+ Picture maPicture;
+ std::unique_ptr<weld::CustomWeld> mxPicture;
+ std::unique_ptr<weld::TextView> mxText;
+ std::unique_ptr<weld::Button> mxSave;
+
+ // save as text
+ OUString maSaveAsText;
+ OUString maMainMarkupText;
+
+ // folder URL
+ static OUString maLastFolderURL;
+public:
+ void Paint(vcl::RenderContext& rRenderContext);
+ bool MouseMove(const MouseEvent& rMouseEvent);
+ bool MouseButtonUp();
+};
+
+OUString ScreenshotAnnotationDlg_Impl::maLastFolderURL = OUString();
+
+ScreenshotAnnotationDlg_Impl::ScreenshotAnnotationDlg_Impl(
+ weld::Window* pParent,
+ weld::Builder& rParentBuilder,
+ weld::Dialog& rParentDialog)
+: mpParentWindow(pParent),
+ mrParentDialog(rParentDialog),
+ mxVirtualBufferDevice(nullptr),
+ mpHilighted(nullptr),
+ maPicture(this),
+ maSaveAsText(CuiResId(RID_CUISTR_SAVE_SCREENSHOT_AS))
+{
+ VclPtr<VirtualDevice> xParentDialogSurface(rParentDialog.screenshot());
+ maParentDialogSize = xParentDialogSurface->GetOutputSizePixel();
+ maParentDialogBitmap = xParentDialogSurface->GetBitmapEx(Point(), maParentDialogSize);
+ maDimmedDialogBitmap = maParentDialogBitmap;
+
+ // image ain't empty
+ assert(!maParentDialogBitmap.IsEmpty());
+ assert(0 != maParentDialogBitmap.GetSizePixel().Width());
+ assert(0 != maParentDialogBitmap.GetSizePixel().Height());
+
+ // get needed widgets
+ mxPicture.reset(new weld::CustomWeld(rParentBuilder, "picture", maPicture));
+ assert(mxPicture);
+ mxText = rParentBuilder.weld_text_view("text");
+ assert(mxText);
+ mxSave = rParentBuilder.weld_button("save");
+ assert(mxSave);
+
+ // set screenshot image at DrawingArea, resize, set event listener
+ if (mxPicture)
+ {
+ maAllChildren = mrParentDialog.collect_screenshot_data();
+
+ // to make clear that maParentDialogBitmap is a background image, adjust
+ // luminance a bit for maDimmedDialogBitmap - other methods may be applied
+ maDimmedDialogBitmap.Adjust(-15, 0, 0, 0, 0);
+
+ // init paint buffering VirtualDevice
+ mxVirtualBufferDevice = VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT);
+ mxVirtualBufferDevice->SetOutputSizePixel(maParentDialogSize);
+ mxVirtualBufferDevice->SetFillColor(COL_TRANSPARENT);
+
+ // initially set image for picture control
+ mxVirtualBufferDevice->DrawBitmapEx(Point(0, 0), maDimmedDialogBitmap);
+
+ // set size for picture control, this will re-layout so that
+ // the picture control shows the whole dialog
+ maPicture.SetOutputSizePixel(maParentDialogSize);
+ mxPicture->set_size_request(maParentDialogSize.Width(), maParentDialogSize.Height());
+
+ mxPicture->queue_draw();
+ }
+
+ // set some test text at VclMultiLineEdit and make read-only - only
+ // copying content to clipboard is allowed
+ if (mxText)
+ {
+ mxText->set_size_request(400, mxText->get_height_rows(10));
+ OUString aHelpId = OStringToOUString( mrParentDialog.get_help_id(), RTL_TEXTENCODING_UTF8 );
+ Size aSizeCm = Application::GetDefaultDevice()->PixelToLogic(maParentDialogSize, MapMode(MapUnit::MapCM));
+ maMainMarkupText = lcl_ParagraphWithImage( aHelpId, aSizeCm );
+ mxText->set_text( maMainMarkupText );
+ mxText->set_editable(false);
+ }
+
+ // set click handler for save button
+ if (mxSave)
+ {
+ mxSave->connect_clicked(LINK(this, ScreenshotAnnotationDlg_Impl, saveButtonHandler));
+ }
+}
+
+ScreenshotAnnotationDlg_Impl::~ScreenshotAnnotationDlg_Impl()
+{
+ mxVirtualBufferDevice.disposeAndClear();
+}
+
+IMPL_LINK_NOARG(ScreenshotAnnotationDlg_Impl, saveButtonHandler, weld::Button&, void)
+{
+ // 'save screenshot...' pressed, offer to save maParentDialogBitmap
+ // as PNG image, use *.id file name as screenshot file name offering
+ // get a suggestion for the filename from buildable name
+ OString aDerivedFileName = mrParentDialog.get_buildable_name();
+
+ auto xFileDlg = std::make_unique<sfx2::FileDialogHelper>(ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
+ FileDialogFlags::NONE, mpParentWindow);
+ xFileDlg->SetContext(sfx2::FileDialogHelper::ScreenshotAnnotation);
+
+ const uno::Reference< ui::dialogs::XFilePicker3 > xFilePicker = xFileDlg->GetFilePicker();
+
+ xFilePicker->setTitle(maSaveAsText);
+
+ if (!maLastFolderURL.isEmpty())
+ {
+ xFilePicker->setDisplayDirectory(maLastFolderURL);
+ }
+
+ xFilePicker->appendFilter("*.png", "*.png");
+ xFilePicker->setCurrentFilter("*.png");
+ xFilePicker->setDefaultName(OStringToOUString(aDerivedFileName, RTL_TEXTENCODING_UTF8));
+ xFilePicker->setMultiSelectionMode(false);
+
+ if (xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK)
+ return;
+
+ maLastFolderURL = xFilePicker->getDisplayDirectory();
+ const uno::Sequence< OUString > files(xFilePicker->getSelectedFiles());
+
+ if (!files.hasElements())
+ return;
+
+ OUString aConfirmedName = files[0];
+
+ if (aConfirmedName.isEmpty())
+ return;
+
+ INetURLObject aConfirmedURL(aConfirmedName);
+ OUString aCurrentExtension(aConfirmedURL.getExtension());
+
+ if (!aCurrentExtension.isEmpty() && aCurrentExtension != "png")
+ {
+ aConfirmedURL.removeExtension();
+ aCurrentExtension.clear();
+ }
+
+ if (aCurrentExtension.isEmpty())
+ {
+ aConfirmedURL.setExtension(u"png");
+ }
+
+ // open stream
+ SvFileStream aNew(aConfirmedURL.PathToFileName(), StreamMode::WRITE | StreamMode::TRUNC);
+
+ if (!aNew.IsOpen())
+ return;
+
+ // prepare bitmap to save - do use the original screenshot here,
+ // not the dimmed one
+ RepaintToBuffer();
+
+ // extract Bitmap
+ const BitmapEx aTargetBitmap(
+ mxVirtualBufferDevice->GetBitmapEx(
+ Point(0, 0),
+ mxVirtualBufferDevice->GetOutputSizePixel()));
+
+ // write as PNG
+ vcl::PNGWriter aPNGWriter(aTargetBitmap);
+ aPNGWriter.Write(aNew);
+}
+
+weld::ScreenShotEntry* ScreenshotAnnotationDlg_Impl::CheckHit(const basegfx::B2IPoint& rPosition)
+{
+ weld::ScreenShotEntry* pRetval = nullptr;
+
+ for (auto&& rCandidate : maAllChildren)
+ {
+ if (rCandidate.getB2IRange().isInside(rPosition))
+ {
+ if (pRetval)
+ {
+ if (pRetval->getB2IRange().isInside(rCandidate.getB2IRange().getMinimum())
+ && pRetval->getB2IRange().isInside(rCandidate.getB2IRange().getMaximum()))
+ {
+ pRetval = &rCandidate;
+ }
+ }
+ else
+ {
+ pRetval = &rCandidate;
+ }
+ }
+ }
+
+ return pRetval;
+}
+
+void ScreenshotAnnotationDlg_Impl::PaintScreenShotEntry(
+ const weld::ScreenShotEntry& rEntry,
+ const Color& rColor,
+ double fLineWidth,
+ double fTransparency)
+{
+ if (!(mxPicture && mxVirtualBufferDevice))
+ return;
+
+ basegfx::B2DRange aB2DRange(rEntry.getB2IRange());
+
+ // grow in pixels to be a little bit 'outside'. This also
+ // ensures that getWidth()/getHeight() ain't 0.0 (see division below)
+ static const double fGrowTopLeft(1.5);
+ static const double fGrowBottomRight(0.5);
+ aB2DRange.expand(aB2DRange.getMinimum() - basegfx::B2DPoint(fGrowTopLeft, fGrowTopLeft));
+ aB2DRange.expand(aB2DRange.getMaximum() + basegfx::B2DPoint(fGrowBottomRight, fGrowBottomRight));
+
+ // edge rounding in pixel. Need to convert, value for
+ // createPolygonFromRect is relative [0.0 .. 1.0]
+ static const double fEdgeRoundPixel(8.0);
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::utils::createPolygonFromRect(
+ aB2DRange,
+ fEdgeRoundPixel / aB2DRange.getWidth(),
+ fEdgeRoundPixel / aB2DRange.getHeight()));
+
+ mxVirtualBufferDevice->SetLineColor(rColor);
+
+ // try to use transparency
+ if (!mxVirtualBufferDevice->DrawPolyLineDirect(
+ basegfx::B2DHomMatrix(),
+ aPolygon,
+ fLineWidth,
+ fTransparency,
+ nullptr, // MM01
+ basegfx::B2DLineJoin::Round))
+ {
+ // no transparency, draw without
+ mxVirtualBufferDevice->DrawPolyLine(
+ aPolygon,
+ fLineWidth);
+ }
+}
+
+Point ScreenshotAnnotationDlg_Impl::GetOffsetInPicture() const
+{
+ const Size aPixelSizeTarget(maPicture.GetOutputSizePixel());
+
+ return Point(
+ aPixelSizeTarget.Width() > maParentDialogSize.Width() ? (aPixelSizeTarget.Width() - maParentDialogSize.Width()) >> 1 : 0,
+ aPixelSizeTarget.Height() > maParentDialogSize.Height() ? (aPixelSizeTarget.Height() - maParentDialogSize.Height()) >> 1 : 0);
+}
+
+void ScreenshotAnnotationDlg_Impl::RepaintToBuffer(
+ bool bUseDimmed,
+ bool bPaintHilight)
+{
+ if (!mxVirtualBufferDevice)
+ return;
+
+ // reset with original screenshot bitmap
+ mxVirtualBufferDevice->DrawBitmapEx(
+ Point(0, 0),
+ bUseDimmed ? maDimmedDialogBitmap : maParentDialogBitmap);
+
+ // get various options
+ const Color aHilightColor(SvtOptionsDrawinglayer::getHilightColor());
+ const double fTransparence(SvtOptionsDrawinglayer::GetTransparentSelectionPercent() * 0.01);
+ const bool bIsAntiAliasing(SvtOptionsDrawinglayer::IsAntiAliasing());
+ const AntialiasingFlags nOldAA(mxVirtualBufferDevice->GetAntialiasing());
+
+ if (bIsAntiAliasing)
+ {
+ mxVirtualBufferDevice->SetAntialiasing(AntialiasingFlags::Enable);
+ }
+
+ // paint selected entries
+ for (auto&& rCandidate : maSelected)
+ {
+ static const double fLineWidthEntries(5.0);
+ PaintScreenShotEntry(*rCandidate, COL_LIGHTRED, fLineWidthEntries, fTransparence * 0.2);
+ }
+
+ // paint highlighted entry
+ if (mpHilighted && bPaintHilight)
+ {
+ static const double fLineWidthHilight(7.0);
+ PaintScreenShotEntry(*mpHilighted, aHilightColor, fLineWidthHilight, fTransparence);
+ }
+
+ if (bIsAntiAliasing)
+ {
+ mxVirtualBufferDevice->SetAntialiasing(nOldAA);
+ }
+}
+
+void ScreenshotAnnotationDlg_Impl::RepaintPictureElement()
+{
+ if (mxPicture && mxVirtualBufferDevice)
+ {
+ // reset image in buffer, use dimmed version and allow highlight
+ RepaintToBuffer(true, true);
+ mxPicture->queue_draw();
+ }
+}
+
+void ScreenshotAnnotationDlg_Impl::Paint(vcl::RenderContext& rRenderContext)
+{
+ Point aPos(GetOffsetInPicture());
+ Size aSize(mxVirtualBufferDevice->GetOutputSizePixel());
+ rRenderContext.DrawOutDev(aPos, aSize, Point(), aSize, *mxVirtualBufferDevice);
+}
+
+void Picture::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ m_pDialog->Paint(rRenderContext);
+}
+
+bool ScreenshotAnnotationDlg_Impl::MouseMove(const MouseEvent& rMouseEvent)
+{
+ bool bRepaint(false);
+
+ if (maPicture.IsMouseOver())
+ {
+ const weld::ScreenShotEntry* pOldHit = mpHilighted;
+ const Point aOffset(GetOffsetInPicture());
+ const basegfx::B2IPoint aMousePos(
+ rMouseEvent.GetPosPixel().X() - aOffset.X(),
+ rMouseEvent.GetPosPixel().Y() - aOffset.Y());
+ const weld::ScreenShotEntry* pHit = CheckHit(aMousePos);
+
+ if (pHit && pOldHit != pHit)
+ {
+ mpHilighted = const_cast<weld::ScreenShotEntry*>(pHit);
+ bRepaint = true;
+ }
+ }
+ else if (mpHilighted)
+ {
+ mpHilighted = nullptr;
+ bRepaint = true;
+ }
+
+ if (bRepaint)
+ {
+ RepaintPictureElement();
+ }
+
+ return true;
+}
+
+bool Picture::MouseMove(const MouseEvent& rMouseEvent)
+{
+ if (rMouseEvent.IsEnterWindow())
+ m_bMouseOver = true;
+ if (rMouseEvent.IsLeaveWindow())
+ m_bMouseOver = false;
+ return m_pDialog->MouseMove(rMouseEvent);
+}
+
+bool ScreenshotAnnotationDlg_Impl::MouseButtonUp()
+{
+ // event in picture frame
+ bool bRepaint(false);
+
+ if (maPicture.IsMouseOver() && mpHilighted)
+ {
+ if (maSelected.erase(mpHilighted) == 0)
+ {
+ maSelected.insert(mpHilighted);
+ }
+
+ OUStringBuffer aBookmarks(maMainMarkupText);
+ for (auto&& rCandidate : maSelected)
+ {
+ OUString aHelpId = OStringToOUString( rCandidate->GetHelpId(), RTL_TEXTENCODING_UTF8 );
+ aBookmarks.append(lcl_Bookmark( aHelpId ));
+ }
+
+ mxText->set_text( aBookmarks.makeStringAndClear() );
+ bRepaint = true;
+ }
+
+ if (bRepaint)
+ {
+ RepaintPictureElement();
+ }
+
+ return true;
+}
+
+bool Picture::MouseButtonUp(const MouseEvent&)
+{
+ return m_pDialog->MouseButtonUp();
+}
+
+ScreenshotAnnotationDlg::ScreenshotAnnotationDlg(weld::Dialog& rParentDialog)
+ : GenericDialogController(&rParentDialog, "cui/ui/screenshotannotationdialog.ui", "ScreenshotAnnotationDialog")
+{
+ m_pImpl.reset(new ScreenshotAnnotationDlg_Impl(m_xDialog.get(), *m_xBuilder, rParentDialog));
+}
+
+ScreenshotAnnotationDlg::~ScreenshotAnnotationDlg()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/scriptdlg.cxx b/cui/source/dialogs/scriptdlg.cxx
new file mode 100644
index 000000000..8e787e8d1
--- /dev/null
+++ b/cui/source/dialogs/scriptdlg.cxx
@@ -0,0 +1,1338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <string_view>
+#include <utility>
+
+#include <sfx2/objsh.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <scriptdlg.hxx>
+#include <dialmgr.hxx>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/provider/ScriptErrorRaisedException.hpp>
+#include <com/sun/star/script/provider/ScriptExceptionRaisedException.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+
+#include <comphelper/lok.hxx>
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/processfactory.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <svtools/imagemgr.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace css::uno;
+using namespace css::script;
+using namespace css::frame;
+using namespace css::document;
+
+void SvxScriptOrgDialog::delUserData(const weld::TreeIter& rIter)
+{
+ SFEntry* pUserData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(rIter));
+ if (pUserData)
+ {
+ delete pUserData;
+ // TBD seem to get a Select event on node that is remove ( below )
+ // so need to be able to detect that this node is not to be
+ // processed in order to do this, setting userData to NULL ( must
+ // be a better way to do this )
+ m_xScriptsBox->set_id(rIter, OUString());
+ }
+}
+
+void SvxScriptOrgDialog::deleteTree(const weld::TreeIter& rIter)
+{
+ delUserData(rIter);
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator(&rIter);
+ if (!m_xScriptsBox->iter_children(*xIter))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xAltIter = m_xScriptsBox->make_iterator();
+ bool bNextEntry;
+ do
+ {
+ m_xScriptsBox->copy_iterator(*xIter, *xAltIter);
+ bNextEntry = m_xScriptsBox->iter_next_sibling(*xAltIter);
+ deleteTree(*xIter);
+ m_xScriptsBox->remove(*xIter);
+ m_xScriptsBox->copy_iterator(*xAltIter, *xIter);
+ }
+ while (bNextEntry);
+}
+
+void SvxScriptOrgDialog::deleteAllTree()
+{
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_iter_first(*xIter))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xAltIter = m_xScriptsBox->make_iterator();
+ // TBD - below is a candidate for a destroyAllTrees method
+ bool bNextEntry;
+ do
+ {
+ m_xScriptsBox->copy_iterator(*xIter, *xAltIter);
+ bNextEntry = m_xScriptsBox->iter_next_sibling(*xAltIter);
+ deleteTree(*xIter);
+ m_xScriptsBox->remove(*xIter);
+ m_xScriptsBox->copy_iterator(*xAltIter, *xIter);
+ }
+ while (bNextEntry);
+}
+
+void SvxScriptOrgDialog::Init( std::u16string_view language )
+{
+ m_xScriptsBox->freeze();
+
+ deleteAllTree();
+
+ Reference< browse::XBrowseNode > rootNode;
+ Reference< XComponentContext > xCtx(
+ comphelper::getProcessComponentContext() );
+
+ Sequence< Reference< browse::XBrowseNode > > children;
+
+ OUString userStr("user");
+ OUString const shareStr("share");
+
+ try
+ {
+ Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get(xCtx);
+
+ rootNode.set( xFac->createView(
+ browse::BrowseNodeFactoryViewTypes::MACROORGANIZER ) );
+
+ if ( rootNode.is() && rootNode->hasChildNodes() )
+ {
+ children = rootNode->getChildNodes();
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Exception getting root browse node from factory");
+ // TODO exception handling
+ }
+
+ Reference<XModel> xDocumentModel;
+ for ( const Reference< browse::XBrowseNode >& childNode : std::as_const(children) )
+ {
+ bool app = false;
+ OUString uiName = childNode->getName();
+ OUString factoryURL;
+ if ( uiName == userStr || uiName == shareStr )
+ {
+ app = true;
+ if ( uiName == userStr )
+ {
+ uiName = m_sMyMacros;
+ }
+ else
+ {
+ uiName = m_sProdMacros;
+ }
+ }
+ else
+ {
+ xDocumentModel.set(getDocumentModel(xCtx, uiName ), UNO_QUERY);
+
+ if ( xDocumentModel.is() )
+ {
+ Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
+
+ // get the long name of the document:
+ Sequence<beans::PropertyValue> moduleDescr;
+ try{
+ OUString appModule = xModuleManager->identify( xDocumentModel );
+ xModuleManager->getByName(appModule) >>= moduleDescr;
+ } catch(const uno::Exception&)
+ {}
+
+ for ( const beans::PropertyValue& prop : std::as_const(moduleDescr))
+ {
+ if ( prop.Name == "ooSetupFactoryEmptyDocumentURL" )
+ {
+ prop.Value >>= factoryURL;
+ break;
+ }
+ }
+ }
+ }
+
+ Reference< browse::XBrowseNode > langEntries =
+ getLangNodeFromRootNode( childNode, language );
+
+ insertEntry( uiName, app ? OUString(RID_CUIBMP_HARDDISK) : OUString(RID_CUIBMP_DOC),
+ nullptr, true, std::make_unique< SFEntry >( langEntries, xDocumentModel ), factoryURL, false );
+ }
+
+ m_xScriptsBox->thaw();
+}
+
+Reference< XInterface >
+SvxScriptOrgDialog::getDocumentModel( Reference< XComponentContext > const & xCtx, std::u16string_view docName )
+{
+ Reference< XInterface > xModel;
+ Reference< frame::XDesktop2 > desktop = frame::Desktop::create(xCtx);
+
+ Reference< container::XEnumerationAccess > componentsAccess =
+ desktop->getComponents();
+ Reference< container::XEnumeration > components =
+ componentsAccess->createEnumeration();
+ while (components->hasMoreElements())
+ {
+ Reference< frame::XModel > model(
+ components->nextElement(), UNO_QUERY );
+ if ( model.is() )
+ {
+ OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
+ if( sTdocUrl == docName )
+ {
+ xModel = model;
+ break;
+ }
+ }
+ }
+ return xModel;
+}
+
+Reference< browse::XBrowseNode >
+SvxScriptOrgDialog::getLangNodeFromRootNode( Reference< browse::XBrowseNode > const & rootNode, std::u16string_view language )
+{
+ Reference< browse::XBrowseNode > langNode;
+
+ try
+ {
+ auto tryFind = [&] {
+ const Sequence<Reference<browse::XBrowseNode>> children = rootNode->getChildNodes();
+ const auto it = std::find_if(children.begin(), children.end(),
+ [&](const Reference<browse::XBrowseNode>& child) {
+ return child->getName() == language;
+ });
+ return (it != children.end()) ? *it : nullptr;
+ };
+ {
+ // First try without Java interaction, to avoid warnings for non-JRE-dependent providers
+ css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
+ langNode = tryFind();
+ }
+ if (!langNode)
+ {
+ // Now try with Java interaction enabled
+ langNode = tryFind();
+ }
+ }
+ catch ( Exception& )
+ {
+ // if getChildNodes() throws an exception we just return
+ // the empty Reference
+ }
+ return langNode;
+}
+
+void SvxScriptOrgDialog::RequestSubEntries(const weld::TreeIter& rRootEntry, Reference< css::script::browse::XBrowseNode > const & node,
+ Reference< XModel >& model)
+{
+ if (!node.is())
+ {
+ return;
+ }
+
+ Sequence< Reference< browse::XBrowseNode > > children;
+ try
+ {
+ children = node->getChildNodes();
+ }
+ catch ( Exception& )
+ {
+ // if we catch an exception in getChildNodes then no entries are added
+ }
+
+ for ( const Reference< browse::XBrowseNode >& childNode : std::as_const(children) )
+ {
+ OUString name( childNode->getName() );
+ if ( childNode->getType() != browse::BrowseNodeTypes::SCRIPT)
+ {
+ insertEntry(name, RID_CUIBMP_LIB, &rRootEntry, true, std::make_unique<SFEntry>(childNode, model), false);
+ }
+ else
+ {
+ insertEntry(name, RID_CUIBMP_MACRO, &rRootEntry, false, std::make_unique<SFEntry>(childNode, model), false);
+ }
+ }
+}
+
+void SvxScriptOrgDialog::insertEntry(const OUString& rText, const OUString& rBitmap,
+ const weld::TreeIter* pParent, bool bChildrenOnDemand, std::unique_ptr<SFEntry> && aUserData,
+ std::u16string_view factoryURL, bool bSelect)
+{
+ if (rBitmap == RID_CUIBMP_DOC && !factoryURL.empty())
+ {
+ OUString aImage = SvFileInformationManager::GetFileImageId(INetURLObject(factoryURL));
+ insertEntry(rText, aImage, pParent, bChildrenOnDemand, std::move(aUserData), bSelect);
+ return;
+ }
+ insertEntry(rText, rBitmap, pParent, bChildrenOnDemand, std::move(aUserData), bSelect);
+}
+
+void SvxScriptOrgDialog::insertEntry(
+ const OUString& rText, const OUString& rBitmap, const weld::TreeIter* pParent,
+ bool bChildrenOnDemand, std::unique_ptr<SFEntry> && aUserData, bool bSelect)
+{
+ OUString sId(weld::toId(aUserData.release())); // XXX possible leak
+ m_xScriptsBox->insert(pParent, -1, &rText, &sId, nullptr, nullptr,
+ bChildrenOnDemand, m_xScratchIter.get());
+ m_xScriptsBox->set_image(*m_xScratchIter, rBitmap);
+ if (bSelect)
+ {
+ m_xScriptsBox->set_cursor(*m_xScratchIter);
+ m_xScriptsBox->select(*m_xScratchIter);
+ }
+}
+
+IMPL_LINK(SvxScriptOrgDialog, ExpandingHdl, const weld::TreeIter&, rIter, bool)
+{
+ SFEntry* userData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(rIter));
+
+ Reference< browse::XBrowseNode > node;
+ Reference< XModel > model;
+ if ( userData && !userData->isLoaded() )
+ {
+ node = userData->GetNode();
+ model = userData->GetModel();
+ RequestSubEntries(rIter, node, model);
+ userData->setLoaded();
+ }
+
+ return true;
+}
+
+// CuiInputDialog ------------------------------------------------------------
+CuiInputDialog::CuiInputDialog(weld::Window * pParent, InputDialogMode nMode)
+ : GenericDialogController(pParent, "cui/ui/newlibdialog.ui", "NewLibDialog")
+ , m_xEdit(m_xBuilder->weld_entry("entry"))
+{
+ m_xEdit->grab_focus();
+
+ std::unique_ptr<weld::Label> xNewLibFT(m_xBuilder->weld_label("newlibft"));
+
+ if ( nMode == InputDialogMode::NEWMACRO )
+ {
+ xNewLibFT->hide();
+ std::unique_ptr<weld::Label> xNewMacroFT(m_xBuilder->weld_label("newmacroft"));
+ xNewMacroFT->show();
+ std::unique_ptr<weld::Label> xAltTitle(m_xBuilder->weld_label("altmacrotitle"));
+ m_xDialog->set_title(xAltTitle->get_label());
+ }
+ else if ( nMode == InputDialogMode::RENAME )
+ {
+ xNewLibFT->hide();
+ std::unique_ptr<weld::Label> xRenameFT(m_xBuilder->weld_label("renameft"));
+ xRenameFT->show();
+ std::unique_ptr<weld::Label> xAltTitle(m_xBuilder->weld_label("altrenametitle"));
+ m_xDialog->set_title(xAltTitle->get_label());
+ }
+}
+
+// ScriptOrgDialog ------------------------------------------------------------
+
+SvxScriptOrgDialog::SvxScriptOrgDialog(weld::Window* pParent, OUString language)
+ : SfxDialogController(pParent, "cui/ui/scriptorganizer.ui", "ScriptOrganizerDialog")
+ , m_pParent(pParent)
+ , m_sLanguage(std::move(language))
+ , m_delErrStr(CuiResId(RID_CUISTR_DELFAILED))
+ , m_delErrTitleStr(CuiResId(RID_CUISTR_DELFAILED_TITLE))
+ , m_delQueryStr(CuiResId(RID_CUISTR_DELQUERY))
+ , m_delQueryTitleStr(CuiResId(RID_CUISTR_DELQUERY_TITLE))
+ , m_createErrStr(CuiResId(RID_CUISTR_CREATEFAILED))
+ , m_createDupStr(CuiResId(RID_CUISTR_CREATEFAILEDDUP))
+ , m_createErrTitleStr(CuiResId(RID_CUISTR_CREATEFAILED_TITLE))
+ , m_renameErrStr(CuiResId(RID_CUISTR_RENAMEFAILED))
+ , m_renameErrTitleStr(CuiResId(RID_CUISTR_RENAMEFAILED_TITLE))
+ , m_sMyMacros(CuiResId(RID_CUISTR_MYMACROS))
+ , m_sProdMacros(CuiResId(RID_CUISTR_PRODMACROS))
+ , m_xScriptsBox(m_xBuilder->weld_tree_view("scripts"))
+ , m_xScratchIter(m_xScriptsBox->make_iterator())
+ , m_xRunButton(m_xBuilder->weld_button("ok"))
+ , m_xCloseButton(m_xBuilder->weld_button("close"))
+ , m_xCreateButton(m_xBuilder->weld_button("create"))
+ , m_xEditButton(m_xBuilder->weld_button("edit"))
+ , m_xRenameButton(m_xBuilder->weld_button("rename"))
+ , m_xDelButton(m_xBuilder->weld_button("delete"))
+{
+ // must be a neater way to deal with the strings than as above
+ // append the language to the dialog title
+ OUString winTitle(m_xDialog->get_title());
+ winTitle = winTitle.replaceFirst( "%MACROLANG", m_sLanguage );
+ m_xDialog->set_title(winTitle);
+
+ m_xScriptsBox->set_size_request(m_xScriptsBox->get_approximate_digit_width() * 45,
+ m_xScriptsBox->get_height_rows(12));
+
+ m_xScriptsBox->connect_changed( LINK( this, SvxScriptOrgDialog, ScriptSelectHdl ) );
+ m_xScriptsBox->connect_expanding(LINK( this, SvxScriptOrgDialog, ExpandingHdl ) );
+ m_xRunButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xCloseButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xRenameButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xEditButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xDelButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xCreateButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+
+ m_xRunButton->set_sensitive(false);
+ m_xRenameButton->set_sensitive(false);
+ m_xEditButton->set_sensitive(false);
+ m_xDelButton->set_sensitive(false);
+ m_xCreateButton->set_sensitive(false);
+
+ Init(m_sLanguage);
+ RestorePreviousSelection();
+}
+
+SvxScriptOrgDialog::~SvxScriptOrgDialog()
+{
+ deleteAllTree();
+}
+
+short SvxScriptOrgDialog::run()
+{
+ SfxObjectShell *pDoc = SfxObjectShell::GetFirst();
+
+ // force load of MSPs for all documents
+ while ( pDoc )
+ {
+ Reference< provider::XScriptProviderSupplier > xSPS( pDoc->GetModel(), UNO_QUERY );
+ if ( xSPS.is() )
+ {
+ xSPS->getScriptProvider();
+ }
+
+ pDoc = SfxObjectShell::GetNext(*pDoc);
+ }
+
+ return SfxDialogController::run();
+}
+
+void SvxScriptOrgDialog::CheckButtons( Reference< browse::XBrowseNode > const & node )
+{
+ if ( node.is() )
+ {
+ if ( node->getType() == browse::BrowseNodeTypes::SCRIPT)
+ {
+ m_xRunButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xRunButton->set_sensitive(false);
+ }
+ Reference< beans::XPropertySet > xProps( node, UNO_QUERY );
+
+ if ( !xProps.is() )
+ {
+ m_xEditButton->set_sensitive(false);
+ m_xDelButton->set_sensitive(false);
+ m_xCreateButton->set_sensitive(false);
+ m_xRunButton->set_sensitive(false);
+ return;
+ }
+
+ OUString sName("Editable");
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xEditButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xEditButton->set_sensitive(false);
+ }
+
+ sName = "Deletable";
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xDelButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xDelButton->set_sensitive(false);
+ }
+
+ sName = "Creatable";
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xCreateButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xCreateButton->set_sensitive(false);
+ }
+
+ sName = "Renamable";
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xRenameButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xRenameButton->set_sensitive(false);
+ }
+ }
+ else
+ {
+ // no node info available, disable all configurable actions
+ m_xDelButton->set_sensitive(false);
+ m_xCreateButton->set_sensitive(false);
+ m_xEditButton->set_sensitive(false);
+ m_xRunButton->set_sensitive(false);
+ m_xRenameButton->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxScriptOrgDialog, ScriptSelectHdl, weld::TreeView&, void)
+{
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_selected(xIter.get()))
+ return;
+
+ SFEntry* userData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(*xIter));
+
+ Reference< browse::XBrowseNode > node;
+ if (userData)
+ {
+ node = userData->GetNode();
+ CheckButtons(node);
+ }
+}
+
+IMPL_LINK(SvxScriptOrgDialog, ButtonHdl, weld::Button&, rButton, void)
+{
+ if ( &rButton == m_xCloseButton.get() )
+ {
+ StoreCurrentSelection();
+ m_xDialog->response(RET_CANCEL);
+ }
+ if (!(&rButton == m_xEditButton.get() ||
+ &rButton == m_xCreateButton.get() ||
+ &rButton == m_xDelButton.get() ||
+ &rButton == m_xRunButton.get() ||
+ &rButton == m_xRenameButton.get()))
+
+ return;
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_selected(xIter.get()))
+ return;
+ SFEntry* userData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(*xIter));
+ if (!userData)
+ return;
+
+ Reference< browse::XBrowseNode > node;
+ Reference< XModel > xModel;
+
+ node = userData->GetNode();
+ xModel = userData->GetModel();
+
+ if ( !node.is() )
+ {
+ return;
+ }
+
+ if (&rButton == m_xRunButton.get())
+ {
+ OUString tmpString;
+ Reference< beans::XPropertySet > xProp( node, UNO_QUERY );
+ Reference< provider::XScriptProvider > mspNode;
+ if( !xProp.is() )
+ {
+ return;
+ }
+
+ if ( xModel.is() )
+ {
+ Reference< XEmbeddedScripts > xEmbeddedScripts( xModel, UNO_QUERY);
+ if( !xEmbeddedScripts.is() )
+ {
+ return;
+ }
+
+ if (!xEmbeddedScripts->getAllowMacroExecution())
+ {
+ // Please FIXME: Show a message box if AllowMacroExecution is false
+ return;
+ }
+ }
+
+ std::unique_ptr<weld::TreeIter> xParentIter = m_xScriptsBox->make_iterator(xIter.get());
+ bool bParent = m_xScriptsBox->iter_parent(*xParentIter);
+ while (bParent && !mspNode.is() )
+ {
+ SFEntry* mspUserData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(*xParentIter));
+ mspNode.set( mspUserData->GetNode() , UNO_QUERY );
+ bParent = m_xScriptsBox->iter_parent(*xParentIter);
+ }
+ xProp->getPropertyValue("URI") >>= tmpString;
+ const OUString scriptURL( tmpString );
+
+ if ( mspNode.is() )
+ {
+ try
+ {
+ Reference< provider::XScript > xScript(
+ mspNode->getScript( scriptURL ), UNO_SET_THROW );
+
+ const Sequence< Any > args(0);
+ Sequence< sal_Int16 > outIndex;
+ Sequence< Any > outArgs( 0 );
+ xScript->invoke( args, outIndex, outArgs );
+ }
+ catch ( reflection::InvocationTargetException& ite )
+ {
+ SvxScriptErrorDialog::ShowAsyncErrorDialog(m_pParent, css::uno::Any(ite));
+ }
+ catch ( provider::ScriptFrameworkErrorException& ite )
+ {
+ SvxScriptErrorDialog::ShowAsyncErrorDialog(m_pParent, css::uno::Any(ite));
+ }
+ catch ( RuntimeException& re )
+ {
+ SvxScriptErrorDialog::ShowAsyncErrorDialog(m_pParent, css::uno::Any(re));
+ }
+ catch ( Exception& e )
+ {
+ SvxScriptErrorDialog::ShowAsyncErrorDialog(m_pParent, css::uno::Any(e));
+ }
+ }
+ StoreCurrentSelection();
+ m_xDialog->response(RET_CANCEL);
+ }
+ else if ( &rButton == m_xEditButton.get() )
+ {
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+ if ( xInv.is() )
+ {
+ StoreCurrentSelection();
+ m_xDialog->response(RET_CANCEL);
+ Sequence< Any > args(0);
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ // ISSUE need code to run script here
+ xInv->invoke( "Editable", args, outIndex, outArgs );
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to invoke" );
+ }
+ }
+ }
+ else if ( &rButton == m_xCreateButton.get() )
+ {
+ createEntry(*xIter);
+ }
+ else if ( &rButton == m_xDelButton.get() )
+ {
+ deleteEntry(*xIter);
+ }
+ else if ( &rButton == m_xRenameButton.get() )
+ {
+ renameEntry(*xIter);
+ }
+}
+
+Reference< browse::XBrowseNode > SvxScriptOrgDialog::getBrowseNode(const weld::TreeIter& rEntry)
+{
+ Reference< browse::XBrowseNode > node;
+ SFEntry* userData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(rEntry));
+ if (userData)
+ {
+ node = userData->GetNode();
+ }
+ return node;
+}
+
+Reference< XModel > SvxScriptOrgDialog::getModel(const weld::TreeIter& rEntry)
+{
+ Reference< XModel > model;
+ SFEntry* userData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(rEntry));
+ if ( userData )
+ {
+ model = userData->GetModel();
+ }
+ return model;
+}
+
+void SvxScriptOrgDialog::createEntry(const weld::TreeIter& rEntry)
+{
+
+ Reference< browse::XBrowseNode > aChildNode;
+ Reference< browse::XBrowseNode > node = getBrowseNode( rEntry );
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+
+ if ( xInv.is() )
+ {
+ OUString aNewName;
+ OUString aNewStdName;
+ InputDialogMode nMode = InputDialogMode::NEWLIB;
+ if (m_xScriptsBox->get_iter_depth(rEntry) == 0)
+ {
+ aNewStdName = "Library" ;
+ }
+ else
+ {
+ aNewStdName = "Macro" ;
+ nMode = InputDialogMode::NEWMACRO;
+ }
+ //do we need L10N for this? ie something like:
+ //String aNewStdName( ResId( STR_STDMODULENAME ) );
+ bool bValid = false;
+ sal_Int32 i = 1;
+
+ Sequence< Reference< browse::XBrowseNode > > childNodes;
+ // no children => ok to create Parcel1 or Script1 without checking
+ try
+ {
+ if( !node->hasChildNodes() )
+ {
+ aNewName = aNewStdName + OUString::number(i);
+ bValid = true;
+ }
+ else
+ {
+ childNodes = node->getChildNodes();
+ }
+ }
+ catch ( Exception& )
+ {
+ // ignore, will continue on with empty sequence
+ }
+
+ OUString extn;
+ while ( !bValid )
+ {
+ aNewName = aNewStdName + OUString::number(i);
+ bool bFound = false;
+ if(childNodes.hasElements() )
+ {
+ OUString nodeName = childNodes[0]->getName();
+ sal_Int32 extnPos = nodeName.lastIndexOf( '.' );
+ if(extnPos>0)
+ extn = nodeName.copy(extnPos);
+ }
+ for( const Reference< browse::XBrowseNode >& n : std::as_const(childNodes) )
+ {
+ if (OUStringConcatenation(aNewName+extn) == n->getName())
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if( bFound )
+ {
+ i++;
+ }
+ else
+ {
+ bValid = true;
+ }
+ }
+
+ CuiInputDialog aNewDlg(m_xDialog.get(), nMode);
+ aNewDlg.SetObjectName(aNewName);
+
+ do
+ {
+ if (aNewDlg.run() && !aNewDlg.GetObjectName().isEmpty())
+ {
+ OUString aUserSuppliedName = aNewDlg.GetObjectName();
+ bValid = true;
+ for( const Reference< browse::XBrowseNode >& n : std::as_const(childNodes) )
+ {
+ if (OUStringConcatenation(aUserSuppliedName+extn) == n->getName())
+ {
+ bValid = false;
+ OUString aError = m_createErrStr + m_createDupStr;
+
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aError));
+ xErrorBox->set_title(m_createErrTitleStr);
+ xErrorBox->run();
+ aNewDlg.SetObjectName(aNewName);
+ break;
+ }
+ }
+ if( bValid )
+ aNewName = aUserSuppliedName;
+ }
+ else
+ {
+ // user hit cancel or hit OK with nothing in the editbox
+
+ return;
+ }
+ }
+ while ( !bValid );
+
+ // open up parent node (which ensures it's loaded)
+ m_xScriptsBox->expand_row(rEntry);
+
+ Sequence< Any > args{ Any(aNewName) };
+ Sequence< Any > outArgs;
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ Any aResult = xInv->invoke( "Creatable", args, outIndex, outArgs );
+ Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
+ aChildNode = newNode;
+
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Create" );
+ }
+ }
+ if ( aChildNode.is() )
+ {
+ OUString aChildName = aChildNode->getName();
+
+ Reference<XModel> xDocumentModel = getModel( rEntry );
+
+ // ISSUE do we need to remove all entries for parent
+ // to achieve sort? Just need to determine position
+ // -- Basic doesn't do this on create.
+ // Suppose we could avoid this too. -> created nodes are
+ // not in alphabetical order
+ if ( aChildNode->getType() == browse::BrowseNodeTypes::SCRIPT )
+ {
+ insertEntry(aChildName, RID_CUIBMP_MACRO, &rEntry, false,
+ std::make_unique<SFEntry>(aChildNode,xDocumentModel), true);
+ }
+ else
+ {
+ insertEntry(aChildName, RID_CUIBMP_LIB, &rEntry, false,
+ std::make_unique<SFEntry>(aChildNode,xDocumentModel), true);
+
+ // If the Parent is not loaded then set to
+ // loaded, this will prevent RequestingChildren ( called
+ // from vcl via RequestingChildren ) from
+ // creating new ( duplicate ) children
+ SFEntry* userData = weld::fromId<SFEntry*>(m_xScriptsBox->get_id(rEntry));
+ if ( userData && !userData->isLoaded() )
+ {
+ userData->setLoaded();
+ }
+ }
+ }
+ else
+ {
+ //ISSUE L10N & message from exception?
+ OUString aError( m_createErrStr );
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aError));
+ xErrorBox->set_title(m_createErrTitleStr);
+ xErrorBox->run();
+ }
+}
+
+void SvxScriptOrgDialog::renameEntry(const weld::TreeIter& rEntry)
+{
+
+ Reference< browse::XBrowseNode > aChildNode;
+ Reference< browse::XBrowseNode > node = getBrowseNode(rEntry);
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+
+ if ( xInv.is() )
+ {
+ OUString aNewName = node->getName();
+ sal_Int32 extnPos = aNewName.lastIndexOf( '.' );
+ if(extnPos>0)
+ {
+ aNewName = aNewName.copy(0,extnPos);
+ }
+ CuiInputDialog aNewDlg(m_xDialog.get(), InputDialogMode::RENAME);
+ aNewDlg.SetObjectName(aNewName);
+
+ if (!aNewDlg.run() || aNewDlg.GetObjectName().isEmpty())
+ return; // user hit cancel or hit OK with nothing in the editbox
+
+ aNewName = aNewDlg.GetObjectName();
+
+ Sequence< Any > args{ Any(aNewName) };
+ Sequence< Any > outArgs;
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ Any aResult = xInv->invoke( "Renamable", args, outIndex, outArgs );
+ Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
+ aChildNode = newNode;
+
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Rename" );
+ }
+ }
+ if ( aChildNode.is() )
+ {
+ m_xScriptsBox->set_text(rEntry, aChildNode->getName());
+ m_xScriptsBox->set_cursor(rEntry);
+ m_xScriptsBox->select(rEntry);
+
+ }
+ else
+ {
+ //ISSUE L10N & message from exception?
+ OUString aError( m_renameErrStr );
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aError));
+ xErrorBox->set_title(m_renameErrTitleStr);
+ xErrorBox->run();
+ }
+}
+
+void SvxScriptOrgDialog::deleteEntry(const weld::TreeIter& rEntry)
+{
+ bool result = false;
+ Reference< browse::XBrowseNode > node = getBrowseNode(rEntry);
+ // ISSUE L10N string & can we center list?
+ OUString aQuery = m_delQueryStr + getListOfChildren( node, 0 );
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo, aQuery));
+ xQueryBox->set_title(m_delQueryTitleStr);
+ if (xQueryBox->run() == RET_NO)
+ {
+ return;
+ }
+
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+ if ( xInv.is() )
+ {
+ Sequence< Any > args( 0 );
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ Any aResult = xInv->invoke( "Deletable", args, outIndex, outArgs );
+ aResult >>= result; // or do we just assume true if no exception ?
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to delete" );
+ }
+ }
+
+ if ( result )
+ {
+ deleteTree(rEntry);
+ m_xScriptsBox->remove(rEntry);
+ }
+ else
+ {
+ //ISSUE L10N & message from exception?
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, m_delErrStr));
+ xErrorBox->set_title(m_delErrTitleStr);
+ xErrorBox->run();
+ }
+
+}
+
+bool SvxScriptOrgDialog::getBoolProperty( Reference< beans::XPropertySet > const & xProps,
+ OUString const & propName )
+{
+ bool result = false;
+ try
+ {
+ xProps->getPropertyValue( propName ) >>= result;
+ }
+ catch ( Exception& )
+ {
+ return result;
+ }
+ return result;
+}
+
+OUString SvxScriptOrgDialog::getListOfChildren( const Reference< browse::XBrowseNode >& node, int depth )
+{
+ OUStringBuffer result = "\n";
+ for( int i=0;i<=depth;i++ )
+ {
+ result.append("\t");
+ }
+ result.append(node->getName());
+
+ try
+ {
+ if ( node->hasChildNodes() )
+ {
+ const Sequence< Reference< browse::XBrowseNode > > children
+ = node->getChildNodes();
+ for( const Reference< browse::XBrowseNode >& n : children )
+ {
+ result.append( getListOfChildren( n , depth+1 ) );
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ // ignore, will return an empty string
+ }
+
+ return result.makeStringAndClear();
+}
+
+Selection_hash SvxScriptOrgDialog::m_lastSelection;
+
+void SvxScriptOrgDialog::StoreCurrentSelection()
+{
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_selected(xIter.get()))
+ return;
+ OUString aDescription;
+ bool bEntry;
+ do
+ {
+ aDescription = m_xScriptsBox->get_text(*xIter) + aDescription;
+ bEntry = m_xScriptsBox->iter_parent(*xIter);
+ if (bEntry)
+ aDescription = ";" + aDescription;
+ }
+ while (bEntry);
+ OUString sDesc( aDescription );
+ m_lastSelection[ m_sLanguage ] = sDesc;
+}
+
+void SvxScriptOrgDialog::RestorePreviousSelection()
+{
+ OUString aStoredEntry = m_lastSelection[ m_sLanguage ];
+ if( aStoredEntry.isEmpty() )
+ return;
+ std::unique_ptr<weld::TreeIter> xEntry;
+ std::unique_ptr<weld::TreeIter> xTmpEntry(m_xScriptsBox->make_iterator());
+ sal_Int32 nIndex = 0;
+ while (nIndex != -1)
+ {
+ std::u16string_view aTmp( o3tl::getToken(aStoredEntry, 0, ';', nIndex ) );
+
+ bool bTmpEntry;
+ if (!xEntry)
+ {
+ xEntry = m_xScriptsBox->make_iterator();
+ bTmpEntry = m_xScriptsBox->get_iter_first(*xEntry);
+ m_xScriptsBox->copy_iterator(*xEntry, *xTmpEntry);
+ }
+ else
+ {
+ m_xScriptsBox->copy_iterator(*xEntry, *xTmpEntry);
+ bTmpEntry = m_xScriptsBox->iter_children(*xTmpEntry);
+ }
+
+ while (bTmpEntry)
+ {
+ if (m_xScriptsBox->get_text(*xTmpEntry) == aTmp)
+ {
+ m_xScriptsBox->copy_iterator(*xTmpEntry, *xEntry);
+ break;
+ }
+ bTmpEntry = m_xScriptsBox->iter_next_sibling(*xTmpEntry);
+ }
+
+ if (!bTmpEntry)
+ break;
+
+ m_xScriptsBox->expand_row(*xEntry);
+ }
+
+ if (xEntry)
+ {
+ m_xScriptsBox->set_cursor(*xEntry);
+ ScriptSelectHdl(*m_xScriptsBox);
+ }
+}
+
+namespace {
+
+OUString ReplaceString(
+ const OUString& source,
+ const OUString& token,
+ std::u16string_view value )
+{
+ sal_Int32 pos = source.indexOf( token );
+
+ if ( pos != -1 && !value.empty() )
+ {
+ return source.replaceAt( pos, token.getLength(), value );
+ }
+ else
+ {
+ return source;
+ }
+}
+
+OUString FormatErrorString(
+ const OUString& unformatted,
+ std::u16string_view language,
+ std::u16string_view script,
+ std::u16string_view line,
+ std::u16string_view type,
+ std::u16string_view message )
+{
+ OUString result = unformatted;
+
+ result = ReplaceString(result, "%LANGUAGENAME", language );
+ result = ReplaceString(result, "%SCRIPTNAME", script );
+ result = ReplaceString(result, "%LINENUMBER", line );
+
+ if ( !type.empty() )
+ {
+ result += "\n\n" + CuiResId(RID_CUISTR_ERROR_TYPE_LABEL) + " " + type;
+ }
+
+ if ( !message.empty() )
+ {
+ result += "\n\n" + CuiResId(RID_CUISTR_ERROR_MESSAGE_LABEL) + " " + message;
+ }
+
+ return result;
+}
+
+OUString GetErrorMessage(
+ const provider::ScriptErrorRaisedException& eScriptError )
+{
+ OUString unformatted = CuiResId( RID_CUISTR_ERROR_AT_LINE );
+
+ OUString unknown("UNKNOWN");
+ OUString language = unknown;
+ OUString script = unknown;
+ OUString line = unknown;
+ OUString message = eScriptError.Message;
+
+ if ( !eScriptError.language.isEmpty() )
+ {
+ language = eScriptError.language;
+ }
+
+ if ( !eScriptError.scriptName.isEmpty() )
+ {
+ script = eScriptError.scriptName;
+ }
+
+ if ( !eScriptError.Message.isEmpty() )
+ {
+ message = eScriptError.Message;
+ }
+ if ( eScriptError.lineNum != -1 )
+ {
+ line = OUString::number( eScriptError.lineNum );
+ unformatted = CuiResId( RID_CUISTR_ERROR_AT_LINE );
+ }
+ else
+ {
+ unformatted = CuiResId( RID_CUISTR_ERROR_RUNNING );
+ }
+
+ return FormatErrorString(
+ unformatted, language, script, line, u"", message );
+}
+
+OUString GetErrorMessage(
+ const provider::ScriptExceptionRaisedException& eScriptException )
+{
+ OUString unformatted = CuiResId( RID_CUISTR_EXCEPTION_AT_LINE );
+
+ OUString unknown("UNKNOWN");
+ OUString language = unknown;
+ OUString script = unknown;
+ OUString line = unknown;
+ OUString type = unknown;
+ OUString message = eScriptException.Message;
+
+ if ( !eScriptException.language.isEmpty() )
+ {
+ language = eScriptException.language;
+ }
+ if ( !eScriptException.scriptName.isEmpty() )
+ {
+ script = eScriptException.scriptName;
+ }
+
+ if ( !eScriptException.Message.isEmpty() )
+ {
+ message = eScriptException.Message;
+ }
+
+ if ( eScriptException.lineNum != -1 )
+ {
+ line = OUString::number( eScriptException.lineNum );
+ unformatted = CuiResId( RID_CUISTR_EXCEPTION_AT_LINE );
+ }
+ else
+ {
+ unformatted = CuiResId( RID_CUISTR_EXCEPTION_RUNNING );
+ }
+
+ if ( !eScriptException.exceptionType.isEmpty() )
+ {
+ type = eScriptException.exceptionType;
+ }
+
+ return FormatErrorString(
+ unformatted, language, script, line, type, message );
+
+}
+OUString GetErrorMessage(
+ const provider::ScriptFrameworkErrorException& sError )
+{
+ OUString unformatted = CuiResId( RID_CUISTR_FRAMEWORK_ERROR_RUNNING );
+
+ OUString language("UNKNOWN");
+
+ OUString script("UNKNOWN");
+
+ OUString message;
+
+ if ( !sError.scriptName.isEmpty() )
+ {
+ script = sError.scriptName;
+ }
+ if ( !sError.language.isEmpty() )
+ {
+ language = sError.language;
+ }
+ if ( sError.errorType == provider::ScriptFrameworkErrorType::NOTSUPPORTED )
+ {
+ message = CuiResId(RID_CUISTR_ERROR_LANG_NOT_SUPPORTED);
+ message = ReplaceString(message, "%LANGUAGENAME", language );
+
+ }
+ else
+ {
+ message = sError.Message;
+ }
+ return FormatErrorString(
+ unformatted, language, script, u"", std::u16string_view(), message );
+}
+
+OUString GetErrorMessage( const css::uno::Any& aException )
+{
+ if ( aException.getValueType() ==
+ cppu::UnoType<reflection::InvocationTargetException>::get())
+ {
+ reflection::InvocationTargetException ite;
+ aException >>= ite;
+ if ( ite.TargetException.getValueType() == cppu::UnoType<provider::ScriptErrorRaisedException>::get())
+ {
+ // Error raised by script
+ provider::ScriptErrorRaisedException scriptError;
+ ite.TargetException >>= scriptError;
+ return GetErrorMessage( scriptError );
+ }
+ else if ( ite.TargetException.getValueType() == cppu::UnoType<provider::ScriptExceptionRaisedException>::get())
+ {
+ // Exception raised by script
+ provider::ScriptExceptionRaisedException scriptException;
+ ite.TargetException >>= scriptException;
+ return GetErrorMessage( scriptException );
+ }
+ else
+ {
+ // Unknown error, shouldn't happen
+ // OSL_ASSERT(...)
+ }
+
+ }
+ else if ( aException.getValueType() == cppu::UnoType<provider::ScriptFrameworkErrorException>::get())
+ {
+ // A Script Framework error has occurred
+ provider::ScriptFrameworkErrorException sfe;
+ aException >>= sfe;
+ return GetErrorMessage( sfe );
+
+ }
+ // unknown exception
+ auto msg = aException.getValueTypeName();
+ Exception e;
+ if ( (aException >>= e) && !e.Message.isEmpty() )
+ {
+ msg += ": " + e.Message;
+ }
+ return msg;
+}
+
+}
+
+// Show Error dialog asynchronously
+void SvxScriptErrorDialog::ShowAsyncErrorDialog( weld::Window* pParent, css::uno::Any const & aException )
+{
+ SolarMutexGuard aGuard;
+ OUString sMessage = GetErrorMessage( aException );
+
+ // Pass a copy of the message to the ShowDialog method as the
+ // SvxScriptErrorDialog may be deleted before ShowDialog is called
+ DialogData* pData = new DialogData;
+ pData->sMessage = sMessage;
+ pData->pParent = pParent;
+ Application::PostUserEvent(
+ LINK( nullptr, SvxScriptErrorDialog, ShowDialog ),
+ pData );
+}
+
+IMPL_STATIC_LINK( SvxScriptErrorDialog, ShowDialog, void*, p, void )
+{
+ std::unique_ptr<DialogData> xData(static_cast<DialogData*>(p));
+ OUString message = xData->sMessage;
+
+ if ( message.isEmpty() )
+ message = CuiResId( RID_CUISTR_ERROR_TITLE );
+
+ std::shared_ptr<weld::MessageDialog> xBox;
+ xBox.reset(Application::CreateMessageDialog(
+ xData->pParent,
+ VclMessageType::Warning,
+ VclButtonsType::Ok,
+ message,
+ comphelper::LibreOfficeKit::isActive()));
+
+ xBox->set_title(CuiResId(RID_CUISTR_ERROR_TITLE));
+
+ xBox->runAsync(xBox, [](sal_Int32 /*nResult*/) {});
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/sdrcelldlg.cxx b/cui/source/dialogs/sdrcelldlg.cxx
new file mode 100644
index 000000000..fda8b4ce1
--- /dev/null
+++ b/cui/source/dialogs/sdrcelldlg.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sdrcelldlg.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svdmodel.hxx>
+#include <border.hxx>
+#include <svx/dialogs.hrc>
+
+SvxFormatCellsDialog::SvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel)
+ : SfxTabDialogController(pParent, "cui/ui/formatcellsdialog.ui", "FormatCellsDialog", pAttr)
+ , mrOutAttrs(*pAttr)
+ , mpColorTab(rModel.GetColorList())
+ , mnColorTabState ( ChangeType::NONE )
+ , mpGradientList(rModel.GetGradientList())
+ , mpHatchingList(rModel.GetHatchList())
+ , mpBitmapList(rModel.GetBitmapList())
+ , mpPatternList(rModel.GetPatternList())
+{
+ AddTabPage("name", RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", RID_SVXPAGE_CHAR_EFFECTS);
+ AddTabPage("border", RID_SVXPAGE_BORDER );
+ AddTabPage("area", RID_SVXPAGE_AREA);
+ AddTabPage("shadow", SvxShadowTabPage::Create, nullptr);
+}
+
+void SvxFormatCellsDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "area")
+ {
+ SvxAreaTabPage& rAreaPage = static_cast<SvxAreaTabPage&>(rPage);
+ rAreaPage.SetColorList( mpColorTab );
+ rAreaPage.SetGradientList( mpGradientList );
+ rAreaPage.SetHatchingList( mpHatchingList );
+ rAreaPage.SetBitmapList( mpBitmapList );
+ rAreaPage.SetPatternList( mpPatternList );
+ rAreaPage.ActivatePage( mrOutAttrs );
+ }
+ else if (rId == "border")
+ {
+ SvxBorderTabPage& rBorderPage = static_cast<SvxBorderTabPage&>(rPage);
+ rBorderPage.SetTableMode();
+ }
+ else if (rId == "shadow")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( mpColorTab );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorTabState );
+ }
+ else
+ SfxTabDialogController::PageCreated(rId, rPage);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/showcols.cxx b/cui/source/dialogs/showcols.cxx
new file mode 100644
index 000000000..1e8485513
--- /dev/null
+++ b/cui/source/dialogs/showcols.cxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <showcols.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <comphelper/types.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+
+constexpr OUStringLiteral CUIFM_PROP_HIDDEN = u"Hidden";
+constexpr OUStringLiteral CUIFM_PROP_LABEL = u"Label";
+
+FmShowColsDialog::FmShowColsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/showcoldialog.ui", "ShowColDialog")
+ , m_xList(m_xBuilder->weld_tree_view("treeview"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+{
+ m_xList->set_size_request(m_xList->get_approximate_digit_width() * 40,
+ m_xList->get_height_rows(8));
+ m_xList->set_selection_mode(SelectionMode::Multiple);
+ m_xOK->connect_clicked(LINK(this, FmShowColsDialog, OnClickedOk));
+}
+
+FmShowColsDialog::~FmShowColsDialog() {}
+
+IMPL_LINK_NOARG(FmShowColsDialog, OnClickedOk, weld::Button&, void)
+{
+ DBG_ASSERT(
+ m_xColumns.is(),
+ "FmShowColsDialog::OnClickedOk : you should call SetColumns before executing the dialog !");
+ if (m_xColumns.is())
+ {
+ css::uno::Reference<css::beans::XPropertySet> xCol;
+ auto nSelectedRows = m_xList->get_selected_rows();
+ for (auto i : nSelectedRows)
+ {
+ m_xColumns->getByIndex(m_xList->get_id(i).toInt32()) >>= xCol;
+ if (xCol.is())
+ {
+ try
+ {
+ xCol->setPropertyValue(CUIFM_PROP_HIDDEN, css::uno::Any(false));
+ }
+ catch (...)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs",
+ "FmShowColsDialog::OnClickedOk Exception occurred!");
+ }
+ }
+ }
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+void FmShowColsDialog::SetColumns(const css::uno::Reference<css::container::XIndexContainer>& xCols)
+{
+ DBG_ASSERT(xCols.is(), "FmShowColsDialog::SetColumns : invalid columns !");
+ if (!xCols.is())
+ return;
+ m_xColumns = xCols.get();
+
+ m_xList->clear();
+
+ css::uno::Reference<css::beans::XPropertySet> xCurCol;
+ OUString sCurName;
+ for (sal_Int32 i = 0; i < xCols->getCount(); ++i)
+ {
+ sCurName.clear();
+ xCurCol.set(xCols->getByIndex(i), css::uno::UNO_QUERY);
+ bool bIsHidden = false;
+ try
+ {
+ css::uno::Any aHidden = xCurCol->getPropertyValue(CUIFM_PROP_HIDDEN);
+ bIsHidden = ::comphelper::getBOOL(aHidden);
+
+ OUString sName;
+ xCurCol->getPropertyValue(CUIFM_PROP_LABEL) >>= sName;
+ sCurName = sName;
+ }
+ catch (...)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "FmShowColsDialog::SetColumns Exception occurred!");
+ }
+
+ // if the col is hidden, put it into the list
+ if (bIsHidden)
+ m_xList->append(OUString::number(i), sCurName);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/signature-line-draw.svg b/cui/source/dialogs/signature-line-draw.svg
new file mode 100644
index 000000000..b8552c41b
--- /dev/null
+++ b/cui/source/dialogs/signature-line-draw.svg
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.2" width="90mm" height="45mm" viewBox="0 0 9000 4500" preserveAspectRatio="xMidYMid" xml:space="preserve" id="svg577" inkscape:version="0.92.2 5c3e80d, 2017-08-06" sodipodi:docname="test.svg" stroke-linejoin="round" stroke-width="28.222" fill-rule="evenodd">
+ <metadata id="metadata581">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1920" inkscape:window-height="1015" id="namedview579" showgrid="false" inkscape:zoom="3.6100926" inkscape:cx="133.43144" inkscape:cy="97.595557" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="g569" inkscape:pagecheckerboard="false" units="cm"/>
+ <defs class="ClipPathGroup" id="defs8">
+ <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
+ <rect x="0" y="0" width="9000" height="4500" id="rect2"/>
+ </clipPath>
+ </defs>
+ <defs id="defs49"/>
+ <defs id="defs86"/>
+ <defs class="TextShapeIndex" id="defs90"/>
+ <defs class="EmbeddedBulletChars" id="defs122"/>
+ <defs class="TextEmbeddedBitmaps" id="defs124"/>
+ <g id="g129">
+ <g id="id2" class="Master_Slide">
+ <g id="bg-id2" class="Background"/>
+ <g id="bo-id2" class="BackgroundObjects"/>
+ </g>
+ </g>
+ <g class="SlideGroup" id="g575">
+ <path inkscape:connector-curvature="0" style="fill:none;stroke:#ffcccc;stroke-width:355.69763184;stroke-linecap:round;stroke-linejoin:round" d="M 2677.6009,4322.3785 C 4637.7107,2683.4298 4480.4998,1439.2788 4416.8177,177.68919 4135.9768,2203.3862 5181.4191,2928.0647 6822.3029,3068.6459 5584.8956,2678.4757 4273.5892,2702.5453 2677.6009,4322.3785 Z" id="path8"/>
+ <g id="g569" class="Page"><text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:493.88882446px;line-height:1.25;font-family:'Liberation Sans', sans-serif;-inkscape-font-specification:'Liberation Sans, sans-serif';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:746.70703125" x="265.50031" y="877.50842" id="text31-3"><tspan sodipodi:role="line" id="tspan29-6" x="265.50031" y="877.50842" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:493.88882446px;font-family:'Liberation Sans', sans-serif;-inkscape-font-specification:'Liberation Sans, sans-serif';stroke-width:746.70703125">[SIGNED_BY]</tspan></text>
+<text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:493.88879395px;line-height:1.25;font-family:'Liberation Sans', sans-serif;-inkscape-font-specification:'Liberation Sans, sans-serif';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:746.70697021" x="228.1967" y="2377.5085" id="text31-3-3"><tspan sodipodi:role="line" id="tspan29-6-5" x="228.1967" y="2377.5085" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:493.88879395px;font-family:'Liberation Sans', sans-serif;-inkscape-font-specification:'Liberation Sans, sans-serif';stroke-width:746.70697021">[SIGNER_NAME]</tspan></text>
+<text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:493.6913147px;line-height:1.25;font-family:'Liberation Sans', sans-serif;-inkscape-font-specification:'Liberation Sans, sans-serif';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:746.40844727" x="206.12776" y="3879.1411" id="text31-3-3-9" transform="scale(1.0003999,0.99960029)"><tspan sodipodi:role="line" id="tspan29-6-5-1" x="206.12776" y="3879.1411" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:493.6913147px;font-family:'Liberation Sans', sans-serif;-inkscape-font-specification:'Liberation Sans, sans-serif';stroke-width:746.40844727">[DATE]</tspan></text>
+</g>
+ </g>
+</svg>
diff --git a/cui/source/dialogs/signature-line.svg b/cui/source/dialogs/signature-line.svg
new file mode 100644
index 000000000..7ad3fad30
--- /dev/null
+++ b/cui/source/dialogs/signature-line.svg
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.2" width="90mm" height="45mm" viewBox="0 0 9000 4500" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xml:space="preserve" id="svg577" inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
+ <metadata id="metadata581">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1865" inkscape:window-height="1145" id="namedview579" showgrid="false" inkscape:zoom="3.6100926" inkscape:cx="231.72208" inkscape:cy="122.80267" inkscape:window-x="55" inkscape:window-y="27" inkscape:window-maximized="1" inkscape:current-layer="g575" inkscape:pagecheckerboard="false"/>
+ <defs class="ClipPathGroup" id="defs8">
+ <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
+ <rect x="0" y="0" width="9000" height="4500" id="rect2"/>
+ </clipPath>
+ </defs>
+ <defs id="defs49"/>
+ <defs id="defs86"/>
+ <defs class="TextShapeIndex" id="defs90"/>
+ <defs class="EmbeddedBulletChars" id="defs122"/>
+ <defs class="TextEmbeddedBitmaps" id="defs124"/>
+ <g id="g129">
+ <g id="id2" class="Master_Slide">
+ <g id="bg-id2" class="Background"/>
+ <g id="bo-id2" class="BackgroundObjects"/>
+ </g>
+ </g>
+ <g class="SlideGroup" id="g575"><g id="g573"><g id="container-id1"><g id="id1" class="Slide" clip-path="url(#presentation_clip_path)"><g class="Page" id="g569"><g class="com.sun.star.drawing.LineShape" id="g154"><g id="id3"><rect class="BoundingBox" stroke="none" fill="none" x="-27" y="2373" width="9055" height="55" id="rect131"/><desc id="desc133">150</desc><desc id="desc135">139</desc><desc id="desc137">132</desc><desc id="desc139">512: XPATHSTROKE_SEQ_BEGIN</desc><desc id="desc141">132</desc><desc id="desc143">133</desc><desc id="desc145">109</desc><path fill="none" stroke="rgb(0,0,0)" stroke-width="53" stroke-linejoin="round" d="M 0,2400 L 9000,2400" id="path147"/><desc id="desc149">512: XPATHSTROKE_SEQ_END</desc><desc id="desc151">140</desc></g></g><g class="com.sun.star.drawing.ClosedBezierShape" id="g173"><g id="id4"><rect class="BoundingBox" stroke="none" fill="none" x="301" y="1400" width="801" height="801" id="rect156"/><desc id="desc158">150</desc><desc id="desc160">139</desc><desc id="desc162">133</desc><desc id="desc164">132</desc><desc id="desc166">111</desc><path fill="rgb(0,0,0)" stroke="none" d="M 969,2200 C 880,2083 792,1967 704,1850 614,1967 523,2083 433,2200 389,2200 345,2200 301,2200 413,2061 525,1923 637,1784 533,1656 430,1528 327,1400 371,1400 415,1400 459,1400 541,1505 623,1609 704,1714 784,1609 863,1505 943,1400 987,1400 1031,1400 1075,1400 975,1527 874,1653 773,1780 882,1920 992,2060 1101,2200 1057,2200 1013,2200 969,2200 Z" id="path168"/><desc id="desc170">140</desc></g></g><g class="com.sun.star.drawing.TextShape" id="g236"><g id="id5"><rect class="BoundingBox" stroke="none" fill="none" x="1300" y="1500" width="8001" height="925" id="rect175"/><desc id="desc177">150</desc><desc id="desc179">512: XTEXT_PAINTSHAPE_BEGIN</desc><text class="TextShape" id="text233"><desc class="Paragraph" id="desc181"/><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="600px" font-weight="400" id="tspan231"><desc id="desc183">138</desc><desc id="desc185">136</desc><desc id="desc187">135</desc><desc id="desc189">134</desc><desc id="desc191">113</desc><desc class="TextPortion" id="desc193">type: Text; content: [SIGNATURE]; </desc><tspan class="TextPosition" x="1550" y="2171" id="tspan229"><tspan fill="rgb(0,0,0)" stroke="none" id="tspan195">[SIGNATURE]</tspan><desc id="desc197">512: XTEXT_EOC</desc><desc id="desc199">512: XTEXT_EOC</desc><desc id="desc201">512: XTEXT_EOW</desc><desc id="desc203">512: XTEXT_EOC</desc><desc id="desc205">512: XTEXT_EOC</desc><desc id="desc207">512: XTEXT_EOC</desc><desc id="desc209">512: XTEXT_EOC</desc><desc id="desc211">512: XTEXT_EOC</desc><desc id="desc213">512: XTEXT_EOC</desc><desc id="desc215">512: XTEXT_EOC</desc><desc id="desc217">512: XTEXT_EOC</desc><desc id="desc219">512: XTEXT_EOC</desc><desc id="desc221">512: XTEXT_EOW</desc><desc id="desc223">512: XTEXT_EOL</desc><desc id="desc225">512: XTEXT_EOP</desc><desc id="desc227">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g class="com.sun.star.drawing.TextShape" id="g303"><g id="id6"><rect class="BoundingBox" stroke="none" fill="none" x="100" y="2500" width="8901" height="726" id="rect238"/><desc id="desc240">150</desc><desc id="desc242">512: XTEXT_PAINTSHAPE_BEGIN</desc><text class="TextShape" id="text300"><desc class="Paragraph" id="desc244"/><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="423px" font-weight="400" id="tspan298"><desc id="desc246">138</desc><desc id="desc248">136</desc><desc id="desc250">135</desc><desc id="desc252">134</desc><desc id="desc254">113</desc><desc class="TextPortion" id="desc256">type: Text; content: [SIGNER_NAME]; </desc><tspan class="TextPosition" x="350" y="3010" id="tspan296"><tspan fill="rgb(0,0,0)" stroke="none" id="tspan258">[SIGNER_NAME]</tspan><desc id="desc260">512: XTEXT_EOC</desc><desc id="desc262">512: XTEXT_EOC</desc><desc id="desc264">512: XTEXT_EOW</desc><desc id="desc266">512: XTEXT_EOC</desc><desc id="desc268">512: XTEXT_EOC</desc><desc id="desc270">512: XTEXT_EOC</desc><desc id="desc272">512: XTEXT_EOC</desc><desc id="desc274">512: XTEXT_EOC</desc><desc id="desc276">512: XTEXT_EOC</desc><desc id="desc278">512: XTEXT_EOC</desc><desc id="desc280">512: XTEXT_EOC</desc><desc id="desc282">512: XTEXT_EOC</desc><desc id="desc284">512: XTEXT_EOC</desc><desc id="desc286">512: XTEXT_EOC</desc><desc id="desc288">512: XTEXT_EOW</desc><desc id="desc290">512: XTEXT_EOL</desc><desc id="desc292">512: XTEXT_EOP</desc><desc id="desc294">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g class="com.sun.star.drawing.TextShape" id="g372"><g id="id7"><rect class="BoundingBox" stroke="none" fill="none" x="100" y="3075" width="8901" height="726" id="rect305"/><desc id="desc307">150</desc><desc id="desc309">512: XTEXT_PAINTSHAPE_BEGIN</desc><text class="TextShape" id="text369"><desc class="Paragraph" id="desc311"/><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="423px" font-weight="400" id="tspan367"><desc id="desc313">138</desc><desc id="desc315">136</desc><desc id="desc317">135</desc><desc id="desc319">134</desc><desc id="desc321">113</desc><desc class="TextPortion" id="desc323">type: Text; content: [SIGNER_TITLE]; </desc><tspan class="TextPosition" x="350" y="3585" id="tspan365"><tspan fill="rgb(0,0,0)" stroke="none" id="tspan325">[SIGNER_TITLE]</tspan><desc id="desc327">512: XTEXT_EOC</desc><desc id="desc329">512: XTEXT_EOC</desc><desc id="desc331">512: XTEXT_EOW</desc><desc id="desc333">512: XTEXT_EOC</desc><desc id="desc335">512: XTEXT_EOC</desc><desc id="desc337">512: XTEXT_EOC</desc><desc id="desc339">512: XTEXT_EOC</desc><desc id="desc341">512: XTEXT_EOC</desc><desc id="desc343">512: XTEXT_EOC</desc><desc id="desc345">512: XTEXT_EOC</desc><desc id="desc347">512: XTEXT_EOC</desc><desc id="desc349">512: XTEXT_EOC</desc><desc id="desc351">512: XTEXT_EOC</desc><desc id="desc353">512: XTEXT_EOC</desc><desc id="desc355">512: XTEXT_EOC</desc><desc id="desc357">512: XTEXT_EOW</desc><desc id="desc359">512: XTEXT_EOL</desc><desc id="desc361">512: XTEXT_EOP</desc><desc id="desc363">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g class="com.sun.star.drawing.TextShape" id="g435"><g id="id8"><rect class="BoundingBox" stroke="none" fill="none" x="100" y="3660" width="8901" height="726" id="rect374"/><desc id="desc376">150</desc><desc id="desc378">512: XTEXT_PAINTSHAPE_BEGIN</desc><text class="TextShape" id="text432"><desc class="Paragraph" id="desc380"/><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="423px" font-weight="400" id="tspan430"><desc id="desc382">138</desc><desc id="desc384">136</desc><desc id="desc386">135</desc><desc id="desc388">134</desc><desc id="desc390">113</desc><desc class="TextPortion" id="desc392">type: Text; content: [SIGNED_BY]; </desc><tspan class="TextPosition" x="350" y="4170" id="tspan428"><tspan fill="rgb(0,0,0)" stroke="none" id="tspan394">[SIGNED_BY]</tspan><desc id="desc396">512: XTEXT_EOC</desc><desc id="desc398">512: XTEXT_EOC</desc><desc id="desc400">512: XTEXT_EOW</desc><desc id="desc402">512: XTEXT_EOC</desc><desc id="desc404">512: XTEXT_EOC</desc><desc id="desc406">512: XTEXT_EOC</desc><desc id="desc408">512: XTEXT_EOC</desc><desc id="desc410">512: XTEXT_EOC</desc><desc id="desc412">512: XTEXT_EOC</desc><desc id="desc414">512: XTEXT_EOC</desc><desc id="desc416">512: XTEXT_EOC</desc><desc id="desc418">512: XTEXT_EOC</desc><desc id="desc420">512: XTEXT_EOW</desc><desc id="desc422">512: XTEXT_EOL</desc><desc id="desc424">512: XTEXT_EOP</desc><desc id="desc426">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g class="com.sun.star.drawing.TextShape" id="g488"><g id="id9"><rect class="BoundingBox" stroke="none" fill="none" x="4800" y="0" width="4201" height="726" id="rect437"/><desc id="desc439">150</desc><desc id="desc441">512: XTEXT_PAINTSHAPE_BEGIN</desc><text class="TextShape" id="text485" x="2648.345" y="0" style="text-align:end;text-anchor:end"><desc class="Paragraph" id="desc443"/><tspan class="TextParagraph" font-size="423px" font-weight="400" id="tspan483" style="font-weight:400;font-size:423px;font-family:'Liberation Sans', sans-serif;text-align:end;text-anchor:end"><desc id="desc445">138</desc><desc id="desc447">136</desc><desc id="desc449">135</desc><desc id="desc451">134</desc><desc id="desc453">113</desc><desc class="TextPortion" id="desc455">type: Text; content: [DATE]; </desc><tspan class="TextPosition" x="8792.835" y="510" id="tspan481" style="text-align:end;text-anchor:end"><tspan id="tspan457" style="text-align:end;text-anchor:end;fill:#000000;stroke:none">[DATE]</tspan><desc id="desc459">512: XTEXT_EOC</desc><desc id="desc461">512: XTEXT_EOC</desc><desc id="desc463">512: XTEXT_EOW</desc><desc id="desc465">512: XTEXT_EOC</desc><desc id="desc467">512: XTEXT_EOC</desc><desc id="desc469">512: XTEXT_EOC</desc><desc id="desc471">512: XTEXT_EOC</desc><desc id="desc473">512: XTEXT_EOW</desc><desc id="desc475">512: XTEXT_EOL</desc><desc id="desc477">512: XTEXT_EOP</desc><desc id="desc479">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g class="com.sun.star.drawing.TextShape" id="g567"><g id="id10"><rect class="BoundingBox" stroke="none" fill="none" x="0" y="1" width="9001" height="726" id="rect490"/><desc id="desc492">150</desc><desc id="desc494">512: XTEXT_PAINTSHAPE_BEGIN</desc><text class="TextShape" id="text564"><desc class="Paragraph" id="desc496"/><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="423px" font-weight="700" id="tspan562"><desc id="desc498">138</desc><desc id="desc500">136</desc><desc id="desc502">135</desc><desc id="desc504">134</desc><desc id="desc506">113</desc><desc class="TextPortion" id="desc508">type: Text; content: [INVALID_SIGNATURE]; </desc><tspan class="TextPosition" x="2180" y="511" id="tspan560"><tspan fill="rgb(239,65,61)" stroke="none" id="tspan510">[INVALID_SIGNATURE]</tspan><desc id="desc512">512: XTEXT_EOC</desc><desc id="desc514">512: XTEXT_EOC</desc><desc id="desc516">512: XTEXT_EOW</desc><desc id="desc518">512: XTEXT_EOC</desc><desc id="desc520">512: XTEXT_EOC</desc><desc id="desc522">512: XTEXT_EOC</desc><desc id="desc524">512: XTEXT_EOC</desc><desc id="desc526">512: XTEXT_EOC</desc><desc id="desc528">512: XTEXT_EOC</desc><desc id="desc530">512: XTEXT_EOC</desc><desc id="desc532">512: XTEXT_EOC</desc><desc id="desc534">512: XTEXT_EOC</desc><desc id="desc536">512: XTEXT_EOC</desc><desc id="desc538">512: XTEXT_EOC</desc><desc id="desc540">512: XTEXT_EOC</desc><desc id="desc542">512: XTEXT_EOC</desc><desc id="desc544">512: XTEXT_EOC</desc><desc id="desc546">512: XTEXT_EOC</desc><desc id="desc548">512: XTEXT_EOC</desc><desc id="desc550">512: XTEXT_EOC</desc><desc id="desc552">512: XTEXT_EOW</desc><desc id="desc554">512: XTEXT_EOL</desc><desc id="desc556">512: XTEXT_EOP</desc><desc id="desc558">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g></g></g></g></g>[SIGNATURE_IMAGE]</g>
+</svg>
diff --git a/cui/source/dialogs/splitcelldlg.cxx b/cui/source/dialogs/splitcelldlg.cxx
new file mode 100644
index 000000000..14146b44c
--- /dev/null
+++ b/cui/source/dialogs/splitcelldlg.cxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <splitcelldlg.hxx>
+
+SvxSplitTableDlg::SvxSplitTableDlg(weld::Window *pParent, bool bIsTableVertical, tools::Long nMaxVertical, tools::Long nMaxHorizontal)
+ : GenericDialogController(pParent, "cui/ui/splitcellsdialog.ui", "SplitCellsDialog")
+ , m_xCountEdit(m_xBuilder->weld_spin_button("countnf"))
+ , m_xHorzBox(!bIsTableVertical ? m_xBuilder->weld_radio_button("hori") : m_xBuilder->weld_radio_button("vert"))
+ , m_xVertBox(!bIsTableVertical ? m_xBuilder->weld_radio_button("vert") : m_xBuilder->weld_radio_button("hori"))
+ , m_xPropCB(m_xBuilder->weld_check_button("prop"))
+ , mnMaxVertical(nMaxVertical)
+ , mnMaxHorizontal(nMaxHorizontal)
+{
+ m_xHorzBox->connect_toggled(LINK(this, SvxSplitTableDlg, ToggleHdl));
+ m_xVertBox->connect_toggled(LINK(this, SvxSplitTableDlg, ToggleHdl));
+
+ if (mnMaxVertical < 2)
+ {
+ if (!bIsTableVertical)
+ m_xVertBox->set_sensitive(false);
+ else
+ m_xHorzBox->set_sensitive(false);
+ }
+
+ //exchange the meaning of horizontal and vertical for vertical text
+ if (bIsTableVertical)
+ {
+ int nHorzTopAttach = m_xHorzBox->get_grid_top_attach();
+ int nVertTopAttach = m_xVertBox->get_grid_top_attach();
+ m_xHorzBox->set_grid_top_attach(nVertTopAttach);
+ m_xVertBox->set_grid_top_attach(nHorzTopAttach);
+ m_xHorzBox->set_active(m_xVertBox->get_active());
+ }
+}
+
+IMPL_LINK(SvxSplitTableDlg, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ const bool bIsVert = m_xVertBox->get_active();
+ tools::Long nMax = bIsVert ? mnMaxVertical : mnMaxHorizontal;
+ m_xPropCB->set_sensitive(!bIsVert);
+ m_xCountEdit->set_max(nMax);
+}
+
+bool SvxSplitTableDlg::IsHorizontal() const
+{
+ return m_xHorzBox->get_active();
+}
+
+bool SvxSplitTableDlg::IsProportional() const
+{
+ return m_xPropCB->get_active() && m_xHorzBox->get_active();
+}
+
+tools::Long SvxSplitTableDlg::GetCount() const
+{
+ return m_xCountEdit->get_value();
+}
+
+void SvxSplitTableDlg::SetSplitVerticalByDefault()
+{
+ if( mnMaxVertical >= 2 )
+ m_xVertBox->set_active(true); // tdf#60242
+}
+
+bool SvxAbstractSplitTableDialog_Impl::IsHorizontal() const
+{
+ return m_xDlg->IsHorizontal();
+}
+
+bool SvxAbstractSplitTableDialog_Impl::IsProportional() const
+{
+ return m_xDlg->IsProportional();
+}
+
+tools::Long SvxAbstractSplitTableDialog_Impl::GetCount() const
+{
+ return m_xDlg->GetCount();
+}
+
+void SvxAbstractSplitTableDialog_Impl::SetSplitVerticalByDefault()
+{
+ m_xDlg->SetSplitVerticalByDefault();
+}
+
+short SvxAbstractSplitTableDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool SvxAbstractSplitTableDialog_Impl::StartExecuteAsync(AsyncContext& rContext)
+{
+ return weld::DialogController::runAsync(m_xDlg, rContext.maEndDialogFn);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/srchxtra.cxx b/cui/source/dialogs/srchxtra.cxx
new file mode 100644
index 000000000..40c2e369a
--- /dev/null
+++ b/cui/source/dialogs/srchxtra.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <srchxtra.hxx>
+#include <sal/log.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/intitem.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/strarray.hxx>
+#include <editeng/flstitem.hxx>
+#include <chardlg.hxx>
+#include <paragrph.hxx>
+#include <backgrnd.hxx>
+#include <editeng/editids.hrc>
+#include <svx/svxids.hrc>
+#include <tools/debug.hxx>
+#include <tools/resary.hxx>
+#include <vcl/svapp.hxx>
+
+SvxSearchFormatDialog::SvxSearchFormatDialog(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxTabDialogController(pParent, "cui/ui/searchformatdialog.ui", "SearchFormatDialog", &rSet)
+{
+ AddTabPage("font", SvxCharNamePage::Create, nullptr);
+ AddTabPage("fonteffects", SvxCharEffectsPage::Create, nullptr);
+ AddTabPage("position", SvxCharPositionPage::Create, nullptr);
+ AddTabPage("asianlayout", SvxCharTwoLinesPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_STD", SvxStdParagraphTabPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_ALIGN", SvxParaAlignTabPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_EXT", SvxExtParagraphTabPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_ASIAN", SvxAsianTabPage::Create, nullptr );
+ AddTabPage("background", SvxBkgTabPage::Create, nullptr);
+
+ // remove asian tabpages if necessary
+ if ( !SvtCJKOptions::IsDoubleLinesEnabled() )
+ RemoveTabPage("asianlayout");
+ if ( !SvtCJKOptions::IsAsianTypographyEnabled() )
+ RemoveTabPage("labelTP_PARA_ASIAN");
+}
+
+SvxSearchFormatDialog::~SvxSearchFormatDialog()
+{
+}
+
+void SvxSearchFormatDialog::PageCreated(const OString& rId, SfxTabPage& rPage)
+{
+ if (rId == "font")
+ {
+ const FontList* pApm_pFontList = nullptr;
+ if (SfxObjectShell* pSh = SfxObjectShell::Current())
+ {
+ const SvxFontListItem* pFLItem = static_cast<const SvxFontListItem*>(
+ pSh->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ if ( pFLItem )
+ pApm_pFontList = pFLItem->GetFontList();
+ }
+
+ const FontList* pList = pApm_pFontList;
+
+ if ( !pList )
+ {
+ if ( !m_pFontList )
+ m_pFontList.reset(new FontList(Application::GetDefaultDevice()));
+ pList = m_pFontList.get();
+ }
+
+ static_cast<SvxCharNamePage&>(rPage).
+ SetFontList( SvxFontListItem( pList, SID_ATTR_CHAR_FONTLIST ) );
+ static_cast<SvxCharNamePage&>(rPage).EnableSearchMode();
+ }
+ else if (rId == "labelTP_PARA_STD")
+ {
+ static_cast<SvxStdParagraphTabPage&>(rPage).EnableAutoFirstLine();
+ }
+ else if (rId == "labelTP_PARA_ALIGN")
+ {
+ static_cast<SvxParaAlignTabPage&>(rPage).EnableJustifyExt();
+ }
+ else if (rId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put(SfxUInt32Item(SID_FLAG_TYPE,static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_HIGHLIGHTING)));
+ rPage.PageCreated(aSet);
+ }
+}
+
+SvxSearchAttributeDialog::SvxSearchAttributeDialog(weld::Window* pParent,
+ SearchAttrItemList& rLst, const WhichRangesContainer& pWhRanges)
+ : GenericDialogController(pParent, "cui/ui/searchattrdialog.ui", "SearchAttrDialog")
+ , rList(rLst)
+ , m_xAttrLB(m_xBuilder->weld_tree_view("treeview"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ m_xAttrLB->set_size_request(m_xAttrLB->get_approximate_digit_width() * 50,
+ m_xAttrLB->get_height_rows(12));
+
+ m_xAttrLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ m_xOKBtn->connect_clicked(LINK( this, SvxSearchAttributeDialog, OKHdl));
+
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+ DBG_ASSERT( pSh, "No DocShell" );
+ if (pSh)
+ {
+ SfxItemPool& rPool = pSh->GetPool();
+ SfxItemSet aSet( rPool, pWhRanges );
+ SfxWhichIter aIter( aSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ sal_uInt16 nSlot = rPool.GetSlotId( nWhich );
+ if ( nSlot >= SID_SVX_START )
+ {
+ bool bChecked = false, bFound = false;
+ for ( sal_uInt16 i = 0; !bFound && i < rList.Count(); ++i )
+ {
+ if ( nSlot == rList[i].nSlot )
+ {
+ bFound = true;
+ if ( IsInvalidItem( rList[i].pItem ) )
+ bChecked = true;
+ }
+ }
+
+ // item resources are in svx
+ sal_uInt32 nId = SvxAttrNameTable::FindIndex(nSlot);
+ if (RESARRAY_INDEX_NOTFOUND != nId)
+ {
+ m_xAttrLB->append();
+ const int nRow = m_xAttrLB->n_children() - 1;
+ m_xAttrLB->set_toggle(nRow, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xAttrLB->set_text(nRow, SvxAttrNameTable::GetString(nId), 0);
+ m_xAttrLB->set_id(nRow, OUString::number(nSlot));
+ }
+ else
+ SAL_WARN( "cui.dialogs", "no resource for slot id " << static_cast<sal_Int32>(nSlot) );
+ }
+ nWhich = aIter.NextWhich();
+ }
+ }
+
+ m_xAttrLB->make_sorted();
+ m_xAttrLB->select(0);
+}
+
+SvxSearchAttributeDialog::~SvxSearchAttributeDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxSearchAttributeDialog, OKHdl, weld::Button&, void)
+{
+ SearchAttrItem aInvalidItem;
+ aInvalidItem.pItem = INVALID_POOL_ITEM;
+
+ for (int i = 0, nCount = m_xAttrLB->n_children(); i < nCount; ++i)
+ {
+ sal_uInt16 nSlot = m_xAttrLB->get_id(i).toUInt32();
+ bool bChecked = m_xAttrLB->get_toggle(i) == TRISTATE_TRUE;
+
+ sal_uInt16 j;
+ for ( j = rList.Count(); j; )
+ {
+ SearchAttrItem& rItem = rList[ --j ];
+ if( rItem.nSlot == nSlot )
+ {
+ if( bChecked )
+ {
+ if( !IsInvalidItem( rItem.pItem ) )
+ delete rItem.pItem;
+ rItem.pItem = INVALID_POOL_ITEM;
+ }
+ else if( IsInvalidItem( rItem.pItem ) )
+ rItem.pItem = nullptr;
+ j = 1;
+ break;
+ }
+ }
+
+ if ( !j && bChecked )
+ {
+ aInvalidItem.nSlot = nSlot;
+ rList.Insert( aInvalidItem );
+ }
+ }
+
+ // remove invalid items (pItem == NULL)
+ for ( sal_uInt16 n = rList.Count(); n; )
+ if ( !rList[ --n ].pItem )
+ rList.Remove( n );
+
+ m_xDialog->response(RET_OK);
+}
+
+// class SvxSearchSimilarityDialog ---------------------------------------
+
+SvxSearchSimilarityDialog::SvxSearchSimilarityDialog(weld::Window* pParent, bool bRelax,
+ sal_uInt16 nOther, sal_uInt16 nShorter, sal_uInt16 nLonger)
+ : GenericDialogController(pParent, "cui/ui/similaritysearchdialog.ui", "SimilaritySearchDialog")
+ , m_xOtherFld(m_xBuilder->weld_spin_button("otherfld"))
+ , m_xLongerFld(m_xBuilder->weld_spin_button("longerfld"))
+ , m_xShorterFld(m_xBuilder->weld_spin_button("shorterfld"))
+ , m_xRelaxBox(m_xBuilder->weld_check_button("relaxbox"))
+{
+ m_xOtherFld->set_value(nOther);
+ m_xShorterFld->set_value(nShorter);
+ m_xLongerFld->set_value(nLonger);
+ m_xRelaxBox->set_active(bRelax);
+}
+
+SvxSearchSimilarityDialog::~SvxSearchSimilarityDialog()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/thesdlg.cxx b/cui/source/dialogs/thesdlg.cxx
new file mode 100644
index 000000000..ea98a44a3
--- /dev/null
+++ b/cui/source/dialogs/thesdlg.cxx
@@ -0,0 +1,352 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <thesdlg.hxx>
+
+#include <tools/debug.hxx>
+#include <svl/lngmisc.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/langtab.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <comphelper/string.hxx>
+
+#include <stack>
+#include <algorithm>
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/linguistic2/XMeaning.hpp>
+
+using namespace ::com::sun::star;
+
+IMPL_LINK_NOARG( SvxThesaurusDialog, ModifyTimer_Hdl, Timer *, void )
+{
+ LookUp(m_xWordCB->get_active_text());
+ m_aModifyIdle.Stop();
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, ReplaceEditHdl_Impl, weld::Entry&, void)
+{
+ m_xReplaceBtn->set_sensitive(!m_xReplaceEdit->get_text().isEmpty());
+}
+
+IMPL_LINK(SvxThesaurusDialog, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ const vcl::KeyCode& rKey = rKEvt.GetKeyCode();
+
+ if (rKey.GetCode() == KEY_RETURN)
+ {
+ m_xDialog->response(RET_OK);
+ return true;
+ }
+
+ return false;
+}
+
+uno::Sequence< uno::Reference< linguistic2::XMeaning > > SvxThesaurusDialog::queryMeanings_Impl(
+ OUString& rTerm,
+ const lang::Locale& rLocale,
+ const beans::PropertyValues& rProperties )
+{
+ uno::Sequence< uno::Reference< linguistic2::XMeaning > > aMeanings(
+ xThesaurus->queryMeanings( rTerm, rLocale, rProperties ) );
+
+ // text with '.' at the end?
+ if ( !aMeanings.hasElements() && rTerm.endsWith(".") )
+ {
+ // try again without trailing '.' chars. It may be a word at the
+ // end of a sentence and not an abbreviation...
+ OUString aTxt(comphelper::string::stripEnd(rTerm, '.'));
+ aMeanings = xThesaurus->queryMeanings( aTxt, rLocale, rProperties );
+ if (aMeanings.hasElements())
+ {
+ rTerm = aTxt;
+ }
+ }
+
+ return aMeanings;
+}
+
+bool SvxThesaurusDialog::UpdateAlternativesBox_Impl()
+{
+ lang::Locale aLocale( LanguageTag::convertToLocale( nLookUpLanguage ) );
+ uno::Sequence< uno::Reference< linguistic2::XMeaning > > aMeanings = queryMeanings_Impl(
+ aLookUpText, aLocale, uno::Sequence< beans::PropertyValue >() );
+ const sal_Int32 nMeanings = aMeanings.getLength();
+ const uno::Reference< linguistic2::XMeaning > *pMeanings = aMeanings.getConstArray();
+
+ m_xAlternativesCT->freeze();
+
+ m_xAlternativesCT->clear();
+ int nRow = 0;
+ for (sal_Int32 i = 0; i < nMeanings; ++i)
+ {
+ OUString rMeaningTxt = pMeanings[i]->getMeaning();
+ uno::Sequence< OUString > aSynonyms( pMeanings[i]->querySynonyms() );
+ const sal_Int32 nSynonyms = aSynonyms.getLength();
+ const OUString *pSynonyms = aSynonyms.getConstArray();
+ DBG_ASSERT( !rMeaningTxt.isEmpty(), "meaning with empty text" );
+ DBG_ASSERT( nSynonyms > 0, "meaning without synonym" );
+
+ OUString sHeading = OUString::number(i + 1) + ". " + rMeaningTxt;
+ m_xAlternativesCT->append_text(sHeading);
+ m_xAlternativesCT->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ for (sal_Int32 k = 0; k < nSynonyms; ++k)
+ {
+ // GetThesaurusReplaceText will strip the leading spaces
+ m_xAlternativesCT->append_text(" " + pSynonyms[k]);
+ m_xAlternativesCT->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ m_xAlternativesCT->thaw();
+
+ return nMeanings > 0;
+}
+
+void SvxThesaurusDialog::LookUp( const OUString &rText )
+{
+ if (rText != m_xWordCB->get_active_text()) // avoid moving of the cursor if the text is the same
+ m_xWordCB->set_entry_text(rText);
+ LookUp_Impl();
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, LeftBtnHdl_Impl, weld::Button&, void)
+{
+ if (aLookUpHistory.size() >= 2)
+ {
+ aLookUpHistory.pop(); // remove current look up word from stack
+ m_xWordCB->set_entry_text(aLookUpHistory.top()); // retrieve previous look up word
+ aLookUpHistory.pop();
+ LookUp_Impl();
+ }
+}
+
+IMPL_LINK( SvxThesaurusDialog, LanguageHdl_Impl, weld::ComboBox&, rLB, void )
+{
+ OUString aLangText(rLB.get_active_text());
+ LanguageType nLang = SvtLanguageTable::GetLanguageType( aLangText );
+ DBG_ASSERT( nLang != LANGUAGE_NONE && nLang != LANGUAGE_DONTKNOW, "failed to get language" );
+ if (xThesaurus->hasLocale( LanguageTag::convertToLocale( nLang ) ))
+ nLookUpLanguage = nLang;
+ SetWindowTitle( nLang );
+ LookUp_Impl();
+}
+
+void SvxThesaurusDialog::LookUp_Impl()
+{
+ OUString aText(m_xWordCB->get_active_text());
+
+ aLookUpText = aText;
+ if (!aLookUpText.isEmpty() &&
+ (aLookUpHistory.empty() || aLookUpText != aLookUpHistory.top()))
+ aLookUpHistory.push( aLookUpText );
+
+ m_bWordFound = UpdateAlternativesBox_Impl();
+ m_xAlternativesCT->set_visible(m_bWordFound);
+ m_xNotFound->set_visible(!m_bWordFound);
+
+ if (m_bWordFound && !m_nSelectFirstEvent)
+ m_nSelectFirstEvent = Application::PostUserEvent(LINK(this, SvxThesaurusDialog, SelectFirstHdl_Impl));
+
+ if (m_xWordCB->find_text(aText) == -1)
+ m_xWordCB->append_text(aText);
+
+ m_xReplaceEdit->set_text( OUString() );
+ ReplaceEditHdl_Impl(*m_xReplaceEdit);
+ m_xLeftBtn->set_sensitive( aLookUpHistory.size() > 1 );
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, WordSelectHdl_Impl, weld::ComboBox&, void)
+{
+ m_aModifyIdle.Start();
+}
+
+IMPL_LINK( SvxThesaurusDialog, AlternativesSelectHdl_Impl, weld::TreeView&, rBox, void )
+{
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ bool bIsHeader = rBox.get_text_emphasis(nEntry, 0);
+ if (bIsHeader)
+ {
+ ++nEntry;
+ rBox.select(nEntry);
+ }
+ OUString aStr = linguistic::GetThesaurusReplaceText(rBox.get_text(nEntry));
+ m_xReplaceEdit->set_text(aStr);
+ ReplaceEditHdl_Impl(*m_xReplaceEdit);
+ }
+}
+
+IMPL_LINK( SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl, weld::TreeView&, rBox, bool )
+{
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ bool bIsHeader = rBox.get_text_emphasis(nEntry, 0);
+ if (bIsHeader)
+ {
+ ++nEntry;
+ rBox.select(nEntry);
+ }
+ OUString aStr = linguistic::GetThesaurusReplaceText(rBox.get_text(nEntry));
+ m_xWordCB->set_entry_text(aStr);
+ if (!aStr.isEmpty())
+ LookUp_Impl();
+ }
+
+ //! workaround to set the selection since calling SelectEntryPos within
+ //! the double click handler does not work
+ if (!m_nSelectFirstEvent)
+ m_nSelectFirstEvent = Application::PostUserEvent(LINK(this, SvxThesaurusDialog, SelectFirstHdl_Impl));
+
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, SelectFirstHdl_Impl, void *, void)
+{
+ m_nSelectFirstEvent = nullptr;
+ if (m_xAlternativesCT->n_children() >= 2)
+ {
+ m_xAlternativesCT->select(1); // pos 0 is a 'header' that is not selectable
+ AlternativesSelectHdl_Impl(*m_xAlternativesCT);
+ }
+}
+
+// class SvxThesaurusDialog ----------------------------------------------
+
+SvxThesaurusDialog::SvxThesaurusDialog(
+ weld::Widget* pParent,
+ uno::Reference< linguistic2::XThesaurus > const & xThes,
+ const OUString &rWord,
+ LanguageType nLanguage)
+ : SfxDialogController(pParent, "cui/ui/thesaurus.ui", "ThesaurusDialog")
+ , m_aModifyIdle("cui SvxThesaurusDialog LookUp Modify")
+ , nLookUpLanguage(LANGUAGE_NONE)
+ , m_bWordFound(false)
+ , m_xLeftBtn(m_xBuilder->weld_button("left"))
+ , m_xWordCB(m_xBuilder->weld_combo_box("wordcb"))
+ , m_xAlternativesCT(m_xBuilder->weld_tree_view("alternatives"))
+ , m_xNotFound(m_xBuilder->weld_label("notfound"))
+ , m_xReplaceEdit(m_xBuilder->weld_entry("replaceed"))
+ , m_xLangLB(m_xBuilder->weld_combo_box("langcb"))
+ , m_xReplaceBtn(m_xBuilder->weld_button("ok"))
+ , m_nSelectFirstEvent(nullptr)
+{
+ m_aModifyIdle.SetInvokeHandler( LINK( this, SvxThesaurusDialog, ModifyTimer_Hdl ) );
+ m_aModifyIdle.SetPriority( TaskPriority::LOWEST );
+
+ m_xReplaceEdit->connect_changed( LINK( this, SvxThesaurusDialog, ReplaceEditHdl_Impl ) );
+ m_xReplaceBtn->connect_clicked( LINK( this, SvxThesaurusDialog, ReplaceBtnHdl_Impl ) );
+ m_xLeftBtn->connect_clicked( LINK( this, SvxThesaurusDialog, LeftBtnHdl_Impl ) );
+ m_xWordCB->set_entry_completion(false);
+ m_xWordCB->connect_changed( LINK( this, SvxThesaurusDialog, WordSelectHdl_Impl ) );
+ m_xLangLB->connect_changed( LINK( this, SvxThesaurusDialog, LanguageHdl_Impl ) );
+ m_xAlternativesCT->connect_changed( LINK( this, SvxThesaurusDialog, AlternativesSelectHdl_Impl ));
+ m_xAlternativesCT->connect_row_activated( LINK( this, SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl ));
+ m_xAlternativesCT->connect_key_press(LINK(this, SvxThesaurusDialog, KeyInputHdl));
+
+ xThesaurus = xThes;
+ aLookUpText = rWord;
+ nLookUpLanguage = nLanguage;
+ if (!rWord.isEmpty())
+ aLookUpHistory.push( rWord );
+
+ OUString aTmp( rWord );
+ (void)linguistic::RemoveHyphens( aTmp );
+ (void)linguistic::ReplaceControlChars( aTmp );
+ m_xReplaceEdit->set_text( aTmp );
+ ReplaceEditHdl_Impl(*m_xReplaceEdit);
+ m_xWordCB->append_text( aTmp );
+
+ LookUp( aTmp );
+ m_xAlternativesCT->grab_focus();
+ m_xLeftBtn->set_sensitive(false);
+
+ // fill language menu button list
+ uno::Sequence< lang::Locale > aLocales;
+ if (xThesaurus.is())
+ aLocales = xThesaurus->getLocales();
+ const sal_Int32 nLocales = aLocales.getLength();
+ const lang::Locale *pLocales = aLocales.getConstArray();
+ m_xLangLB->clear();
+ std::vector< OUString > aLangVec;
+ for (sal_Int32 i = 0; i < nLocales; ++i)
+ {
+ const LanguageType nLang = LanguageTag::convertToLanguageType( pLocales[i] );
+ DBG_ASSERT( nLang != LANGUAGE_NONE && nLang != LANGUAGE_DONTKNOW, "failed to get language" );
+ aLangVec.push_back( SvtLanguageTable::GetLanguageString( nLang ) );
+ }
+ std::sort( aLangVec.begin(), aLangVec.end() );
+ m_xLangLB->freeze();
+ for (const OUString & i : aLangVec)
+ m_xLangLB->append_text(i);
+ m_xLangLB->thaw();
+
+ std::vector< OUString >::iterator aI = std::find(aLangVec.begin(), aLangVec.end(),
+ SvtLanguageTable::GetLanguageString(nLanguage));
+ if (aI != aLangVec.end())
+ {
+ m_xLangLB->set_active_text(*aI);
+ }
+
+ SetWindowTitle(nLanguage);
+
+ // disable controls if service is missing
+ if (!xThesaurus.is())
+ m_xDialog->set_sensitive(false);
+ else
+ m_xWordCB->grab_focus();
+}
+
+SvxThesaurusDialog::~SvxThesaurusDialog()
+{
+ if (m_nSelectFirstEvent)
+ {
+ Application::RemoveUserEvent(m_nSelectFirstEvent);
+ m_nSelectFirstEvent = nullptr;
+ }
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, ReplaceBtnHdl_Impl, weld::Button&, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+void SvxThesaurusDialog::SetWindowTitle( LanguageType nLanguage )
+{
+ // adjust language
+ OUString aStr(m_xDialog->get_title());
+ sal_Int32 nIndex = aStr.indexOf( '(' );
+ if( nIndex != -1 )
+ aStr = aStr.copy( 0, nIndex - 1 );
+ aStr += " (" + SvtLanguageTable::GetLanguageString( nLanguage ) + ")";
+ m_xDialog->set_title(aStr); // set window title
+}
+
+OUString SvxThesaurusDialog::GetWord() const
+{
+ return m_xReplaceEdit->get_text();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/tipofthedaydlg.cxx b/cui/source/dialogs/tipofthedaydlg.cxx
new file mode 100644
index 000000000..2c35c3b4c
--- /dev/null
+++ b/cui/source/dialogs/tipofthedaydlg.cxx
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <tipofthedaydlg.hxx>
+#include <tipoftheday.hrc>
+
+#include <sfx2/viewfrm.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/help.hxx>
+#include <vcl/window.hxx>
+
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+
+#include <comphelper/dispatchcommand.hxx>
+#include <dialmgr.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/resmgr.hxx>
+#include <unotools/configmgr.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+//size of preview
+const Size ThumbSize(150, 150);
+
+TipOfTheDayDialog::TipOfTheDayDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/tipofthedaydialog.ui", "TipOfTheDayDialog")
+ , m_pParent(pParent)
+ , m_pText(m_xBuilder->weld_label("lbText"))
+ , m_pShowTip(m_xBuilder->weld_check_button("cbShowTip"))
+ , m_pNext(m_xBuilder->weld_button("btnNext"))
+ , m_pLink(m_xBuilder->weld_link_button("btnLink"))
+ , m_pPreview(new weld::CustomWeld(*m_xBuilder, "imPreview", m_aPreview))
+{
+ m_pShowTip->set_active(officecfg::Office::Common::Misc::ShowTipOfTheDay::get());
+ m_pNext->connect_clicked(LINK(this, TipOfTheDayDialog, OnNextClick));
+ m_nCurrentTip = officecfg::Office::Common::Misc::LastTipOfTheDayID::get();
+ m_pPreview->set_size_request(ThumbSize.Width(), ThumbSize.Height());
+
+ if (pParent != nullptr)
+ {
+ css::uno::Reference<css::awt::XWindow> xWindow = pParent->GetXWindow();
+ if (xWindow.is())
+ {
+ VclPtr<vcl::Window> xVclWin(VCLUnoHelper::GetWindow(xWindow));
+ if (xVclWin != nullptr)
+ xVclWin->AddEventListener(LINK(this, TipOfTheDayDialog, Terminated));
+ }
+ }
+
+ const auto t0 = std::chrono::system_clock::now().time_since_epoch();
+ sal_Int32 nDay = std::chrono::duration_cast<std::chrono::hours>(t0).count() / 24;
+ //show next tip after one day
+ if (nDay > officecfg::Office::Common::Misc::LastTipOfTheDayShown::get())
+ m_nCurrentTip++;
+
+ // save this time to the config now instead of in the dtor otherwise we
+ // end up with multiple copies of this dialog every time we open a new
+ // document if the first one isn't closed
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::LastTipOfTheDayShown::set(nDay, xChanges);
+ xChanges->commit();
+
+ UpdateTip();
+}
+
+IMPL_LINK(TipOfTheDayDialog, Terminated, VclWindowEvent&, rEvent, void)
+{
+ if (rEvent.GetId() == VclEventId::ObjectDying)
+ {
+ m_pParent = nullptr;
+ TipOfTheDayDialog::response(RET_OK);
+ }
+}
+
+TipOfTheDayDialog::~TipOfTheDayDialog()
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::LastTipOfTheDayID::set(m_nCurrentTip, xChanges);
+ officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_pShowTip->get_active(), xChanges);
+ xChanges->commit();
+
+ if (m_pParent != nullptr)
+ {
+ css::uno::Reference<css::awt::XWindow> xWindow = m_pParent->GetXWindow();
+ if (xWindow.is())
+ {
+ VclPtr<vcl::Window> xVclWin(VCLUnoHelper::GetWindow(xWindow));
+ if (xVclWin != nullptr)
+ xVclWin->RemoveEventListener(LINK(this, TipOfTheDayDialog, Terminated));
+ }
+ }
+}
+
+static bool file_exists(const OUString& fileName)
+{
+ ::osl::File aFile(fileName);
+ return aFile.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None;
+}
+
+void TipOfTheDayDialog::UpdateTip()
+{
+ constexpr sal_Int32 nNumberOfTips = SAL_N_ELEMENTS(TIPOFTHEDAY_STRINGARRAY);
+
+ if ((m_nCurrentTip >= nNumberOfTips) || (m_nCurrentTip < 0))
+ m_nCurrentTip = 0;
+
+ //title
+ m_xDialog->set_title(CuiResId(STR_TITLE)
+ .replaceFirst("%CURRENT", OUString::number(m_nCurrentTip + 1))
+ .replaceFirst("%TOTAL", OUString::number(nNumberOfTips)));
+
+ auto[sTip, sLink, sImage] = TIPOFTHEDAY_STRINGARRAY[m_nCurrentTip];
+
+ // text
+//replace MOD1 & MOD2 shortcuts depending on platform
+#ifdef MACOSX
+ const OUString aMOD1 = CuiResId(STR_CMD);
+ const OUString aMOD2 = CuiResId(STR_Option);
+#else
+ const OUString aMOD1 = CuiResId(STR_CTRL);
+ const OUString aMOD2 = CuiResId(STR_Alt);
+#endif
+ m_pText->set_label(CuiResId(sTip).replaceAll("%MOD1", aMOD1).replaceAll("%MOD2", aMOD2));
+
+ // hyperlink
+ if (sLink.isEmpty())
+ {
+ m_pLink->set_visible(false);
+ }
+ else if (sLink.startsWith(".uno:"))
+ {
+ m_pLink->set_visible(false);
+ //show the link only if the UNO command is available in the current module
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if (pViewFrame)
+ {
+ const auto xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ const css::uno::Reference<css::frame::XDispatchProvider> xDispatchProvider(
+ xFrame, css::uno::UNO_QUERY);
+ if (xDispatchProvider.is())
+ {
+ css::util::URL aCommandURL;
+ aCommandURL.Complete = sLink;
+ const css::uno::Reference<css::uno::XComponentContext> xContext
+ = comphelper::getProcessComponentContext();
+ const css::uno::Reference<css::util::XURLTransformer> xParser
+ = css::util::URLTransformer::create(xContext);
+ xParser->parseStrict(aCommandURL);
+ const css::uno::Reference<css::frame::XDispatch> xDisp
+ = xDispatchProvider->queryDispatch(aCommandURL, OUString(), 0);
+ if (xDisp.is())
+ {
+ m_pLink->set_label(CuiResId(STR_UNO_LINK));
+ m_pLink->set_uri(sLink);
+
+ const OUString aModuleName(
+ vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
+ const auto aProperties
+ = vcl::CommandInfoProvider::GetCommandProperties(sLink, aModuleName);
+ m_pLink->set_tooltip_text(
+ vcl::CommandInfoProvider::GetTooltipForCommand(sLink, aProperties, xFrame));
+
+ m_pLink->set_visible(true);
+ m_pLink->connect_activate_link(LINK(this, TipOfTheDayDialog, OnLinkClick));
+ }
+ }
+ }
+ }
+ else if (sLink.startsWith("http"))
+ {
+ // Links may have some %PRODUCTVERSION which need to be expanded
+ OUString aText = Translate::ExpandVariables(sLink);
+ OUString aLang = LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
+ if (aLang == "en" || aLang == "pt" || aLang == "zh") //en-US/GB, pt-BR, zh-CH/TW
+ aLang = LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
+ m_pLink->set_uri(aText.replaceFirst("%LANGUAGENAME", aLang));
+ m_pLink->set_label(CuiResId(STR_MORE_LINK));
+ m_pLink->set_visible(true);
+ m_pLink->connect_activate_link(Link<weld::LinkButton&, bool>());
+ }
+ else
+ {
+ m_pLink->set_uri(sLink);
+ m_pLink->set_label(CuiResId(STR_HELP_LINK));
+ m_pLink->set_visible(true);
+ m_pLink->connect_activate_link(LINK(this, TipOfTheDayDialog, OnLinkClick));
+ }
+ // image
+ OUString aURL("$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/tipoftheday/");
+ rtl::Bootstrap::expandMacros(aURL);
+ OUString aImageName = sImage;
+ // use default image if none is available with the number
+ if (aImageName.isEmpty() || !file_exists(aURL + aImageName))
+ aImageName = "tipoftheday.png";
+ Graphic aGraphic;
+ GraphicFilter::LoadGraphic(aURL + aImageName, OUString(), aGraphic);
+
+ if (!aGraphic.IsAnimated())
+ {
+ BitmapEx aBmpEx(aGraphic.GetBitmapEx());
+ if (aBmpEx.Scale(ThumbSize))
+ aGraphic = aBmpEx;
+ }
+ m_aPreview.SetPreview(aGraphic);
+}
+
+IMPL_LINK(TipOfTheDayDialog, OnLinkClick, weld::LinkButton&, rButton, bool)
+{
+ const OUString sLink = rButton.get_uri();
+ if (sLink.startsWith(".uno:"))
+ {
+ comphelper::dispatchCommand(sLink, {});
+ TipOfTheDayDialog::response(RET_OK);
+ }
+ else
+ {
+ Application::GetHelp()->Start(sLink, static_cast<weld::Widget*>(nullptr));
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(TipOfTheDayDialog, OnNextClick, weld::Button&, void)
+{
+ m_nCurrentTip++; //zeroed at updatetip when out of range
+ UpdateTip();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/toolbarmodedlg.cxx b/cui/source/dialogs/toolbarmodedlg.cxx
new file mode 100644
index 000000000..f1dbdeb10
--- /dev/null
+++ b/cui/source/dialogs/toolbarmodedlg.cxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <toolbarmodedlg.hxx>
+#include <toolbarmode.hrc>
+
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/types.hxx>
+#include <dialmgr.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/UI/ToolbarMode.hxx>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <strings.hrc>
+#include <unotools/confignode.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/EnumContext.hxx>
+#include <vcl/weld.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+static OUString GetCurrentApp()
+{
+ OUString sResult;
+ if (SfxViewFrame* pViewFrame = SfxViewFrame::Current())
+ {
+ const auto xCurrentFrame = pViewFrame->GetFrame().GetFrameInterface();
+ const auto xContext = comphelper::getProcessComponentContext();
+ const auto xModuleManager = css::frame::ModuleManager::create(xContext);
+ switch (vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xCurrentFrame)))
+ {
+ case vcl::EnumContext::Application::Writer:
+ sResult = "Writer";
+ break;
+ case vcl::EnumContext::Application::Calc:
+ sResult = "Calc";
+ break;
+ case vcl::EnumContext::Application::Impress:
+ sResult = "Impress";
+ break;
+ case vcl::EnumContext::Application::Draw:
+ sResult = "Draw";
+ break;
+ case vcl::EnumContext::Application::Formula:
+ sResult = "Formula";
+ break;
+ case vcl::EnumContext::Application::Base:
+ sResult = "Base";
+ break;
+ default:
+ sResult = "Unsupported";
+ }
+ }
+ return sResult;
+}
+
+static OUString GetCurrentMode()
+{
+ OUString sResult;
+ if (SfxViewFrame::Current())
+ {
+ const auto xContext = comphelper::getProcessComponentContext();
+ const utl::OConfigurationTreeRoot aAppNode(
+ xContext, "org.openoffice.Office.UI.ToolbarMode/Applications/" + GetCurrentApp(), true);
+ if (aAppNode.isValid())
+ sResult = comphelper::getString(aAppNode.getNodeValue("Active"));
+ };
+ return sResult;
+}
+
+ToolbarmodeDialog::ToolbarmodeDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/toolbarmodedialog.ui", "ToolbarmodeDialog")
+ , m_pImage(m_xBuilder->weld_image("imImage"))
+ , m_pApply(m_xBuilder->weld_button("btnApply"))
+ , m_pApplyAll(m_xBuilder->weld_button("btnApplyAll"))
+ , m_pRadioButtons{ (m_xBuilder->weld_radio_button("rbButton1")),
+ (m_xBuilder->weld_radio_button("rbButton2")),
+ (m_xBuilder->weld_radio_button("rbButton3")),
+ (m_xBuilder->weld_radio_button("rbButton4")),
+ (m_xBuilder->weld_radio_button("rbButton5")),
+ (m_xBuilder->weld_radio_button("rbButton6")),
+ (m_xBuilder->weld_radio_button("rbButton7")),
+ (m_xBuilder->weld_radio_button("rbButton8")),
+ (m_xBuilder->weld_radio_button("rbButton9")) }
+ , m_pInfoLabel(m_xBuilder->weld_label("lbInfo"))
+{
+ static_assert(SAL_N_ELEMENTS(m_pRadioButtons) == SAL_N_ELEMENTS(TOOLBARMODES_ARRAY));
+
+ Link<weld::Toggleable&, void> aLink = LINK(this, ToolbarmodeDialog, SelectToolbarmode);
+
+ const OUString sCurrentMode = GetCurrentMode();
+ for (tools::ULong i = 0; i < std::size(m_pRadioButtons); i++)
+ {
+ m_pRadioButtons[i]->connect_toggled(aLink);
+ if (sCurrentMode == std::get<1>(TOOLBARMODES_ARRAY[i]))
+ {
+ m_pRadioButtons[i]->set_active(true);
+ UpdateImage(std::get<2>(TOOLBARMODES_ARRAY[i]));
+ m_pInfoLabel->set_label(CuiResId(std::get<0>(TOOLBARMODES_ARRAY[i])));
+ }
+ }
+
+ m_pApply->set_label(CuiResId(RID_CUISTR_UI_APPLYALL).replaceFirst("%MODULE", GetCurrentApp()));
+ m_pApply->connect_clicked(LINK(this, ToolbarmodeDialog, OnApplyClick));
+ m_pApplyAll->connect_clicked(LINK(this, ToolbarmodeDialog, OnApplyClick));
+
+ if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
+ {
+ m_pRadioButtons[nGroupedbarFull]->set_visible(false);
+ m_pRadioButtons[nContextualGroups]->set_visible(false);
+ }
+}
+
+ToolbarmodeDialog::~ToolbarmodeDialog() = default;
+
+static bool file_exists(const OUString& fileName)
+{
+ osl::File aFile(fileName);
+ return aFile.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None;
+}
+
+int ToolbarmodeDialog::GetActiveRadioButton()
+{
+ for (tools::ULong i = 0; i < std::size(m_pRadioButtons); i++)
+ {
+ if (m_pRadioButtons[i]->get_active())
+ return i;
+ }
+ return -1;
+}
+
+void ToolbarmodeDialog::UpdateImage(std::u16string_view sFileName)
+{
+ // load image
+ OUString aURL("$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/toolbarmode/");
+ rtl::Bootstrap::expandMacros(aURL);
+ aURL += sFileName;
+ if (sFileName.empty() || !file_exists(aURL))
+ return;
+ // draw image
+ Graphic aGraphic;
+ if (GraphicFilter::LoadGraphic(aURL, OUString(), aGraphic) == ERRCODE_NONE)
+ {
+ ScopedVclPtr<VirtualDevice> m_pVirDev = m_pImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aGraphic.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aGraphic.GetBitmapEx());
+ m_pImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+ }
+}
+
+IMPL_LINK_NOARG(ToolbarmodeDialog, SelectToolbarmode, weld::Toggleable&, void)
+{
+ const int i = GetActiveRadioButton();
+ if (i > -1)
+ {
+ UpdateImage(std::get<2>(TOOLBARMODES_ARRAY[i]));
+ m_pInfoLabel->set_label(CuiResId(std::get<0>(TOOLBARMODES_ARRAY[i])));
+ }
+}
+
+IMPL_LINK(ToolbarmodeDialog, OnApplyClick, weld::Button&, rButton, void)
+{
+ const int i = GetActiveRadioButton();
+ if (i == -1)
+ return;
+ const OUString sCmd = std::get<1>(TOOLBARMODES_ARRAY[i]);
+ //apply to all except current module
+ if (&rButton == m_pApplyAll.get())
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> aBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::UI::ToolbarMode::ActiveWriter::set(sCmd, aBatch);
+ officecfg::Office::UI::ToolbarMode::ActiveCalc::set(sCmd, aBatch);
+ officecfg::Office::UI::ToolbarMode::ActiveImpress::set(sCmd, aBatch);
+ officecfg::Office::UI::ToolbarMode::ActiveDraw::set(sCmd, aBatch);
+ aBatch->commit();
+
+ OUString sCurrentApp = GetCurrentApp();
+ if (SfxViewFrame::Current())
+ {
+ const auto xContext = comphelper::getProcessComponentContext();
+ const utl::OConfigurationTreeRoot aAppNode(
+ xContext, "org.openoffice.Office.UI.ToolbarMode/Applications/", true);
+ if (sCurrentApp != "Writer")
+ aAppNode.setNodeValue("Writer/Active", css::uno::Any(sCmd));
+ if (sCurrentApp != "Calc")
+ aAppNode.setNodeValue("Calc/Active", css::uno::Any(sCmd));
+ if (sCurrentApp != "Impress")
+ aAppNode.setNodeValue("Impress/Active", css::uno::Any(sCmd));
+ if (sCurrentApp != "Draw")
+ aAppNode.setNodeValue("Draw/Active", css::uno::Any(sCmd));
+ aAppNode.commit();
+ };
+ }
+ //apply to current module
+ comphelper::dispatchCommand(".uno:ToolbarMode?Mode:string=" + sCmd, {});
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/zoom.cxx b/cui/source/dialogs/zoom.cxx
new file mode 100644
index 000000000..0d6f44e40
--- /dev/null
+++ b/cui/source/dialogs/zoom.cxx
@@ -0,0 +1,397 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/diagnose.h>
+#include <svl/itemset.hxx>
+#include <svl/itempool.hxx>
+#include <sfx2/objsh.hxx>
+#include <zoom.hxx>
+#include <sfx2/zoomitem.hxx>
+#include <svx/viewlayoutitem.hxx>
+#include <svx/zoom_def.hxx>
+
+namespace
+{
+const sal_uInt16 SPECIAL_FACTOR = 0xFFFF;
+
+} // anonymous namespace
+
+sal_uInt16 SvxZoomDialog::GetFactor() const
+{
+ if (m_x100Btn->get_active())
+ return 100;
+
+ if (m_xUserBtn->get_active())
+ return static_cast<sal_uInt16>(m_xUserEdit->get_value(FieldUnit::PERCENT));
+ else
+ return SPECIAL_FACTOR;
+}
+
+void SvxZoomDialog::SetFactor(sal_uInt16 nNewFactor, ZoomButtonId nButtonId)
+{
+ m_xUserEdit->set_sensitive(false);
+
+ if (nButtonId == ZoomButtonId::NONE)
+ {
+ if (nNewFactor == 100)
+ {
+ m_x100Btn->set_active(true);
+ m_x100Btn->grab_focus();
+ }
+ else
+ {
+ m_xUserBtn->set_active(true);
+ m_xUserEdit->set_sensitive(true);
+ m_xUserEdit->set_value(nNewFactor, FieldUnit::PERCENT);
+ m_xUserEdit->grab_focus();
+ }
+ }
+ else
+ {
+ m_xUserEdit->set_value(nNewFactor, FieldUnit::PERCENT);
+ switch (nButtonId)
+ {
+ case ZoomButtonId::OPTIMAL:
+ {
+ m_xOptimalBtn->set_active(true);
+ m_xOptimalBtn->grab_focus();
+ break;
+ }
+ case ZoomButtonId::PAGEWIDTH:
+ {
+ m_xPageWidthBtn->set_active(true);
+ m_xPageWidthBtn->grab_focus();
+ break;
+ }
+ case ZoomButtonId::WHOLEPAGE:
+ {
+ m_xWholePageBtn->set_active(true);
+ m_xWholePageBtn->grab_focus();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void SvxZoomDialog::HideButton(ZoomButtonId nButtonId)
+{
+ switch (nButtonId)
+ {
+ case ZoomButtonId::OPTIMAL:
+ m_xOptimalBtn->hide();
+ break;
+
+ case ZoomButtonId::PAGEWIDTH:
+ m_xPageWidthBtn->hide();
+ break;
+
+ case ZoomButtonId::WHOLEPAGE:
+ m_xWholePageBtn->hide();
+ break;
+
+ default:
+ OSL_FAIL("Wrong button number!");
+ }
+}
+
+void SvxZoomDialog::SetLimits(sal_uInt16 nMin, sal_uInt16 nMax)
+{
+ DBG_ASSERT(nMin < nMax, "invalid limits");
+ m_xUserEdit->set_range(nMin, nMax, FieldUnit::PERCENT);
+}
+
+const SfxItemSet* SvxZoomDialog::GetOutputItemSet() const { return m_pOutSet.get(); }
+
+SvxZoomDialog::SvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet)
+ : SfxDialogController(pParent, "cui/ui/zoomdialog.ui", "ZoomDialog")
+ , m_rSet(rCoreSet)
+ , m_bModified(false)
+ , m_xOptimalBtn(m_xBuilder->weld_radio_button("optimal"))
+ , m_xWholePageBtn(m_xBuilder->weld_radio_button("fitwandh"))
+ , m_xPageWidthBtn(m_xBuilder->weld_radio_button("fitw"))
+ , m_x100Btn(m_xBuilder->weld_radio_button("100pc"))
+ , m_xUserBtn(m_xBuilder->weld_radio_button("variable"))
+ , m_xUserEdit(m_xBuilder->weld_metric_spin_button("zoomsb", FieldUnit::PERCENT))
+ , m_xViewFrame(m_xBuilder->weld_widget("viewframe"))
+ , m_xAutomaticBtn(m_xBuilder->weld_radio_button("automatic"))
+ , m_xSingleBtn(m_xBuilder->weld_radio_button("singlepage"))
+ , m_xColumnsBtn(m_xBuilder->weld_radio_button("columns"))
+ , m_xColumnsEdit(m_xBuilder->weld_spin_button("columnssb"))
+ , m_xBookModeChk(m_xBuilder->weld_check_button("bookmode"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ Link<weld::Toggleable&, void> aLink = LINK(this, SvxZoomDialog, UserHdl);
+ m_x100Btn->connect_toggled(aLink);
+ m_xOptimalBtn->connect_toggled(aLink);
+ m_xPageWidthBtn->connect_toggled(aLink);
+ m_xWholePageBtn->connect_toggled(aLink);
+ m_xUserBtn->connect_toggled(aLink);
+
+ Link<weld::Toggleable&, void> aViewLayoutLink = LINK(this, SvxZoomDialog, ViewLayoutUserHdl);
+ m_xAutomaticBtn->connect_toggled(aViewLayoutLink);
+ m_xSingleBtn->connect_toggled(aViewLayoutLink);
+ m_xColumnsBtn->connect_toggled(aViewLayoutLink);
+
+ Link<weld::SpinButton&, void> aViewLayoutSpinLink
+ = LINK(this, SvxZoomDialog, ViewLayoutSpinHdl);
+ m_xColumnsEdit->connect_value_changed(aViewLayoutSpinLink);
+
+ Link<weld::Toggleable&, void> aViewLayoutCheckLink
+ = LINK(this, SvxZoomDialog, ViewLayoutCheckHdl);
+ m_xBookModeChk->connect_toggled(aViewLayoutCheckLink);
+
+ m_xOKBtn->connect_clicked(LINK(this, SvxZoomDialog, OKHdl));
+ m_xUserEdit->connect_value_changed(LINK(this, SvxZoomDialog, SpinHdl));
+
+ // default values
+ sal_uInt16 nValue = 100;
+ sal_uInt16 nMin = 10;
+ sal_uInt16 nMax = 1000;
+
+ // maybe get the old value first
+ const SfxUInt16Item* pOldUserItem = nullptr;
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pOldUserItem = pShell->GetItem(SID_ATTR_ZOOM_USER);
+
+ if (pOldUserItem)
+ nValue = pOldUserItem->GetValue();
+
+ // initialize UserEdit
+ if (nMin > nValue)
+ nMin = nValue;
+ if (nMax < nValue)
+ nMax = nValue;
+
+ SetLimits(nMin, nMax);
+ m_xUserEdit->set_value(nValue, FieldUnit::PERCENT);
+
+ const SfxPoolItem& rItem = m_rSet.Get(SID_ATTR_ZOOM);
+
+ if (auto pZoomItem = dynamic_cast<const SvxZoomItem*>(&rItem))
+ {
+ const sal_uInt16 nZoom = pZoomItem->GetValue();
+ const SvxZoomType eType = pZoomItem->GetType();
+ const SvxZoomEnableFlags nValSet = pZoomItem->GetValueSet();
+ ZoomButtonId nButtonId = ZoomButtonId::NONE;
+
+ switch (eType)
+ {
+ case SvxZoomType::OPTIMAL:
+ nButtonId = ZoomButtonId::OPTIMAL;
+ break;
+ case SvxZoomType::PAGEWIDTH:
+ nButtonId = ZoomButtonId::PAGEWIDTH;
+ break;
+ case SvxZoomType::WHOLEPAGE:
+ nButtonId = ZoomButtonId::WHOLEPAGE;
+ break;
+ case SvxZoomType::PERCENT:
+ break;
+ case SvxZoomType::PAGEWIDTH_NOBORDER:
+ break;
+ }
+
+ if (!(SvxZoomEnableFlags::N100 & nValSet))
+ m_x100Btn->set_sensitive(false);
+ if (!(SvxZoomEnableFlags::OPTIMAL & nValSet))
+ m_xOptimalBtn->set_sensitive(false);
+ if (!(SvxZoomEnableFlags::PAGEWIDTH & nValSet))
+ m_xPageWidthBtn->set_sensitive(false);
+ if (!(SvxZoomEnableFlags::WHOLEPAGE & nValSet))
+ m_xWholePageBtn->set_sensitive(false);
+
+ SetFactor(nZoom, nButtonId);
+ }
+ else
+ {
+ const sal_uInt16 nZoom = static_cast<const SfxUInt16Item&>(rItem).GetValue();
+ SetFactor(nZoom);
+ }
+
+ if (const SvxViewLayoutItem* pViewLayoutItem = m_rSet.GetItemIfSet(SID_ATTR_VIEWLAYOUT, false))
+ {
+ const sal_uInt16 nColumns = pViewLayoutItem->GetValue();
+ const bool bBookMode = pViewLayoutItem->IsBookMode();
+
+ if (0 == nColumns)
+ {
+ m_xAutomaticBtn->set_active(true);
+ m_xColumnsEdit->set_value(2);
+ m_xColumnsEdit->set_sensitive(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else if (1 == nColumns)
+ {
+ m_xSingleBtn->set_active(true);
+ m_xColumnsEdit->set_value(2);
+ m_xColumnsEdit->set_sensitive(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else
+ {
+ m_xColumnsBtn->set_active(true);
+ if (!bBookMode)
+ {
+ m_xColumnsEdit->set_value(nColumns);
+ if (nColumns % 2 != 0)
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else
+ {
+ m_xColumnsEdit->set_value(nColumns);
+ m_xBookModeChk->set_active(true);
+ }
+ }
+ }
+ else
+ {
+ // hide view layout related controls:
+ m_xViewFrame->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, UserHdl, weld::Toggleable&, void)
+{
+ m_bModified = true;
+
+ if (m_xUserBtn->get_active())
+ {
+ m_xUserEdit->set_sensitive(true);
+ m_xUserEdit->grab_focus();
+ }
+ else
+ {
+ m_xUserEdit->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, SpinHdl, weld::MetricSpinButton&, void)
+{
+ if (!m_xUserBtn->get_active())
+ return;
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, ViewLayoutUserHdl, weld::Toggleable&, void)
+{
+ m_bModified = true;
+
+ if (m_xAutomaticBtn->get_active() || m_xSingleBtn->get_active())
+ {
+ m_xColumnsEdit->set_sensitive(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else if (m_xColumnsBtn->get_active())
+ {
+ m_xColumnsEdit->set_sensitive(true);
+ m_xColumnsEdit->grab_focus();
+ if (m_xColumnsEdit->get_value() % 2 == 0)
+ m_xBookModeChk->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, ViewLayoutSpinHdl, weld::SpinButton&, void)
+{
+ if (!m_xColumnsBtn->get_active())
+ return;
+
+ if (m_xColumnsEdit->get_value() % 2 == 0)
+ {
+ m_xBookModeChk->set_sensitive(true);
+ }
+ else
+ {
+ m_xBookModeChk->set_active(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, ViewLayoutCheckHdl, weld::Toggleable&, void)
+{
+ if (!m_xColumnsBtn->get_active())
+ return;
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, OKHdl, weld::Button&, void)
+{
+ if (m_bModified)
+ {
+ SvxZoomItem aZoomItem(SvxZoomType::PERCENT, 0, SID_ATTR_ZOOM);
+ SvxViewLayoutItem aViewLayoutItem(0, false, SID_ATTR_VIEWLAYOUT);
+
+ sal_uInt16 nFactor = GetFactor();
+
+ if (SPECIAL_FACTOR == nFactor)
+ {
+ if (m_xOptimalBtn->get_active())
+ aZoomItem.SetType(SvxZoomType::OPTIMAL);
+ else if (m_xPageWidthBtn->get_active())
+ aZoomItem.SetType(SvxZoomType::PAGEWIDTH);
+ else if (m_xWholePageBtn->get_active())
+ aZoomItem.SetType(SvxZoomType::WHOLEPAGE);
+ }
+ else
+ {
+ aZoomItem.SetValue(nFactor);
+ }
+
+ if (m_xAutomaticBtn->get_active())
+ {
+ aViewLayoutItem.SetValue(0);
+ aViewLayoutItem.SetBookMode(false);
+ }
+ if (m_xSingleBtn->get_active())
+ {
+ aViewLayoutItem.SetValue(1);
+ aViewLayoutItem.SetBookMode(false);
+ }
+ else if (m_xColumnsBtn->get_active())
+ {
+ aViewLayoutItem.SetValue(static_cast<sal_uInt16>(m_xColumnsEdit->get_value()));
+ aViewLayoutItem.SetBookMode(m_xBookModeChk->get_active());
+ }
+
+ m_pOutSet.reset(new SfxItemSet(m_rSet));
+ m_pOutSet->Put(aZoomItem);
+
+ // don't set attribute in case the whole viewlayout stuff is disabled:
+ if (m_xViewFrame->get_sensitive())
+ m_pOutSet->Put(aViewLayoutItem);
+
+ // memorize value from the UserEdit beyond the dialog
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ {
+ sal_uInt16 nZoomValue
+ = static_cast<sal_uInt16>(m_xUserEdit->get_value(FieldUnit::PERCENT));
+ pShell->PutItem(SfxUInt16Item(SID_ATTR_ZOOM_USER, nZoomValue));
+ }
+ m_xDialog->response(RET_OK);
+ }
+ else
+ m_xDialog->response(RET_CANCEL);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/cuiexp.cxx b/cui/source/factory/cuiexp.cxx
new file mode 100644
index 000000000..06557be56
--- /dev/null
+++ b/cui/source/factory/cuiexp.cxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dlgfact.hxx"
+#include <sal/types.h>
+
+namespace cui
+{
+static AbstractDialogFactory_Impl* GetFactory()
+{
+ static AbstractDialogFactory_Impl* pFactory = new AbstractDialogFactory_Impl;
+ return pFactory;
+}
+}
+
+extern "C" {
+SAL_DLLPUBLIC_EXPORT VclAbstractDialogFactory* CreateDialogFactory() { return ::cui::GetFactory(); }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/cuiresmgr.cxx b/cui/source/factory/cuiresmgr.cxx
new file mode 100644
index 000000000..2b58e5854
--- /dev/null
+++ b/cui/source/factory/cuiresmgr.cxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dialmgr.hxx>
+#include <unotools/resmgr.hxx>
+
+OUString CuiResId(TranslateId aKey) { return Translate::get(aKey, Translate::Create("cui")); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
new file mode 100644
index 000000000..fb61dafce
--- /dev/null
+++ b/cui/source/factory/dlgfact.cxx
@@ -0,0 +1,1547 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_extensions.h>
+#include <config_wasm_strip.h>
+
+#include <align.hxx>
+#include "dlgfact.hxx"
+
+#include <about.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/pageids.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+#include <numfmt.hxx>
+#include <splitcelldlg.hxx>
+#include <cuiimapwnd.hxx>
+#include <cui/cuicharmap.hxx>
+#include <srchxtra.hxx>
+#include <textanim.hxx>
+#include <autocdlg.hxx>
+#include <treeopt.hxx>
+#include <labdlg.hxx>
+#include <hangulhanjadlg.hxx>
+#include <showcols.hxx>
+#include <zoom.hxx>
+#include <cuigaldlg.hxx>
+#include <transfrm.hxx>
+#include <bbdlg.hxx>
+#include <cuisrchdlg.hxx>
+#include <cuitbxform.hxx>
+#include <optdict.hxx>
+#include <dlgname.hxx>
+#include <multipat.hxx>
+#include <cuihyperdlg.hxx>
+#include <cuifmsearch.hxx>
+#include <cuigrfflt.hxx>
+#include <cuitabarea.hxx>
+#include <cuitabline.hxx>
+#include <measure.hxx>
+#include <connect.hxx>
+#include <dbregister.hxx>
+#include <cuioptgenrl.hxx>
+#include <optasian.hxx>
+#include <insdlg.hxx>
+#include <pastedlg.hxx>
+#include <linkdlg.hxx>
+#include <SignatureLineDialog.hxx>
+#include <SignSignatureLineDialog.hxx>
+#include <QrCodeGenDialog.hxx>
+#include <SpellDialog.hxx>
+#include <cfg.hxx>
+#include <numpages.hxx>
+#include <paragrph.hxx>
+#include <tabstpge.hxx>
+#include <textattr.hxx>
+#include <backgrnd.hxx>
+#include <border.hxx>
+#include <chardlg.hxx>
+#include <page.hxx>
+#include <postdlg.hxx>
+#include <grfpage.hxx>
+#include <scriptdlg.hxx>
+#include <cfgutil.hxx>
+#include <macropg.hxx>
+#include <sdrcelldlg.hxx>
+#include <newtabledlg.hxx>
+#include <macroass.hxx>
+#include <insrc.hxx>
+#include <passwdomdlg.hxx>
+#include <screenshotannotationdlg.hxx>
+#include <hyphen.hxx>
+#include <thesdlg.hxx>
+#include <tipofthedaydlg.hxx>
+#include <toolbarmodedlg.hxx>
+#include <DiagramDialog.hxx>
+#include <fileextcheckdlg.hxx>
+#include <TextColumnsPage.hxx>
+#include <themepage.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+
+using ::com::sun::star::uno::Reference;
+
+using namespace svx;
+
+IMPL_ABSTDLG_CLASS(AbstractAdditionsDialog)
+IMPL_ABSTDLG_CLASS(AbstractDiagramDialog)
+IMPL_ABSTDLG_CLASS(AbstractFmInputRecordNoDialog)
+IMPL_ABSTDLG_CLASS(AbstractFmSearchDialog)
+IMPL_ABSTDLG_CLASS(AbstractFmShowColsDialog)
+IMPL_ABSTDLG_CLASS(AbstractGalleryIdDialog)
+IMPL_ABSTDLG_CLASS(AbstractGraphicFilterDialog)
+IMPL_ABSTDLG_CLASS(AbstractHangulHanjaConversionDialog)
+IMPL_ABSTDLG_CLASS(AbstractInsertObjectDialog)
+IMPL_ABSTDLG_CLASS(AbstractLinksDialog)
+IMPL_ABSTDLG_CLASS(AbstractPasswordToOpenModifyDialog)
+IMPL_ABSTDLG_CLASS(AbstractQrCodeGenDialog)
+IMPL_ABSTDLG_CLASS(AbstractScreenshotAnnotationDlg)
+IMPL_ABSTDLG_CLASS(AbstractSignatureLineDialog)
+IMPL_ABSTDLG_CLASS(AbstractSignSignatureLineDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxCharacterMapDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxHpLinkDlg)
+IMPL_ABSTDLG_CLASS(AbstractSvxJSearchOptionsDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxMultiPathDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxNameDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxNewDictionaryDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxObjectNameDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxObjectTitleDescDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxPathSelectDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxPostItDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxSearchSimilarityDialog)
+IMPL_ABSTDLG_CLASS(AbstractSvxZoomDialog)
+IMPL_ABSTDLG_CLASS(AbstractTitleDialog)
+IMPL_ABSTDLG_CLASS(AbstractURLDlg)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractPasteDialog,SfxDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractScriptSelectorDialog,SfxDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractSpellDialog,SfxDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractSvxAreaTabDialog,SfxTabDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractSvxCaptionDialog,SfxTabDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractSvxTransformTabDialog,SfxTabDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(AbstractThesaurusDialog,SfxDialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(CuiAbstractControllerAsync,weld::DialogController)
+IMPL_ABSTDLG_CLASS_ASYNC(CuiAbstractTabController,SfxTabDialogController)
+IMPL_ABSTDLG_CLASS(CuiAbstractController)
+IMPL_ABSTDLG_CLASS(CuiAbstractSingleTabController)
+
+short AbstractHyphenWordDialog_Impl::Execute()
+{
+#if !ENABLE_WASM_STRIP_HUNSPELL
+ return m_xDlg->run();
+#else
+ return 0;
+#endif
+}
+
+const SfxItemSet* AbstractSvxCharacterMapDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractSvxCharacterMapDialog_Impl::SetText(const OUString& rStr)
+{
+ m_xDlg->set_title(rStr);
+}
+
+void CuiAbstractTabController_Impl::SetCurPageId( const OString &rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* CuiAbstractTabController_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer CuiAbstractTabController_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void CuiAbstractTabController_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+//From class Window.
+void CuiAbstractTabController_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+std::vector<OString> CuiAbstractTabController_Impl::getAllPageUIXMLDescriptions() const
+{
+ return m_xDlg->getAllPageUIXMLDescriptions();
+}
+
+bool CuiAbstractTabController_Impl::selectPageByUIXMLDescription(const OString& rUIXMLDescription)
+{
+ return m_xDlg->selectPageByUIXMLDescription(rUIXMLDescription);
+}
+
+BitmapEx CuiAbstractTabController_Impl::createScreenshot() const
+{
+ return m_xDlg->createScreenshot();
+}
+
+OString CuiAbstractTabController_Impl::GetScreenshotId() const
+{
+ return m_xDlg->GetScreenshotId();
+}
+
+const SfxItemSet* CuiAbstractSingleTabController_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void CuiAbstractSingleTabController_Impl::SetText(const OUString& rStr)
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::EndDialog(sal_Int32 nResult)
+{
+ m_xDlg->response(nResult);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::EnableRubySupport( bool _bVal )
+{
+ m_xDlg->EnableRubySupport(_bVal);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetByCharacter( bool _bByCharacter )
+{
+ m_xDlg->SetByCharacter(_bByCharacter);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetConversionDirectionState( bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection )
+{
+ m_xDlg->SetConversionDirectionState(_bTryBothDirections, _ePrimaryConversionDirection);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetConversionFormat( editeng::HangulHanjaConversion::ConversionFormat _eType )
+{
+ m_xDlg->SetConversionFormat(_eType);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl )
+{
+ m_xDlg->SetOptionsChangedHdl(_rHdl );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetIgnoreHdl( const Link<weld::Button&,void>& _rHdl )
+{
+ m_xDlg->SetIgnoreHdl(_rHdl );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetIgnoreAllHdl(const Link<weld::Button&,void>& rHdl)
+{
+ m_xDlg->SetIgnoreAllHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetChangeHdl(const Link<weld::Button&,void>& rHdl)
+{
+ m_xDlg->SetChangeHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetChangeAllHdl( const Link<weld::Button&,void>& rHdl )
+{
+ m_xDlg->SetChangeAllHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetClickByCharacterHdl( const Link<weld::Toggleable&,void>& _rHdl )
+{
+ m_xDlg->SetClickByCharacterHdl(_rHdl );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetConversionFormatChangedHdl(const Link<weld::Toggleable&,void>& rHdl)
+{
+ m_xDlg->SetConversionFormatChangedHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetFindHdl( const Link<weld::Button&,void>& rHdl )
+{
+ m_xDlg->SetFindHdl(rHdl);
+}
+
+bool AbstractHangulHanjaConversionDialog_Impl::GetUseBothDirections( ) const
+{
+ return m_xDlg->GetUseBothDirections();
+}
+
+editeng::HangulHanjaConversion::ConversionDirection AbstractHangulHanjaConversionDialog_Impl::GetDirection( editeng::HangulHanjaConversion::ConversionDirection _eDefaultDirection ) const
+{
+ return m_xDlg->GetDirection( _eDefaultDirection );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetCurrentString(
+ const OUString& _rNewString,
+ const css::uno::Sequence< OUString >& _rSuggestions,
+ bool _bOriginatesFromDocument
+ )
+{
+ m_xDlg->SetCurrentString(_rNewString,_rSuggestions,_bOriginatesFromDocument);
+}
+
+OUString AbstractHangulHanjaConversionDialog_Impl::GetCurrentString( ) const
+{
+ return m_xDlg->GetCurrentString();
+}
+
+editeng::HangulHanjaConversion::ConversionFormat AbstractHangulHanjaConversionDialog_Impl::GetConversionFormat( ) const
+{
+ return m_xDlg->GetConversionFormat();
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::FocusSuggestion( )
+{
+ m_xDlg->FocusSuggestion();
+}
+
+OUString AbstractHangulHanjaConversionDialog_Impl::GetCurrentSuggestion( ) const
+{
+ return m_xDlg->GetCurrentSuggestion();
+}
+
+OUString AbstractThesaurusDialog_Impl::GetWord()
+{
+ return m_xDlg->GetWord();
+};
+
+Reference < css::embed::XEmbeddedObject > AbstractInsertObjectDialog_Impl::GetObject()
+{
+ return m_xDlg->GetObject();
+}
+
+bool AbstractInsertObjectDialog_Impl::IsCreateNew()
+{
+ return m_xDlg->IsCreateNew();
+}
+
+::Reference< css::io::XInputStream > AbstractInsertObjectDialog_Impl::GetIconIfIconified( OUString* pGraphicMediaType )
+{
+ return m_xDlg->GetIconIfIconified( pGraphicMediaType );
+}
+
+void AbstractPasteDialog_Impl::Insert(SotClipboardFormatId nFormat, const OUString& rFormatName)
+{
+ m_xDlg->Insert(nFormat, rFormatName);
+}
+
+void AbstractPasteDialog_Impl::InsertUno(const OUString& sCmd, const OUString& sLabel)
+{
+ m_xDlg->InsertUno(sCmd, sLabel);
+}
+
+void AbstractPasteDialog_Impl::SetObjName(const SvGlobalName & rClass, const OUString& rObjName)
+{
+ m_xDlg->SetObjName(rClass, rObjName);
+}
+
+void AbstractPasteDialog_Impl::PreGetFormat( const TransferableDataHelper& aHelper )
+{
+ m_xDlg->PreGetFormat(aHelper);
+}
+
+SotClipboardFormatId AbstractPasteDialog_Impl::GetFormatOnly()
+{
+ return m_xDlg->GetFormatOnly();
+}
+
+SotClipboardFormatId AbstractPasteDialog_Impl::GetFormat( const TransferableDataHelper& aHelper )
+{
+ return m_xDlg->GetFormat(aHelper);
+}
+
+void AbstractFmShowColsDialog_Impl::SetColumns(const ::Reference< css::container::XIndexContainer>& xCols)
+{
+ m_xDlg->SetColumns(xCols);
+}
+
+void AbstractSvxZoomDialog_Impl::SetLimits( sal_uInt16 nMin, sal_uInt16 nMax )
+{
+ m_xDlg->SetLimits( nMin, nMax );
+}
+
+void AbstractSvxZoomDialog_Impl::HideButton( ZoomButtonId nBtnId )
+{
+ m_xDlg->HideButton( nBtnId );
+}
+
+const SfxItemSet* AbstractSvxZoomDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractSpellDialog_Impl::InvalidateDialog()
+{
+ m_xDlg->InvalidateDialog();
+}
+
+std::shared_ptr<SfxDialogController> AbstractSpellDialog_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+SfxBindings& AbstractSpellDialog_Impl::GetBindings()
+{
+ return m_xDlg->GetBindings();
+}
+
+OUString AbstractTitleDialog_Impl::GetTitle() const
+{
+ return m_xDlg->GetTitle();
+}
+
+sal_uInt32 AbstractGalleryIdDialog_Impl::GetId() const
+{
+ return m_xDlg->GetId();
+}
+
+OUString AbstractURLDlg_Impl::GetURL() const
+{
+ return m_xDlg->GetURL();
+}
+
+OUString AbstractURLDlg_Impl::GetAltText() const
+{
+ return m_xDlg->GetAltText();
+}
+
+OUString AbstractURLDlg_Impl::GetDesc() const
+{
+ return m_xDlg->GetDesc();
+}
+
+OUString AbstractURLDlg_Impl::GetTarget() const
+{
+ return m_xDlg->GetTarget();
+}
+
+OUString AbstractURLDlg_Impl::GetName() const
+{
+ return m_xDlg->GetName();
+}
+
+sal_uInt16 AbstractSvxSearchSimilarityDialog_Impl::GetOther()
+{
+ return m_xDlg->GetOther();
+}
+
+sal_uInt16 AbstractSvxSearchSimilarityDialog_Impl::GetShorter()
+{
+ return m_xDlg->GetShorter();
+}
+
+sal_uInt16 AbstractSvxSearchSimilarityDialog_Impl::GetLonger()
+{
+ return m_xDlg->GetLonger();
+}
+
+bool AbstractSvxSearchSimilarityDialog_Impl::IsRelaxed()
+{
+ return m_xDlg->IsRelaxed();
+}
+
+// AbstractSvxTransformTabDialog implementations just forwards everything to the dialog
+void AbstractSvxTransformTabDialog_Impl::SetCurPageId( const OString& rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractSvxTransformTabDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer AbstractSvxTransformTabDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSvxTransformTabDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+//From class Window.
+void AbstractSvxTransformTabDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSvxTransformTabDialog_Impl::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ m_xDlg->SetValidateFramePosLink( rLink );
+}
+
+// AbstractSvxCaptionDialog implementations just forwards everything to the dialog
+void AbstractSvxCaptionDialog_Impl::SetCurPageId( const OString& rName )
+{
+ m_xDlg->SetCurPageId(rName);
+}
+
+const SfxItemSet* AbstractSvxCaptionDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer AbstractSvxCaptionDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSvxCaptionDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+void AbstractSvxCaptionDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSvxCaptionDialog_Impl::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ m_xDlg->SetValidateFramePosLink( rLink );
+}
+
+TransliterationFlags AbstractSvxJSearchOptionsDialog_Impl::GetTransliterationFlags() const
+{
+ return m_xDlg->GetTransliterationFlags();
+}
+
+void AbstractFmInputRecordNoDialog_Impl::SetValue(tools::Long nNew)
+{
+ m_xDlg->SetValue(nNew);
+}
+
+tools::Long AbstractFmInputRecordNoDialog_Impl::GetValue() const
+{
+ return m_xDlg->GetValue();
+}
+
+::Reference< css::linguistic2::XDictionary > AbstractSvxNewDictionaryDialog_Impl::GetNewDictionary()
+{
+ return m_xDlg->GetNewDictionary();
+}
+
+void AbstractSvxNameDialog_Impl::GetName(OUString& rName)
+{
+ rName = m_xDlg->GetName();
+}
+
+void AbstractSvxNameDialog_Impl::SetCheckNameHdl( const Link<AbstractSvxNameDialog&,bool>& rLink, bool bCheckImmediately )
+{
+ aCheckNameHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetCheckNameHdl( LINK(this, AbstractSvxNameDialog_Impl, CheckNameHdl), bCheckImmediately );
+ else
+ m_xDlg->SetCheckNameHdl( Link<SvxNameDialog&,bool>(), bCheckImmediately );
+}
+
+void AbstractSvxNameDialog_Impl::SetCheckNameTooltipHdl( const Link<AbstractSvxNameDialog&,OUString>& rLink)
+{
+ aCheckNameTooltipHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetCheckNameTooltipHdl( LINK(this, AbstractSvxNameDialog_Impl, CheckNameTooltipHdl));
+ else
+ m_xDlg->SetCheckNameTooltipHdl( Link<SvxNameDialog&,OUString>());
+}
+
+void AbstractSvxNameDialog_Impl::SetEditHelpId(const OString& rHelpId)
+{
+ m_xDlg->SetEditHelpId(rHelpId);
+}
+
+void AbstractSvxNameDialog_Impl::SetHelpId(const OString& rHelpId)
+{
+ m_xDlg->set_help_id(rHelpId);
+}
+
+void AbstractSvxNameDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+IMPL_LINK_NOARG(AbstractSvxNameDialog_Impl, CheckNameHdl, SvxNameDialog&, bool)
+{
+ return aCheckNameHdl.Call(*this);
+}
+
+IMPL_LINK_NOARG(AbstractSvxNameDialog_Impl, CheckNameTooltipHdl, SvxNameDialog&, OUString)
+{
+ return aCheckNameTooltipHdl.Call(*this);
+}
+
+void AbstractSvxObjectNameDialog_Impl::GetName(OUString& rName)
+{
+ rName = m_xDlg->GetName();
+}
+
+void AbstractSvxObjectNameDialog_Impl::SetCheckNameHdl(const Link<AbstractSvxObjectNameDialog&,bool>& rLink)
+{
+ aCheckNameHdl = rLink;
+
+ if(rLink.IsSet())
+ {
+ m_xDlg->SetCheckNameHdl(LINK(this, AbstractSvxObjectNameDialog_Impl, CheckNameHdl));
+ }
+ else
+ {
+ m_xDlg->SetCheckNameHdl(Link<SvxObjectNameDialog&,bool>());
+ }
+}
+
+IMPL_LINK_NOARG(AbstractSvxObjectNameDialog_Impl, CheckNameHdl, SvxObjectNameDialog&, bool)
+{
+ return aCheckNameHdl.Call(*this);
+}
+
+void AbstractSvxObjectTitleDescDialog_Impl::GetTitle(OUString& rTitle)
+{
+ rTitle = m_xDlg->GetTitle();
+}
+
+void AbstractSvxObjectTitleDescDialog_Impl::GetDescription(OUString& rDescription)
+{
+ rDescription = m_xDlg->GetDescription();
+}
+
+OUString AbstractSvxMultiPathDialog_Impl::GetPath() const
+{
+ return m_xDlg->GetPath();
+}
+
+void AbstractSvxMultiPathDialog_Impl::SetPath( const OUString& rPath )
+{
+ m_xDlg->SetPath( rPath );
+}
+
+void AbstractSvxMultiPathDialog_Impl::SetTitle( const OUString& rNewTitle )
+{
+ m_xDlg->SetTitle(rNewTitle);
+}
+
+OUString AbstractSvxPathSelectDialog_Impl::GetPath() const
+{
+ return m_xDlg->GetPath();
+}
+
+void AbstractSvxPathSelectDialog_Impl::SetPath( const OUString& rPath )
+{
+ m_xDlg->SetPath( rPath );
+}
+
+void AbstractSvxPathSelectDialog_Impl::SetTitle( const OUString& rNewTitle )
+{
+ m_xDlg->SetTitle(rNewTitle);
+}
+
+std::shared_ptr<SfxDialogController> AbstractSvxHpLinkDlg_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+bool AbstractSvxHpLinkDlg_Impl::QueryClose()
+{
+ return m_xDlg->QueryClose();
+}
+
+void AbstractFmSearchDialog_Impl::SetFoundHandler(const Link<FmFoundRecordInformation&,void>& lnk)
+{
+ m_xDlg->SetFoundHandler(lnk);
+}
+
+void AbstractFmSearchDialog_Impl::SetCanceledNotFoundHdl(const Link<FmFoundRecordInformation&,void>& lnk)
+{
+ m_xDlg->SetCanceledNotFoundHdl(lnk);
+}
+
+void AbstractFmSearchDialog_Impl::SetActiveField(const OUString& strField)
+{
+ m_xDlg->SetActiveField(strField);
+}
+
+Graphic AbstractGraphicFilterDialog_Impl::GetFilteredGraphic(const Graphic& rGraphic, double fScaleX, double fScaleY)
+{
+ return m_xDlg->GetFilteredGraphic(rGraphic, fScaleX, fScaleY);
+}
+
+// AbstractSvxAreaTabDialog implementations just forwards everything to the dialog
+void AbstractSvxAreaTabDialog_Impl::SetCurPageId( const OString& rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractSvxAreaTabDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer AbstractSvxAreaTabDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSvxAreaTabDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+void AbstractSvxAreaTabDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSvxPostItDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+const SfxItemSet* AbstractSvxPostItDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractSvxPostItDialog_Impl::EnableTravel(bool bNext, bool bPrev)
+{
+ m_xDlg->EnableTravel( bNext, bPrev );
+}
+
+OUString AbstractSvxPostItDialog_Impl::GetNote()
+{
+ return m_xDlg->GetNote();
+}
+
+void AbstractSvxPostItDialog_Impl::SetNote(const OUString& rTxt)
+{
+ m_xDlg->SetNote( rTxt );
+}
+
+void AbstractSvxPostItDialog_Impl::ShowLastAuthor(const OUString& rAuthor, const OUString& rDate)
+{
+ m_xDlg->ShowLastAuthor( rAuthor, rDate );
+}
+
+void AbstractSvxPostItDialog_Impl::DontChangeAuthor()
+{
+ m_xDlg->DontChangeAuthor();
+}
+
+void AbstractSvxPostItDialog_Impl::HideAuthor()
+{
+ m_xDlg->HideAuthor();
+}
+
+void AbstractSvxPostItDialog_Impl::SetNextHdl( const Link<AbstractSvxPostItDialog&,void>& rLink )
+{
+ aNextHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetNextHdl( LINK(this, AbstractSvxPostItDialog_Impl, NextHdl ) );
+ else
+ m_xDlg->SetNextHdl( Link<SvxPostItDialog&,void>() );
+}
+
+void AbstractSvxPostItDialog_Impl::SetPrevHdl( const Link<AbstractSvxPostItDialog&,void>& rLink )
+{
+ aPrevHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetPrevHdl( LINK(this, AbstractSvxPostItDialog_Impl, PrevHdl ) );
+ else
+ m_xDlg->SetPrevHdl( Link<SvxPostItDialog&,void>() );
+}
+
+IMPL_LINK_NOARG(AbstractSvxPostItDialog_Impl, NextHdl, SvxPostItDialog&, void)
+{
+ aNextHdl.Call(*this);
+}
+
+IMPL_LINK_NOARG(AbstractSvxPostItDialog_Impl, PrevHdl, SvxPostItDialog&, void)
+{
+ aPrevHdl.Call(*this);
+}
+
+std::shared_ptr<weld::Dialog> AbstractSvxPostItDialog_Impl::GetDialog()
+{
+ return m_xDlg->GetDialog();
+}
+
+OUString AbstractPasswordToOpenModifyDialog_Impl::GetPasswordToOpen() const
+{
+ return m_xDlg->GetPasswordToOpen();
+}
+
+OUString AbstractPasswordToOpenModifyDialog_Impl::GetPasswordToModify() const
+{
+ return m_xDlg->GetPasswordToModify();
+}
+
+bool AbstractPasswordToOpenModifyDialog_Impl::IsRecommendToOpenReadonly() const
+{
+ return m_xDlg->IsRecommendToOpenReadonly();
+}
+
+// Create dialogs with simplest interface
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateVclDialog(weld::Window* pParent, sal_uInt32 nResId)
+{
+ std::unique_ptr<OfaTreeOptionsDialog> xDlg;
+ switch ( nResId )
+ {
+ case SID_OPTIONS_TREEDIALOG :
+ case SID_OPTIONS_DATABASES :
+ case SID_LANGUAGE_OPTIONS :
+ {
+ bool bActivateLastSelection = false;
+ if (nResId == SID_OPTIONS_TREEDIALOG)
+ bActivateLastSelection = true;
+ Reference< frame::XFrame > xFrame;
+ xDlg = std::make_unique<OfaTreeOptionsDialog>(pParent, xFrame, bActivateLastSelection);
+ if (nResId == SID_OPTIONS_DATABASES)
+ {
+ xDlg->ActivatePage(SID_SB_DBREGISTEROPTIONS);
+ }
+ else if (nResId == SID_LANGUAGE_OPTIONS)
+ {
+ //open the tab page "tools/options/languages"
+ xDlg->ActivatePage(OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (xDlg)
+ return VclPtr<CuiAbstractController_Impl>::Create(std::move(xDlg));
+ return nullptr;
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateFrameDialog(weld::Window* pParent, const Reference< frame::XFrame >& rxFrame,
+ sal_uInt32 nResId, const OUString& rParameter )
+{
+ std::unique_ptr<OfaTreeOptionsDialog> xDlg;
+ if (SID_OPTIONS_TREEDIALOG == nResId || SID_OPTIONS_DATABASES == nResId)
+ {
+ // only activate last page if we don't want to activate a special page
+ bool bActivateLastSelection = ( nResId != SID_OPTIONS_DATABASES && rParameter.isEmpty() );
+ xDlg = std::make_unique<OfaTreeOptionsDialog>(pParent, rxFrame, bActivateLastSelection);
+ if ( nResId == SID_OPTIONS_DATABASES )
+ xDlg->ActivatePage(SID_SB_DBREGISTEROPTIONS);
+ else if ( !rParameter.isEmpty() )
+ xDlg->ActivatePage( rParameter );
+ }
+
+ if (xDlg)
+ return VclPtr<CuiAbstractController_Impl>::Create(std::move(xDlg));
+ return nullptr;
+}
+
+// TabDialog outside the drawing layer
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateAutoCorrTabDialog(weld::Window* pParent, const SfxItemSet* pAttrSet)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<OfaAutoCorrDlg>(pParent, pAttrSet));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateCustomizeTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ const Reference< frame::XFrame >& xViewFrame )
+{
+ auto xDlg1 = std::make_shared<SvxConfigDialog>(pParent, pAttrSet);
+ xDlg1->SetFrame(xViewFrame);
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::move(xDlg1));
+}
+
+// TabDialog that use functionality of the drawing layer
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateTextTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ SdrView* pView)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxTextTabDialog>(pParent, pAttrSet, pView));
+}
+
+// TabDialog that use functionality of the drawing layer and add AnchorTypes -- for SvxCaptionTabDialog
+VclPtr<AbstractSvxCaptionDialog> AbstractDialogFactory_Impl::CreateCaptionDialog(weld::Window* pParent,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes)
+{
+ return VclPtr<AbstractSvxCaptionDialog_Impl>::Create(std::make_shared<SvxCaptionTabDialog>(pParent, pView, nAnchorTypes));
+}
+
+VclPtr<AbstractHangulHanjaConversionDialog> AbstractDialogFactory_Impl::CreateHangulHanjaConversionDialog(weld::Widget* pParent)
+{
+ return VclPtr<AbstractHangulHanjaConversionDialog_Impl>::Create(std::make_unique<HangulHanjaConversionDialog>(pParent));
+}
+
+VclPtr<AbstractThesaurusDialog> AbstractDialogFactory_Impl::CreateThesaurusDialog(weld::Widget* pParent,
+ css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
+ const OUString &rWord, LanguageType nLanguage)
+{
+ return VclPtr<AbstractThesaurusDialog_Impl>::Create(std::make_shared<SvxThesaurusDialog>(pParent, xThesaurus, rWord, nLanguage));
+}
+
+VclPtr<AbstractHyphenWordDialog> AbstractDialogFactory_Impl::CreateHyphenWordDialog(weld::Widget* pParent,
+ const OUString &rWord, LanguageType nLang,
+ css::uno::Reference< css::linguistic2::XHyphenator > &xHyphen,
+ SvxSpellWrapper* pWrapper)
+{
+#if !ENABLE_WASM_STRIP_EXTRA
+ return VclPtr<AbstractHyphenWordDialog_Impl>::Create(std::make_unique<SvxHyphenWordDialog>(rWord, nLang, pParent, xHyphen, pWrapper));
+#else
+ (void) pParent;
+ (void) rWord;
+ (void) nLang;
+ (void) xHyphen;
+ (void) pWrapper;
+ return nullptr;
+#endif
+}
+
+VclPtr<AbstractFmShowColsDialog> AbstractDialogFactory_Impl::CreateFmShowColsDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractFmShowColsDialog_Impl>::Create(std::make_unique<FmShowColsDialog>(pParent));
+}
+
+VclPtr<AbstractSvxZoomDialog> AbstractDialogFactory_Impl::CreateSvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet)
+{
+ return VclPtr<AbstractSvxZoomDialog_Impl>::Create(std::make_unique<SvxZoomDialog>(pParent, rCoreSet));
+}
+
+VclPtr<AbstractSpellDialog> AbstractDialogFactory_Impl::CreateSvxSpellDialog(
+ weld::Window* pParent,
+ SfxBindings* pBindings,
+ svx::SpellDialogChildWindow* pSpellChildWindow)
+{
+ return VclPtr<AbstractSpellDialog_Impl>::Create(std::make_shared<svx::SpellDialog>(pSpellChildWindow, pParent, pBindings));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateActualizeProgressDialog(weld::Widget* pParent,
+ GalleryTheme* pThm)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<ActualizeProgress>(pParent, pThm));
+}
+
+void AbstractDialogFactory_Impl::ShowAsyncScriptErrorDialog(weld::Window* pParent, const css::uno::Any& rException)
+{
+ return SvxScriptErrorDialog::ShowAsyncErrorDialog(pParent, rException);
+}
+
+VclPtr<AbstractScriptSelectorDialog> AbstractDialogFactory_Impl::CreateScriptSelectorDialog(weld::Window* pParent,
+ const Reference<frame::XFrame>& rxFrame)
+{
+ return VclPtr<AbstractScriptSelectorDialog_Impl>::Create(std::make_shared<SvxScriptSelectorDialog>(pParent, rxFrame));
+}
+
+OUString AbstractScriptSelectorDialog_Impl::GetScriptURL() const
+{
+ return m_xDlg->GetScriptURL();
+}
+
+void AbstractScriptSelectorDialog_Impl::SetRunLabel()
+{
+ m_xDlg->SetRunLabel();
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxScriptOrgDialog(weld::Window* pParent,
+ const OUString& rLanguage)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<SvxScriptOrgDialog>(pParent, rLanguage));
+}
+
+VclPtr<AbstractTitleDialog> AbstractDialogFactory_Impl::CreateTitleDialog(weld::Widget* pParent,
+ const OUString& rOldText)
+{
+ return VclPtr<AbstractTitleDialog_Impl>::Create(std::make_unique<TitleDialog>(pParent, rOldText));
+}
+
+VclPtr<AbstractGalleryIdDialog> AbstractDialogFactory_Impl::CreateGalleryIdDialog(weld::Widget* pParent,
+ GalleryTheme* pThm)
+{
+ return VclPtr<AbstractGalleryIdDialog_Impl>::Create(std::make_unique<GalleryIdDialog>(pParent, pThm));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateGalleryThemePropertiesDialog(weld::Widget* pParent,
+ ExchangeData* pData,
+ SfxItemSet* pItemSet)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<GalleryThemeProperties>(
+ pParent, pData, pItemSet));
+}
+
+VclPtr<AbstractURLDlg> AbstractDialogFactory_Impl::CreateURLDialog(weld::Widget* pParent,
+ const OUString& rURL, const OUString& rAltText, const OUString& rDescription,
+ const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList )
+{
+ return VclPtr<AbstractURLDlg_Impl>::Create(std::make_unique<URLDlg>(pParent, rURL, rAltText, rDescription,
+ rTarget, rName, rTargetList));
+
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateTabItemDialog(weld::Window* pParent,
+ const SfxItemSet& rSet)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxSearchFormatDialog>(
+ pParent, rSet));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxSearchAttributeDialog(weld::Window* pParent,
+ SearchAttrItemList& rLst,
+ const WhichRangesContainer& pWhRanges )
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<SvxSearchAttributeDialog>(pParent, rLst, pWhRanges));
+}
+
+VclPtr<AbstractSvxSearchSimilarityDialog> AbstractDialogFactory_Impl::CreateSvxSearchSimilarityDialog(weld::Window* pParent,
+ bool bRelax,
+ sal_uInt16 nOther,
+ sal_uInt16 nShorter,
+ sal_uInt16 nLonger)
+{
+ return VclPtr<AbstractSvxSearchSimilarityDialog_Impl>::Create(std::make_unique<SvxSearchSimilarityDialog>(pParent, bRelax, nOther, nShorter, nLonger));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxBorderBackgroundDlg(
+ weld::Window* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableDrawingLayerFillStyles)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxBorderBackgroundDlg>(
+ pParent,
+ rCoreSet,
+ /*bEnableSelector*/true,
+ bEnableDrawingLayerFillStyles));
+}
+
+VclPtr<AbstractSvxTransformTabDialog> AbstractDialogFactory_Impl::CreateSvxTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes)
+{
+ return VclPtr<AbstractSvxTransformTabDialog_Impl>::Create(std::make_shared<SvxTransformTabDialog>(pParent, pAttr,pView, nAnchorTypes));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSchTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pSdrView,
+ bool bSizeTabPage)
+{
+ auto pDlg = std::make_shared<SvxTransformTabDialog>(pParent, pAttr, pSdrView,
+ bSizeTabPage ? SvxAnchorIds::NoProtect : SvxAnchorIds::NoProtect|SvxAnchorIds::NoResize);
+ pDlg->RemoveTabPage( "RID_SVXPAGE_ANGLE" );
+ pDlg->RemoveTabPage( "RID_SVXPAGE_SLANT" );
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::move(pDlg));
+}
+
+VclPtr<AbstractSvxJSearchOptionsDialog> AbstractDialogFactory_Impl::CreateSvxJSearchOptionsDialog(weld::Window* pParent,
+ const SfxItemSet& rOptionsSet,
+ TransliterationFlags nInitialFlags)
+{
+ return VclPtr<AbstractSvxJSearchOptionsDialog_Impl>::Create(std::make_unique<SvxJSearchOptionsDialog>(pParent, rOptionsSet, nInitialFlags));
+}
+
+VclPtr<AbstractFmInputRecordNoDialog> AbstractDialogFactory_Impl::CreateFmInputRecordNoDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractFmInputRecordNoDialog_Impl>::Create(std::make_unique<FmInputRecordNoDialog>(pParent));
+}
+
+VclPtr<AbstractSvxNewDictionaryDialog> AbstractDialogFactory_Impl::CreateSvxNewDictionaryDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxNewDictionaryDialog_Impl>::Create(std::make_unique<SvxNewDictionaryDialog>(pParent));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxEditDictionaryDialog(weld::Window* pParent, const OUString& rName)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<SvxEditDictionaryDialog>(pParent, rName));
+}
+
+VclPtr<AbstractSvxNameDialog> AbstractDialogFactory_Impl::CreateSvxNameDialog(weld::Window* pParent,
+ const OUString& rName, const OUString& rDesc)
+{
+ return VclPtr<AbstractSvxNameDialog_Impl>::Create(std::make_unique<SvxNameDialog>(pParent, rName, rDesc));
+}
+
+VclPtr<AbstractSvxObjectNameDialog> AbstractDialogFactory_Impl::CreateSvxObjectNameDialog(weld::Window* pParent, const OUString& rName)
+{
+ return VclPtr<AbstractSvxObjectNameDialog_Impl>::Create(std::make_unique<SvxObjectNameDialog>(pParent, rName));
+}
+
+VclPtr<AbstractSvxObjectTitleDescDialog> AbstractDialogFactory_Impl::CreateSvxObjectTitleDescDialog(weld::Window* pParent, const OUString& rTitle, const OUString& rDescription)
+{
+ return VclPtr<AbstractSvxObjectTitleDescDialog_Impl>::Create(std::make_unique<SvxObjectTitleDescDialog>(pParent, rTitle, rDescription));
+}
+
+VclPtr<AbstractSvxMultiPathDialog> AbstractDialogFactory_Impl::CreateSvxMultiPathDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxMultiPathDialog_Impl>::Create(std::make_unique<SvxMultiPathDialog>(pParent));
+}
+
+VclPtr<AbstractSvxMultiPathDialog> AbstractDialogFactory_Impl::CreateSvxPathSelectDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxPathSelectDialog_Impl>::Create(std::make_unique<SvxPathSelectDialog>(pParent));
+}
+
+VclPtr<AbstractSvxHpLinkDlg> AbstractDialogFactory_Impl::CreateSvxHpLinkDlg(SfxChildWindow* pChild, SfxBindings* pBindings, weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxHpLinkDlg_Impl>::Create(std::make_shared<SvxHpLinkDlg>(pBindings, pChild, pParent));
+}
+
+VclPtr<AbstractFmSearchDialog> AbstractDialogFactory_Impl::CreateFmSearchDialog(weld::Window* pParent,
+ const OUString& strInitialText,
+ const std::vector< OUString >& _rContexts,
+ sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier)
+{
+ return VclPtr<AbstractFmSearchDialog_Impl>::Create(std::make_unique<FmSearchDialog>(pParent,
+ strInitialText, _rContexts, nInitialContext, lnkContextSupplier));
+
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterEmboss(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterEmboss>(pParent, rGraphic, RectPoint::MM));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterPoster(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterPoster>(pParent, rGraphic, 16));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterSepia(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterSepia>(pParent, rGraphic, 10));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterSmooth(weld::Window* pParent,
+ const Graphic& rGraphic, double nRadius)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterSmooth>(pParent, rGraphic, nRadius));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterSolarize(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterSolarize>(pParent, rGraphic, 128, false /*bInvert*/));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterMosaic(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterMosaic>(pParent, rGraphic, 4, 4, false /*bEnhanceEdges*/));
+}
+
+VclPtr<AbstractSvxAreaTabDialog> AbstractDialogFactory_Impl::CreateSvxAreaTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow,
+ bool bSlideBackground)
+{
+ return VclPtr<AbstractSvxAreaTabDialog_Impl>::Create(
+ std::make_shared<SvxAreaTabDialog>(pParent, pAttr, pModel, bShadow, bSlideBackground));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, //add forSvxLineTabDialog
+ SdrModel* pModel,
+ const SdrObject* pObj ,
+ bool bHasObj)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxLineTabDialog>(pParent, pAttr, pModel, pObj,bHasObj));
+}
+
+VclPtr<SfxAbstractDialog> AbstractDialogFactory_Impl::CreateCharMapDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ const Reference< XFrame >& rDocumentFrame)
+{
+ return VclPtr<AbstractSvxCharacterMapDialog_Impl>::Create(std::make_unique<SvxCharacterMap>(pParent, &rAttr, rDocumentFrame));
+}
+
+VclPtr<SfxAbstractDialog> AbstractDialogFactory_Impl::CreateEventConfigDialog(weld::Widget* pParent,
+ const SfxItemSet& rAttr,
+ const Reference< XFrame >& rDocumentFrame)
+{
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<SfxMacroAssignDlg>(pParent, rDocumentFrame, rAttr));
+}
+
+VclPtr<SfxAbstractDialog> AbstractDialogFactory_Impl::CreateSfxDialog(weld::Window* pParent,
+ const SfxItemSet& rAttr,
+ const SdrView* pView,
+ sal_uInt32 nResId)
+{
+ switch ( nResId )
+ {
+ case RID_SVXPAGE_MEASURE:
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<SvxMeasureDialog>(pParent, rAttr, pView));
+ case RID_SVXPAGE_CONNECTION:
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<SvxConnectionDialog>(pParent, rAttr, pView));
+ case RID_SFXPAGE_DBREGISTER:
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<DatabaseRegistrationDialog>(pParent, rAttr));
+ }
+
+ return nullptr;
+}
+
+VclPtr<AbstractSvxPostItDialog> AbstractDialogFactory_Impl::CreateSvxPostItDialog(weld::Widget* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bPrevNext)
+{
+ return VclPtr<AbstractSvxPostItDialog_Impl>::Create(std::make_unique<SvxPostItDialog>(pParent, rCoreSet, bPrevNext));
+}
+
+namespace {
+
+class SvxMacroAssignDialog_Impl : public VclAbstractDialog
+{
+public:
+ SvxMacroAssignDialog_Impl( weld::Window* _pParent, const Reference< XFrame >& _rxDocumentFrame, const bool _bUnoDialogMode,
+ const Reference< XNameReplace >& _rxEvents, const sal_uInt16 _nInitiallySelectedEvent )
+ :m_aItems( SfxGetpApp()->GetPool(), svl::Items<SID_ATTR_MACROITEM, SID_ATTR_MACROITEM> )
+ {
+ m_aItems.Put( SfxBoolItem( SID_ATTR_MACROITEM, _bUnoDialogMode ) );
+ m_xDlg.reset(new SvxMacroAssignDlg(_pParent, _rxDocumentFrame, m_aItems, _rxEvents, _nInitiallySelectedEvent));
+ }
+
+ virtual short Execute() override;
+
+private:
+ SfxItemSet m_aItems;
+ std::unique_ptr<SvxMacroAssignDlg> m_xDlg;
+};
+
+IMPL_ABSTDLG_CLASS(SvxMacroAssignDialog)
+}
+
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxMacroAssignDlg(
+ weld::Window* _pParent, const Reference< XFrame >& _rxDocumentFrame, const bool _bUnoDialogMode,
+ const Reference< XNameReplace >& _rxEvents, const sal_uInt16 _nInitiallySelectedEvent )
+{
+ return VclPtr<SvxMacroAssignDialog_Impl>::Create(_pParent, _rxDocumentFrame, _bUnoDialogMode, _rxEvents, _nInitiallySelectedEvent);
+}
+
+// Factories for TabPages
+CreateTabPage AbstractDialogFactory_Impl::GetTabPageCreatorFunc( sal_uInt16 nId )
+{
+ switch ( nId )
+ {
+ case RID_SW_TP_BACKGROUND :
+ case RID_SVXPAGE_BKG :
+ return SvxBkgTabPage::Create;
+ case RID_SVXPAGE_TEXTANIMATION :
+ return SvxTextAnimationPage::Create;
+ case RID_SVXPAGE_TRANSPARENCE :
+ return SvxTransparenceTabPage::Create;
+ case RID_SVXPAGE_AREA :
+ return SvxAreaTabPage::Create;
+ case RID_SVXPAGE_SHADOW :
+ return SvxShadowTabPage::Create;
+ case RID_SVXPAGE_LINE :
+ return SvxLineTabPage::Create;
+ case RID_SVXPAGE_CONNECTION :
+ return SvxConnectionPage::Create;
+ case RID_SVXPAGE_MEASURE :
+ return SvxMeasurePage::Create;
+ case RID_SFXPAGE_GENERAL :
+ return SvxGeneralTabPage::Create;
+ case RID_SVXPAGE_PICK_SINGLE_NUM :
+ return SvxSingleNumPickTabPage::Create;
+ case RID_SVXPAGE_PICK_BMP :
+ return SvxBitmapPickTabPage::Create;
+ case RID_SVXPAGE_PICK_BULLET :
+ return SvxBulletPickTabPage::Create;
+ case RID_SVXPAGE_NUM_OPTIONS :
+ return SvxNumOptionsTabPage::Create;
+ case RID_SVXPAGE_PICK_NUM :
+ return SvxNumPickTabPage::Create;
+ case RID_SVXPAGE_NUM_POSITION :
+ return SvxNumPositionTabPage::Create;
+ case RID_SVXPAGE_PARA_ASIAN :
+ return SvxAsianTabPage::Create;
+ case RID_SVXPAGE_EXT_PARAGRAPH :
+ return SvxExtParagraphTabPage::Create;
+ case RID_SVXPAGE_ALIGN_PARAGRAPH :
+ return SvxParaAlignTabPage::Create;
+ case RID_SVXPAGE_STD_PARAGRAPH :
+ return SvxStdParagraphTabPage::Create;
+ case RID_SVXPAGE_TABULATOR :
+ return SvxTabulatorTabPage::Create;
+ case RID_SVXPAGE_TEXTATTR :
+ return SvxTextAttrPage::Create;
+ case RID_SVXPAGE_ALIGNMENT :
+ return svx::AlignmentTabPage::Create;
+ case RID_SVXPAGE_BORDER :
+ return SvxBorderTabPage::Create;
+ case RID_SVXPAGE_CHAR_NAME :
+ return SvxCharNamePage::Create;
+ case RID_SVXPAGE_CHAR_EFFECTS :
+ return SvxCharEffectsPage::Create;
+ case RID_SVXPAGE_CHAR_POSITION :
+ return SvxCharPositionPage::Create;
+ case RID_SVXPAGE_CHAR_TWOLINES :
+ return SvxCharTwoLinesPage::Create;
+ case RID_SVXPAGE_NUMBERFORMAT :
+ return SvxNumberFormatTabPage::Create;
+ case RID_SVXPAGE_PAGE :
+ return SvxPageDescPage::Create;
+ case RID_SVXPAGE_GRFCROP :
+ return SvxGrfCropPage::Create;
+ case RID_SVXPAGE_MACROASSIGN :
+ return SfxMacroTabPage::Create;
+ case RID_SVXPAGE_TEXTCOLUMNS:
+ return SvxTextColumnsPage::Create;
+ case RID_SVXPAGE_THEME:
+ return SvxThemePage::Create;
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+DialogGetRanges AbstractDialogFactory_Impl::GetDialogGetRangesFunc()
+{
+ return SvxPostItDialog::GetRanges;
+}
+
+GetTabPageRanges AbstractDialogFactory_Impl::GetTabPageRangesFunc( sal_uInt16 nId )
+{
+ switch ( nId )
+ {
+ case RID_SVXPAGE_TEXTANIMATION :
+ return SvxTextAnimationPage::GetRanges;
+ case RID_SVXPAGE_TRANSPARENCE :
+ return SvxTransparenceTabPage::GetRanges;
+ case RID_SVXPAGE_AREA :
+ return SvxAreaTabPage::GetRanges;
+ case RID_SVXPAGE_SHADOW :
+ return SvxShadowTabPage::GetRanges;
+ case RID_SVXPAGE_LINE :
+ return SvxLineTabPage::GetRanges;
+ case RID_SVXPAGE_CONNECTION :
+ return SvxConnectionPage::GetRanges;
+ case RID_SVXPAGE_MEASURE :
+ return SvxMeasurePage::GetRanges;
+ case RID_SVXPAGE_PARA_ASIAN :
+ return SvxAsianTabPage::GetRanges;
+ case RID_SVXPAGE_EXT_PARAGRAPH :
+ return SvxExtParagraphTabPage::GetRanges;
+ case RID_SVXPAGE_ALIGN_PARAGRAPH :
+ return SvxParaAlignTabPage::GetRanges;
+ case RID_SVXPAGE_STD_PARAGRAPH :
+ return SvxStdParagraphTabPage::GetRanges;
+ case RID_SVXPAGE_TABULATOR :
+ return SvxTabulatorTabPage::GetRanges;
+ case RID_SVXPAGE_TEXTATTR :
+ return SvxTextAttrPage::GetRanges;
+ case RID_SVXPAGE_ALIGNMENT :
+ return svx::AlignmentTabPage::GetRanges;
+ case RID_SW_TP_BACKGROUND :
+ case RID_SVXPAGE_BKG:
+ return SvxBkgTabPage::GetRanges;
+ case RID_SVXPAGE_BORDER :
+ return SvxBorderTabPage::GetRanges;
+ case RID_SVXPAGE_CHAR_NAME :
+ return SvxCharNamePage::GetRanges;
+ case RID_SVXPAGE_CHAR_EFFECTS :
+ return SvxCharEffectsPage::GetRanges;
+ case RID_SVXPAGE_CHAR_POSITION :
+ return SvxCharPositionPage::GetRanges;
+ case RID_SVXPAGE_CHAR_TWOLINES :
+ return SvxCharTwoLinesPage::GetRanges;
+ case RID_SVXPAGE_NUMBERFORMAT :
+ return SvxNumberFormatTabPage::GetRanges;
+ case RID_SVXPAGE_PAGE :
+ return SvxPageDescPage::GetRanges;
+ case RID_SVXPAGE_ASIAN_LAYOUT:
+ return SvxAsianLayoutPage::GetRanges;
+ case RID_SVXPAGE_TEXTCOLUMNS:
+ return SvxTextColumnsPage::GetRanges;
+ case RID_SVXPAGE_THEME:
+ return SvxThemePage::GetRanges;
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+VclPtr<SfxAbstractInsertObjectDialog> AbstractDialogFactory_Impl::CreateInsertObjectDialog(weld::Window* pParent, const OUString& rCommand,
+ const Reference <css::embed::XStorage>& xStor, const SvObjectServerList* pList)
+{
+ std::unique_ptr<InsertObjectDialog_Impl> pDlg;
+ if ( rCommand == ".uno:InsertObject" )
+ pDlg.reset(new SvInsertOleDlg(pParent, xStor, pList));
+ else if ( rCommand == ".uno:InsertObjectFloatingFrame" )
+ pDlg.reset(new SfxInsertFloatingFrameDialog(pParent, xStor));
+
+ if ( pDlg )
+ {
+ pDlg->SetHelpId( OUStringToOString( rCommand, RTL_TEXTENCODING_UTF8 ) );
+ return VclPtr<AbstractInsertObjectDialog_Impl>::Create( std::move(pDlg) );
+ }
+ return nullptr;
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateEditObjectDialog(weld::Window* pParent, const OUString& rCommand,
+ const Reference<css::embed::XEmbeddedObject>& xObj)
+{
+ if ( rCommand == ".uno:InsertObjectFloatingFrame" )
+ {
+ auto pDlg = std::make_unique<SfxInsertFloatingFrameDialog>(pParent, xObj);
+ pDlg->SetHelpId( OUStringToOString( rCommand, RTL_TEXTENCODING_UTF8 ) );
+ return VclPtr<AbstractInsertObjectDialog_Impl>::Create( std::move(pDlg) );
+ }
+ return nullptr;
+}
+
+VclPtr<SfxAbstractPasteDialog> AbstractDialogFactory_Impl::CreatePasteDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractPasteDialog_Impl>::Create(std::make_shared<SvPasteObjectDialog>(pParent));
+}
+
+VclPtr<SfxAbstractLinksDialog> AbstractDialogFactory_Impl::CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML, sfx2::SvBaseLink* p)
+{
+ auto xLinkDlg(std::make_unique<SvBaseLinksDlg>(pParent, pMgr, bHTML));
+ if (p)
+ xLinkDlg->SetActLink(p);
+ return VclPtr<AbstractLinksDialog_Impl>::Create(std::move(xLinkDlg));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxFormatCellsDialog>(pParent, pAttr, rModel));
+}
+
+VclPtr<SvxAbstractSplitTableDialog> AbstractDialogFactory_Impl::CreateSvxSplitTableDialog(weld::Window* pParent, bool bIsTableVertical, tools::Long nMaxVertical)
+{
+ return VclPtr<SvxAbstractSplitTableDialog_Impl>::Create( std::make_shared<SvxSplitTableDlg>(pParent, bIsTableVertical, nMaxVertical, 99 ));
+}
+
+std::shared_ptr<SvxAbstractNewTableDialog> AbstractDialogFactory_Impl::CreateSvxNewTableDialog(weld::Window* pParent)
+{
+ return std::make_shared<SvxNewTableDialogWrapper>(pParent);
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateOptionsDialog(weld::Window* pParent, const OUString& rExtensionId)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<OfaTreeOptionsDialog>(pParent, rExtensionId));
+}
+
+VclPtr<SvxAbstractInsRowColDlg> AbstractDialogFactory_Impl::CreateSvxInsRowColDlg(weld::Window* pParent, bool bCol, const OString& rHelpId)
+{
+ return VclPtr<SvxInsRowColDlg>::Create(pParent, bCol, rHelpId);
+}
+
+VclPtr<AbstractPasswordToOpenModifyDialog> AbstractDialogFactory_Impl::CreatePasswordToOpenModifyDialog(
+ weld::Window * pParent, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify)
+{
+ return VclPtr<AbstractPasswordToOpenModifyDialog_Impl>::Create(std::make_unique<PasswordToOpenModifyDialog>(pParent, nMaxPasswdLen, bIsPasswordToModify));
+}
+
+VclPtr<AbstractScreenshotAnnotationDlg> AbstractDialogFactory_Impl::CreateScreenshotAnnotationDlg(weld::Dialog& rParentDialog)
+{
+ return VclPtr<AbstractScreenshotAnnotationDlg_Impl>::Create(std::make_unique<ScreenshotAnnotationDlg>(rParentDialog));
+}
+
+VclPtr<AbstractSignatureLineDialog> AbstractDialogFactory_Impl::CreateSignatureLineDialog(
+ weld::Window* pParent, const Reference<XModel> xModel, bool bEditExisting)
+{
+ return VclPtr<AbstractSignatureLineDialog_Impl>::Create(
+ std::make_unique<SignatureLineDialog>(pParent, xModel, bEditExisting));
+}
+
+VclPtr<AbstractSignSignatureLineDialog>
+AbstractDialogFactory_Impl::CreateSignSignatureLineDialog(weld::Window* pParent,
+ const Reference<XModel> xModel)
+{
+ return VclPtr<AbstractSignSignatureLineDialog_Impl>::Create(
+ std::make_unique<SignSignatureLineDialog>(pParent, xModel));
+}
+
+VclPtr<AbstractQrCodeGenDialog> AbstractDialogFactory_Impl::CreateQrCodeGenDialog(
+ weld::Window* pParent, const Reference<XModel> xModel, bool bEditExisting)
+{
+ return VclPtr<AbstractQrCodeGenDialog_Impl>::Create(
+ std::make_unique<QrCodeGenDialog>(pParent, xModel, bEditExisting));
+}
+
+VclPtr<AbstractAdditionsDialog> AbstractDialogFactory_Impl::CreateAdditionsDialog(
+ weld::Window* pParent, const OUString& sAdditionsTag)
+{
+#if HAVE_FEATURE_EXTENSIONS
+ return VclPtr<AbstractAdditionsDialog_Impl>::Create(
+ std::make_unique<AdditionsDialog>(pParent, sAdditionsTag));
+#else
+ (void) pParent;
+ (void) sAdditionsTag;
+ return nullptr;
+#endif
+}
+
+VclPtr<VclAbstractDialog>
+AbstractDialogFactory_Impl::CreateAboutDialog(weld::Window* pParent)
+{
+ return VclPtr<CuiAbstractControllerAsync_Impl>::Create(
+ std::make_shared<AboutDialog>(pParent));
+}
+
+VclPtr<VclAbstractDialog>
+AbstractDialogFactory_Impl::CreateTipOfTheDayDialog(weld::Window* pParent)
+{
+#if !ENABLE_WASM_STRIP_PINGUSER
+ return VclPtr<CuiAbstractControllerAsync_Impl>::Create(
+ std::make_shared<TipOfTheDayDialog>(pParent));
+#else
+ (void) pParent;
+ return nullptr;
+#endif
+}
+
+VclPtr<VclAbstractDialog>
+AbstractDialogFactory_Impl::CreateToolbarmodeDialog(weld::Window* pParent)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(
+ std::make_unique<ToolbarmodeDialog>(pParent));
+}
+
+VclPtr<AbstractDiagramDialog>
+AbstractDialogFactory_Impl::CreateDiagramDialog(
+ weld::Window* pParent,
+ SdrObjGroup& rDiagram)
+{
+ return VclPtr<AbstractDiagramDialog_Impl>::Create(
+ std::make_unique<DiagramDialog>(pParent, rDiagram));
+}
+
+#ifdef _WIN32
+VclPtr<VclAbstractDialog>
+AbstractDialogFactory_Impl::CreateFileExtCheckDialog(weld::Window* pParent, const OUString& sTitle,
+ const OUString& sMsg)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(
+ std::make_unique<FileExtCheckDialog>(pParent, sTitle, sMsg));
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
new file mode 100644
index 000000000..079af32b4
--- /dev/null
+++ b/cui/source/factory/dlgfact.hxx
@@ -0,0 +1,621 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svx/svxdlg.hxx>
+#include <svx/zoom_def.hxx>
+#include <com/sun/star/container/XNameReplace.hpp>
+
+#include <tools/link.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <cfgutil.hxx>
+#include <cui/cuicharmap.hxx>
+#include <cuifmsearch.hxx>
+#include <cuigaldlg.hxx>
+#include <cuigrfflt.hxx>
+#include <cuihyperdlg.hxx>
+#include <cuiimapwnd.hxx>
+#include <cuisrchdlg.hxx>
+#include <cuitabarea.hxx>
+#include <cuitbxform.hxx>
+#include <dlgname.hxx>
+#include <DiagramDialog.hxx>
+#include <hangulhanjadlg.hxx>
+#include <hyphen.hxx>
+#include <insdlg.hxx>
+#include <labdlg.hxx>
+#include <linkdlg.hxx>
+#include <multipat.hxx>
+#include <optdict.hxx>
+#include <passwdomdlg.hxx>
+#include <pastedlg.hxx>
+#include <postdlg.hxx>
+#include <QrCodeGenDialog.hxx>
+#include <screenshotannotationdlg.hxx>
+#include <showcols.hxx>
+#include <SignatureLineDialog.hxx>
+#include <SignSignatureLineDialog.hxx>
+#include <SpellDialog.hxx>
+#include <srchxtra.hxx>
+#include <thesdlg.hxx>
+#include <transfrm.hxx>
+#include <zoom.hxx>
+#include <AdditionsDialog.hxx>
+
+#define DECL_ABSTDLG_CLASS_(Class,Base,Dialog,StdPtr) \
+class Class##_Impl final : public Base \
+{ \
+ StdPtr<Dialog> m_xDlg; \
+public: \
+ explicit Class##_Impl(StdPtr<Dialog> p) : m_xDlg(std::move(p)) {} \
+ virtual short Execute() override;
+
+#define DECL_ABSTDLG_CLASS_UNIQUE(Class,Base,Dialog) \
+DECL_ABSTDLG_CLASS_(Class,Base,Dialog,std::unique_ptr)
+
+#define DECL_ABSTDLG_CLASS_SHARED(Class,Base,Dialog) \
+DECL_ABSTDLG_CLASS_(Class,Base,Dialog,std::shared_ptr)
+
+#define IMPL_ABSTDLG_CLASS(Class) \
+short Class##_Impl::Execute() \
+{ \
+ return m_xDlg->run(); \
+}
+
+#define DECL_ABSTDLG_CLASS(Class,Dialog) \
+DECL_ABSTDLG_CLASS_UNIQUE(Class,Class,Dialog)
+
+// Async AKA std::shared_ptr
+
+#define DECL_ABSTDLG_CLASS_SHARED_ASYNC(Class,Base,Dialog) \
+DECL_ABSTDLG_CLASS_SHARED(Class,Base,Dialog) \
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+
+#define DECL_ABSTDLG_CLASS_ASYNC(Class,Dialog) \
+DECL_ABSTDLG_CLASS_SHARED_ASYNC(Class,Class,Dialog)
+
+#define IMPL_ABSTDLG_CLASS_ASYNC(Class,Dialog) \
+short Class##_Impl::Execute() \
+{ \
+ return m_xDlg->run(); \
+} \
+bool Class##_Impl::StartExecuteAsync(AsyncContext &rCtx) \
+{ \
+ return Dialog::runAsync(m_xDlg, rCtx.maEndDialogFn); \
+}
+
+// CuiAbstractController_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(CuiAbstractController, VclAbstractDialog, weld::DialogController)
+};
+
+// CuiAbstractControllerAsync_Impl
+DECL_ABSTDLG_CLASS_SHARED_ASYNC(CuiAbstractControllerAsync, VclAbstractDialog, weld::DialogController)
+};
+
+// CuiAbstractSingleTabController_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(CuiAbstractSingleTabController, SfxAbstractDialog, SfxSingleTabDialogController)
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ //From class Window.
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+// CuiAbstractTabController_Impl
+DECL_ABSTDLG_CLASS_SHARED_ASYNC(CuiAbstractTabController, SfxAbstractTabDialog, SfxTabDialogController)
+ virtual void SetCurPageId( const OString &rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ virtual void SetText( const OUString& rStr ) override;
+
+ // screenshotting
+ virtual std::vector<OString> getAllPageUIXMLDescriptions() const override;
+ virtual bool selectPageByUIXMLDescription(const OString& rUIXMLDescription) override;
+ virtual BitmapEx createScreenshot() const override;
+ virtual OString GetScreenshotId() const override;
+};
+
+// AbstractHangulHanjaConversionDialog_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(AbstractHangulHanjaConversionDialog,AbstractHangulHanjaConversionDialog,svx::HangulHanjaConversionDialog)
+ virtual void EndDialog(sal_Int32 nResult) override;
+ virtual void EnableRubySupport( bool _bVal ) override;
+ virtual void SetByCharacter( bool _bByCharacter ) override ;
+ virtual void SetConversionDirectionState( bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection ) override;
+ virtual void SetConversionFormat( editeng::HangulHanjaConversion::ConversionFormat _eType ) override;
+ virtual void SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl ) override;
+ virtual void SetIgnoreHdl( const Link<weld::Button&,void>& _rHdl ) override;
+ virtual void SetIgnoreAllHdl( const Link<weld::Button&,void>& _rHdl ) override ;
+ virtual void SetChangeHdl( const Link<weld::Button&,void>& _rHdl ) override ;
+ virtual void SetChangeAllHdl( const Link<weld::Button&,void>& rHdl ) override ;
+ virtual void SetClickByCharacterHdl( const Link<weld::Toggleable&,void>& rHdl ) override ;
+ virtual void SetConversionFormatChangedHdl( const Link<weld::Toggleable&,void>& _rHdl ) override ;
+ virtual void SetFindHdl( const Link<weld::Button&,void>& _rHdl ) override;
+ virtual bool GetUseBothDirections( ) const override;
+ virtual editeng::HangulHanjaConversion::ConversionDirection
+ GetDirection( editeng::HangulHanjaConversion::ConversionDirection _eDefaultDirection ) const override;
+ virtual void SetCurrentString(
+ const OUString& _rNewString,
+ const css::uno::Sequence< OUString >& _rSuggestions,
+ bool _bOriginatesFromDocument = true
+ ) override;
+ virtual OUString GetCurrentString( ) const override ;
+ virtual editeng::HangulHanjaConversion::ConversionFormat
+ GetConversionFormat( ) const override ;
+ virtual void FocusSuggestion( ) override;
+ virtual OUString GetCurrentSuggestion( ) const override;
+};
+
+// AbstractThesaurusDialog_Impl
+DECL_ABSTDLG_CLASS_ASYNC(AbstractThesaurusDialog,SvxThesaurusDialog)
+ virtual OUString GetWord() override;
+};
+
+// AbstractHyphenWordDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractHyphenWordDialog,SvxHyphenWordDialog)
+};
+
+// AbstractFmShowColsDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractFmShowColsDialog,FmShowColsDialog)
+ virtual void SetColumns(const css::uno::Reference< css::container::XIndexContainer>& xCols) override;
+};
+
+// AbstractSvxZoomDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxZoomDialog,SvxZoomDialog)
+ virtual void SetLimits( sal_uInt16 nMin, sal_uInt16 nMax ) override;
+ virtual void HideButton( ZoomButtonId nBtnId ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override ;
+};
+
+// AbstractSpellDialog_Impl
+DECL_ABSTDLG_CLASS_SHARED_ASYNC(AbstractSpellDialog, AbstractSpellDialog, svx::SpellDialog)
+ virtual void InvalidateDialog() override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+ virtual SfxBindings& GetBindings() override;
+};
+
+// AbstractTitleDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractTitleDialog,TitleDialog)
+ virtual OUString GetTitle() const override ;
+
+};
+
+// AbstractScriptSelectorDialog_Impl
+DECL_ABSTDLG_CLASS_ASYNC(AbstractScriptSelectorDialog,SvxScriptSelectorDialog)
+ virtual OUString GetScriptURL() const override;
+ virtual void SetRunLabel() override;
+};
+
+// AbstractGalleryIdDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractGalleryIdDialog,GalleryIdDialog)
+ virtual sal_uInt32 GetId() const override;
+};
+
+// AbstractURLDlg_Impl
+DECL_ABSTDLG_CLASS(AbstractURLDlg, URLDlg)
+ virtual OUString GetURL() const override;
+ virtual OUString GetAltText() const override;
+ virtual OUString GetDesc() const override;
+ virtual OUString GetTarget() const override;
+ virtual OUString GetName() const override;
+};
+
+// AbstractSvxSearchSimilarityDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxSearchSimilarityDialog,SvxSearchSimilarityDialog)
+ virtual sal_uInt16 GetOther() override;
+ virtual sal_uInt16 GetShorter() override;
+ virtual sal_uInt16 GetLonger() override;
+ virtual bool IsRelaxed() override;
+};
+
+// AbstractSvxJSearchOptionsDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxJSearchOptionsDialog,SvxJSearchOptionsDialog)
+ virtual TransliterationFlags GetTransliterationFlags() const override;
+};
+
+// AbstractSvxTransformTabDialog_Impl
+DECL_ABSTDLG_CLASS_ASYNC(AbstractSvxTransformTabDialog,SvxTransformTabDialog)
+ virtual void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink ) override;
+ virtual void SetCurPageId( const OString& rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+// AbstractSvxCaptionDialog_Impl
+DECL_ABSTDLG_CLASS_ASYNC(AbstractSvxCaptionDialog,SvxCaptionTabDialog)
+ virtual void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink ) override;
+ virtual void SetCurPageId( const OString& rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+// AbstractFmInputRecordNoDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractFmInputRecordNoDialog,FmInputRecordNoDialog)
+ virtual void SetValue(tools::Long nNew) override ;
+ virtual tools::Long GetValue() const override ;
+};
+
+// AbstractSvxNewDictionaryDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxNewDictionaryDialog,SvxNewDictionaryDialog)
+ virtual css::uno::Reference< css::linguistic2::XDictionary > GetNewDictionary() override;
+};
+
+// AbstractSvxNameDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxNameDialog,SvxNameDialog)
+ virtual void GetName( OUString& rName ) override ;
+ virtual void SetCheckNameHdl( const Link<AbstractSvxNameDialog&,bool>& rLink, bool bCheckImmediately = false ) override ;
+ virtual void SetCheckNameTooltipHdl( const Link<AbstractSvxNameDialog&, OUString>& rLink ) override ;
+ virtual void SetEditHelpId(const OString&) override ;
+ //from class Window
+ virtual void SetHelpId( const OString& ) override ;
+ virtual void SetText( const OUString& rStr ) override ;
+
+private:
+ Link<AbstractSvxNameDialog&,bool> aCheckNameHdl;
+ Link<AbstractSvxNameDialog&,OUString> aCheckNameTooltipHdl;
+ DECL_LINK(CheckNameHdl, SvxNameDialog&, bool);
+ DECL_LINK(CheckNameTooltipHdl, SvxNameDialog&, OUString);
+};
+
+class SvxObjectNameDialog;
+class SvxObjectTitleDescDialog;
+
+// AbstractSvxObjectNameDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxObjectNameDialog,SvxObjectNameDialog)
+ virtual void GetName(OUString& rName) override ;
+ virtual void SetCheckNameHdl(const Link<AbstractSvxObjectNameDialog&,bool>& rLink) override;
+
+private:
+ Link<AbstractSvxObjectNameDialog&,bool> aCheckNameHdl;
+ DECL_LINK(CheckNameHdl, SvxObjectNameDialog&, bool);
+};
+
+// AbstractSvxObjectTitleDescDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxObjectTitleDescDialog,SvxObjectTitleDescDialog)
+ virtual void GetTitle(OUString& rName) override;
+ virtual void GetDescription(OUString& rName) override;
+};
+
+// AbstractSvxMultiPathDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxMultiPathDialog,SvxMultiPathDialog)
+ virtual OUString GetPath() const override;
+ virtual void SetPath( const OUString& rPath ) override;
+ virtual void SetTitle( const OUString& rNewTitle ) override;
+};
+
+// AbstractSvxPathSelectDialog_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(AbstractSvxPathSelectDialog,AbstractSvxMultiPathDialog,SvxPathSelectDialog)
+ virtual OUString GetPath() const override;
+ virtual void SetPath( const OUString& rPath ) override;
+ virtual void SetTitle( const OUString& rNewTitle ) override;
+};
+
+// AbstractSvxHpLinkDlg_Impl
+DECL_ABSTDLG_CLASS_SHARED(AbstractSvxHpLinkDlg,AbstractSvxHpLinkDlg,SvxHpLinkDlg)
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+ virtual bool QueryClose() override;
+};
+
+// AbstractFmSearchDialog_Impl
+struct FmFoundRecordInformation;
+DECL_ABSTDLG_CLASS(AbstractFmSearchDialog,FmSearchDialog)
+ virtual void SetFoundHandler(const Link<FmFoundRecordInformation&,void>& lnk) override ;
+ virtual void SetCanceledNotFoundHdl(const Link<FmFoundRecordInformation&,void>& lnk) override;
+ virtual void SetActiveField(const OUString& strField) override;
+};
+
+// AbstractGraphicFilterDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractGraphicFilterDialog,GraphicFilterDialog)
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+// AbstractSvxAreaTabDialog_Impl
+DECL_ABSTDLG_CLASS_ASYNC(AbstractSvxAreaTabDialog,SvxAreaTabDialog)
+ virtual void SetCurPageId(const OString& rName) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet(const SfxItemSet* pInSet) override;
+ virtual void SetText(const OUString& rStr) override;
+};
+
+// AbstractInsertObjectDialog_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(AbstractInsertObjectDialog,SfxAbstractInsertObjectDialog,InsertObjectDialog_Impl)
+ virtual css::uno::Reference < css::embed::XEmbeddedObject > GetObject() override;
+ virtual css::uno::Reference< css::io::XInputStream > GetIconIfIconified( OUString* pGraphicMediaType ) override;
+ virtual bool IsCreateNew() override;
+};
+
+// AbstractPasteDialog_Impl
+DECL_ABSTDLG_CLASS_SHARED_ASYNC(AbstractPasteDialog,SfxAbstractPasteDialog,SvPasteObjectDialog)
+ virtual void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName ) override;
+ virtual void InsertUno( const OUString & sCmd, const OUString& sLabel ) override;
+ virtual void SetObjName( const SvGlobalName & rClass, const OUString & rObjName ) override;
+ virtual void PreGetFormat( const TransferableDataHelper& aHelper ) override;
+ virtual SotClipboardFormatId GetFormatOnly() override;
+ virtual SotClipboardFormatId GetFormat( const TransferableDataHelper& aHelper ) override;
+};
+
+// AbstractLinksDialog_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(AbstractLinksDialog,SfxAbstractLinksDialog,SvBaseLinksDlg)
+};
+
+// AbstractSvxPostItDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSvxPostItDialog,SvxPostItDialog)
+ virtual void SetText( const OUString& rStr ) override; //From class Window
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual void SetPrevHdl( const Link<AbstractSvxPostItDialog&,void>& rLink ) override;
+ virtual void SetNextHdl( const Link<AbstractSvxPostItDialog&,void>& rLink ) override;
+ virtual void EnableTravel(bool bNext, bool bPrev) override;
+ virtual OUString GetNote() override;
+ virtual void SetNote(const OUString& rTxt) override;
+ virtual void ShowLastAuthor(const OUString& rAuthor, const OUString& rDate) override;
+ virtual void DontChangeAuthor() override;
+ virtual void HideAuthor() override;
+ virtual std::shared_ptr<weld::Dialog> GetDialog() override;
+private:
+ Link<AbstractSvxPostItDialog&,void> aNextHdl;
+ Link<AbstractSvxPostItDialog&,void> aPrevHdl;
+ DECL_LINK(NextHdl, SvxPostItDialog&, void);
+ DECL_LINK(PrevHdl, SvxPostItDialog&, void);
+};
+
+// AbstractPasswordToOpenModifyDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractPasswordToOpenModifyDialog,PasswordToOpenModifyDialog)
+ virtual OUString GetPasswordToOpen() const override;
+ virtual OUString GetPasswordToModify() const override;
+ virtual bool IsRecommendToOpenReadonly() const override;
+};
+
+// AbstractSvxCharacterMapDialog_Impl
+DECL_ABSTDLG_CLASS_UNIQUE(AbstractSvxCharacterMapDialog,SfxAbstractDialog,SvxCharacterMap)
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual void SetText(const OUString& rStr) override;
+};
+
+// AbstractScreenshotAnnotationDlg_Impl
+DECL_ABSTDLG_CLASS(AbstractScreenshotAnnotationDlg,ScreenshotAnnotationDlg)
+};
+
+// AbstractSignatureLineDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSignatureLineDialog,SignatureLineDialog)
+};
+
+// AbstractQrCodeGenDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractQrCodeGenDialog,QrCodeGenDialog)
+};
+
+// AbstractSignSignatureLineDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractSignSignatureLineDialog,SignSignatureLineDialog)
+};
+
+// AbstractAdditionsDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractAdditionsDialog,weld::GenericDialogController)
+};
+
+// AbstractDiagramDialog_Impl
+DECL_ABSTDLG_CLASS(AbstractDiagramDialog,DiagramDialog)
+};
+
+//AbstractDialogFactory_Impl implementations
+class AbstractDialogFactory_Impl : public SvxAbstractDialogFactory
+{
+public:
+ virtual VclPtr<VclAbstractDialog> CreateVclDialog(weld::Window* pParent, sal_uInt32 nResId) override;
+
+ virtual VclPtr<SfxAbstractDialog> CreateSfxDialog( weld::Window* pParent,
+ const SfxItemSet& rAttr,
+ const SdrView* pView,
+ sal_uInt32 nResId ) override;
+ virtual VclPtr<SfxAbstractDialog> CreateCharMapDialog(weld::Window* pParent,
+ const SfxItemSet& rAttr,
+ const css::uno::Reference< css::frame::XFrame >& rFrame) override;
+ virtual VclPtr<SfxAbstractDialog> CreateEventConfigDialog(weld::Widget* pParent,
+ const SfxItemSet& rAttr,
+ const css::uno::Reference< css::frame::XFrame >& rFrame) override;
+ virtual VclPtr<VclAbstractDialog> CreateFrameDialog(weld::Window* pParent, const css::uno::Reference< css::frame::XFrame >& rxFrame,
+ sal_uInt32 nResId,
+ const OUString& rParameter ) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateAutoCorrTabDialog(weld::Window* pParent, const SfxItemSet* pAttrSet) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateCustomizeTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ const css::uno::Reference< css::frame::XFrame >& xViewFrame ) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateTextTabDialog( weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ SdrView* pView ) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateTabItemDialog(weld::Window* pParent, const SfxItemSet& rSet) override;
+ virtual VclPtr<AbstractSvxCaptionDialog>
+ CreateCaptionDialog(weld::Window* pParent,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes = SvxAnchorIds::NONE) override;
+ virtual VclPtr<SfxAbstractInsertObjectDialog>
+ CreateInsertObjectDialog(weld::Window* pParent, const OUString& rCommand,
+ const css::uno::Reference < css::embed::XStorage >& xStor,
+ const SvObjectServerList* pList ) override;
+ virtual VclPtr<VclAbstractDialog> CreateEditObjectDialog(weld::Window* pParent, const OUString& rCommand,
+ const css::uno::Reference < css::embed::XEmbeddedObject >& xObj ) override;
+ virtual VclPtr<SfxAbstractPasteDialog> CreatePasteDialog(weld::Window* pParent) override;
+ virtual VclPtr<SfxAbstractLinksDialog> CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML = false, sfx2::SvBaseLink* p=nullptr) override;
+
+ virtual VclPtr<AbstractHangulHanjaConversionDialog> CreateHangulHanjaConversionDialog(weld::Widget* pParent) override;
+ virtual VclPtr<AbstractThesaurusDialog> CreateThesaurusDialog(weld::Widget*,
+ css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
+ const OUString &rWord, LanguageType nLanguage) override;
+
+ virtual VclPtr<AbstractHyphenWordDialog> CreateHyphenWordDialog(weld::Widget*,
+ const OUString &rWord, LanguageType nLang,
+ css::uno::Reference< css::linguistic2::XHyphenator > &xHyphen,
+ SvxSpellWrapper* pWrapper) override;
+
+ virtual VclPtr<AbstractFmShowColsDialog> CreateFmShowColsDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxZoomDialog> CreateSvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet) override;
+ // add for SvxBorderBackgroundDlg
+ virtual VclPtr<SfxAbstractTabDialog> CreateSvxBorderBackgroundDlg(
+ weld::Window* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableDrawingLayerFillStyles) override;
+
+ virtual VclPtr<AbstractSvxTransformTabDialog> CreateSvxTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes = SvxAnchorIds::NONE) override ;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSchTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pSdrView,
+ bool bSizeTabPage) override;
+ virtual VclPtr<AbstractSpellDialog> CreateSvxSpellDialog(
+ weld::Window* pParent,
+ SfxBindings* pBindings,
+ svx::SpellDialogChildWindow* pSpellChildWindow ) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateActualizeProgressDialog(weld::Widget* pParent, GalleryTheme* pThm) override;
+ virtual VclPtr<AbstractTitleDialog> CreateTitleDialog(weld::Widget* pParent, const OUString& rOldText) override;
+ virtual VclPtr<AbstractGalleryIdDialog> CreateGalleryIdDialog(weld::Widget* pParent,
+ GalleryTheme* pThm) override;
+ virtual VclPtr<VclAbstractDialog> CreateGalleryThemePropertiesDialog(weld::Widget* pParent,
+ ExchangeData* pData,
+ SfxItemSet* pItemSet) override;
+
+ virtual VclPtr<AbstractURLDlg> CreateURLDialog(weld::Widget* pParent,
+ const OUString& rURL, const OUString& rAltText, const OUString& rDescription,
+ const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList ) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateSvxSearchAttributeDialog(weld::Window* pParent,
+ SearchAttrItemList& rLst,
+ const WhichRangesContainer& pWhRanges) override;
+ virtual VclPtr<AbstractSvxSearchSimilarityDialog> CreateSvxSearchSimilarityDialog( weld::Window* pParent,
+ bool bRelax,
+ sal_uInt16 nOther,
+ sal_uInt16 nShorter,
+ sal_uInt16 nLonger) override;
+ virtual VclPtr<AbstractSvxJSearchOptionsDialog> CreateSvxJSearchOptionsDialog(weld::Window* pParent,
+ const SfxItemSet& rOptionsSet,
+ TransliterationFlags nInitialFlags) override;
+ virtual VclPtr<AbstractFmInputRecordNoDialog> CreateFmInputRecordNoDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxNewDictionaryDialog> CreateSvxNewDictionaryDialog(weld::Window* pParent) override;
+ virtual VclPtr<VclAbstractDialog> CreateSvxEditDictionaryDialog(weld::Window* pParent, const OUString& rName) override;
+ virtual VclPtr<AbstractSvxNameDialog> CreateSvxNameDialog(weld::Window* pParent,
+ const OUString& rName, const OUString& rDesc) override;
+ // #i68101#
+ virtual VclPtr<AbstractSvxObjectNameDialog> CreateSvxObjectNameDialog(weld::Window* pParent, const OUString& rName) override;
+ virtual VclPtr<AbstractSvxObjectTitleDescDialog> CreateSvxObjectTitleDescDialog(weld::Window* pParent, const OUString& rTitle, const OUString& rDescription) override;
+ virtual VclPtr<AbstractSvxMultiPathDialog> CreateSvxMultiPathDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxMultiPathDialog> CreateSvxPathSelectDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxHpLinkDlg> CreateSvxHpLinkDlg(SfxChildWindow* pChild, SfxBindings* pBindings, weld::Window* pParent) override;
+ virtual VclPtr<AbstractFmSearchDialog> CreateFmSearchDialog(weld::Window* pParent,
+ const OUString& strInitialText,
+ const std::vector< OUString >& _rContexts,
+ sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterEmboss(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterPoster(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterSepia(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterSmooth(weld::Window* pParent,
+ const Graphic& rGraphic, double nRadius) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterSolarize(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterMosaic(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractSvxAreaTabDialog> CreateSvxAreaTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow,
+ bool bSlideBackground) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ const SdrObject* pObj,
+ bool bHasObj ) override;
+ virtual VclPtr<AbstractSvxPostItDialog> CreateSvxPostItDialog(weld::Widget* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bPrevNext = false) override;
+
+ // For TabPage
+ virtual CreateTabPage GetTabPageCreatorFunc( sal_uInt16 nId ) override;
+
+ virtual GetTabPageRanges GetTabPageRangesFunc( sal_uInt16 nId ) override;
+ virtual DialogGetRanges GetDialogGetRangesFunc() override;
+ virtual VclPtr<VclAbstractDialog> CreateSvxScriptOrgDialog(weld::Window* pParent, const OUString& rLanguage) override;
+
+ virtual VclPtr<AbstractScriptSelectorDialog> CreateScriptSelectorDialog(weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& rxFrame) override;
+
+ virtual void ShowAsyncScriptErrorDialog(weld::Window* pParent, const css::uno::Any& rException) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateSvxMacroAssignDlg(
+ weld::Window* _pParent,
+ const css::uno::Reference< css::frame::XFrame >& _rxDocumentFrame,
+ const bool _bUnoDialogMode,
+ const css::uno::Reference< css::container::XNameReplace >& _rxEvents,
+ const sal_uInt16 _nInitiallySelectedEvent
+ ) override;
+
+ virtual VclPtr<SfxAbstractTabDialog> CreateSvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel) override;
+
+ virtual VclPtr<SvxAbstractSplitTableDialog> CreateSvxSplitTableDialog(weld::Window* pParent, bool bIsTableVertical, tools::Long nMaxVertical) override;
+
+ virtual std::shared_ptr<SvxAbstractNewTableDialog> CreateSvxNewTableDialog(weld::Window* pParent) override ;
+
+ virtual VclPtr<VclAbstractDialog> CreateOptionsDialog(
+ weld::Window* pParent, const OUString& rExtensionId ) override;
+
+ virtual VclPtr<SvxAbstractInsRowColDlg> CreateSvxInsRowColDlg(weld::Window* pParent, bool bCol, const OString& rHelpId) override;
+
+ virtual VclPtr<AbstractPasswordToOpenModifyDialog> CreatePasswordToOpenModifyDialog(weld::Window* pParent, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify) override;
+
+ virtual VclPtr<AbstractScreenshotAnnotationDlg> CreateScreenshotAnnotationDlg(weld::Dialog& rParentDialog) override;
+
+ virtual VclPtr<AbstractSignatureLineDialog>
+ CreateSignatureLineDialog(weld::Window* pParent,
+ const css::uno::Reference<css::frame::XModel> xModel, bool bEditExisting) override;
+
+ virtual VclPtr<AbstractSignSignatureLineDialog>
+ CreateSignSignatureLineDialog(weld::Window* pParent,
+ const css::uno::Reference<css::frame::XModel> xModel) override;
+
+ virtual VclPtr<AbstractQrCodeGenDialog>
+ CreateQrCodeGenDialog(weld::Window* pParent,
+ const css::uno::Reference<css::frame::XModel> xModel, bool bEditExisting) override;
+
+ virtual VclPtr<AbstractAdditionsDialog>
+ CreateAdditionsDialog(weld::Window* pParent, const OUString& sAdditionsTag) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateAboutDialog(weld::Window* pParent) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateTipOfTheDayDialog(weld::Window* pParent) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateToolbarmodeDialog(weld::Window* pParent) override;
+
+ virtual VclPtr<AbstractDiagramDialog> CreateDiagramDialog(
+ weld::Window* pParent,
+ SdrObjGroup& rDiagram) override;
+
+#ifdef _WIN32
+ virtual VclPtr<VclAbstractDialog> CreateFileExtCheckDialog(weld::Window* pParent,
+ const OUString& sTitle,
+ const OUString& sMsg) override;
+#endif
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/init.cxx b/cui/source/factory/init.cxx
new file mode 100644
index 000000000..87f3105a0
--- /dev/null
+++ b/cui/source/factory/init.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cui/cuicharmap.hxx>
+
+// hook to call special character dialog for edits
+// caution: needs C-Linkage since dynamically loaded via symbol name
+extern "C"
+{
+SAL_DLLPUBLIC_EXPORT bool GetSpecialCharsForEdit(weld::Widget* i_pParent, const vcl::Font& i_rFont, OUString& o_rResult)
+{
+ bool bRet = false;
+ SvxCharacterMap aDlg(i_pParent, nullptr, nullptr);
+ aDlg.DisableFontSelection();
+ aDlg.SetCharFont(i_rFont);
+ if (aDlg.run() == RET_OK)
+ {
+ sal_UCS4 cChar = aDlg.GetChar();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ o_rResult = aOUStr;
+ bRet = true;
+ }
+ return bRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/AdditionsDialog.hxx b/cui/source/inc/AdditionsDialog.hxx
new file mode 100644
index 000000000..0e7620b38
--- /dev/null
+++ b/cui/source/inc/AdditionsDialog.hxx
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <salhelper/thread.hxx>
+#include <rtl/ref.hxx>
+#include <vcl/weld.hxx>
+
+// Detect changes on the UI
+#include <vcl/timer.hxx>
+
+// Search and filter
+#include <i18nutil/searchopt.hxx>
+
+// Extension Manager Connection
+#include <com/sun/star/deployment/XExtensionManager.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <atomic>
+
+class AdditionsDialog;
+class SearchAndParseThread;
+class AdditionsItem;
+
+struct AdditionInfo
+{
+ OUString sExtensionID;
+ OUString sName;
+ OUString sAuthorName;
+ OUString sExtensionURL;
+ OUString sScreenshotURL;
+ OUString sIntroduction;
+ OUString sDescription;
+ OUString sCompatibleVersion;
+ OUString sReleaseVersion;
+ OUString sLicense;
+ OUString sCommentNumber;
+ OUString sCommentURL;
+ OUString sRating;
+ OUString sDownloadNumber;
+ OUString sDownloadURL;
+};
+
+class AdditionsDialog : public weld::GenericDialogController
+{
+private:
+ Timer m_aSearchDataTimer;
+
+ DECL_LINK(GearHdl, const OString&, void);
+ DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
+ DECL_LINK(ImplUpdateDataHdl, Timer*, void);
+ DECL_LINK(FocusOut_Impl, weld::Widget&, void);
+ DECL_LINK(CloseButtonHdl, weld::Button&, void);
+
+public:
+ css::uno::Reference<css::deployment::XExtensionManager> m_xExtensionManager;
+ std::unique_ptr<weld::Entry> m_xEntrySearch;
+ std::unique_ptr<weld::Button> m_xButtonClose;
+ std::unique_ptr<weld::MenuButton> m_xMenuButtonSettings;
+ std::vector<std::shared_ptr<AdditionsItem>> m_aAdditionsItems; // UI components
+ std::vector<AdditionInfo> m_aAllExtensionsVector; // Stores the all extensions' info
+
+ std::unique_ptr<weld::ScrolledWindow> m_xContentWindow;
+ std::unique_ptr<weld::Container> m_xContentGrid;
+
+ std::unique_ptr<weld::Label> m_xLabelProgress;
+ std::unique_ptr<weld::MenuButton> m_xGearBtn;
+
+ ::rtl::Reference<SearchAndParseThread> m_pSearchThread;
+
+ OUString m_sURL;
+ OUString m_sTag;
+ size_t
+ m_nMaxItemCount; // Max number of item which will appear on the list before the press to the show more button.
+ size_t m_nCurrentListItemCount; // Current number of item on the list
+ i18nutil::SearchOptions2 m_searchOptions;
+
+ AdditionsDialog(weld::Window* pParent, const OUString& sAdditionsTag);
+ ~AdditionsDialog() override;
+ css::uno::Sequence<css::uno::Sequence<css::uno::Reference<css::deployment::XPackage>>>
+ getInstalledExtensions();
+ void SetProgress(const OUString& rProgress);
+ void ClearList();
+ void RefreshUI();
+
+ static bool sortByComment(const AdditionInfo& a, const AdditionInfo& b);
+ static bool sortByRating(const AdditionInfo& a, const AdditionInfo& b);
+ static bool sortByDownload(const AdditionInfo& a, const AdditionInfo& b);
+};
+
+class AdditionsItem
+{
+public:
+ AdditionsItem(weld::Widget* pParent, AdditionsDialog* pParentDialog,
+ const AdditionInfo& additionInfo);
+ bool getExtensionFile(OUString& sExtensionFile);
+
+ DECL_LINK(ShowMoreHdl, weld::Button&, void);
+ DECL_LINK(InstallHdl, weld::Button&, void);
+
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Widget> m_xContainer;
+ std::unique_ptr<weld::Image> m_xImageScreenshot;
+ std::unique_ptr<weld::Button> m_xButtonInstall;
+ std::unique_ptr<weld::LinkButton> m_xLinkButtonWebsite;
+ std::unique_ptr<weld::Label> m_xLabelName;
+ std::unique_ptr<weld::Label> m_xLabelAuthor;
+ std::unique_ptr<weld::Label> m_xLabelDesc;
+ std::unique_ptr<weld::Label> m_xLabelDescription;
+ std::unique_ptr<weld::Label> m_xLabelLicense;
+ std::unique_ptr<weld::Label> m_xLabelVersion;
+ std::unique_ptr<weld::Label> m_xLabelComments;
+ std::unique_ptr<weld::LinkButton> m_xLinkButtonComments;
+ std::unique_ptr<weld::Image> m_xImageVoting1;
+ std::unique_ptr<weld::Image> m_xImageVoting2;
+ std::unique_ptr<weld::Image> m_xImageVoting3;
+ std::unique_ptr<weld::Image> m_xImageVoting4;
+ std::unique_ptr<weld::Image> m_xImageVoting5;
+ std::unique_ptr<weld::Label> m_xLabelNoVoting;
+ std::unique_ptr<weld::Image> m_xImageDownloadNumber;
+ std::unique_ptr<weld::Label> m_xLabelDownloadNumber;
+ std::unique_ptr<weld::Button> m_xButtonShowMore;
+ AdditionsDialog* m_pParentDialog;
+ OUString m_sDownloadURL;
+ OUString m_sExtensionID;
+};
+
+class SearchAndParseThread : public salhelper::Thread
+{
+private:
+ AdditionsDialog* m_pAdditionsDialog;
+ std::atomic<bool> m_bExecute;
+ bool m_bIsFirstLoading;
+
+ void Search();
+ void Append(AdditionInfo& additionInfo);
+ void CheckInstalledExtensions();
+
+ virtual ~SearchAndParseThread() override;
+ virtual void execute() override;
+
+public:
+ SearchAndParseThread(AdditionsDialog* pDialog, bool bIsFirstLoading);
+
+ void StopExecution() { m_bExecute = false; }
+};
+
+class TmpRepositoryCommandEnv
+ : public ::cppu::WeakImplHelper<css::ucb::XCommandEnvironment, css::task::XInteractionHandler,
+ css::ucb::XProgressHandler>
+{
+public:
+ virtual ~TmpRepositoryCommandEnv() override;
+ TmpRepositoryCommandEnv();
+
+ // XCommandEnvironment
+ virtual css::uno::Reference<css::task::XInteractionHandler>
+ SAL_CALL getInteractionHandler() override;
+ virtual css::uno::Reference<css::ucb::XProgressHandler> SAL_CALL getProgressHandler() override;
+
+ // XInteractionHandler
+ virtual void SAL_CALL
+ handle(css::uno::Reference<css::task::XInteractionRequest> const& xRequest) override;
+
+ // XProgressHandler
+ virtual void SAL_CALL push(css::uno::Any const& Status) override;
+ virtual void SAL_CALL update(css::uno::Any const& Status) override;
+ virtual void SAL_CALL pop() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/CommandCategoryListBox.hxx b/cui/source/inc/CommandCategoryListBox.hxx
new file mode 100644
index 000000000..c4882ae17
--- /dev/null
+++ b/cui/source/inc/CommandCategoryListBox.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <i18nutil/searchopt.hxx>
+#include "cfgutil.hxx"
+
+class CommandCategoryListBox
+{
+ SfxGroupInfoArr_Impl m_aGroupInfo;
+ OUString m_sModuleLongName;
+ css::uno::Reference<css::uno::XComponentContext> m_xContext;
+ css::uno::Reference<css::frame::XFrame> m_xFrame;
+ css::uno::Reference<css::container::XNameAccess> m_xGlobalCategoryInfo;
+ css::uno::Reference<css::container::XNameAccess> m_xModuleCategoryInfo;
+ css::uno::Reference<css::container::XNameAccess> m_xUICmdDescription;
+
+ // For search
+ i18nutil::SearchOptions2 m_searchOptions;
+
+ SfxStylesInfo_Impl* pStylesInfo;
+ SfxStylesInfo_Impl m_aStylesInfo;
+
+ std::unique_ptr<weld::ComboBox> m_xControl;
+
+public:
+ CommandCategoryListBox(std::unique_ptr<weld::ComboBox> xControl);
+ ~CommandCategoryListBox();
+ void ClearAll();
+
+ void Init(const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::frame::XFrame>& xFrame,
+ const OUString& sModuleLongName);
+ void FillFunctionsList(const css::uno::Sequence<css::frame::DispatchInformation>& xCommands,
+ CuiConfigFunctionListBox* pFunctionListBox, const OUString& filterTerm,
+ SaveInData* pCurrentSaveInData);
+ OUString getCommandName(const OUString& sCommand);
+
+ void connect_changed(const Link<weld::ComboBox&, void>& rLink)
+ {
+ m_xControl->connect_changed(rLink);
+ }
+
+ /**
+ Signals that a command category has been selected.
+ And updates the functions list box to include
+ the commands in the selected category.
+ */
+ void categorySelected(CuiConfigFunctionListBox* pFunctionListBox, const OUString& filterTerm,
+ SaveInData* pCurrentSaveInData = nullptr);
+
+ void SetStylesInfo(SfxStylesInfo_Impl* pStyles);
+
+ // Adds children of the given macro group to the functions list
+ void
+ addChildren(const weld::TreeIter* parentEntry,
+ const css::uno::Reference<com::sun::star::script::browse::XBrowseNode>& parentNode,
+ CuiConfigFunctionListBox* pFunctionListBox, const OUString& filterTerm,
+ SaveInData* pCurrentSaveInData,
+ std::vector<std::unique_ptr<weld::TreeIter>>& rNodesToExpand);
+
+ void set_visible(bool bVisible) { m_xControl->set_visible(bVisible); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/CustomNotebookbarGenerator.hxx b/cui/source/inc/CustomNotebookbarGenerator.hxx
new file mode 100644
index 000000000..b06848dbb
--- /dev/null
+++ b/cui/source/inc/CustomNotebookbarGenerator.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <rtl/ustring.hxx>
+
+using namespace css::uno;
+
+class CustomNotebookbarGenerator
+{
+public:
+ CustomNotebookbarGenerator();
+ static OUString getCustomizedUIPath();
+ static OUString getOriginalUIPath();
+ static OString getSystemPath(OUString const& sURL);
+ static Sequence<OUString> getCustomizedUIItem(OUString sNotebookbarConfigType);
+ static void getFileNameAndAppName(OUString& sAppName, OUString& sNotebookbarUIFileName);
+ static void modifyCustomizedUIFile(const Sequence<OUString>& sUIItemProperties);
+ static void createCustomizedUIFile();
+ static void setCustomizedUIItem(Sequence<OUString> sUIItemProperties,
+ OUString sNotebookbarConfigType);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/DiagramDialog.hxx b/cui/source/inc/DiagramDialog.hxx
new file mode 100644
index 000000000..71a5bd9b7
--- /dev/null
+++ b/cui/source/inc/DiagramDialog.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+* This file is part of the LibreOffice project.
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#pragma once
+
+#include <tools/link.hxx>
+#include <vcl/weld.hxx>
+
+class SdrObjGroup;
+
+/** Edit Diagram dialog */
+class DiagramDialog : public weld::GenericDialogController
+{
+public:
+ DiagramDialog(weld::Window* pWindow, SdrObjGroup& rDiagram);
+ virtual ~DiagramDialog() override;
+
+private:
+ SdrObjGroup& m_rDiagram;
+ sal_uInt32 m_nUndos;
+
+ std::unique_ptr<weld::Button> mpBtnOk;
+ std::unique_ptr<weld::Button> mpBtnCancel;
+ std::unique_ptr<weld::Button> mpBtnAdd;
+ std::unique_ptr<weld::Button> mpBtnRemove;
+ std::unique_ptr<weld::TreeView> mpTreeDiagram;
+ std::unique_ptr<weld::TextView> mpTextAdd;
+
+ DECL_LINK(OnAddCancel, weld::Button&, void);
+ DECL_LINK(OnAddClick, weld::Button&, void);
+ DECL_LINK(OnRemoveClick, weld::Button&, void);
+
+ void populateTree(const weld::TreeIter* pParent, const OUString& rParentId);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/FontFeatures.hxx b/cui/source/inc/FontFeatures.hxx
new file mode 100644
index 000000000..f16c11628
--- /dev/null
+++ b/cui/source/inc/FontFeatures.hxx
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+#pragma once
+
+#include <vector>
+#include <vcl/font/Feature.hxx>
+#include <vcl/virdev.hxx>
+
+std::vector<vcl::font::Feature> getFontFeatureList(OUString const& rFontName, VirtualDevice& rVDev);
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file
diff --git a/cui/source/inc/FontFeaturesDialog.hxx b/cui/source/inc/FontFeaturesDialog.hxx
new file mode 100644
index 000000000..f542566ae
--- /dev/null
+++ b/cui/source/inc/FontFeaturesDialog.hxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/font/Feature.hxx>
+#include <svx/fntctrl.hxx>
+#include <memory>
+
+namespace cui
+{
+struct FontFeatureItem
+{
+ FontFeatureItem(weld::Widget* pParent)
+ : m_aFeatureCode(0)
+ , m_nDefault(0)
+ , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/fontfragment.ui"))
+ , m_xContainer(m_xBuilder->weld_widget("fontentry"))
+ , m_xText(m_xBuilder->weld_label("label"))
+ , m_xCombo(m_xBuilder->weld_combo_box("combo"))
+ , m_xCheck(m_xBuilder->weld_check_button("check"))
+ {
+ }
+
+ sal_uInt32 m_aFeatureCode;
+ sal_uInt32 m_nDefault;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Widget> m_xContainer;
+ std::unique_ptr<weld::Label> m_xText;
+ std::unique_ptr<weld::ComboBox> m_xCombo;
+ std::unique_ptr<weld::CheckButton> m_xCheck;
+};
+
+class FontFeaturesDialog : public weld::GenericDialogController
+{
+private:
+ std::vector<FontFeatureItem> m_aFeatureItems;
+ OUString m_sFontName;
+ OUString m_sResultFontName;
+
+ SvxFontPrevWindow m_aPreviewWindow;
+ std::unique_ptr<weld::ScrolledWindow> m_xContentWindow;
+ std::unique_ptr<weld::Container> m_xContentGrid;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWindow;
+
+ void initialize();
+ OUString createFontNameWithFeatures();
+
+ // returns the max height of a row
+ int fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures);
+
+ DECL_LINK(ComboBoxSelectedHdl, weld::ComboBox&, void);
+ DECL_LINK(CheckBoxToggledHdl, weld::Toggleable&, void);
+
+public:
+ FontFeaturesDialog(weld::Window* pParent, OUString aFontName);
+ ~FontFeaturesDialog() override;
+ virtual short run() override;
+
+ OUString const& getResultFontName() const { return m_sResultFontName; }
+
+ void updateFontPreview();
+};
+
+} // end svx namespaces
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/GraphicsTestsDialog.hxx b/cui/source/inc/GraphicsTestsDialog.hxx
new file mode 100644
index 000000000..2bf18de5d
--- /dev/null
+++ b/cui/source/inc/GraphicsTestsDialog.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <vcl/bitmap.hxx>
+#include <vcl/weld.hxx>
+#include <tools/link.hxx>
+
+#include <vector>
+
+class GraphicTestEntry final
+{
+private:
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xContainer;
+ std::unique_ptr<weld::Label> m_xTestLabel;
+ std::unique_ptr<weld::Button> m_xTestButton;
+
+ weld::Dialog* m_xParentDialog;
+
+ Bitmap m_xResultBitmap;
+
+public:
+ DECL_LINK(HandleResultViewRequest, weld::Button&, void);
+ GraphicTestEntry(weld::Container* pParent, weld::Dialog* pDialog, OUString aTestName,
+ OUString aTestStatus, Bitmap aTestBitmap);
+ weld::Widget* get_widget() const { return m_xContainer.get(); }
+};
+
+class GraphicsTestsDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::TextView> m_xResultLog;
+ std::unique_ptr<weld::Button> m_xDownloadResults;
+ std::unique_ptr<weld::Box> m_xContainerBox;
+
+ std::vector<std::unique_ptr<GraphicTestEntry>> m_xGraphicTestEntries;
+
+ OUString m_xZipFileUrl;
+ OUString m_xCreateFolderUrl;
+
+ DECL_LINK(HandleDownloadRequest, weld::Button&, void);
+ DECL_LINK(HandleResultViewRequest, weld::Button&, void);
+
+public:
+ GraphicsTestsDialog(weld::Container* pParent);
+ ~GraphicsTestsDialog();
+ virtual short run() override;
+};
diff --git a/cui/source/inc/ImageViewerDialog.hxx b/cui/source/inc/ImageViewerDialog.hxx
new file mode 100644
index 000000000..884deb18d
--- /dev/null
+++ b/cui/source/inc/ImageViewerDialog.hxx
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/weld.hxx>
+
+class ImageViewerDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Image> m_xDisplayImage;
+
+public:
+ ImageViewerDialog(weld::Dialog* pParent, BitmapEx aBitmap, OUString atitle);
+};
diff --git a/cui/source/inc/QrCodeGenDialog.hxx b/cui/source/inc/QrCodeGenDialog.hxx
new file mode 100644
index 000000000..7404b95f6
--- /dev/null
+++ b/cui/source/inc/QrCodeGenDialog.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <config_zxing.h>
+
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+class QrCodeGenDialog : public weld::GenericDialogController
+{
+public:
+ QrCodeGenDialog(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel,
+ bool bEditExisting);
+
+ virtual short run() override;
+
+protected:
+ css::uno::Reference<css::frame::XModel> m_xModel;
+ void Apply();
+
+private:
+ std::unique_ptr<weld::TextView> m_xEdittext;
+ std::unique_ptr<weld::RadioButton> m_xECC[4];
+ std::unique_ptr<weld::SpinButton> m_xSpinBorder;
+ std::unique_ptr<weld::ComboBox> m_xComboType;
+#if ENABLE_ZXING
+ weld::Widget* mpParent;
+#endif
+
+ css::uno::Reference<css::beans::XPropertySet> m_xExistingShapeProperties;
+
+ void GetErrorCorrection(tools::Long);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SignSignatureLineDialog.hxx b/cui/source/inc/SignSignatureLineDialog.hxx
new file mode 100644
index 000000000..5abe1969e
--- /dev/null
+++ b/cui/source/inc/SignSignatureLineDialog.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include "SignatureLineDialogBase.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class SignSignatureLineDialog : public SignatureLineDialogBase
+{
+public:
+ SignSignatureLineDialog(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel);
+
+private:
+ std::unique_ptr<weld::Entry> m_xEditName;
+ std::unique_ptr<weld::TextView> m_xEditComment;
+ std::unique_ptr<weld::Button> m_xBtnLoadImage;
+ std::unique_ptr<weld::Button> m_xBtnClearImage;
+ std::unique_ptr<weld::Button> m_xBtnChooseCertificate;
+ std::unique_ptr<weld::Button> m_xBtnSign;
+ std::unique_ptr<weld::Label> m_xLabelHint;
+ std::unique_ptr<weld::Label> m_xLabelHintText;
+ std::unique_ptr<weld::Label> m_xLabelAddComment;
+
+ css::uno::Reference<css::beans::XPropertySet> m_xShapeProperties;
+ css::uno::Reference<css::security::XCertificate> m_xSelectedCertifate;
+ css::uno::Reference<css::graphic::XGraphic> m_xSignatureImage;
+ OUString m_aSignatureLineId;
+ OUString m_aSuggestedSignerName;
+ OUString m_aSuggestedSignerTitle;
+ bool m_bShowSignDate;
+ OUString m_sOriginalImageBtnLabel;
+
+ void ValidateFields();
+ css::uno::Reference<css::graphic::XGraphic> getSignedGraphic(bool bValid);
+ virtual void Apply() override;
+
+ DECL_LINK(clearImage, weld::Button&, void);
+ DECL_LINK(loadImage, weld::Button&, void);
+ DECL_LINK(chooseCertificate, weld::Button&, void);
+ DECL_LINK(entryChanged, weld::Entry&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SignatureLineDialog.hxx b/cui/source/inc/SignatureLineDialog.hxx
new file mode 100644
index 000000000..73b093f60
--- /dev/null
+++ b/cui/source/inc/SignatureLineDialog.hxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include "SignatureLineDialogBase.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class SignatureLineDialog : public SignatureLineDialogBase
+{
+public:
+ SignatureLineDialog(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel,
+ bool bEditExisting);
+
+private:
+ std::unique_ptr<weld::Entry> m_xEditName;
+ std::unique_ptr<weld::Entry> m_xEditTitle;
+ std::unique_ptr<weld::Entry> m_xEditEmail;
+ std::unique_ptr<weld::TextView> m_xEditInstructions;
+ std::unique_ptr<weld::CheckButton> m_xCheckboxCanAddComments;
+ std::unique_ptr<weld::CheckButton> m_xCheckboxShowSignDate;
+
+ css::uno::Reference<css::beans::XPropertySet> m_xExistingShapeProperties;
+ OUString m_aSignatureLineId;
+
+ virtual void Apply() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SignatureLineDialogBase.hxx b/cui/source/inc/SignatureLineDialogBase.hxx
new file mode 100644
index 000000000..3cc645819
--- /dev/null
+++ b/cui/source/inc/SignatureLineDialogBase.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class SignatureLineDialogBase : public weld::GenericDialogController
+{
+public:
+ SignatureLineDialogBase(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel,
+ const OUString& rUIFile, const OString& rDialogId);
+
+ virtual short run() override;
+
+protected:
+ css::uno::Reference<css::frame::XModel> m_xModel;
+ virtual void Apply() = 0;
+ static OUString getCDataString(std::u16string_view rString);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SpellDialog.hxx b/cui/source/inc/SpellDialog.hxx
new file mode 100644
index 000000000..da5fee960
--- /dev/null
+++ b/cui/source/inc/SpellDialog.hxx
@@ -0,0 +1,228 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/basedlgs.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+
+#include <svx/langbox.hxx>
+#include <memory>
+#include <svl/undo.hxx>
+#include <vcl/customweld.hxx>
+#include <svx/weldeditview.hxx>
+#include <editeng/SpellPortions.hxx>
+
+#include <set>
+
+namespace svx{ class SpellUndoAction_Impl;}
+class UndoChangeGroupGuard;
+
+// forward ---------------------------------------------------------------
+
+struct SpellDialog_Impl;
+namespace com::sun::star::linguistic2 { class XSpellChecker1; }
+
+namespace svx{
+class SpellDialog;
+struct SpellErrorDescription;
+
+class SentenceEditWindow_Impl : public WeldEditView
+{
+private:
+ std::set<sal_Int32> m_aIgnoreErrorsAt;
+ SpellDialog* m_pSpellDialog;
+ weld::Toolbar* m_pToolbar;
+ sal_Int32 m_nErrorStart;
+ sal_Int32 m_nErrorEnd;
+ bool m_bIsUndoEditMode;
+
+ Link<LinkParamNone*,void> m_aModifyLink;
+
+ void CallModifyLink() {m_aModifyLink.Call(nullptr); }
+
+ SpellDialog* GetSpellDialog() const { return m_pSpellDialog; }
+
+ bool GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, sal_Int32 nPosition);
+
+ DECL_LINK(ToolbarHdl, const OString&, void);
+
+protected:
+ virtual bool KeyInput( const KeyEvent& rKEvt ) override;
+
+public:
+ SentenceEditWindow_Impl();
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ void SetSpellDialog(SpellDialog* pDialog) { m_pSpellDialog = pDialog; }
+ virtual ~SentenceEditWindow_Impl() override;
+
+ void Init(weld::Toolbar* pToolbar);
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rLink)
+ {
+ m_aModifyLink = rLink;
+ m_xEditEngine->SetModifyHdl(m_aModifyLink);
+ }
+
+ void SetAttrib(const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd);
+
+ void SetText(const OUString& rStr);
+
+ bool MarkNextError( bool bIgnoreCurrentError, const css::uno::Reference<css::linguistic2::XSpellChecker1>& );
+ int ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage);
+ void MoveErrorMarkTo(sal_Int32 nErrorStart, sal_Int32 nErrorEnd, bool bGrammar);
+ OUString GetErrorText() const;
+ void RestoreCurrentError();
+
+ void SetAlternatives(
+ const css::uno::Reference<css::linguistic2::XSpellAlternatives>& );
+
+ bool GetAlternatives(SpellErrorDescription& rDesc);
+
+ void ClearModifyFlag() { m_xEditEngine->ClearModifyFlag(); }
+ void ResetModified() { ClearModifyFlag(); m_bIsUndoEditMode = false;}
+ bool IsModified() const { return m_xEditEngine->IsModified(); }
+
+ bool IsUndoEditMode() const { return m_bIsUndoEditMode;}
+ void SetUndoEditMode(bool bSet);
+
+ svx::SpellPortions CreateSpellPortions() const;
+
+ void ResetUndo();
+ void Undo();
+ void AddUndoAction( std::unique_ptr<SfxUndoAction> pAction );
+ size_t GetUndoActionCount() const;
+ void UndoActionStart( sal_uInt16 nId );
+ void UndoActionEnd();
+
+ void MoveErrorEnd(tools::Long nOffset);
+
+ void ResetIgnoreErrorsAt() { m_aIgnoreErrorsAt.clear(); }
+};
+
+// class SvxSpellDialog ---------------------------------------------
+class SpellDialogChildWindow;
+
+class SpellDialog : public SfxModelessDialogController
+{
+ friend class SentenceEditWindow_Impl;
+private:
+ OUString m_sResumeST;
+ OUString m_sIgnoreOnceST;
+ OUString m_sNoSuggestionsST;
+
+ OUString m_sTitleSpelling;
+ OUString m_sTitleSpellingGrammar;
+
+ Link<SpellUndoAction_Impl&,void> aDialogUndoLink;
+ ImplSVEvent * m_pInitHdlEvent;
+ bool bFocusLocked;
+
+ svx::SpellDialogChildWindow& rParent;
+ svx::SpellPortions m_aSavedSentence;
+
+ std::unique_ptr<SpellDialog_Impl> pImpl;
+ css::uno::Reference<
+ css::linguistic2::XSpellChecker1 > xSpell;
+
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<weld::Label> m_xResumeFT;
+ std::unique_ptr<weld::Label> m_xNoSuggestionsFT;
+ std::unique_ptr<weld::Label> m_xIgnoreOnceFT;
+ std::unique_ptr<weld::Label> m_xLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+ std::unique_ptr<weld::Label> m_xExplainFT;
+ std::unique_ptr<weld::LinkButton> m_xExplainLink;
+ std::unique_ptr<weld::Label> m_xNotInDictFT;
+ std::unique_ptr<SentenceEditWindow_Impl> m_xSentenceED;
+ std::unique_ptr<weld::Label> m_xSuggestionFT;
+ std::unique_ptr<weld::TreeView> m_xSuggestionLB;
+ std::unique_ptr<weld::Button> m_xIgnorePB;
+ std::unique_ptr<weld::Button> m_xIgnoreAllPB;
+ std::unique_ptr<weld::Button> m_xIgnoreRulePB;
+ std::unique_ptr<weld::Button> m_xAddToDictPB;
+ std::unique_ptr<weld::MenuButton> m_xAddToDictMB;
+ std::unique_ptr<weld::Button> m_xChangePB;
+ std::unique_ptr<weld::Button> m_xChangeAllPB;
+ std::unique_ptr<weld::Button> m_xAutoCorrPB;
+ std::unique_ptr<weld::CheckButton> m_xCheckGrammarCB;
+ std::unique_ptr<weld::Button> m_xOptionsPB;
+ std::unique_ptr<weld::Button> m_xUndoPB;
+ std::unique_ptr<weld::Button> m_xClosePB;
+ std::unique_ptr<weld::Toolbar> m_xToolbar;
+ std::unique_ptr<weld::CustomWeld> m_xSentenceEDWeld;
+
+ DECL_LINK(ChangeHdl, weld::Button&, void);
+ DECL_LINK(DoubleClickChangeHdl, weld::TreeView&, bool);
+ DECL_LINK(ChangeAllHdl, weld::Button&, void);
+ DECL_LINK(IgnoreAllHdl, weld::Button&, void);
+ DECL_LINK(IgnoreHdl, weld::Button&, void);
+ DECL_LINK(CheckGrammarHdl, weld::Toggleable&, void);
+ DECL_LINK(ExtClickHdl, weld::Button&, void);
+ DECL_LINK(CancelHdl, weld::Button&, void);
+ DECL_LINK(ModifyHdl, LinkParamNone*, void);
+ DECL_LINK(UndoHdl, weld::Button&, void);
+ DECL_LINK(AddToDictSelectHdl, const OString&, void);
+ DECL_LINK(AddToDictClickHdl, weld::Button&, void);
+ DECL_LINK(LanguageSelectHdl, weld::ComboBox&, void);
+ DECL_LINK(DialogUndoHdl, SpellUndoAction_Impl&, void);
+
+ DECL_LINK(InitHdl, void*, void);
+
+ void AddToDictionaryExecute(const OString& rItemId);
+ void StartSpellOptDlg_Impl();
+ int InitUserDicts();
+ void UpdateBoxes_Impl(bool bCallFromSelectHdl = false);
+ void Init_Impl();
+ void SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard = nullptr, bool UseSavedSentence = false, bool bIgnoreCurrentError = false );
+ void LockFocusChanges( bool bLock ) {bFocusLocked = bLock;}
+ void ToplevelFocusChanged();
+ void Impl_Restore(bool bUseSavedSentence);
+
+ LanguageType GetSelectedLang_Impl() const;
+
+ /** Retrieves the next sentence.
+ */
+ bool GetNextSentence_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bRecheck /*for rechecking the current sentence*/);
+ /** Corrects all errors that have been selected to be changed always
+ */
+ static bool ApplyChangeAllList_Impl(SpellPortions& rSentence, bool& bHasReplaced);
+ void SetTitle_Impl(LanguageType nLang);
+
+protected:
+
+ OUString getReplacementString() const;
+
+public:
+ SpellDialog(
+ svx::SpellDialogChildWindow* pChildWindow,
+ weld::Window * pParent,
+ SfxBindings* pBindings);
+ virtual ~SpellDialog() override;
+
+ virtual void Activate() override;
+ virtual void Deactivate() override;
+
+ virtual void Close() override;
+
+ void InvalidateDialog();
+};
+
+} //namespace svx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxConfigPageHelper.hxx b/cui/source/inc/SvxConfigPageHelper.hxx
new file mode 100644
index 000000000..025c4aad1
--- /dev/null
+++ b/cui/source/inc/SvxConfigPageHelper.hxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/frame/XModuleManager2.hpp>
+
+#include "cfg.hxx"
+
+class SvxConfigPageHelper
+{
+public:
+ static void RemoveEntry(SvxEntries* pEntries, SvxConfigEntry const* pChildEntry);
+
+ static OUString replaceSaveInName(const OUString& rMessage, std::u16string_view rSaveInName);
+ static OUString stripHotKey(const OUString& str);
+ static OUString replaceSixteen(const OUString& str, sal_Int32 nReplacement);
+
+ static sal_Int16 GetImageType();
+ static void InitImageType();
+ static css::uno::Reference<css::graphic::XGraphic>
+ GetGraphic(const css::uno::Reference<css::ui::XImageManager>& xImageManager,
+ const OUString& rCommandURL);
+
+ static OUString generateCustomName(const OUString& prefix, SvxEntries* entries,
+ sal_Int32 suffix = 1);
+ static OUString generateCustomMenuURL(SvxEntries* entries, sal_Int32 suffix = 1);
+ static sal_uInt32 generateRandomValue();
+ /**
+ Generates a custom resource URL for a new toolbar.
+ Typically something like: private:resource/toolbar/custom_toolbar_########
+ The last 8 letters are randomly generated alphanumeric characters.
+ */
+ static OUString generateCustomURL(SvxEntries* entries);
+
+ static OUString GetModuleName(std::u16string_view aModuleId);
+ static OUString
+ GetUIModuleName(const OUString& aModuleId,
+ const css::uno::Reference<css::frame::XModuleManager2>& rModuleManager);
+
+ static bool
+ GetMenuItemData(const css::uno::Reference<css::container::XIndexAccess>& rItemContainer,
+ sal_Int32 nIndex, OUString& rCommandURL, OUString& rLabel, sal_uInt16& rType,
+ sal_Int32& rStyle, css::uno::Reference<css::container::XIndexAccess>& rSubMenu);
+ static bool
+ GetToolbarItemData(const css::uno::Reference<css::container::XIndexAccess>& rItemContainer,
+ sal_Int32 nIndex, OUString& rCommandURL, OUString& rLabel, sal_uInt16& rType,
+ bool& rIsVisible, sal_Int32& rStyle);
+
+ static css::uno::Sequence<css::beans::PropertyValue>
+ ConvertSvxConfigEntry(const SvxConfigEntry* pEntry);
+ static css::uno::Sequence<css::beans::PropertyValue>
+ ConvertToolbarEntry(const SvxConfigEntry* pEntry);
+
+ static bool EntrySort(SvxConfigEntry const* a, SvxConfigEntry const* b);
+
+ static bool SvxConfigEntryModified(SvxConfigEntry const* pEntry);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxMenuConfigPage.hxx b/cui/source/inc/SvxMenuConfigPage.hxx
new file mode 100644
index 000000000..bc8fba3f5
--- /dev/null
+++ b/cui/source/inc/SvxMenuConfigPage.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include "cfg.hxx" //for SvxConfigPage and SaveInData
+
+class SvxMenuConfigPage : public SvxConfigPage
+{
+private:
+ bool m_bIsMenuBar;
+
+ DECL_LINK(SelectMenuEntry, weld::TreeView&, void);
+ DECL_LINK(ContentContextMenuHdl, const CommandEvent&, bool);
+ DECL_LINK(FunctionContextMenuHdl, const CommandEvent&, bool);
+
+ DECL_LINK(GearHdl, const OString&, void);
+
+ DECL_LINK(SelectCategory, weld::ComboBox&, void);
+
+ DECL_LINK(AddCommandHdl, weld::Button&, void);
+ DECL_LINK(RemoveCommandHdl, weld::Button&, void);
+
+ DECL_LINK(InsertHdl, const OString&, void);
+ DECL_LINK(ModifyItemHdl, const OString&, void);
+ DECL_LINK(ResetMenuHdl, weld::Button&, void);
+
+ DECL_LINK(MenuEntriesSizeAllocHdl, const Size&, void);
+
+ virtual void ListModified() override;
+
+ void Init() override;
+ void UpdateButtonStates() override;
+ short QueryReset() override;
+ void DeleteSelectedContent() override;
+ void DeleteSelectedTopLevel() override;
+
+ virtual void SelectElement() override;
+
+public:
+ SvxMenuConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rItemSet, bool bIsMenuBar = true);
+ virtual ~SvxMenuConfigPage() override;
+
+ SaveInData* CreateSaveInData(const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const OUString& aModuleId, bool docConfig) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxNotebookbarConfigPage.hxx b/cui/source/inc/SvxNotebookbarConfigPage.hxx
new file mode 100644
index 000000000..7e417463a
--- /dev/null
+++ b/cui/source/inc/SvxNotebookbarConfigPage.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <libxml/parser.h>
+#include <vcl/weld.hxx>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include <memory>
+#include <vector>
+
+#include "cfg.hxx" //for SvxConfigPage and SaveInData
+
+class SvxNotebookbarConfigPage : public SvxConfigPage
+{
+private:
+ void UpdateButtonStates() override;
+ short QueryReset() override;
+ void Init() override;
+ void DeleteSelectedContent() override;
+ void DeleteSelectedTopLevel() override;
+ virtual void SelectElement() override;
+ void SetElement();
+
+public:
+ struct NotebookbarEntries
+ {
+ OUString sUIItemId;
+ OUString sClassId;
+ OUString sActionName;
+ OUString sDisplayName;
+ OUString sVisibleValue;
+ };
+ struct CategoriesEntries
+ {
+ OUString sDisplayName;
+ OUString sUIItemId;
+ OUString sClassType;
+ };
+ SvxNotebookbarConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rItemSet);
+ virtual ~SvxNotebookbarConfigPage() override;
+ SaveInData* CreateSaveInData(const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const OUString& aModuleId, bool docConfig) override;
+ static void FillFunctionsList(xmlNodePtr pRootNodePtr,
+ std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory);
+ static void searchNodeandAttribute(std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory,
+ CategoriesEntries& aCurCategoryEntry, xmlNode* pNodePtr,
+ bool isCategory);
+ static void getNodeValue(xmlNode* pNodePtr, NotebookbarEntries& aNodeEntries);
+};
+
+class SvxNotebookbarEntriesListBox final : public SvxMenuEntriesListBox
+{
+ void ChangedVisibility(int nRow);
+ DECL_LINK(CheckButtonHdl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+ SvxNotebookbarEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxConfigPage* pPg);
+ virtual ~SvxNotebookbarEntriesListBox() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxToolbarConfigPage.hxx b/cui/source/inc/SvxToolbarConfigPage.hxx
new file mode 100644
index 000000000..e035d6b7e
--- /dev/null
+++ b/cui/source/inc/SvxToolbarConfigPage.hxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include <memory>
+
+#include "cfg.hxx" //for SvxConfigPage and SaveInData
+
+class SvxToolbarConfigPage : public SvxConfigPage
+{
+private:
+ DECL_LINK(SelectToolbarEntry, weld::TreeView&, void);
+ DECL_LINK(MoveHdl, weld::Button&, void);
+
+ DECL_LINK(GearHdl, const OString&, void);
+
+ DECL_LINK(SelectCategory, weld::ComboBox&, void);
+
+ DECL_LINK(ContentContextMenuHdl, const CommandEvent&, bool);
+ DECL_LINK(FunctionContextMenuHdl, const CommandEvent&, bool);
+
+ DECL_LINK(AddCommandHdl, weld::Button&, void);
+ DECL_LINK(RemoveCommandHdl, weld::Button&, void);
+
+ DECL_LINK(InsertHdl, const OString&, void);
+ DECL_LINK(ModifyItemHdl, const OString&, void);
+ DECL_LINK(ResetToolbarHdl, weld::Button&, void);
+
+ virtual void ListModified() override;
+
+ void UpdateButtonStates() override;
+ short QueryReset() override;
+ void Init() override;
+ void DeleteSelectedContent() override;
+ void DeleteSelectedTopLevel() override;
+ virtual void SelectElement() override;
+
+public:
+ SvxToolbarConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rItemSet);
+ virtual ~SvxToolbarConfigPage() override;
+
+ void AddFunction(int nTarget = -1);
+
+ void MoveEntry(bool bMoveUp) override;
+
+ SaveInData* CreateSaveInData(const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const OUString& aModuleId, bool docConfig) override;
+};
+
+class SvxToolbarEntriesListBox final : public SvxMenuEntriesListBox
+{
+ void ChangedVisibility(int nRow);
+
+ DECL_LINK(CheckButtonHdl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+ SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxToolbarConfigPage* pPg);
+ virtual ~SvxToolbarEntriesListBox() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/TextColumnsPage.hxx b/cui/source/inc/TextColumnsPage.hxx
new file mode 100644
index 000000000..af45c23c9
--- /dev/null
+++ b/cui/source/inc/TextColumnsPage.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <sfx2/tabdlg.hxx>
+
+#include <memory>
+
+/// Tab page for EditEngine columns properties
+class SvxTextColumnsPage : public SfxTabPage
+{
+private:
+ static const WhichRangesContainer pRanges;
+
+ std::unique_ptr<weld::SpinButton> m_xColumnsNumber;
+ std::unique_ptr<weld::MetricSpinButton> m_xColumnsSpacing;
+
+public:
+ SvxTextColumnsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+ virtual ~SvxTextColumnsPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet*);
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/about.hxx b/cui/source/inc/about.hxx
new file mode 100644
index 000000000..2cfc65a89
--- /dev/null
+++ b/cui/source/inc/about.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class AboutDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::LinkButton> m_pCreditsButton;
+ std::unique_ptr<weld::LinkButton> m_pWebsiteButton;
+ std::unique_ptr<weld::LinkButton> m_pReleaseNotesButton;
+ std::unique_ptr<weld::Button> m_pCloseButton;
+ std::unique_ptr<weld::Button> m_pCopyButton;
+
+ std::unique_ptr<weld::Image> m_pBrandImage;
+ std::unique_ptr<weld::Image> m_pAboutImage;
+ std::unique_ptr<weld::Label> m_pVersionLabel;
+ std::unique_ptr<weld::Label> m_pBuildCaption;
+ std::unique_ptr<weld::LinkButton> m_pBuildLabel;
+ std::unique_ptr<weld::Label> m_pEnvLabel;
+ std::unique_ptr<weld::Label> m_pUILabel;
+ std::unique_ptr<weld::Label> m_pLocaleLabel;
+ std::unique_ptr<weld::Label> m_pMiscLabel;
+ std::unique_ptr<weld::Label> m_pCopyrightLabel;
+
+ static OUString GetVersionString();
+ static OUString GetBuildString();
+ static OUString GetLocaleString(bool bLocalized = true);
+ static OUString GetMiscString();
+
+ static OUString GetCopyrightString();
+ static bool IsStringValidGitHash(const OUString& hash);
+
+ DECL_LINK(HandleClick, weld::Button&, void);
+
+public:
+ AboutDialog(weld::Window* pParent);
+ virtual ~AboutDialog() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/acccfg.hxx b/cui/source/inc/acccfg.hxx
new file mode 100644
index 000000000..e9207d5a1
--- /dev/null
+++ b/cui/source/inc/acccfg.hxx
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/keycod.hxx>
+#include <i18nutil/searchopt.hxx>
+#include <config_features.h>
+#include "cfgutil.hxx"
+
+#if HAVE_FEATURE_SCRIPTING
+class SfxMacroInfoItem;
+#endif
+class CuiConfigFunctionListBox;
+class SfxAcceleratorConfigPage;
+class SfxStringItem;
+
+// class SfxAcceleratorConfigPage ----------------------------------------
+
+struct TAccInfo
+{
+public:
+ TAccInfo(sal_Int32 nKeyPos, sal_Int32 nListPos, const vcl::KeyCode& aKey)
+ : m_nKeyPos(nKeyPos)
+ , m_nListPos(nListPos)
+ , m_bIsConfigurable(true) /**< it's important to set true as default -
+ because only fix entries will be disabled later... */
+ , m_sCommand()
+ , m_aKey(aKey)
+ {
+ }
+
+ bool isConfigured() const
+ {
+ return (m_nKeyPos > -1 && m_nListPos > -1 && !m_sCommand.isEmpty());
+ }
+
+ sal_Int32 m_nKeyPos;
+ sal_Int32 m_nListPos;
+ bool m_bIsConfigurable;
+ OUString m_sCommand;
+ vcl::KeyCode m_aKey;
+};
+
+namespace sfx2
+{
+class FileDialogHelper;
+}
+
+enum class StartFileDialogType
+{
+ Open,
+ SaveAs
+};
+
+class SfxAcceleratorConfigPage : public SfxTabPage
+{
+private:
+#if HAVE_FEATURE_SCRIPTING
+ const SfxMacroInfoItem* m_pMacroInfoItem;
+#endif
+ std::unique_ptr<sfx2::FileDialogHelper> m_pFileDlg;
+
+ OUString aLoadAccelConfigStr;
+ OUString aSaveAccelConfigStr;
+ OUString aFilterAllStr;
+ OUString aFilterCfgStr;
+ SfxStylesInfo_Impl m_aStylesInfo;
+ bool m_bStylesInfoInitialized;
+
+ css::uno::Reference<css::uno::XComponentContext> m_xContext;
+ css::uno::Reference<css::ui::XAcceleratorConfiguration> m_xGlobal;
+ css::uno::Reference<css::ui::XAcceleratorConfiguration> m_xModule;
+ css::uno::Reference<css::ui::XAcceleratorConfiguration> m_xAct;
+ css::uno::Reference<css::container::XNameAccess> m_xUICmdDescription;
+ css::uno::Reference<css::frame::XFrame> m_xFrame;
+
+ OUString m_sModuleLongName;
+ OUString m_sModuleUIName;
+
+ // For search
+ Timer m_aUpdateDataTimer;
+ i18nutil::SearchOptions2 m_options;
+
+ Idle m_aFillGroupIdle;
+
+ std::unique_ptr<weld::TreeView> m_xEntriesBox;
+ std::unique_ptr<weld::RadioButton> m_xOfficeButton;
+ std::unique_ptr<weld::RadioButton> m_xModuleButton;
+ std::unique_ptr<weld::Button> m_xChangeButton;
+ std::unique_ptr<weld::Button> m_xRemoveButton;
+ std::unique_ptr<CuiConfigGroupListBox> m_xGroupLBox;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xFunctionBox;
+ std::unique_ptr<weld::TreeView> m_xKeyBox;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::Button> m_xLoadButton;
+ std::unique_ptr<weld::Button> m_xSaveButton;
+ std::unique_ptr<weld::Button> m_xResetButton;
+
+ DECL_LINK(ChangeHdl, weld::Button&, void);
+ DECL_LINK(RemoveHdl, weld::Button&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
+ DECL_LINK(Save, weld::Button&, void);
+ DECL_LINK(Load, weld::Button&, void);
+ DECL_LINK(Default, weld::Button&, void);
+ DECL_LINK(RadioHdl, weld::Toggleable&, void);
+ DECL_LINK(ImplUpdateDataHdl, Timer*, void);
+ DECL_LINK(FocusOut_Impl, weld::Widget&, void);
+ DECL_LINK(TimeOut_Impl, Timer*, void);
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+ DECL_LINK(LoadHdl, sfx2::FileDialogHelper*, void);
+ DECL_LINK(SaveHdl, sfx2::FileDialogHelper*, void);
+
+ OUString GetLabel4Command(const OUString& rCommand);
+ int applySearchFilter(OUString const& rSearchTerm);
+ void InitAccCfg();
+ sal_Int32 MapKeyCodeToPos(const vcl::KeyCode& rCode) const;
+ void StartFileDialog(StartFileDialogType nType, const OUString& rTitle);
+
+ void Init(const css::uno::Reference<css::ui::XAcceleratorConfiguration>& pAccMgr);
+ void ResetConfig();
+
+public:
+ SfxAcceleratorConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rItemSet);
+ virtual ~SfxAcceleratorConfigPage() override;
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+
+ void Apply(const css::uno::Reference<css::ui::XAcceleratorConfiguration>& pAccMgr);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/align.hxx b/cui/source/inc/align.hxx
new file mode 100644
index 000000000..7f4b906a3
--- /dev/null
+++ b/cui/source/inc/align.hxx
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+// list box indexes
+#define ALIGNDLG_HORALIGN_STD 0
+#define ALIGNDLG_HORALIGN_LEFT 1
+#define ALIGNDLG_HORALIGN_CENTER 2
+#define ALIGNDLG_HORALIGN_RIGHT 3
+#define ALIGNDLG_HORALIGN_BLOCK 4
+#define ALIGNDLG_HORALIGN_FILL 5
+#define ALIGNDLG_HORALIGN_DISTRIBUTED 6
+
+#define ALIGNDLG_VERALIGN_STD 0
+#define ALIGNDLG_VERALIGN_TOP 1
+#define ALIGNDLG_VERALIGN_MID 2
+#define ALIGNDLG_VERALIGN_BOTTOM 3
+#define ALIGNDLG_VERALIGN_BLOCK 4
+#define ALIGNDLG_VERALIGN_DISTRIBUTED 5
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/valueset.hxx>
+#include <svx/dialcontrol.hxx>
+#include <svx/frmdirlbox.hxx>
+#include <vcl/weld.hxx>
+
+class SfxEnumItemInterface;
+
+namespace svx {
+
+
+class AlignmentTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer s_pRanges;
+
+public:
+ virtual ~AlignmentTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ explicit AlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet);
+
+ static WhichRangesContainer GetRanges() { return s_pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ void InitVsRefEgde();
+ void UpdateEnableControls();
+
+ bool HasAlignmentChanged( const SfxItemSet& rNew, TypedWhichId<SfxEnumItemInterface> nWhich ) const;
+
+ DECL_LINK(UpdateEnableHdl, weld::ComboBox&, void);
+ DECL_LINK(StackedClickHdl, weld::Toggleable&, void);
+ DECL_LINK(AsianModeClickHdl, weld::Toggleable&, void);
+ DECL_LINK(WrapClickHdl, weld::Toggleable&, void);
+ DECL_LINK(HyphenClickHdl, weld::Toggleable&, void);
+ DECL_LINK(ShrinkClickHdl, weld::Toggleable&, void);
+
+private:
+ weld::TriStateEnabled m_aStackedState;
+ weld::TriStateEnabled m_aAsianModeState;
+ weld::TriStateEnabled m_aWrapState;
+ weld::TriStateEnabled m_aHyphenState;
+ weld::TriStateEnabled m_aShrinkState;
+
+ ValueSet m_aVsRefEdge;
+
+ std::unique_ptr<weld::ComboBox> m_xLbHorAlign;
+ std::unique_ptr<weld::Label> m_xFtIndent;
+ std::unique_ptr<weld::MetricSpinButton> m_xEdIndent;
+ std::unique_ptr<weld::Label> m_xFtVerAlign;
+ std::unique_ptr<weld::ComboBox> m_xLbVerAlign;
+
+ std::unique_ptr<weld::Label> m_xFtRotate;
+ std::unique_ptr<weld::MetricSpinButton> m_xNfRotate;
+ std::unique_ptr<weld::Label> m_xFtRefEdge;
+ std::unique_ptr<weld::CheckButton> m_xCbStacked;
+ std::unique_ptr<weld::CheckButton> m_xCbAsianMode;
+
+ std::unique_ptr<weld::Widget> m_xBoxDirection;
+ std::unique_ptr<weld::CheckButton> m_xBtnWrap;
+ std::unique_ptr<weld::CheckButton> m_xBtnHyphen;
+ std::unique_ptr<weld::CheckButton> m_xBtnShrink;
+ std::unique_ptr<svx::FrameDirectionListBox> m_xLbFrameDir;
+
+ // hidden labels/string
+ std::unique_ptr<weld::Label> m_xFtBotLock;
+ std::unique_ptr<weld::Label> m_xFtTopLock;
+ std::unique_ptr<weld::Label> m_xFtCelLock;
+ std::unique_ptr<weld::Label> m_xFtABCD;
+
+ std::unique_ptr<weld::Widget> m_xAlignmentFrame;
+ std::unique_ptr<weld::Widget> m_xOrientFrame;
+ std::unique_ptr<weld::Widget> m_xPropertiesFrame;
+
+ std::unique_ptr<weld::CustomWeld> m_xVsRefEdge;
+ std::unique_ptr<DialControl> m_xCtrlDial;
+ std::unique_ptr<weld::CustomWeld> m_xCtrlDialWin;
+};
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/autocdlg.hxx b/cui/source/inc/autocdlg.hxx
new file mode 100644
index 000000000..a1a6146fa
--- /dev/null
+++ b/cui/source/inc/autocdlg.hxx
@@ -0,0 +1,420 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+
+#include <map>
+#include <set>
+#include <utility>
+
+class CharClass;
+class CollatorWrapper;
+class SmartTagMgr;
+
+namespace editeng { class SortedAutoCompleteStrings; }
+
+// class OfaAutoCorrDlg --------------------------------------------------
+
+class OfaAutoCorrDlg : public SfxTabDialogController
+{
+ std::unique_ptr<weld::Widget> m_xLanguageBox;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+
+ DECL_LINK(SelectLanguageHdl, weld::ComboBox&, void);
+public:
+
+ OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet *pSet);
+ virtual ~OfaAutoCorrDlg() override;
+
+ void EnableLanguage(bool bEnable);
+};
+
+// class OfaAutocorrOptionsPage ------------------------------------------
+
+class OfaAutocorrOptionsPage : public SfxTabPage
+{
+private:
+ OUString m_sInput;
+ OUString m_sDoubleCaps;
+ OUString m_sStartCap;
+ OUString m_sBoldUnderline;
+ OUString m_sURL;
+ OUString m_sNoDblSpaces;
+ OUString m_sDash;
+ OUString m_sAccidentalCaps;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+
+ void InsertEntry(const OUString& rTxt);
+
+public:
+ OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaAutocorrOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+
+};
+
+// class OfaSwAutoFmtOptionsPage ----------------------------------------------------
+
+class OfaSwAutoFmtOptionsPage : public SfxTabPage
+{
+ OUString sDeleteEmptyPara;
+ OUString sUseReplaceTbl;
+ OUString sCapitalStartWord;
+ OUString sCapitalStartSentence;
+ OUString sUserStyle;
+ OUString sBullet;
+ OUString sBoldUnder;
+ OUString sNoDblSpaces;
+ OUString sCorrectCapsLock;
+ OUString sDetectURL;
+ OUString sDash;
+ OUString sRightMargin;
+ OUString sNum;
+ OUString sBorder;
+ OUString sTable;
+ OUString sReplaceTemplates;
+ OUString sDelSpaceAtSttEnd;
+ OUString sDelSpaceBetweenLines;
+
+ OUString sMargin;
+ OUString sBulletChar;
+ OUString sByInputBulletChar;
+
+ vcl::Font aBulletFont;
+ vcl::Font aByInputBulletFont;
+ sal_uInt16 nPercent;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::Button> m_xEditPB;
+
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(EditHdl, weld::Button&, void);
+ DECL_LINK(DoubleClickEditHdl, weld::TreeView&, bool);
+
+ void CreateEntry(const OUString& rTxt, sal_uInt16 nCol);
+
+public:
+ OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ virtual ~OfaSwAutoFmtOptionsPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+};
+
+// class OfaAutocorrReplacePage ------------------------------------------
+
+struct DoubleString
+{
+ OUString sShort;
+ OUString sLong;
+ void* pUserData; ///< CheckBox -> form. Text Bool -> selection text
+ DoubleString(OUString aShort, OUString aLong)
+ : sShort(std::move(aShort))
+ , sLong(std::move(aLong))
+ , pUserData(nullptr)
+ {
+ }
+};
+
+typedef std::vector<DoubleString> DoubleStringArray;
+
+struct StringChangeList
+{
+ DoubleStringArray aNewEntries;
+ DoubleStringArray aDeletedEntries;
+};
+
+typedef std::map<LanguageType, StringChangeList> StringChangeTable;
+
+class OfaAutocorrReplacePage : public SfxTabPage
+{
+private:
+
+ StringChangeTable aChangesTable;
+
+ OUString sModify;
+ OUString sNew;
+
+ std::set<OUString> aFormatText;
+ std::map<LanguageType, DoubleStringArray>
+ aDoubleStringTable;
+ std::unique_ptr<CollatorWrapper> pCompareClass;
+ std::unique_ptr<CharClass> pCharClass;
+ LanguageType eLang;
+
+ bool bHasSelectionText;
+ bool bFirstSelect:1;
+ bool bReplaceEditChanged:1;
+ bool bSWriter:1;
+
+ std::vector<int> m_aReplaceFixedWidths;
+ std::unique_ptr<weld::CheckButton> m_xTextOnlyCB;
+ std::unique_ptr<weld::Entry> m_xShortED;
+ std::unique_ptr<weld::Entry> m_xReplaceED;
+ std::unique_ptr<weld::TreeView> m_xReplaceTLB;
+ std::unique_ptr<weld::Button> m_xNewReplacePB;
+ std::unique_ptr<weld::Button> m_xReplacePB;
+ std::unique_ptr<weld::Button> m_xDeleteReplacePB;
+ std::unique_ptr<weld::Container> m_xButtonBox;
+
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(NewDelButtonHdl, weld::Button&, void);
+ DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
+ DECL_LINK(EntrySizeAllocHdl, const Size&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ bool NewDelHdl(const weld::Widget*);
+
+ void RefillReplaceBox( bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage);
+
+public:
+ OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaAutocorrReplacePage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetLanguage(LanguageType eSet);
+ void DeleteEntry(const OUString& sShort, const OUString& sLong);
+ void NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting);
+};
+
+// class OfaAutocorrExceptPage ---------------------------------------------
+
+struct StringsArrays
+{
+ std::vector<OUString> aAbbrevStrings;
+ std::vector<OUString> aDoubleCapsStrings;
+
+ StringsArrays() { }
+};
+typedef std::map<LanguageType, StringsArrays> StringsTable;
+
+class OfaAutocorrExceptPage : public SfxTabPage
+{
+private:
+ StringsTable aStringsTable;
+ std::unique_ptr<CollatorWrapper> pCompareClass;
+ LanguageType eLang;
+
+ std::unique_ptr<weld::Entry> m_xAbbrevED;
+ std::unique_ptr<weld::TreeView> m_xAbbrevLB;
+ std::unique_ptr<weld::Button> m_xNewAbbrevPB;
+ std::unique_ptr<weld::Button> m_xDelAbbrevPB;
+ std::unique_ptr<weld::CheckButton> m_xAutoAbbrevCB;
+
+ std::unique_ptr<weld::Entry> m_xDoubleCapsED;
+ std::unique_ptr<weld::TreeView> m_xDoubleCapsLB;
+ std::unique_ptr<weld::Button> m_xNewDoublePB;
+ std::unique_ptr<weld::Button> m_xDelDoublePB;
+ std::unique_ptr<weld::CheckButton> m_xAutoCapsCB;
+
+ DECL_LINK(NewDelButtonHdl, weld::Button&, void);
+ DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ bool NewDelHdl(const weld::Widget*);
+ /// Box filled with new language
+ void RefillReplaceBoxes(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage);
+public:
+ OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaAutocorrExceptPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ void SetLanguage(LanguageType eSet);
+
+};
+
+// class OfaQuoteTabPage -------------------------------------------------
+
+class OfaQuoteTabPage : public SfxTabPage
+{
+private:
+ OUString sNonBrkSpace;
+ OUString sOrdinal;
+ OUString sTransliterateRTL;
+ OUString sAngleQuotes;
+
+ sal_UCS4 cSglStartQuote;
+ sal_UCS4 cSglEndQuote;
+
+ sal_UCS4 cStartQuote;
+ sal_UCS4 cEndQuote;
+
+ std::unique_ptr<weld::CheckButton> m_xSingleTypoCB;
+ std::unique_ptr<weld::Button> m_xSglStartQuotePB;
+ std::unique_ptr<weld::Label> m_xSglStartExFT;
+ std::unique_ptr<weld::Button> m_xSglEndQuotePB;
+ std::unique_ptr<weld::Label> m_xSglEndExFT;
+ std::unique_ptr<weld::Button> m_xSglStandardPB;
+ std::unique_ptr<weld::CheckButton> m_xDoubleTypoCB;
+ std::unique_ptr<weld::Button> m_xDblStartQuotePB;
+ std::unique_ptr<weld::Label> m_xDblStartExFT;
+ std::unique_ptr<weld::Button> m_xDblEndQuotePB;
+ std::unique_ptr<weld::Label> m_xDblEndExFT;
+ std::unique_ptr<weld::Button> m_xDblStandardPB;
+ OUString m_sStandard;
+ /// For anything but writer
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ /// Just for writer
+ std::unique_ptr<weld::TreeView> m_xSwCheckLB;
+
+
+ DECL_LINK(QuoteHdl, weld::Button&, void);
+ DECL_LINK(StdQuoteHdl, weld::Button&, void);
+
+ OUString ChangeStringExt_Impl( sal_UCS4 );
+
+ static void CreateEntry(weld::TreeView& rLstBox, const OUString& rTxt,
+ sal_uInt16 nCol, sal_uInt16 nTextCol);
+
+public:
+ OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ virtual ~OfaQuoteTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+};
+
+// class OfaAutoCompleteTabPage ---------------------------------------------
+
+class OfaAutoCompleteTabPage : public SfxTabPage
+{
+private:
+ editeng::SortedAutoCompleteStrings* m_pAutoCompleteList;
+ sal_uInt16 m_nAutoCmpltListCnt;
+
+ std::unique_ptr<weld::CheckButton> m_xCBActiv; ///<Enable word completion
+ std::unique_ptr<weld::CheckButton> m_xCBAppendSpace;///<Append space
+ std::unique_ptr<weld::CheckButton> m_xCBAsTip; ///<Show as tip
+
+ std::unique_ptr<weld::CheckButton> m_xCBCollect;///<Collect words
+ std::unique_ptr<weld::CheckButton> m_xCBRemoveList;///<...save the list for later use...
+
+ std::unique_ptr<weld::ComboBox> m_xDCBExpandKey;
+ std::unique_ptr<weld::SpinButton> m_xNFMinWordlen;
+ std::unique_ptr<weld::SpinButton> m_xNFMaxEntries;
+ std::unique_ptr<weld::TreeView> m_xLBEntries;
+ std::unique_ptr<weld::Button> m_xPBEntries;
+
+ DECL_LINK(CheckHdl, weld::Toggleable&, void);
+ DECL_LINK(KeyReleaseHdl, const KeyEvent&, bool);
+
+public:
+ OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ virtual ~OfaAutoCompleteTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+
+ void CopyToClipboard() const;
+ DECL_LINK(DeleteHdl, weld::Button&, void);
+};
+
+// class OfaSmartTagOptionsTabPage ---------------------------------------------
+
+/** Smart tag options tab page
+
+ This tab page is used to enable/disable smart tag types
+*/
+class OfaSmartTagOptionsTabPage : public SfxTabPage
+{
+private:
+
+ // controls
+ std::unique_ptr<weld::CheckButton> m_xMainCB;
+ std::unique_ptr<weld::TreeView> m_xSmartTagTypesLB;
+ std::unique_ptr<weld::Button> m_xPropertiesPB;
+
+ /** Inserts items into m_aSmartTagTypesLB
+
+ Reads out the smart tag types supported by the SmartTagMgr and
+ inserts the associated strings into the list box.
+ */
+ void FillListBox( const SmartTagMgr& rSmartTagMgr );
+
+ /** Clears the m_aSmartTagTypesLB
+ */
+ void ClearListBox();
+
+ /** Handler for the check box
+
+ Enables/disables all controls in the tab page (except from the
+ check box.
+ */
+ DECL_LINK(CheckHdl, weld::Toggleable&, void);
+
+ /** Handler for the push button
+
+ Calls the displayPropertyPage function of the smart tag recognizer
+ associated with the currently selected smart tag type.
+ */
+ DECL_LINK(ClickHdl, weld::Button&, void);
+
+ /** Handler for the list box
+
+ Enables/disables the properties push button if selection in the
+ smart tag types list box changes.
+ */
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+public:
+ /// construction via Create()
+ OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaSmartTagOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/backgrnd.hxx b/cui/source/inc/backgrnd.hxx
new file mode 100644
index 000000000..450fbdaaa
--- /dev/null
+++ b/cui/source/inc/backgrnd.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+
+#include "cuitabarea.hxx"
+
+class BackgroundPreviewImpl;
+class SvxOpenGraphicDialog;
+class SvxBrushItem;
+
+/** class SvxBackgroundTabPage --------------------------------------------
+
+ [Description]
+ With this TabPage a Brush (e. g. for a frame's background color)
+ can be set.
+ [Items]
+ <SvxBrushItem>: <SID_ATTR_BRUSH>;
+*/
+
+class SvxBkgTabPage : public SvxAreaTabPage
+{
+ static const WhichRangesContainer pPageRanges;
+
+ std::unique_ptr<weld::ComboBox> m_xTblLBox;
+ bool bHighlighting : 1;
+ bool bCharBackColor : 1;
+ SfxItemSet maSet;
+ std::unique_ptr<SfxItemSet> m_pResetSet;
+
+ sal_Int32 m_nActPos = -1;
+
+ DECL_LINK(TblDestinationHdl_Impl, weld::ComboBox&, void);
+public:
+ SvxBkgTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxBkgTabPage() override;
+
+ // returns the area of the which-values
+ static WhichRangesContainer GetRanges() { return pPageRanges; }
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void PageCreated( const SfxAllItemSet& aSet ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/bbdlg.hxx b/cui/source/inc/bbdlg.hxx
new file mode 100644
index 000000000..1c7a28972
--- /dev/null
+++ b/cui/source/inc/bbdlg.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+/*--------------------------------------------------------------------
+ Description: bunch the border background pages
+ --------------------------------------------------------------------*/
+
+class SvxBorderBackgroundDlg: public SfxTabDialogController
+{
+public:
+ SvxBorderBackgroundDlg(weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableSelector,
+ bool bEnableDrawingLayerFillStyles);
+protected:
+ virtual void PageCreated(const OString& rPageId, SfxTabPage& rTabPage) override;
+
+private:
+ bool mbEnableBackgroundSelector : 1; ///< for Border/Background
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/border.hxx b/cui/source/inc/border.hxx
new file mode 100644
index 000000000..586b05f94
--- /dev/null
+++ b/cui/source/inc/border.hxx
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <editeng/shaditem.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/valueset.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/algitem.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/frmsel.hxx>
+#include <svx/flagsdef.hxx>
+#include <unotools/resmgr.hxx>
+
+#include <set>
+
+// forward ---------------------------------------------------------------
+
+namespace editeng
+{
+ class SvxBorderLine;
+}
+
+class ShadowControlsWrapper
+{
+public:
+ explicit ShadowControlsWrapper(ValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor);
+
+ SvxShadowItem GetControlValue(const SvxShadowItem& rItem) const;
+ void SetControlValue(const SvxShadowItem& rItem);
+ void SetControlDontKnow();
+
+ bool get_value_changed_from_saved() const;
+
+private:
+ ValueSet& mrVsPos;
+ weld::MetricSpinButton& mrMfSize;
+ ColorListBox& mrLbColor;
+};
+
+class MarginControlsWrapper
+{
+public:
+ explicit MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
+ weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom);
+
+ SvxMarginItem GetControlValue(const SvxMarginItem& rItem) const;
+ void SetControlValue(const SvxMarginItem& rItem);
+ void SetControlDontKnow();
+
+ bool get_value_changed_from_saved() const;
+
+private:
+ weld::MetricSpinButton& mrLeftWrp;
+ weld::MetricSpinButton& mrRightWrp;
+ weld::MetricSpinButton& mrTopWrp;
+ weld::MetricSpinButton& mrBottomWrp;
+};
+
+class SvxBorderTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pRanges;
+ static const std::vector<int> m_aLineWidths;
+
+public:
+ SvxBorderTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~SvxBorderTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rCoreAttrs ) override;
+ virtual void Reset( const SfxItemSet* ) override;
+ virtual void ChangesApplied() override;
+
+ void HideShadowControls();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+ void SetTableMode();
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ std::vector<Image> m_aShadowImgVec;
+ std::vector<Image> m_aBorderImgVec;
+
+ tools::Long nMinValue; ///< minimum distance
+ SwBorderModes nSWMode; ///< table, textframe, paragraph
+ sal_uInt16 mnBoxSlot;
+ sal_uInt16 mnShadowSlot;
+
+ bool mbHorEnabled; ///< true = Inner horizontal border enabled.
+ bool mbVerEnabled; ///< true = Inner vertical border enabled.
+ bool mbTLBREnabled; ///< true = Top-left to bottom-right border enabled.
+ bool mbBLTREnabled; ///< true = Bottom-left to top-right border enabled.
+ bool mbUseMarginItem;
+ bool mbLeftModified;
+ bool mbRightModified;
+ bool mbTopModified;
+ bool mbBottomModified;
+ bool mbSync;
+ bool mbRemoveAdjacentCellBorders;
+ bool bIsCalcDoc;
+
+ std::set<SvxBorderLineStyle> maUsedBorderStyles;
+
+ // Controls
+ svx::FrameSelector m_aFrameSel;
+ std::unique_ptr<ValueSet> m_xWndPresets;
+ std::unique_ptr<weld::CustomWeld> m_xWndPresetsWin;
+ std::unique_ptr<weld::Label> m_xUserDefFT;
+ std::unique_ptr<weld::CustomWeld> m_xFrameSelWin;
+
+ std::unique_ptr<SvtLineListBox> m_xLbLineStyle;
+ std::unique_ptr<ColorListBox> m_xLbLineColor;
+ std::unique_ptr<weld::ComboBox> m_xLineWidthLB;
+ std::unique_ptr<weld::MetricSpinButton> m_xLineWidthMF;
+
+ std::unique_ptr<weld::Container> m_xSpacingFrame;
+ std::unique_ptr<weld::Label> m_xLeftFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMF;
+ std::unique_ptr<weld::Label> m_xRightFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightMF;
+ std::unique_ptr<weld::Label> m_xTopFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMF;
+ std::unique_ptr<weld::Label> m_xBottomFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xBottomMF;
+ std::unique_ptr<weld::CheckButton> m_xSynchronizeCB;
+
+ std::unique_ptr<weld::Container> m_xShadowFrame;
+ std::unique_ptr<ValueSet> m_xWndShadows;
+ std::unique_ptr<weld::CustomWeld> m_xWndShadowsWin;
+ std::unique_ptr<weld::Label> m_xFtShadowSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xEdShadowSize;
+ std::unique_ptr<weld::Label> m_xFtShadowColor;
+ std::unique_ptr<ColorListBox> m_xLbShadowColor;
+
+ std::unique_ptr<weld::Container> m_xPropertiesFrame;///< properties - "Merge with next paragraph" in Writer
+ std::unique_ptr<weld::CheckButton> m_xMergeWithNextCB;
+ // #i29550#
+ std::unique_ptr<weld::CheckButton> m_xMergeAdjacentBordersCB;
+ std::unique_ptr<weld::CheckButton> m_xRemoveAdjacentCellBordersCB;
+ std::unique_ptr<weld::Label> m_xRemoveAdjacentCellBordersFT;
+ std::unique_ptr<ShadowControlsWrapper> m_xShadowControls;
+ std::unique_ptr<MarginControlsWrapper> m_xMarginControls;
+
+ // Handler
+ DECL_LINK(SelStyleHdl_Impl, SvtLineListBox&, void);
+ DECL_LINK(SelColHdl_Impl, ColorListBox&, void);
+ DECL_LINK(SelPreHdl_Impl, ValueSet*, void);
+ DECL_LINK(SelSdwHdl_Impl, ValueSet*, void);
+ DECL_LINK(LinesChanged_Impl, LinkParamNone*, void);
+ DECL_LINK(ModifyDistanceHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifyWidthLBHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ModifyWidthMFHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(SyncHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(RemoveAdjacentCellBorderHdl_Impl, weld::Toggleable&, void);
+
+ sal_uInt16 GetPresetImageId(sal_uInt16 nValueSetIdx) const;
+ TranslateId GetPresetStringId(sal_uInt16 nValueSetIdx) const;
+
+ void FillPresetVS();
+ void FillShadowVS();
+ void FillValueSets();
+ void SetLineWidth(sal_Int64 nWidth, sal_Int32 nRemovedType = 0);
+
+ // Filler
+ void FillLineListBox_Impl();
+
+ /// share for individual Frame-/Core-Line
+ void ResetFrameLine_Impl( svx::FrameBorderType eBorder,
+ const editeng::SvxBorderLine* pCurLine,
+ bool bValid );
+
+ bool IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) const;
+ void UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset );
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx
new file mode 100644
index 000000000..12dbae017
--- /dev/null
+++ b/cui/source/inc/cfg.hxx
@@ -0,0 +1,672 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/timer.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/weldutils.hxx>
+#include <svtools/valueset.hxx>
+
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XImageManager.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+
+#include <sfx2/tabdlg.hxx>
+#include <memory>
+#include <string_view>
+#include <vector>
+
+#include "cfgutil.hxx"
+#include "CommandCategoryListBox.hxx"
+
+inline constexpr OUStringLiteral notebookbarTabScope = u"notebookbarTabScope";
+
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL = u"CommandURL";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER = u"ItemDescriptorContainer";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL = u"Label";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_TYPE = u"Type";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_STYLE = u"Style";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_ISVISIBLE = u"IsVisible";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_RESOURCEURL = u"ResourceURL";
+inline constexpr OUStringLiteral ITEM_DESCRIPTOR_UINAME = u"UIName";
+
+inline constexpr OUStringLiteral ITEM_MENUBAR_URL = u"private:resource/menubar/menubar";
+inline constexpr OUStringLiteral ITEM_TOOLBAR_URL = u"private:resource/toolbar/";
+
+inline constexpr OUStringLiteral CUSTOM_TOOLBAR_STR = u"custom_toolbar_";
+
+inline constexpr OUStringLiteral aMenuSeparatorStr = u" | ";
+
+class SvxConfigEntry;
+class SvxConfigPage;
+
+typedef std::vector< SvxConfigEntry* > SvxEntries;
+
+class SvxConfigDialog : public SfxTabDialogController
+{
+private:
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ DECL_LINK(ActivatePageHdl, const OString&, void);
+public:
+ SvxConfigDialog(weld::Window*, const SfxItemSet*);
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+ void SetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame);
+};
+
+class SaveInData
+{
+private:
+
+ bool bModified;
+
+ bool bDocConfig;
+ bool bReadOnly;
+
+ css::uno::Reference
+ < css::ui::XUIConfigurationManager > m_xCfgMgr;
+
+ css::uno::Reference
+ < css::ui::XUIConfigurationManager > m_xParentCfgMgr;
+
+ css::uno::Reference
+ < css::ui::XImageManager > m_xImgMgr;
+
+ css::uno::Reference
+ < css::ui::XImageManager > m_xParentImgMgr;
+
+ static css::uno::Reference
+ < css::ui::XImageManager >* xDefaultImgMgr;
+
+protected:
+
+ void ApplyMenu(
+ css::uno::Reference< css::container::XIndexContainer > const & rMenuBar,
+ css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry *pMenuData );
+
+ void LoadSubMenus(
+ const css::uno::Reference< css::container::XIndexAccess >& xMenuSettings,
+ const OUString& rBaseTitle, SvxConfigEntry const * pParentData, bool bContextMenu );
+
+public:
+
+ SaveInData(
+ css::uno::Reference < css::ui::XUIConfigurationManager > xCfgMgr,
+ css::uno::Reference < css::ui::XUIConfigurationManager > xParentCfgMgr,
+ const OUString& aModuleId,
+ bool docConfig );
+
+ virtual ~SaveInData() {}
+
+ bool PersistChanges(
+ const css::uno::Reference< css::uno::XInterface >& xManager );
+
+ void SetModified( bool bValue = true ) { bModified = bValue; }
+ bool IsModified( ) const { return bModified; }
+
+ bool IsReadOnly( ) const { return bReadOnly; }
+ bool IsDocConfig( ) const { return bDocConfig; }
+
+ const css::uno::Reference
+ < css::ui::XUIConfigurationManager >&
+ GetConfigManager() const { return m_xCfgMgr; };
+
+ const css::uno::Reference
+ < css::ui::XUIConfigurationManager >&
+ GetParentConfigManager() const { return m_xParentCfgMgr; };
+
+ const css::uno::Reference
+ < css::ui::XImageManager >&
+ GetImageManager() const { return m_xImgMgr; };
+
+ const css::uno::Reference
+ < css::ui::XImageManager >&
+ GetParentImageManager() const { return m_xParentImgMgr; };
+
+ css::uno::Reference
+ < css::container::XNameAccess > m_xCommandToLabelMap;
+
+ css::uno::Sequence
+ < css::beans::PropertyValue > m_aSeparatorSeq;
+
+ css::uno::Reference<css::graphic::XGraphic> GetImage(const OUString& rCommandURL);
+
+ virtual bool HasURL( const OUString& aURL ) = 0;
+ virtual bool HasSettings() = 0;
+ virtual SvxEntries* GetEntries() = 0;
+ virtual void SetEntries( std::unique_ptr<SvxEntries> ) = 0;
+ virtual void Reset() = 0;
+ virtual bool Apply() = 0;
+};
+
+class MenuSaveInData : public SaveInData
+{
+private:
+
+ OUString m_aMenuResourceURL;
+ OUString m_aDescriptorContainer;
+
+ css::uno::Reference
+ < css::container::XIndexAccess > m_xMenuSettings;
+
+ std::unique_ptr<SvxConfigEntry> pRootEntry;
+
+
+ static MenuSaveInData* pDefaultData; ///< static holder of the default menu data
+
+ static void SetDefaultData( MenuSaveInData* pData ) {pDefaultData = pData;}
+ static MenuSaveInData* GetDefaultData() { return pDefaultData; }
+
+ void Apply(
+ css::uno::Reference< css::container::XIndexContainer > const & rNewMenuBar,
+ css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory );
+
+public:
+
+ MenuSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig );
+
+ virtual ~MenuSaveInData() override;
+
+ /// methods inherited from SaveInData
+ SvxEntries* GetEntries() override;
+ void SetEntries( std::unique_ptr<SvxEntries> ) override;
+ bool HasURL( const OUString& ) override { return false; }
+ bool HasSettings() override { return m_xMenuSettings.is(); }
+ void Reset() override;
+ bool Apply() override;
+};
+
+class ContextMenuSaveInData : public SaveInData
+{
+private:
+ std::unique_ptr< SvxConfigEntry > m_pRootEntry;
+ css::uno::Reference< css::container::XNameAccess > m_xPersistentWindowState;
+ OUString GetUIName( const OUString& rResourceURL );
+
+public:
+ ContextMenuSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId, bool bIsDocConfig );
+ virtual ~ContextMenuSaveInData() override;
+
+ SvxEntries* GetEntries() override;
+ void SetEntries( std::unique_ptr<SvxEntries> pNewEntries ) override;
+ bool HasSettings() override;
+ bool HasURL( const OUString& rURL ) override;
+ void Reset() override;
+ bool Apply() override;
+
+ void ResetContextMenu( const SvxConfigEntry* pEntry );
+};
+
+class SvxConfigEntry
+{
+private:
+
+ /// common properties
+ sal_uInt16 nId;
+ OUString aLabel;
+ OUString aCommand;
+
+ bool bPopUp;
+ bool bStrEdited;
+ bool bIsUserDefined;
+ bool bIsMain;
+ bool bIsParentData;
+ bool bIsModified;
+
+ /// toolbar specific properties
+ bool bIsVisible;
+ sal_Int32 nStyle;
+
+ css::uno::Reference<
+ css::graphic::XGraphic > xBackupGraphic;
+
+ std::unique_ptr<SvxEntries> mpEntries;
+
+public:
+
+ SvxConfigEntry( OUString aDisplayName,
+ OUString aCommandURL,
+ bool bPopup,
+ bool bParentData );
+
+ SvxConfigEntry()
+ :
+ nId( 0 ),
+ bPopUp( false ),
+ bStrEdited( false ),
+ bIsUserDefined( false ),
+ bIsMain( false ),
+ bIsParentData( false ),
+ bIsModified( false ),
+ bIsVisible( true ),
+ nStyle( 0 )
+ {}
+
+ ~SvxConfigEntry();
+
+ const OUString& GetCommand() const { return aCommand; }
+
+ const OUString& GetName() const { return aLabel; }
+ void SetName( const OUString& rStr ) { aLabel = rStr; bStrEdited = true; }
+ bool HasChangedName() const { return bStrEdited; }
+
+ bool IsPopup() const { return bPopUp; }
+
+ void SetUserDefined( bool bOn = true ) { bIsUserDefined = bOn; }
+ bool IsUserDefined() const { return bIsUserDefined; }
+
+ bool IsBinding() const { return !bPopUp; }
+ bool IsSeparator() const { return nId == 0; }
+
+ SvxEntries* GetEntries() const { return mpEntries.get(); }
+ void SetEntries( std::unique_ptr<SvxEntries> entries ) { mpEntries = std::move(entries); }
+
+ void SetMain() { bIsMain = true; }
+ bool IsMain() const { return bIsMain; }
+
+ void SetParentData( bool bValue = true ) { bIsParentData = bValue; }
+ bool IsParentData() const { return bIsParentData; }
+
+ void SetModified( bool bValue = true ) { bIsModified = bValue; }
+ bool IsModified() const { return bIsModified; }
+
+ bool IsMovable() const;
+ bool IsDeletable() const;
+ bool IsRenamable() const;
+
+ void SetVisible( bool b ) { bIsVisible = b; }
+ bool IsVisible() const { return bIsVisible; }
+
+ void SetBackupGraphic( css::uno::Reference< css::graphic::XGraphic > const & graphic )
+ { xBackupGraphic = graphic; }
+
+ const css::uno::Reference< css::graphic::XGraphic >& GetBackupGraphic() const
+ { return xBackupGraphic; }
+
+ sal_Int32 GetStyle() const { return nStyle; }
+ void SetStyle( sal_Int32 style ) { nStyle = style; }
+};
+
+class SvxMenuEntriesListBox
+{
+protected:
+ std::unique_ptr<weld::TreeView> m_xControl;
+ ScopedVclPtr<VirtualDevice> m_xDropDown;
+ SvxConfigPage* m_pPage;
+
+public:
+ SvxMenuEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxConfigPage* pPage);
+ virtual ~SvxMenuEntriesListBox();
+
+ VirtualDevice& get_dropdown_image() const { return *m_xDropDown; }
+
+ int get_selected_index() const { return m_xControl->get_selected_index(); }
+ OUString get_id(int nPos) const { return m_xControl->get_id(nPos); }
+ void remove(int nPos) { m_xControl->remove(nPos); }
+ int n_children() const { return m_xControl->n_children(); }
+ void set_text(int row, const OUString& rText, int col) { m_xControl->set_text(row, rText, col); }
+ void clear() { m_xControl->clear(); } //need frees ?
+ void set_toggle(int row, TriState eState) { m_xControl->set_toggle(row, eState); }
+ void scroll_to_row(int pos) { m_xControl->scroll_to_row(pos); }
+ void select(int pos) { m_xControl->select(pos); }
+
+ weld::TreeView& get_widget() { return *m_xControl; }
+
+ void insert(int pos, const OUString& rId)
+ {
+ m_xControl->insert(nullptr, pos, nullptr, &rId,
+ nullptr, nullptr, false, nullptr);
+ }
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+ void CreateDropDown();
+};
+
+class SvxConfigPageFunctionDropTarget : public weld::ReorderingDropTarget
+{
+private:
+ SvxConfigPage& m_rPage;
+
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
+
+public:
+ SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& rTreeView);
+};
+
+class SvxConfigPage : public SfxTabPage
+{
+private:
+
+ Timer m_aUpdateDataTimer;
+ bool bInitialised;
+ SaveInData* pCurrentSaveInData;
+
+ DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
+
+protected:
+
+ /// the ResourceURL to select when opening the dialog
+ OUString m_aURLToSelect;
+
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ OUString m_aModuleId;
+
+ // Left side of the dialog where command categories and the available
+ // commands in them are displayed as a searchable list
+ std::unique_ptr<CommandCategoryListBox> m_xCommandCategoryListBox;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xFunctions;
+
+ std::unique_ptr<weld::Label> m_xCategoryLabel;
+ std::unique_ptr<weld::Label> m_xDescriptionFieldLb;
+ std::unique_ptr<weld::TextView> m_xDescriptionField;
+ std::unique_ptr<weld::Label> m_xLeftFunctionLabel;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::Label> m_xSearchLabel;
+
+
+ // Right side of the dialog where the contents of the selected
+ // menu or toolbar are displayed
+ std::unique_ptr<weld::Label> m_xCustomizeLabel;
+ std::unique_ptr<weld::ComboBox> m_xTopLevelListBox;
+ // Used to add and remove toolbars/menus
+ std::unique_ptr<weld::MenuButton> m_xGearBtn;
+ std::unique_ptr<SvxMenuEntriesListBox> m_xContentsListBox;
+ std::unique_ptr<SvxConfigPageFunctionDropTarget> m_xDropTargetHelper;
+
+ std::unique_ptr<weld::Button> m_xMoveUpButton;
+ std::unique_ptr<weld::Button> m_xMoveDownButton;
+
+ std::unique_ptr<weld::ComboBox> m_xSaveInListBox;
+
+ std::unique_ptr<weld::MenuButton> m_xInsertBtn;
+ std::unique_ptr<weld::MenuButton> m_xModifyBtn;
+ // Used to reset the selected toolbar/menu/context menu
+ std::unique_ptr<weld::Button> m_xResetBtn;
+
+ // Middle buttons
+ std::unique_ptr<weld::Button> m_xAddCommandButton;
+ std::unique_ptr<weld::Button> m_xRemoveCommandButton;
+
+ OUString m_sAppName;
+ OUString m_sFileName;
+
+ SvxConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet&);
+
+ DECL_LINK(MoveHdl, weld::Button&, void);
+ DECL_LINK(SelectFunctionHdl, weld::TreeView&, void);
+ DECL_LINK(FunctionDoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(SelectSaveInLocation, weld::ComboBox&, void);
+ DECL_LINK(SelectElementHdl, weld::ComboBox&, void);
+ DECL_LINK(ImplUpdateDataHdl, Timer*, void);
+ DECL_LINK(FocusOut_Impl, weld::Widget&, void);
+
+ virtual SaveInData* CreateSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig ) = 0;
+
+ virtual void Init() = 0;
+ virtual void UpdateButtonStates() = 0;
+ virtual short QueryReset() = 0;
+
+ virtual void SelectElement() = 0;
+
+ int AppendEntry(SvxConfigEntry* pNewEntryData,
+ int nTarget);
+
+ void AddSubMenusToUI( std::u16string_view rBaseTitle,
+ SvxConfigEntry const * pParentData );
+
+ void InsertEntryIntoUI(SvxConfigEntry* pNewEntryData,
+ weld::TreeView& rTreeView, int nPos,
+ bool bMenu = false);
+ void InsertEntryIntoUI(SvxConfigEntry* pNewEntryData,
+ weld::TreeView& rTreeView, weld::TreeIter& rIter,
+ bool bMenu = false);
+
+ void InsertEntryIntoNotebookbarTabUI(std::u16string_view sClassId, const OUString& sUIItemId,
+ const OUString& sUIItemCommand,
+ weld::TreeView& rTreeView, const weld::TreeIter& rIter);
+
+ SvxEntries* FindParentForChild( SvxEntries* pParentEntries,
+ SvxConfigEntry* pChildData );
+
+ void ReloadTopLevelListBox( SvxConfigEntry const * pSelection = nullptr );
+
+ static bool IsCommandInMenuList(const SvxConfigEntry *pEntryData,
+ const SvxEntries *pEntries);
+
+ SvxConfigEntry *CreateCommandFromSelection(const OUString &aURL);
+
+public:
+
+ virtual ~SvxConfigPage() override;
+
+ static bool CanConfig( std::u16string_view rModuleId );
+
+ SaveInData* GetSaveInData() { return pCurrentSaveInData; }
+ const OUString& GetAppName() const { return m_sAppName; }
+ const OUString& GetFileName() const { return m_sFileName; }
+
+ int AddFunction(int nTarget,
+ bool bAllowDuplicates);
+
+ virtual void MoveEntry( bool bMoveUp );
+
+ bool MoveEntryData(int SourceEntry, int nTargetEntry);
+
+ bool FillItemSet( SfxItemSet* ) override;
+ void Reset( const SfxItemSet* ) override;
+
+ virtual void DeleteSelectedContent() = 0;
+ virtual void DeleteSelectedTopLevel() = 0;
+
+ virtual void ListModified() {}
+
+ SvxConfigEntry* GetTopLevelSelection()
+ {
+ return weld::fromId<SvxConfigEntry*>(m_xTopLevelListBox->get_active_id());
+ }
+
+ /** identifies the module in the given frame. If the frame is <NULL/>, a default
+ frame will be determined beforehand.
+
+ If the given frame is <NULL/>, a default frame will be used: The method the active
+ frame of the desktop, then the current frame. If both are <NULL/>,
+ the SfxViewFrame::Current's XFrame is used. If this is <NULL/>, too, an empty string is returned.
+
+ If the given frame is not <NULL/>, or a default frame could be successfully determined, then
+ the ModuleManager is asked for the module ID of the component in the frame.
+ */
+ static OUString
+ GetFrameWithDefaultAndIdentify( css::uno::Reference< css::frame::XFrame >& _inout_rxFrame );
+
+ OUString GetScriptURL() const;
+ OUString GetSelectedDisplayName() const;
+};
+
+class SvxMainMenuOrganizerDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<SvxEntries> mpEntries;
+ OUString m_sNewMenuEntryId;
+
+ std::unique_ptr<weld::Widget> m_xMenuBox;
+ std::unique_ptr<weld::Entry> m_xMenuNameEdit;
+ std::unique_ptr<weld::TreeView> m_xMenuListBox;
+ std::unique_ptr<weld::Button> m_xMoveUpButton;
+ std::unique_ptr<weld::Button> m_xMoveDownButton;
+
+ void UpdateButtonStates();
+
+ DECL_LINK(MoveHdl, weld::Button&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+public:
+ SvxMainMenuOrganizerDialog(
+ weld::Window*, SvxEntries*,
+ SvxConfigEntry const *, bool bCreateMenu);
+ virtual ~SvxMainMenuOrganizerDialog() override;
+
+ std::unique_ptr<SvxEntries> ReleaseEntries() { return std::move(mpEntries);}
+ SvxConfigEntry* GetSelectedEntry();
+};
+
+class ToolbarSaveInData : public SaveInData
+{
+private:
+
+ std::unique_ptr<SvxConfigEntry> pRootEntry;
+ OUString m_aDescriptorContainer;
+
+ css::uno::Reference
+ < css::container::XNameAccess > m_xPersistentWindowState;
+
+ void LoadToolbar(
+ const css::uno::Reference< css::container::XIndexAccess >& xToolBarSettings,
+ SvxConfigEntry const * pParentData );
+
+ void ApplyToolbar(
+ css::uno::Reference< css::container::XIndexContainer > const & rNewToolbarBar,
+ css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry const *pToolbar );
+
+public:
+
+ ToolbarSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig );
+
+ virtual ~ToolbarSaveInData() override;
+
+ void CreateToolbar( SvxConfigEntry* pToolbar );
+ void RestoreToolbar( SvxConfigEntry* pToolbar );
+ void RemoveToolbar( SvxConfigEntry* pToolbar );
+ void ApplyToolbar( SvxConfigEntry* pToolbar );
+
+ OUString GetSystemUIName( const OUString& rResourceURL );
+
+ sal_Int32 GetSystemStyle( const OUString& rResourceURL );
+
+ void SetSystemStyle( const OUString& rResourceURL, sal_Int32 nStyle );
+
+ void SetSystemStyle(
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& rResourceURL, sal_Int32 nStyle );
+
+ SvxEntries* GetEntries() override;
+ void SetEntries( std::unique_ptr<SvxEntries> ) override;
+ bool HasSettings() override;
+ bool HasURL( const OUString& rURL ) override;
+ void Reset() override;
+ bool Apply() override;
+};
+
+class SvxNewToolbarDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<weld::Button> m_xBtnOK;
+public:
+ std::unique_ptr<weld::ComboBox> m_xSaveInListBox;
+
+ SvxNewToolbarDialog(weld::Window* pWindow, const OUString& rName);
+ virtual ~SvxNewToolbarDialog() override;
+
+ OUString GetName() const
+ {
+ return m_xEdtName->get_text();
+ }
+};
+
+class SvxIconSelectorDialog : public weld::GenericDialogController
+{
+private:
+ sal_Int32 m_nExpectedSize;
+
+ css::uno::Reference<
+ css::ui::XImageManager > m_xImageManager;
+
+ css::uno::Reference<
+ css::ui::XImageManager > m_xParentImageManager;
+
+ css::uno::Reference<
+ css::ui::XImageManager > m_xImportedImageManager;
+
+ css::uno::Reference<
+ css::graphic::XGraphicProvider > m_xGraphProvider;
+
+ std::vector<css::uno::Reference<css::graphic::XGraphic>> m_aGraphics;
+
+ std::unique_ptr<ValueSet> m_xTbSymbol;
+ std::unique_ptr<weld::CustomWeld> m_xTbSymbolWin;
+ std::unique_ptr<weld::Label> m_xFtNote;
+ std::unique_ptr<weld::Button> m_xBtnImport;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+
+ bool ReplaceGraphicItem( const OUString& aURL );
+
+ bool ImportGraphic( const OUString& aURL );
+
+ void ImportGraphics( const css::uno::Sequence< OUString >& aURLs );
+
+public:
+
+ SvxIconSelectorDialog(
+ weld::Window *pWindow,
+ css::uno::Reference< css::ui::XImageManager > xImageManager,
+ css::uno::Reference< css::ui::XImageManager > xParentImageManager);
+
+ virtual ~SvxIconSelectorDialog() override;
+
+ css::uno::Reference< css::graphic::XGraphic >
+ GetSelectedIcon();
+
+ DECL_LINK(SelectHdl, ValueSet*, void);
+ DECL_LINK(ImportHdl, weld::Button&, void);
+ DECL_LINK(DeleteHdl, weld::Button&, void);
+};
+
+//added for issue83555
+class SvxIconChangeDialog : public weld::MessageDialogController
+{
+private:
+ std::unique_ptr<weld::TextView> m_xLineEditDescription;
+public:
+ SvxIconChangeDialog(weld::Window *pWindow, const OUString& rMessage);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cfgutil.hxx b/cui/source/inc/cfgutil.hxx
new file mode 100644
index 000000000..d4da1e76f
--- /dev/null
+++ b/cui/source/inc/cfgutil.hxx
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vector>
+#include <memory>
+#include <string_view>
+
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/frame/DispatchInformation.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <vcl/weld.hxx>
+#include <config_features.h>
+
+class Button;
+class SaveInData;
+#if HAVE_FEATURE_SCRIPTING
+class SfxMacroInfoItem;
+#endif
+
+struct SfxStyleInfo_Impl
+{
+ OUString sFamily;
+ OUString sStyle;
+ OUString sCommand;
+ OUString sLabel;
+
+ SfxStyleInfo_Impl()
+ {}
+
+ SfxStyleInfo_Impl(const SfxStyleInfo_Impl& rCopy)
+ {
+ sFamily = rCopy.sFamily;
+ sStyle = rCopy.sStyle;
+ sCommand = rCopy.sCommand;
+ sLabel = rCopy.sLabel;
+ }
+};
+
+struct SfxStylesInfo_Impl
+{
+private:
+ OUString m_aModuleName;
+ css::uno::Reference< css::frame::XModel > m_xDoc;
+
+public:
+
+ SfxStylesInfo_Impl();
+ void init(const OUString& rModuleName, const css::uno::Reference< css::frame::XModel >& xModel);
+
+ static bool parseStyleCommand(SfxStyleInfo_Impl& aStyle);
+ void getLabel4Style(SfxStyleInfo_Impl& aStyle);
+
+ std::vector< SfxStyleInfo_Impl > getStyleFamilies() const;
+ std::vector< SfxStyleInfo_Impl > getStyles(const OUString& sFamily);
+
+ static OUString generateCommand(std::u16string_view sFamily, std::u16string_view sStyle);
+};
+
+enum class SfxCfgKind
+{
+ GROUP_FUNCTION = 1,
+ FUNCTION_SLOT = 2,
+ GROUP_SCRIPTCONTAINER = 3,
+ FUNCTION_SCRIPT = 4,
+ GROUP_STYLES = 5,
+ GROUP_ALLFUNCTIONS = 6,
+ GROUP_SIDEBARDECKS = 7
+};
+
+struct SfxGroupInfo_Impl
+{
+ SfxCfgKind nKind;
+ sal_uInt16 nUniqueID;
+ void* pObject;
+ OUString sCommand;
+ OUString sLabel;
+ OUString sHelpText;
+ OUString sTooltip;
+
+ SfxGroupInfo_Impl( SfxCfgKind n, sal_uInt16 nr, void* pObj = nullptr ) :
+ nKind( n ), nUniqueID( nr ), pObject( pObj ) {}
+};
+
+typedef std::vector<std::unique_ptr<SfxGroupInfo_Impl> > SfxGroupInfoArr_Impl;
+
+class CuiConfigFunctionListBox
+{
+ friend class CuiConfigGroupListBox;
+ SfxGroupInfoArr_Impl aArr;
+
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+
+public:
+ CuiConfigFunctionListBox(std::unique_ptr<weld::TreeView> xTreeView);
+ void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
+ void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xTreeView->connect_changed(rLink); }
+ void connect_popup_menu(const Link<const CommandEvent&, bool>& rLink) { m_xTreeView->connect_popup_menu(rLink); }
+ void connect_row_activated(const Link<weld::TreeView&, bool>& rLink) { m_xTreeView->connect_row_activated(rLink); }
+ void freeze() { m_xTreeView->freeze(); }
+ void thaw() { m_xTreeView->thaw(); }
+ void append(const OUString& rId, const OUString& rStr, const weld::TreeIter* pParent = nullptr)
+ {
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, false, nullptr);
+ }
+ std::unique_ptr<weld::TreeIter> tree_append(const OUString& rId, const OUString& rStr, const weld::TreeIter* pParent = nullptr)
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, false, xIter.get());
+ return xIter;
+ }
+ void append(const OUString& rId, const OUString& rStr, const OUString& rImage, const weld::TreeIter* pParent = nullptr)
+ {
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xTreeView->set_image(*m_xScratchIter, rImage);
+ }
+ void append(const OUString& rId, const OUString& rStr, const css::uno::Reference<css::graphic::XGraphic>& rImage, const weld::TreeIter* pParent = nullptr)
+ {
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xTreeView->set_image(*m_xScratchIter, rImage, -1);
+ }
+ void remove(int nPos) { m_xTreeView->remove(nPos); }
+ void scroll_to_row(int pos) { m_xTreeView->scroll_to_row(pos); }
+ void remove(const weld::TreeIter& rIter) { m_xTreeView->remove(rIter); }
+ void expand_row(const weld::TreeIter& rIter) { m_xTreeView->expand_row(rIter); }
+ int n_children() const { return m_xTreeView->n_children(); }
+ std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig = nullptr) const { return m_xTreeView->make_iterator(pOrig); }
+ bool iter_has_child(const weld::TreeIter& rIter) const { return m_xTreeView->iter_has_child(rIter); }
+ OUString get_text(int nPos) const { return m_xTreeView->get_text(nPos); }
+ OUString get_id(const weld::TreeIter& rIter) const { return m_xTreeView->get_id(rIter); }
+ bool get_selected(weld::TreeIter* pIter) const { return m_xTreeView->get_selected(pIter); }
+ OUString get_selected_text() const
+ {
+ if (!m_xTreeView->get_selected(m_xScratchIter.get()))
+ return OUString();
+ return m_xTreeView->get_text(*m_xScratchIter);
+ }
+ OUString get_selected_id() const
+ {
+ if (!m_xTreeView->get_selected(m_xScratchIter.get()))
+ return OUString();
+ return m_xTreeView->get_id(*m_xScratchIter);
+ }
+ void select(int pos) { m_xTreeView->select(pos); }
+ void set_size_request(int nWidth, int nHeight) { m_xTreeView->set_size_request(nWidth, nHeight); }
+ Size get_size_request() const { return m_xTreeView->get_size_request(); }
+ weld::TreeView& get_widget() { return *m_xTreeView; }
+
+ ~CuiConfigFunctionListBox();
+
+ void ClearAll();
+ OUString GetSelectedScriptURI() const;
+ OUString GetHelpText( bool bConsiderParent = true );
+ OUString GetCurCommand() const;
+ OUString GetCurLabel() const;
+
+ DECL_LINK(QueryTooltip, const weld::TreeIter& rIter, OUString);
+};
+
+struct SvxConfigGroupBoxResource_Impl;
+class CuiConfigGroupListBox
+{
+ std::unique_ptr<SvxConfigGroupBoxResource_Impl> xImp;
+ CuiConfigFunctionListBox* m_pFunctionListBox;
+ SfxGroupInfoArr_Impl aArr;
+ OUString m_sModuleLongName;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ css::uno::Reference< css::container::XNameAccess > m_xGlobalCategoryInfo;
+ css::uno::Reference< css::container::XNameAccess > m_xModuleCategoryInfo;
+ css::uno::Reference< css::container::XNameAccess > m_xUICmdDescription;
+ SfxStylesInfo_Impl* m_pStylesInfo;
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+
+ static OUString GetImage(
+ const css::uno::Reference< css::script::browse::XBrowseNode >& node,
+ css::uno::Reference< css::uno::XComponentContext > const & xCtx,
+ bool bIsRootNode);
+
+ static css::uno::Reference< css::uno::XInterface > getDocumentModel(
+ css::uno::Reference< css::uno::XComponentContext > const & xCtx,
+ std::u16string_view docName);
+
+ void InitModule();
+ void FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
+ const weld::TreeIter* pParentEntry);
+ void FillFunctionsList(const css::uno::Sequence< css::frame::DispatchInformation >& xCommands);
+ OUString MapCommand2UIName(const OUString& sCommand);
+
+ DECL_LINK(ExpandingHdl, const weld::TreeIter&, bool);
+
+public:
+ CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView);
+ void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
+ void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xTreeView->connect_changed(rLink); }
+ void set_size_request(int nWidth, int nHeight) { m_xTreeView->set_size_request(nWidth, nHeight); }
+ weld::TreeView& get_widget() { return *m_xTreeView; }
+ ~CuiConfigGroupListBox();
+ void ClearAll();
+
+ void Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& sModuleLongName,
+ bool bEventMode);
+ void SetFunctionListBox( CuiConfigFunctionListBox *pBox )
+ { m_pFunctionListBox = pBox; }
+ void GroupSelected();
+#if HAVE_FEATURE_SCRIPTING
+ void SelectMacro(const SfxMacroInfoItem*);
+ void SelectMacro(std::u16string_view, std::u16string_view);
+#endif
+ void SetStylesInfo(SfxStylesInfo_Impl* pStyles);
+};
+
+class SvxScriptSelectorDialog : public weld::GenericDialogController
+{
+ OUString m_sDefaultDesc;
+ SfxStylesInfo_Impl m_aStylesInfo;
+
+ std::unique_ptr<weld::Label> m_xDialogDescription;
+ std::unique_ptr<CuiConfigGroupListBox> m_xCategories;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xCommands;
+ std::unique_ptr<weld::Label> m_xLibraryFT;
+ std::unique_ptr<weld::Label> m_xMacronameFT;
+ std::unique_ptr<weld::Button> m_xOKButton;
+ std::unique_ptr<weld::Button> m_xCancelButton;
+ std::unique_ptr<weld::TextView> m_xDescriptionText;
+ std::unique_ptr<weld::Frame> m_xDescriptionFrame;
+
+ DECL_LINK(ClickHdl, weld::Button&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(FunctionDoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(ContextMenuHdl, const CommandEvent&, bool);
+
+ void UpdateUI();
+
+public:
+ SvxScriptSelectorDialog(weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& xFrame);
+ virtual ~SvxScriptSelectorDialog() override;
+
+ OUString GetScriptURL() const;
+ void SetRunLabel();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx
new file mode 100644
index 000000000..e61675c1e
--- /dev/null
+++ b/cui/source/inc/chardlg.hxx
@@ -0,0 +1,341 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svtools/ctrlbox.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/fntctrl.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/langbox.hxx>
+#include <vcl/weld.hxx>
+#include <memory>
+
+// forward ---------------------------------------------------------------
+
+class SvxFontListItem;
+class FontList;
+
+class SvxCharBasePage : public SfxTabPage
+{
+protected:
+ SvxFontPrevWindow m_aPreviewWin;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWin;
+
+ bool m_bPreviewBackgroundToCharacter;
+
+ SvxCharBasePage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rAttrSet);
+
+ void SetPrevFontWidthScale( const SfxItemSet& rSet );
+ void SetPrevFontEscapement( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc );
+
+ inline SvxFont& GetPreviewFont();
+ inline SvxFont& GetPreviewCJKFont();
+ inline SvxFont& GetPreviewCTLFont();
+
+public:
+ virtual ~SvxCharBasePage() override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+};
+
+// class SvxCharNamePage -------------------------------------------------
+
+struct SvxCharNamePage_Impl;
+
+class SvxCharNamePage : public SvxCharBasePage
+{
+private:
+ static const WhichRangesContainer pNameRanges;
+
+ std::unique_ptr<SvxCharNamePage_Impl> m_pImpl;
+
+ std::unique_ptr<weld::Notebook> m_xWestern;
+ std::unique_ptr<weld::Label> m_xWestFontNameFT;
+ std::unique_ptr<weld::ComboBox> m_xWestFontNameLB;
+ std::unique_ptr<weld::Label> m_xWestFontStyleFT;
+ std::unique_ptr<FontStyleBox> m_xWestFontStyleLB;
+ std::unique_ptr<weld::Label> m_xWestFontSizeFT;
+ std::unique_ptr<FontSizeBox> m_xWestFontSizeLB;
+ std::unique_ptr<weld::Label> m_xWestFontLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xWestFontLanguageLB;
+ std::unique_ptr<weld::Button> m_xWestFontFeaturesButton;
+ std::unique_ptr<weld::Label> m_xWestFontTypeFT;
+
+ std::unique_ptr<weld::Notebook> m_xCJK_CTL;
+ std::unique_ptr<weld::Label> m_xEastFontNameFT;
+ std::unique_ptr<weld::ComboBox> m_xEastFontNameLB;
+ std::unique_ptr<weld::Label> m_xEastFontStyleFT;
+ std::unique_ptr<FontStyleBox> m_xEastFontStyleLB;
+ std::unique_ptr<weld::Label> m_xEastFontSizeFT;
+ std::unique_ptr<FontSizeBox> m_xEastFontSizeLB;
+ std::unique_ptr<weld::Label> m_xEastFontLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xEastFontLanguageLB;
+ std::unique_ptr<weld::Button> m_xEastFontFeaturesButton;
+ std::unique_ptr<weld::Label> m_xEastFontTypeFT;
+
+ std::unique_ptr<weld::Label> m_xCTLFontNameFT;
+ std::unique_ptr<weld::ComboBox> m_xCTLFontNameLB;
+ std::unique_ptr<weld::Label> m_xCTLFontStyleFT;
+ std::unique_ptr<FontStyleBox> m_xCTLFontStyleLB;
+ std::unique_ptr<weld::Label> m_xCTLFontSizeFT;
+ std::unique_ptr<FontSizeBox> m_xCTLFontSizeLB;
+ std::unique_ptr<weld::Label> m_xCTLFontLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xCTLFontLanguageLB;
+ std::unique_ptr<weld::Button> m_xCTLFontFeaturesButton;
+ std::unique_ptr<weld::Label> m_xCTLFontTypeFT;
+
+ //for getting FontFeatures
+ ScopedVclPtrInstance<VirtualDevice> m_xVDev;
+
+ void Initialize();
+ const FontList* GetFontList() const;
+ void UpdatePreview_Impl();
+ void FillStyleBox_Impl(const weld::Widget& rBox);
+ void FillSizeBox_Impl(const weld::Widget& rBox);
+ void EnableFeatureButton(const weld::Widget& rNameBox);
+
+ enum LanguageGroup
+ {
+ /** Language for western text.
+ */
+ Western = 0,
+
+ /** Language for asian text.
+ */
+ Asian,
+
+ /** Language for ctl text.
+ */
+ Ctl
+ };
+
+ void Reset_Impl( const SfxItemSet& rSet, LanguageGroup eLangGrp );
+ bool FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp );
+
+ DECL_LINK(UpdateHdl_Impl, Timer *, void );
+ DECL_LINK(FontModifyComboBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(FontFeatureButtonClicked, weld::Button&, void);
+
+ void FontModifyHdl_Impl(const weld::Widget&);
+
+public:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxCharNamePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharNamePage() override;
+
+ static WhichRangesContainer GetRanges() { return pNameRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void SetFontList( const SvxFontListItem& rItem );
+ void EnableRelativeMode();
+ void EnableSearchMode();
+
+ void DisableControls( sal_uInt16 nDisable );
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxCharEffectsPage ----------------------------------------------
+
+class SvxCharEffectsPage : public SvxCharBasePage
+{
+private:
+ static const WhichRangesContainer pEffectsRanges;
+ bool m_bOrigFontColor;
+ bool m_bNewFontColor;
+ bool m_bEnableNoneFontColor;
+ Color m_aOrigFontColor;
+ sal_uInt16 m_nHtmlMode;
+
+ weld::TriStateEnabled m_aOutlineState;
+ weld::TriStateEnabled m_aShadowState;
+ weld::TriStateEnabled m_aHiddenState;
+ weld::TriStateEnabled m_aIndividualWordsState;
+
+ std::unique_ptr<weld::Label> m_xFontColorFT;
+ std::unique_ptr<ColorListBox> m_xFontColorLB;
+ std::unique_ptr<weld::Label> m_xFontTransparencyFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xFontTransparencyMtr;
+ std::unique_ptr<weld::Label> m_xEffectsFT;
+ std::unique_ptr<weld::ComboBox> m_xEffectsLB;
+ std::unique_ptr<weld::Label> m_xReliefFT;
+ std::unique_ptr<weld::ComboBox> m_xReliefLB;
+ std::unique_ptr<weld::CheckButton> m_xOutlineBtn;
+ std::unique_ptr<weld::CheckButton> m_xShadowBtn;
+ std::unique_ptr<weld::CheckButton> m_xHiddenBtn;
+ std::unique_ptr<weld::ComboBox> m_xOverlineLB;
+ std::unique_ptr<weld::Label> m_xOverlineColorFT;
+ std::unique_ptr<ColorListBox> m_xOverlineColorLB;
+ std::unique_ptr<weld::ComboBox> m_xStrikeoutLB;
+ std::unique_ptr<weld::ComboBox> m_xUnderlineLB;
+ std::unique_ptr<weld::Label> m_xUnderlineColorFT;
+ std::unique_ptr<ColorListBox> m_xUnderlineColorLB;
+ std::unique_ptr<weld::CheckButton> m_xIndividualWordsBtn;
+ std::unique_ptr<weld::Label> m_xEmphasisFT;
+ std::unique_ptr<weld::ComboBox> m_xEmphasisLB;
+ std::unique_ptr<weld::Label> m_xPositionFT;
+ std::unique_ptr<weld::ComboBox> m_xPositionLB;
+ std::unique_ptr<weld::Label> m_xA11yWarningFT;
+
+ void Initialize();
+ void UpdatePreview_Impl();
+ void SetCaseMap_Impl( SvxCaseMap eCaseMap );
+ void ResetColor_Impl( const SfxItemSet& rSet );
+ bool FillItemSetColor_Impl( SfxItemSet& rSet );
+ void EnableNoneFontColor();
+
+ void SelectHdl_Impl(const weld::ComboBox*);
+ DECL_LINK(SelectListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(OutlineBtnClickHdl, weld::Toggleable&, void);
+ DECL_LINK(ShadowBtnClickHdl, weld::Toggleable&, void);
+ DECL_LINK(HiddenBtnClickHdl, weld::Toggleable&, void);
+ DECL_LINK(CbClickHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ColorBoxSelectHdl_Impl, ColorListBox&, void);
+ DECL_LINK(ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void);
+
+public:
+ SvxCharEffectsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharEffectsPage() override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ static WhichRangesContainer GetRanges() { return pEffectsRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void DisableControls( sal_uInt16 nDisable );
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxCharPositionPage ---------------------------------------------
+class SvxCharPositionPage : public SvxCharBasePage
+{
+ static const WhichRangesContainer pPositionRanges;
+
+private:
+ short m_nSuperEsc;
+ short m_nSubEsc;
+
+ sal_uInt16 m_nScaleWidthItemSetVal;
+ sal_uInt16 m_nScaleWidthInitialVal;
+
+ sal_uInt8 m_nSuperProp;
+ sal_uInt8 m_nSubProp;
+
+ std::unique_ptr<weld::RadioButton> m_xHighPosBtn;
+ std::unique_ptr<weld::RadioButton> m_xNormalPosBtn;
+ std::unique_ptr<weld::RadioButton> m_xLowPosBtn;
+ std::unique_ptr<weld::Label> m_xHighLowFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xHighLowMF;
+ std::unique_ptr<weld::CheckButton> m_xHighLowRB;
+ std::unique_ptr<weld::Label> m_xFontSizeFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xFontSizeMF;
+
+ std::unique_ptr<weld::Widget> m_xRotationContainer;
+
+ std::unique_ptr<weld::Label> m_xScalingFT;
+ std::unique_ptr<weld::Label> m_xScalingAndRotationFT;
+ std::unique_ptr<weld::RadioButton> m_x0degRB;
+ std::unique_ptr<weld::RadioButton> m_x90degRB;
+ std::unique_ptr<weld::RadioButton> m_x270degRB;
+ std::unique_ptr<weld::CheckButton> m_xFitToLineCB;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xScaleWidthMF;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xKerningMF;
+ std::unique_ptr<weld::CheckButton> m_xPairKerningBtn;
+
+ void Initialize();
+ void UpdatePreview_Impl( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc );
+ void SetEscapement_Impl( SvxEscapement nEsc );
+
+ DECL_LINK(PositionHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(RotationHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(AutoPositionHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(FitToLineHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(KerningModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ValueChangedHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ScaleWidthModifyHdl_Impl, weld::MetricSpinButton&, void);
+ void FontModifyHdl_Impl();
+
+public:
+ SvxCharPositionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharPositionPage() override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ static WhichRangesContainer GetRanges() { return pPositionRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+ virtual void FillUserData() override;
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxCharTwoLinesPage ---------------------------------------------
+
+class SvxCharTwoLinesPage : public SvxCharBasePage
+{
+private:
+ static const WhichRangesContainer pTwoLinesRanges;
+ sal_uInt16 m_nStartBracketPosition;
+ sal_uInt16 m_nEndBracketPosition;
+
+ std::unique_ptr<weld::CheckButton> m_xTwoLinesBtn;
+ std::unique_ptr<weld::Widget> m_xEnclosingFrame;
+ std::unique_ptr<weld::TreeView> m_xStartBracketLB;
+ std::unique_ptr<weld::TreeView> m_xEndBracketLB;
+
+ void UpdatePreview_Impl();
+ void Initialize();
+ void SelectCharacter(weld::TreeView* pBox);
+ void SetBracket(sal_Unicode cBracket, bool bStart);
+
+ DECL_LINK(TwoLinesHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(CharacterMapHdl_Impl, weld::TreeView&, void);
+
+public:
+ SvxCharTwoLinesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharTwoLinesPage() override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ static WhichRangesContainer GetRanges() { return pTwoLinesRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/connect.hxx b/cui/source/inc/connect.hxx
new file mode 100644
index 000000000..8b7119f0d
--- /dev/null
+++ b/cui/source/inc/connect.hxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svx/connctrl.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/basedlgs.hxx>
+
+class SdrView;
+
+/// Dialog for changing connectors.
+class SvxConnectionPage : public SfxTabPage
+{
+private:
+ static const WhichRangesContainer pRanges;
+ const SfxItemSet& rOutAttrs;
+ SfxItemSet aAttrSet;
+ const SdrView* pView;
+ MapUnit eUnit;
+
+ SvxXConnectionPreview m_aCtlPreview;
+ std::unique_ptr<weld::ComboBox> m_xLbType;
+ std::unique_ptr<weld::Label> m_xFtLine1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLine1;
+ std::unique_ptr<weld::Label> m_xFtLine2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLine2;
+ std::unique_ptr<weld::Label> m_xFtLine3;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLine3;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHorz1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldVert1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHorz2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldVert2;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ void FillTypeLB();
+
+ DECL_LINK(ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void);
+
+public:
+
+ SvxConnectionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxConnectionPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* Derived from SfxSingleTabDialogController, in order to be informed about
+ virtual methods by the control. */
+class SvxConnectionDialog : public SfxSingleTabDialogController
+{
+public:
+ SvxConnectionDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ const SdrView* pView);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuifmsearch.hxx b/cui/source/inc/cuifmsearch.hxx
new file mode 100644
index 000000000..29484ef8f
--- /dev/null
+++ b/cui/source/inc/cuifmsearch.hxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include <svx/fmsearch.hxx>
+#include <vcl/weld.hxx>
+#include <tools/link.hxx>
+#include <rtl/ustring.hxx>
+
+namespace svxform
+{
+class FmSearchConfigItem;
+}
+
+struct FmSearchProgress;
+
+class FmSearchEngine;
+
+/// Dialog for searching in Forms/Tables
+class FmSearchDialog final : public weld::GenericDialogController
+{
+ friend class FmSearchEngine;
+
+ OUString m_sSearch;
+ OUString m_sCancel;
+
+ Link<FmFoundRecordInformation&, void> m_lnkFoundHandler; ///< Handler for "found"
+ Link<FmFoundRecordInformation&, void>
+ m_lnkCanceledNotFoundHdl; ///< Handler for Positioning the Cursors
+
+ Link<FmSearchContext&, sal_uInt32> m_lnkContextSupplier; ///< for search in contexts
+
+ /// memorize the currently selected field for every context
+ std::vector<OUString> m_arrContextFields;
+
+ std::unique_ptr<FmSearchEngine> m_pSearchEngine;
+
+ // see EnableSearchUI
+ std::unique_ptr<::svxform::FmSearchConfigItem> m_pConfig;
+
+ // my all Controls
+ std::unique_ptr<weld::RadioButton> m_prbSearchForText;
+ std::unique_ptr<weld::RadioButton> m_prbSearchForNull;
+ std::unique_ptr<weld::RadioButton> m_prbSearchForNotNull;
+ std::unique_ptr<weld::ComboBox> m_pcmbSearchText;
+ std::unique_ptr<weld::Label> m_pftForm;
+ std::unique_ptr<weld::ComboBox> m_plbForm;
+ std::unique_ptr<weld::RadioButton> m_prbAllFields;
+ std::unique_ptr<weld::RadioButton> m_prbSingleField;
+ std::unique_ptr<weld::ComboBox> m_plbField;
+ std::unique_ptr<weld::Label> m_pftPosition;
+ std::unique_ptr<weld::ComboBox> m_plbPosition;
+ std::unique_ptr<weld::CheckButton> m_pcbUseFormat;
+ std::unique_ptr<weld::CheckButton> m_pcbCase;
+ std::unique_ptr<weld::CheckButton> m_pcbBackwards;
+ std::unique_ptr<weld::CheckButton> m_pcbStartOver;
+ std::unique_ptr<weld::CheckButton> m_pcbWildCard;
+ std::unique_ptr<weld::CheckButton> m_pcbRegular;
+ std::unique_ptr<weld::CheckButton> m_pcbApprox;
+ std::unique_ptr<weld::Button> m_ppbApproxSettings;
+ std::unique_ptr<weld::CheckButton> m_pHalfFullFormsCJK;
+ std::unique_ptr<weld::CheckButton> m_pSoundsLikeCJK;
+ std::unique_ptr<weld::Button> m_pSoundsLikeCJKSettings;
+ std::unique_ptr<weld::Label> m_pftRecord;
+ std::unique_ptr<weld::Label> m_pftHint;
+ std::unique_ptr<weld::Button> m_pbSearchAgain;
+ std::unique_ptr<weld::Button> m_pbClose;
+
+public:
+ /** This can search in different sets of fields. There is a number of contexts; their names are in strContexts (separated
+ by ';'), the user can choose one of them.
+ When the user chooses a context, lnkContextSupplier is called, it gets a pointer on a FmSearchContext-structure,
+ that has to be filled.
+ The following counts for the search :
+ a) in case of formatted search the iterator itself is used (like in the first constructor)
+ b) in case of formatted search NOT the FormatKey at the fields of the iterator is used, but the respective TextComponent
+ is asked (that's why the original iterator is used; by its move the controls behind the TextComponent-interface are
+ updated hopefully)
+ c) in case of not-formatted search a clone of the iterator is used (because the TextComponent-interfaces don't need to
+ be asked)
+ (of course needed : the string number i in strUsedFields of a context must correspond with the interface number i in the
+ arrFields of the context)
+ */
+ FmSearchDialog(weld::Window* pParent, const OUString& strInitialText,
+ const std::vector<OUString>& _rContexts, sal_Int16 nInitialContext,
+ const Link<FmSearchContext&, sal_uInt32>& lnkContextSupplier);
+
+ virtual short run() override;
+
+ virtual ~FmSearchDialog() override;
+
+ /** The found-handler gets in the 'found'-case a pointer on a FmFoundRecordInformation-structure
+ (which is only valid in the handler; so if one needs to memorize the data, don't copy the pointer but
+ the structure).
+ This handler MUST be set.
+ Furthermore, it should be considered, that during the handler the search-dialog is still modal.
+ */
+ void SetFoundHandler(const Link<FmFoundRecordInformation&, void>& lnk)
+ {
+ m_lnkFoundHandler = lnk;
+ }
+ /**
+ If the search has been cancelled or has been finished without success, the current data set is always displayed in the
+ search dialog. This handler exists to make this synchronous with the possible display of the caller (it does not
+ necessarily need to be set).
+ The pointer that is passed to the handler points to a FmFoundRecordInformation-structure, for which aPosition and
+ possibly (in a search with contexts) nContext are valid.
+ */
+ void SetCanceledNotFoundHdl(const Link<FmFoundRecordInformation&, void>& lnk)
+ {
+ m_lnkCanceledNotFoundHdl = lnk;
+ }
+
+ inline void SetActiveField(const OUString& strField);
+
+private:
+ void Init(std::u16string_view strVisibleFields, const OUString& strInitialText);
+ // only to be used out of the constructors
+
+ void OnFound(const css::uno::Any& aCursorPos, sal_Int16 nFieldPos);
+
+ void EnableSearchUI(bool bEnable);
+
+ void EnableSearchForDependees(bool bEnable);
+
+ void InitContext(sal_Int16 nContext);
+
+ void LoadParams();
+ void SaveParams() const;
+
+ // Handler for the Controls
+ DECL_LINK(OnToggledSearchRadio, weld::Toggleable&, void);
+ DECL_LINK(OnToggledFieldRadios, weld::Toggleable&, void);
+ DECL_LINK(OnClickedSearchAgain, weld::Button&, void);
+ DECL_LINK(OnClickedSpecialSettings, weld::Button&, void);
+
+ DECL_LINK(OnSearchTextModified, weld::ComboBox&, void);
+
+ DECL_LINK(OnPositionSelected, weld::ComboBox&, void);
+ DECL_LINK(OnFieldSelected, weld::ComboBox&, void);
+
+ DECL_LINK(OnFocusGrabbed, weld::Widget&, void);
+ DECL_LINK(OnCheckBoxToggled, weld::Toggleable&, void);
+
+ DECL_LINK(OnContextSelection, weld::ComboBox&, void);
+
+ DECL_LINK(OnSearchProgress, const FmSearchProgress*, void);
+
+ void initCommon(const css::uno::Reference<css::sdbc::XResultSet>& _rxCursor);
+};
+
+inline void FmSearchDialog::SetActiveField(const OUString& strField)
+{
+ int nInitialField = m_plbField->find_text(strField);
+ if (nInitialField == -1)
+ nInitialField = 0;
+ m_plbField->set_active(nInitialField);
+ OnFieldSelected(*m_plbField);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuigaldlg.hxx b/cui/source/inc/cuigaldlg.hxx
new file mode 100644
index 000000000..8e88b84a6
--- /dev/null
+++ b/cui/source/inc/cuigaldlg.hxx
@@ -0,0 +1,276 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <salhelper/thread.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/idle.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/galctrl.hxx>
+#include <svx/galmisc.hxx>
+#include <com/sun/star/media/XPlayer.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+
+#include <string_view>
+#include <vector>
+
+class GalleryTheme;
+class SearchProgress;
+class TakeProgress;
+class TPGalleryThemeProperties;
+
+typedef std::vector< sal_uLong > TokenList_impl;
+
+struct FilterEntry
+{
+ OUString aFilterName;
+};
+
+class SearchThread: public salhelper::Thread
+{
+private:
+
+ SearchProgress* mpProgress;
+ TPGalleryThemeProperties* mpBrowser;
+ INetURLObject maStartURL;
+
+ void ImplSearch( const INetURLObject& rStartURL,
+ const std::vector< OUString >& rFormats,
+ bool bRecursive );
+
+ virtual ~SearchThread() override;
+ virtual void execute() override;
+
+public:
+
+ SearchThread(SearchProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ INetURLObject aStartURL);
+};
+
+class SearchProgress : public weld::GenericDialogController
+{
+private:
+ INetURLObject startUrl_;
+ TPGalleryThemeProperties* m_pTabPage;
+ rtl::Reference< SearchThread > m_aSearchThread;
+ std::unique_ptr<weld::Label> m_xFtSearchDir;
+ std::unique_ptr<weld::Label> m_xFtSearchType;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+
+ DECL_LINK(ClickCancelBtn, weld::Button&, void);
+
+public:
+ SearchProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage, INetURLObject aStartURL);
+ void LaunchThread();
+ virtual ~SearchProgress() override;
+
+ DECL_LINK( CleanUpHdl, void*, void );
+
+ void SetFileType( const OUString& rType ) { m_xFtSearchType->set_label(rType); }
+ void SetDirectory( const INetURLObject& rURL ) { m_xFtSearchDir->set_label(GetReducedString(rURL, 30)); }
+};
+
+class TakeThread: public salhelper::Thread
+{
+private:
+
+ TakeProgress* mpProgress;
+ TPGalleryThemeProperties* mpBrowser;
+ TokenList_impl& mrTakenList;
+
+ virtual ~TakeThread() override;
+ virtual void execute() override;
+
+public:
+
+ TakeThread(
+ TakeProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ TokenList_impl& rTakenList
+ );
+};
+
+class TakeProgress : public weld::GenericDialogController
+{
+private:
+ weld::Window* m_pParent;
+ TPGalleryThemeProperties* m_pTabPage;
+ rtl::Reference< TakeThread > maTakeThread;
+ TokenList_impl maTakenList;
+ std::unique_ptr<weld::Label> m_xFtTakeFile;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+
+ DECL_LINK(ClickCancelBtn, weld::Button&, void);
+
+public:
+
+ TakeProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage);
+ void LaunchThread();
+ virtual ~TakeProgress() override;
+
+ DECL_LINK( CleanUpHdl, void*, void );
+
+ void SetFile( const INetURLObject& rURL ) { m_xFtTakeFile->set_label(GetReducedString(rURL, 30)); }
+};
+
+class ActualizeProgress : public weld::GenericDialogController
+{
+private:
+ Idle* pIdle;
+ GalleryTheme* pTheme;
+ GalleryProgress aStatusProgress;
+ std::unique_ptr<weld::Label> m_xFtActualizeFile;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+
+ DECL_LINK(ClickCancelBtn, weld::Button&, void);
+ DECL_LINK(TimeoutHdl, Timer*, void);
+ DECL_LINK(ActualizeHdl, const INetURLObject&, void);
+
+public:
+ ActualizeProgress(weld::Widget* pWindow, GalleryTheme* pThm);
+ virtual ~ActualizeProgress() override;
+
+ virtual short run() override;
+};
+
+class TitleDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdit;
+public:
+ TitleDialog(weld::Widget* pParent, const OUString& rOldText);
+ virtual ~TitleDialog() override;
+ OUString GetTitle() const { return m_xEdit->get_text(); }
+};
+
+class GalleryIdDialog : public weld::GenericDialogController
+{
+private:
+ GalleryTheme* m_pThm;
+ std::unique_ptr<weld::Button> m_xBtnOk;
+ std::unique_ptr<weld::ComboBox> m_xLbResName;
+
+ DECL_LINK(ClickOkHdl, weld::Button&, void);
+public:
+ GalleryIdDialog(weld::Widget* pParent, GalleryTheme* pThm);
+ virtual ~GalleryIdDialog() override;
+ sal_uInt32 GetId() const { return m_xLbResName->get_active(); }
+};
+
+class GalleryThemeProperties : public SfxTabDialogController
+{
+ ExchangeData* pData;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ GalleryThemeProperties(weld::Widget* pParent, ExchangeData* pData, SfxItemSet const * pItemSet);
+};
+
+class TPGalleryThemeGeneral : public SfxTabPage
+{
+private:
+ ExchangeData* pData;
+
+ std::unique_ptr<weld::Image> m_xFiMSImage;
+ std::unique_ptr<weld::Entry> m_xEdtMSName;
+ std::unique_ptr<weld::Label> m_xFtMSShowType;
+ std::unique_ptr<weld::Label> m_xFtMSShowPath;
+ std::unique_ptr<weld::Label> m_xFtMSShowContent;
+ std::unique_ptr<weld::Label> m_xFtMSShowChangeDate;
+
+ virtual void Reset( const SfxItemSet* ) override {}
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+public:
+ TPGalleryThemeGeneral(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ void SetXChgData( ExchangeData* pData );
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+};
+
+class TPGalleryThemeProperties : public SfxTabPage
+{
+ friend class SearchThread;
+ friend class TakeProgress;
+ friend class TakeThread;
+
+ ExchangeData* pData;
+ std::vector<OUString> aFoundList;
+ std::vector< std::unique_ptr<FilterEntry> >
+ aFilterEntryList;
+ Timer aPreviewTimer;
+ OUString aLastFilterName;
+ OUString aPreviewString;
+ INetURLObject aURL;
+ bool bEntriesFound;
+ bool bInputAllowed;
+ bool bTakeAll;
+ bool bSearchRecursive;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::media::XPlayer > xMediaPlayer;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ DialogGalleryPreview m_aWndPreview;
+ std::unique_ptr<weld::ComboBox> m_xCbbFileType;
+ std::unique_ptr<weld::TreeView> m_xLbxFound;
+ std::unique_ptr<weld::Button> m_xBtnSearch;
+ std::unique_ptr<weld::Button> m_xBtnTake;
+ std::unique_ptr<weld::Button> m_xBtnTakeAll;
+ std::unique_ptr<weld::CheckButton> m_xCbxPreview;
+ std::unique_ptr<weld::CustomWeld> m_xWndPreview;
+
+ virtual void Reset( const SfxItemSet* /*rSet*/ ) override {}
+ virtual bool FillItemSet( SfxItemSet* /*rSet*/ ) override { return true; }
+ static OUString addExtension( const OUString&, std::u16string_view );
+ void FillFilterList();
+
+ void SearchFiles();
+ void TakeFiles();
+ void DoPreview();
+ void EndSearchProgressHdl(sal_Int32 nResult);
+
+ DECL_LINK(ClickPreviewHdl, weld::Toggleable&, void);
+ DECL_LINK(ClickSearchHdl, weld::Button&, void);
+ DECL_LINK(ClickTakeHdl, weld::Button&, void);
+ DECL_LINK(ClickTakeAllHdl, weld::Button&, void);
+ DECL_LINK(SelectFoundHdl, weld::TreeView&, void);
+ DECL_LINK(SelectFileTypeHdl, weld::ComboBox&, void);
+ DECL_LINK(DClickFoundHdl, weld::TreeView&, bool);
+ DECL_LINK(PreviewTimerHdl, Timer*, void);
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+public:
+ TPGalleryThemeProperties(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~TPGalleryThemeProperties() override;
+
+ void SetXChgData( ExchangeData* pData );
+ const ExchangeData* GetXChgData() const { return pData; }
+
+ void StartSearchFiles( std::u16string_view _rFolderURL, short _nDlgResult );
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuigrfflt.hxx b/cui/source/inc/cuigrfflt.hxx
new file mode 100644
index 000000000..122ac8772
--- /dev/null
+++ b/cui/source/inc/cuigrfflt.hxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/timer.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/rectenum.hxx>
+
+class CuiGraphicPreviewWindow : public weld::CustomWidgetController
+{
+private:
+ const Graphic* mpOrigGraphic;
+ Size maOrigGraphicSizePixel;
+ Size maOutputSizePixel;
+ Link<LinkParamNone*,void> maModifyHdl;
+ Graphic maScaledOrig;
+ Graphic maPreview;
+ double mfScaleX;
+ double mfScaleY;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+ virtual void Resize() override;
+
+ void ScaleImageToFit();
+
+public:
+ CuiGraphicPreviewWindow();
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ void init(const Graphic* pOrigGraphic, const Link<LinkParamNone*,void>& rLink)
+ {
+ mpOrigGraphic = pOrigGraphic;
+ maModifyHdl = rLink;
+ maOrigGraphicSizePixel = GetDrawingArea()->get_ref_device().LogicToPixel(mpOrigGraphic->GetPrefSize(),
+ mpOrigGraphic->GetPrefMapMode());
+ ScaleImageToFit();
+ }
+
+ void SetPreview(const Graphic& rGraphic);
+ const Graphic& GetScaledOriginal() const { return maScaledOrig; }
+ double GetScaleX() const { return mfScaleX; }
+ double GetScaleY() const { return mfScaleY; }
+ const Size& GetGraphicSizePixel() const { return maOrigGraphicSizePixel; }
+};
+
+class GraphicFilterDialog : public weld::GenericDialogController
+{
+private:
+
+ Timer maTimer;
+ Link<LinkParamNone*,void> maModifyHdl;
+ bool bIsBitmap;
+
+ DECL_LINK( ImplPreviewTimeoutHdl, Timer *, void );
+ DECL_LINK( ImplModifyHdl, LinkParamNone*, void);
+
+ CuiGraphicPreviewWindow maPreview;
+ std::unique_ptr<weld::CustomWeld> mxPreview;
+
+protected:
+ const Link<LinkParamNone*,void>& GetModifyHdl() const { return maModifyHdl; }
+ const Size& GetGraphicSizePixel() const { return maPreview.GetGraphicSizePixel(); }
+
+public:
+
+ GraphicFilterDialog(weld::Window* pParent, const OUString& rUIXMLDescription, const OString& rID, const Graphic& rGraphic);
+ virtual Graphic GetFilteredGraphic(const Graphic& rGraphic, double fScaleX, double fScaleY) = 0;
+};
+
+class GraphicFilterSmooth : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::SpinButton> mxMtrRadius;
+ DECL_LINK(EditModifyHdl, weld::SpinButton&, void);
+
+public:
+
+ GraphicFilterSmooth(weld::Window* pParent, const Graphic& rGraphic, double nRadius);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class GraphicFilterMosaic : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::MetricSpinButton> mxMtrWidth;
+ std::unique_ptr<weld::MetricSpinButton> mxMtrHeight;
+ std::unique_ptr<weld::CheckButton> mxCbxEdges;
+ DECL_LINK(CheckBoxModifyHdl, weld::Toggleable&, void);
+ DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
+public:
+
+ GraphicFilterMosaic(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges);
+
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+ bool IsEnhanceEdges() const { return mxCbxEdges->get_active(); }
+};
+
+class GraphicFilterSolarize : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::MetricSpinButton> mxMtrThreshold;
+ std::unique_ptr<weld::CheckButton> mxCbxInvert;
+ DECL_LINK(CheckBoxModifyHdl, weld::Toggleable&, void);
+ DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
+
+public:
+ GraphicFilterSolarize(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt8 nGreyThreshold, bool bInvert);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+ bool IsInvert() const { return mxCbxInvert->get_active(); }
+};
+
+class GraphicFilterSepia : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::MetricSpinButton> mxMtrSepia;
+ DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
+public:
+ GraphicFilterSepia(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nSepiaPercent);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class GraphicFilterPoster : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::SpinButton> mxNumPoster;
+ DECL_LINK(EditModifyHdl, weld::SpinButton&, void);
+public:
+ GraphicFilterPoster(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nPosterColorCount);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class EmbossControl : public SvxRectCtl
+{
+private:
+ Link<LinkParamNone*, void> maModifyHdl;
+ virtual bool MouseButtonDown( const MouseEvent& rEvt ) override;
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+public:
+ EmbossControl()
+ : SvxRectCtl(nullptr)
+ {
+ }
+
+ void SetModifyHdl( const Link<LinkParamNone*,void>& rHdl ) { maModifyHdl = rHdl; }
+};
+
+class GraphicFilterEmboss : public GraphicFilterDialog
+{
+private:
+ EmbossControl maCtlLight;
+ std::unique_ptr<weld::CustomWeld> mxCtlLight;
+public:
+ GraphicFilterEmboss(weld::Window* pParent, const Graphic& rGraphic,
+ RectPoint eLightSource);
+ virtual ~GraphicFilterEmboss() override;
+
+ virtual Graphic GetFilteredGraphic(const Graphic& rGraphic, double fScaleX, double fScaleY) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuihyperdlg.hxx b/cui/source/inc/cuihyperdlg.hxx
new file mode 100644
index 000000000..b43361edf
--- /dev/null
+++ b/cui/source/inc/cuihyperdlg.hxx
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <memory>
+#include <string_view>
+
+#include <svx/hlnkitem.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/ctrlitem.hxx>
+#include <sfx2/bindings.hxx>
+
+#include "iconcdlg.hxx"
+
+/*************************************************************************
+|*
+|* Hyperlink-Dialog
+|*
+\************************************************************************/
+
+class SvxHpLinkDlg;
+class SvxHlinkCtrl : public SfxControllerItem
+{
+private:
+ SvxHpLinkDlg* pParent;
+
+ SfxStatusForwarder aRdOnlyForwarder;
+
+public:
+ SvxHlinkCtrl( sal_uInt16 nId, SfxBindings & rBindings, SvxHpLinkDlg* pDlg);
+ virtual void dispose() override;
+
+ virtual void StateChangedAtToolBoxControl( sal_uInt16 nSID, SfxItemState eState,
+ const SfxPoolItem* pState ) override;
+};
+
+
+/*************************************************************************
+|*
+|* Hyperlink-Dialog
+|*
+\************************************************************************/
+
+class SvxHpLinkDlg : public SfxModelessDialogController
+{
+private:
+ friend class IconChoicePage;
+
+ std::vector< std::unique_ptr<IconChoicePageData> > maPageList;
+
+ OString msCurrentPageId;
+
+ const SfxItemSet* pSet;
+ std::unique_ptr<SfxItemSet> pOutSet;
+ std::unique_ptr<SfxItemSet> pExampleSet;
+ WhichRangesContainer pRanges;
+
+ SvxHlinkCtrl maCtrl; ///< Controller
+ std::unique_ptr<SfxItemSet> mpItemSet;
+
+ bool mbGrabFocus : 1;
+ bool mbIsHTMLDoc : 1;
+
+ std::unique_ptr<weld::Notebook> m_xIconCtrl;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::Button> m_xApplyBtn;
+ std::unique_ptr<weld::Button> m_xCancelBtn;
+ std::unique_ptr<weld::Button> m_xHelpBtn;
+ std::unique_ptr<weld::Button> m_xResetBtn;
+
+ DECL_LINK( ChosePageHdl_Impl, const OString&, void );
+
+ IconChoicePageData* GetPageData ( std::string_view rId );
+
+ void SwitchPage( const OString& rId );
+
+ DECL_LINK( ResetHdl, weld::Button&, void) ;
+ DECL_LINK (ClickOkHdl_Impl, weld::Button&, void );
+ DECL_LINK (ClickApplyHdl_Impl, weld::Button&, void );
+
+ IconChoicePage* GetTabPage( std::string_view rPageId )
+ { return GetPageData(rPageId)->xPage.get(); }
+
+ void ActivatePageImpl ();
+ void DeActivatePageImpl ();
+ void ResetPageImpl ();
+
+ void Activate() override;
+ virtual void Close() override;
+ void Apply();
+
+public:
+ SvxHpLinkDlg(SfxBindings* pBindings, SfxChildWindow* pChild, weld::Window* pParent);
+ virtual ~SvxHpLinkDlg () override;
+
+ // interface
+ void AddTabPage(const OString &rId, CreatePage pCreateFunc /* != NULL */);
+
+ void SetCurPageId( const OString& rId ) { msCurrentPageId = rId; SwitchPage(rId ); }
+ const OString & GetCurPageId() const { return msCurrentPageId; }
+ void ShowPage( const OString& rId );
+
+ /// gives via map converted local slots if applicable
+ WhichRangesContainer GetInputRanges( const SfxItemPool& );
+ void SetInputSet( const SfxItemSet* pInSet );
+
+ void Start();
+ bool QueryClose();
+
+ void PageCreated(IconChoicePage& rPage);
+
+ void SetPage( SvxHyperlinkItem const * pItem );
+ void SetReadOnlyMode( bool bReadOnly );
+ bool IsHTMLDoc() const { return mbIsHTMLDoc; }
+
+ SfxDispatcher* GetDispatcher() const { return GetBindings().GetDispatcher(); }
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuiimapwnd.hxx b/cui/source/inc/cuiimapwnd.hxx
new file mode 100644
index 000000000..ccb65bd48
--- /dev/null
+++ b/cui/source/inc/cuiimapwnd.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <sfx2/frame.hxx>
+
+class URLDlg : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Entry> m_xEdtURL;
+ std::unique_ptr<weld::ComboBox> m_xCbbTargets;
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<weld::Entry> m_xEdtAlternativeText;
+ std::unique_ptr<weld::TextView> m_xEdtDescription;
+
+public:
+
+ URLDlg(weld::Widget* pWindow,
+ const OUString& rURL, const OUString& rAlternativeText, const OUString& rDescription,
+ const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList);
+ virtual ~URLDlg() override;
+
+ OUString GetURL() const { return m_xEdtURL->get_text(); }
+ OUString GetAltText() const { return m_xEdtAlternativeText->get_text(); }
+ OUString GetDesc() const { return m_xEdtDescription->get_text(); }
+ OUString GetTarget() const { return m_xCbbTargets->get_active_text(); }
+ OUString GetName() const { return m_xEdtName->get_text(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuioptgenrl.hxx b/cui/source/inc/cuioptgenrl.hxx
new file mode 100644
index 000000000..42cdbbec3
--- /dev/null
+++ b/cui/source/inc/cuioptgenrl.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+// include ---------------------------------------------------------------
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/weld.hxx>
+
+#include <vector>
+
+// class SvxGeneralTabPage -----------------------------------------------
+
+class SvxGeneralTabPage : public SfxTabPage
+{
+private:
+ // the "Use data for document properties" checkbox
+ std::unique_ptr<weld::CheckButton> m_xUseDataCB;
+ std::unique_ptr<weld::Widget> m_xCryptoFrame;
+ std::unique_ptr<weld::ComboBox> m_xSigningKeyLB;
+ std::unique_ptr<weld::ComboBox> m_xEncryptionKeyLB;
+ std::unique_ptr<weld::CheckButton> m_xEncryptToSelfCB;
+ // rows
+ struct Row;
+ std::vector<std::shared_ptr<Row> > vRows;
+ // fields
+ struct Field;
+ std::vector<std::shared_ptr<Field> > vFields;
+ // "name" fields
+ unsigned nNameRow;
+ unsigned nShortNameField;
+
+ DECL_LINK( ModifyHdl_Impl, weld::Entry&, void );
+
+ bool GetData_Impl();
+ void SetData_Impl();
+
+ void InitControls ();
+ void InitCryptography();
+ void SetLinks ();
+
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxGeneralTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxGeneralTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuisrchdlg.hxx b/cui/source/inc/cuisrchdlg.hxx
new file mode 100644
index 000000000..b22b34102
--- /dev/null
+++ b/cui/source/inc/cuisrchdlg.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <i18nutil/transliteration.hxx>
+#include <sfx2/basedlgs.hxx>
+
+class SvxJSearchOptionsPage;
+
+class SvxJSearchOptionsDialog : public SfxSingleTabDialogController
+{
+ SvxJSearchOptionsPage* m_pPage;
+
+ SvxJSearchOptionsDialog( const SvxJSearchOptionsDialog & ) = delete;
+ SvxJSearchOptionsDialog & operator == ( const SvxJSearchOptionsDialog & ) = delete;
+
+public:
+ SvxJSearchOptionsDialog(weld::Window *pParent,
+ const SfxItemSet& rOptionsSet, TransliterationFlags nInitialFlags);
+ virtual ~SvxJSearchOptionsDialog() override;
+
+ TransliterationFlags GetTransliterationFlags() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuitabarea.hxx b/cui/source/inc/cuitabarea.hxx
new file mode 100644
index 000000000..1d2c5cb0a
--- /dev/null
+++ b/cui/source/inc/cuitabarea.hxx
@@ -0,0 +1,742 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svtools/valueset.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/xflasit.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/hexcolorcontrol.hxx>
+#include <svx/SvxColorValueSet.hxx>
+#include <svx/SvxPresetListBox.hxx>
+#include <svx/PaletteManager.hxx>
+#include <svx/svdview.hxx>
+
+#define NO_BUTTON_SELECTED -1
+
+class ColorListBox;
+class SdrModel;
+class SvxBitmapCtl;
+
+/************************************************************************/
+class ButtonBox
+{
+ private:
+ sal_Int32 mnCurrentButton;
+ std::vector<weld::Toggleable*> maButtonList;
+ std::map<weld::Toggleable*, sal_Int32 > maButtonToPos;
+ void SelectButtonImpl( sal_Int32 nPos )
+ {
+ if(mnCurrentButton != NO_BUTTON_SELECTED)
+ {
+ maButtonList[mnCurrentButton]->set_active(false);
+ }
+ mnCurrentButton = nPos;
+ maButtonList[mnCurrentButton]->set_active(true);
+ };
+ public:
+ ButtonBox()
+ {
+ mnCurrentButton = NO_BUTTON_SELECTED;
+ };
+ void AddButton(weld::Toggleable* pButton)
+ {
+ maButtonList.push_back(pButton);
+ maButtonToPos.insert( std::make_pair(pButton, maButtonList.size() - 1) );
+ }
+ sal_Int32 GetCurrentButtonPos() const { return mnCurrentButton; }
+ sal_Int32 GetButtonPos(weld::Toggleable* pButton)
+ {
+ std::map<weld::Toggleable*, sal_Int32>::const_iterator aBtnPos = maButtonToPos.find(pButton);
+ if(aBtnPos != maButtonToPos.end())
+ return aBtnPos->second;
+ else
+ return -1;
+ }
+ void SelectButton(weld::Toggleable* pButton)
+ {
+ sal_Int32 nPos = GetButtonPos(pButton);
+ if(nPos != -1)
+ SelectButtonImpl(nPos);
+ }
+};
+
+enum class PageType
+{
+ Area,
+ Gradient,
+ Hatch,
+ Bitmap,
+ Shadow,
+ Transparence,
+};
+
+class SvxAreaTabDialog final : public SfxTabDialogController
+{
+ SdrModel* mpDrawModel;
+
+ XColorListRef mpColorList;
+ XColorListRef mpNewColorList;
+ XGradientListRef mpGradientList;
+ XGradientListRef mpNewGradientList;
+ XHatchListRef mpHatchingList;
+ XHatchListRef mpNewHatchingList;
+ XBitmapListRef mpBitmapList;
+ XBitmapListRef mpNewBitmapList;
+ XPatternListRef mpPatternList;
+ XPatternListRef mpNewPatternList;
+
+ ChangeType mnColorListState;
+ ChangeType mnBitmapListState;
+ ChangeType mnPatternListState;
+ ChangeType mnGradientListState;
+ ChangeType mnHatchingListState;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+ virtual short Ok() override;
+ DECL_LINK(CancelHdlImpl, weld::Button&, void);
+ void SavePalettes();
+
+public:
+ SvxAreaTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, SdrModel* pModel, bool bShadow,
+ bool bSlideBackground);
+
+ void SetNewColorList( XColorListRef const & pColorList )
+ { mpNewColorList = pColorList; }
+ const XColorListRef& GetNewColorList() const { return mpNewColorList; }
+};
+
+/************************************************************************/
+
+class SvxTransparenceTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pTransparenceRanges;
+
+ const SfxItemSet& rOutAttrs;
+
+ PageType nPageType;
+ sal_uInt16 nDlgType;
+
+ bool bBitmap;
+
+ XFillAttrSetItem aXFillAttr;
+ SfxItemSet& rXFSet;
+
+ SvxXRectPreview m_aCtlBitmapPreview;
+ SvxXRectPreview m_aCtlXRectPreview;
+
+ // main selection
+ std::unique_ptr<weld::RadioButton> m_xRbtTransOff;
+ std::unique_ptr<weld::RadioButton> m_xRbtTransLinear;
+ std::unique_ptr<weld::RadioButton> m_xRbtTransGradient;
+
+ /// linear transparency
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTransparent;
+
+ // gradient transparency
+ std::unique_ptr<weld::Widget> m_xGridGradient;
+ std::unique_ptr<weld::ComboBox> m_xLbTrgrGradientType;
+ std::unique_ptr<weld::Label> m_xFtTrgrCenterX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrCenterX;
+ std::unique_ptr<weld::Label> m_xFtTrgrCenterY;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrCenterY;
+ std::unique_ptr<weld::Label> m_xFtTrgrAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrBorder;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrStartValue;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrEndValue;
+ std::unique_ptr<weld::Widget> m_xCtlBitmapBorder;
+ std::unique_ptr<weld::Widget> m_xCtlXRectBorder;
+
+ // preview
+ std::unique_ptr<weld::CustomWeld> m_xCtlBitmapPreview;
+ std::unique_ptr<weld::CustomWeld> m_xCtlXRectPreview;
+
+ DECL_LINK(ClickTransOffHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ClickTransLinearHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ClickTransGradientHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK(ModifyTransparentHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifiedTrgrEditHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifiedTrgrListBoxHdl_Impl, weld::ComboBox&, void);
+ void ModifiedTrgrHdl_Impl(const weld::ComboBox*);
+
+ void ActivateLinear(bool bActivate);
+ void ActivateGradient(bool bActivate);
+ void SetControlState_Impl(css::awt::GradientStyle eXGS);
+
+ bool InitPreview ( const SfxItemSet& rSet );
+ void InvalidatePreview (bool bEnable = true );
+
+public:
+ SvxTransparenceTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxTransparenceTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet*);
+ static WhichRangesContainer GetRanges() { return pTransparenceRanges; }
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+ virtual void ChangesApplied() override;
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+
+ void SetPageType(PageType nInType) { nPageType = nInType; }
+ void SetDlgType(sal_uInt16 nInType) { nDlgType = nInType; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/************************************************************************/
+
+class SvxAreaTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pAreaRanges;
+private:
+ std::unique_ptr<SfxTabPage> m_xFillTabPage;
+ ButtonBox maBox;
+
+ XColorListRef m_pColorList;
+ XGradientListRef m_pGradientList;
+ XHatchListRef m_pHatchingList;
+ XBitmapListRef m_pBitmapList;
+ XPatternListRef m_pPatternList;
+
+ // Placeholders for pointer-based entries; these will be inited
+ // to point to these so that the page is usable without that
+ // SvxAreaTabDialog has to call the setter methods (e.g. SetColorChgd).
+ // Without that the pages used in SvxAreaTabDialog are not usable
+ ChangeType maFixed_ChangeType;
+
+ ChangeType* m_pnColorListState;
+ ChangeType* m_pnBitmapListState;
+ ChangeType* m_pnPatternListState;
+ ChangeType* m_pnGradientListState;
+ ChangeType* m_pnHatchingListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ bool m_bBtnClicked = false;
+
+protected:
+ std::unique_ptr<weld::Container> m_xFillTab;
+ std::unique_ptr<weld::Toggleable> m_xBtnNone;
+ std::unique_ptr<weld::Toggleable> m_xBtnColor;
+ std::unique_ptr<weld::Toggleable> m_xBtnGradient;
+ std::unique_ptr<weld::Toggleable> m_xBtnHatch;
+ std::unique_ptr<weld::Toggleable> m_xBtnBitmap;
+ std::unique_ptr<weld::Toggleable> m_xBtnPattern;
+ std::unique_ptr<weld::Toggleable> m_xBtnUseBackground;
+
+ void SetOptimalSize(weld::DialogController* pController);
+
+ void SelectFillType( weld::Toggleable& rButton, const SfxItemSet* _pSet = nullptr );
+ SfxTabPage* GetFillTabPage() { return m_xFillTabPage.get(); }
+
+ bool IsBtnClicked() const { return m_bBtnClicked; }
+
+private:
+ DECL_LINK(SelectFillTypeHdl_Impl, weld::Toggleable&, void);
+
+ template< typename TabPage >
+ bool FillItemSet_Impl( SfxItemSet* );
+ template< typename TabPage >
+ void Reset_Impl( const SfxItemSet* );
+ template< typename TabPage >
+ DeactivateRC DeactivatePage_Impl( SfxItemSet* pSet );
+
+public:
+ SvxAreaTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs, bool bSlideBackground = false);
+ virtual ~SvxAreaTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static std::unique_ptr<SfxTabPage>
+ CreateWithSlideBackground(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet*);
+ static WhichRangesContainer GetRanges() { return pAreaRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetGradientList( XGradientListRef const & pGrdLst)
+ { m_pGradientList = pGrdLst; }
+ void SetHatchingList( XHatchListRef const & pHtchLst)
+ { m_pHatchingList = pHtchLst; }
+ void SetBitmapList( XBitmapListRef const & pBmpLst) { m_pBitmapList = pBmpLst; }
+ void SetPatternList( XPatternListRef const &pPtrnLst ) { m_pPatternList = pPtrnLst; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+ void CreatePage(sal_Int32 nId, SfxTabPage& rTab);
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+ void SetGrdChgd( ChangeType* pIn ) { m_pnGradientListState = pIn; }
+ void SetHtchChgd( ChangeType* pIn ) { m_pnHatchingListState = pIn; }
+ void SetBmpChgd( ChangeType* pIn ) { m_pnBitmapListState = pIn; }
+ void SetPtrnChgd( ChangeType* pIn ) { m_pnPatternListState = pIn; }
+};
+
+
+class SvxShadowTabPage : public SvxTabPage
+{
+ static const WhichRangesContainer pShadowRanges;
+
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ ChangeType* m_pnColorListState;
+ PageType m_nPageType;
+ sal_uInt16 m_nDlgType;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+ MapUnit m_ePoolUnit;
+
+ SvxRectCtl m_aCtlPosition;
+ SvxXShadowPreview m_aCtlXRectPreview;
+ std::unique_ptr<weld::CheckButton> m_xTsbShowShadow;
+ std::unique_ptr<weld::Widget> m_xGridShadow;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrDistance;
+ std::unique_ptr<ColorListBox> m_xLbShadowColor;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTransparent;
+ std::unique_ptr<weld::MetricSpinButton> m_xLbShadowBlurMetric;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPosition;
+ std::unique_ptr<weld::CustomWeld> m_xCtlXRectPreview;
+
+ DECL_LINK(ClickShadowHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ModifyShadowHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(SelectShadowHdl_Impl, ColorListBox&, void);
+
+public:
+ SvxShadowTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxShadowTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pShadowRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetPageType( PageType nInType ) { m_nPageType = nInType; }
+ void SetDlgType( sal_uInt16 nInType ) { m_nDlgType = nInType; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/************************************************************************/
+
+class SvxGradientTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ XGradientListRef m_pGradientList;
+
+ ChangeType* m_pnGradientListState;
+ ChangeType* m_pnColorListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ SvxXRectPreview m_aCtlPreview;
+ std::unique_ptr<weld::ComboBox> m_xLbGradientType;
+ std::unique_ptr<weld::Label> m_xFtCenter;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrCenterX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrCenterY;
+ std::unique_ptr<weld::Label> m_xFtAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrAngle;
+ std::unique_ptr<weld::Scale> m_xSliderAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrBorder;
+ std::unique_ptr<weld::Scale> m_xSliderBorder;
+ std::unique_ptr<ColorListBox> m_xLbColorFrom;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrColorFrom;
+ std::unique_ptr<ColorListBox> m_xLbColorTo;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrColorTo;
+ std::unique_ptr<SvxPresetListBox> m_xGradientLB;
+ std::unique_ptr<weld::SpinButton> m_xMtrIncrement;
+ std::unique_ptr<weld::CheckButton> m_xCbIncrement;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+ std::unique_ptr<weld::CustomWeld> m_xGradientLBWin;
+
+ DECL_LINK( ClickAddHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickModifyHdl_Impl, weld::Button&, void );
+ DECL_LINK( ChangeGradientHdl, ValueSet*, void );
+ void ChangeGradientHdl_Impl();
+ DECL_LINK( ClickRenameHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ModifiedEditHdl_Impl, weld::SpinButton&, void );
+ DECL_LINK( ModifiedMetricHdl_Impl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifiedColorListBoxHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ModifiedListBoxHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( ChangeAutoStepHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK( ModifiedSliderHdl_Impl, weld::Scale&, void );
+ void ModifiedHdl_Impl(void const *);
+
+ void SetControlState_Impl( css::awt::GradientStyle eXGS );
+ sal_Int32 SearchGradientList(std::u16string_view rGradientName);
+
+public:
+ SvxGradientTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxGradientTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetGradientList( XGradientListRef const & pGrdLst)
+ { m_pGradientList = pGrdLst; }
+ void SetGrdChgd( ChangeType* pIn ) { m_pnGradientListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+};
+
+/************************************************************************/
+
+class SvxHatchTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ XHatchListRef m_pHatchingList;
+
+ ChangeType* m_pnHatchingListState;
+ ChangeType* m_pnColorListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ MapUnit m_ePoolUnit;
+
+ SvxXRectPreview m_aCtlPreview;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrDistance;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrAngle;
+ std::unique_ptr<weld::Scale> m_xSliderAngle;
+ std::unique_ptr<weld::ComboBox> m_xLbLineType;
+ std::unique_ptr<ColorListBox> m_xLbLineColor;
+ std::unique_ptr<weld::CheckButton> m_xCbBackgroundColor;
+ std::unique_ptr<ColorListBox> m_xLbBackgroundColor;
+ std::unique_ptr<SvxPresetListBox> m_xHatchLB;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::CustomWeld> m_xHatchLBWin;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ DECL_LINK(ChangeHatchHdl, ValueSet*, void);
+ void ChangeHatchHdl_Impl();
+ DECL_LINK( ModifiedEditHdl_Impl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifiedListBoxHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( ModifiedColorListBoxHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ToggleHatchBackgroundColor_Impl, weld::Toggleable&, void );
+ DECL_LINK( ModifiedBackgroundHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ModifiedSliderHdl_Impl, weld::Scale&, void );
+ void ModifiedHdl_Impl(void const *);
+ DECL_LINK( ClickAddHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickModifyHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickRenameHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl_Impl, SvxPresetListBox*, void );
+
+ sal_Int32 SearchHatchList(std::u16string_view rHatchName);
+
+public:
+ SvxHatchTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxHatchTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetHatchingList( XHatchListRef const & pHtchLst)
+ { m_pHatchingList = pHtchLst; }
+
+ void SetHtchChgd( ChangeType* pIn ) { m_pnHatchingListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+};
+
+/************************************************************************/
+
+class SvxBitmapTabPage : public SfxTabPage
+{
+private:
+
+ const SfxItemSet& m_rOutAttrs;
+
+ XBitmapListRef m_pBitmapList;
+ ChangeType* m_pnBitmapListState;
+
+ double m_fObjectWidth;
+ double m_fObjectHeight;
+ bool m_bLogicalSize;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+ const SdrView* mpView;
+ MapUnit mePoolUnit;
+ FieldUnit meFieldUnit;
+ Size rBitmapSize;
+ Size rFilledSize;
+ Size rZoomedSize;
+
+ SvxXRectPreview m_aCtlBitmapPreview;
+ std::unique_ptr<SvxPresetListBox> m_xBitmapLB;
+ std::unique_ptr<weld::ComboBox> m_xBitmapStyleLB;
+ std::unique_ptr<weld::Container> m_xSizeBox;
+ std::unique_ptr<weld::CheckButton> m_xTsbScale;
+ std::unique_ptr<weld::MetricSpinButton> m_xBitmapWidth;
+ std::unique_ptr<weld::MetricSpinButton> m_xBitmapHeight;
+ std::unique_ptr<weld::Container> m_xPositionBox;
+ std::unique_ptr<weld::ComboBox> m_xPositionLB;
+ std::unique_ptr<weld::Container> m_xPositionOffBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xPositionOffX;
+ std::unique_ptr<weld::MetricSpinButton> m_xPositionOffY;
+ std::unique_ptr<weld::Container> m_xTileOffBox;
+ std::unique_ptr<weld::ComboBox> m_xTileOffLB;
+ std::unique_ptr<weld::MetricSpinButton> m_xTileOffset;
+ std::unique_ptr<weld::Button> m_xBtnImport;
+ std::unique_ptr<weld::CustomWeld> m_xCtlBitmapPreview;
+ std::unique_ptr<weld::CustomWeld> m_xBitmapLBWin;
+
+ DECL_LINK( ModifyBitmapHdl, ValueSet*, void );
+ DECL_LINK( ClickScaleHdl, weld::Toggleable&, void );
+ DECL_LINK( ModifyBitmapStyleHdl, weld::ComboBox&, void );
+ DECL_LINK( ModifyBitmapSizeHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifyBitmapPositionHdl, weld::ComboBox&, void );
+ DECL_LINK( ModifyPositionOffsetHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifyTileOffsetHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ClickRenameHdl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl, SvxPresetListBox*, void );
+ DECL_LINK( ClickImportHdl, weld::Button&, void );
+ void ClickBitmapHdl_Impl();
+ void CalculateBitmapPresetSize();
+ sal_Int32 SearchBitmapList(std::u16string_view rBitmapName);
+ sal_Int32 SearchBitmapList(const GraphicObject& rGraphicObject);
+
+public:
+ SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxBitmapTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetBitmapList( const XBitmapListRef& pBmpLst) { m_pBitmapList = pBmpLst; }
+ void SetBmpChgd( ChangeType* pIn ) { m_pnBitmapListState = pIn; }
+};
+
+/************************************************************************/
+
+class SvxPatternTabPage : public SvxTabPage
+{
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ XPatternListRef m_pPatternList;
+
+ ChangeType* m_pnPatternListState;
+ ChangeType* m_pnColorListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ SvxXRectPreview m_aCtlPreview;
+ std::unique_ptr<SvxPixelCtl> m_xCtlPixel;
+ std::unique_ptr<ColorListBox> m_xLbColor;
+ std::unique_ptr<ColorListBox> m_xLbBackgroundColor;
+ std::unique_ptr<SvxPresetListBox> m_xPatternLB;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPixelWin;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+ std::unique_ptr<weld::CustomWeld> m_xPatternLBWin;
+ std::unique_ptr<SvxBitmapCtl> m_xBitmapCtl;
+
+ DECL_LINK( ClickAddHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickModifyHdl_Impl, weld::Button&, void );
+ DECL_LINK( ChangePatternHdl_Impl, ValueSet*, void );
+ DECL_LINK( ChangeColorHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ClickRenameHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl_Impl, SvxPresetListBox*, void );
+
+ sal_Int32 SearchPatternList(std::u16string_view rPatternName);
+
+public:
+ SvxPatternTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxPatternTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void PointChanged( weld::DrawingArea*, RectPoint eRP ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetPatternList( XPatternListRef const & pPatternList) { m_pPatternList = pPatternList; }
+ void SetPtrnChgd( ChangeType* pIn ) { m_pnPatternListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+ void ChangeColor_Impl();
+};
+
+/************************************************************************/
+
+enum class ColorModel
+{
+ RGB,
+ CMYK
+};
+
+class SvxColorTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& rOutAttrs;
+
+ XColorListRef pColorList;
+
+ ChangeType* pnColorListState;
+
+ XFillAttrSetItem aXFillAttr;
+ SfxItemSet& rXFSet;
+
+ ColorModel eCM;
+
+ Color aPreviousColor;
+ svx::NamedThemedColor aCurrentColor;
+
+ PaletteManager maPaletteManager;
+ SvxXRectPreview m_aCtlPreviewOld;
+ SvxXRectPreview m_aCtlPreviewNew;
+ std::unique_ptr<SvxColorValueSet> m_xValSetColorList;
+ std::unique_ptr<SvxColorValueSet> m_xValSetRecentList;
+ std::unique_ptr<weld::ComboBox> m_xSelectPalette;
+ std::unique_ptr<weld::RadioButton> m_xRbRGB;
+ std::unique_ptr<weld::RadioButton> m_xRbCMYK;
+ std::unique_ptr<weld::Widget> m_xRGBcustom;
+ std::unique_ptr<weld::Widget> m_xRGBpreset;
+ std::unique_ptr<weld::Entry> m_xRpreset;
+ std::unique_ptr<weld::Entry> m_xGpreset;
+ std::unique_ptr<weld::Entry> m_xBpreset;
+ std::unique_ptr<weld::SpinButton> m_xRcustom;
+ std::unique_ptr<weld::SpinButton> m_xGcustom;
+ std::unique_ptr<weld::SpinButton> m_xBcustom;
+ std::unique_ptr<weld::HexColorControl> m_xHexpreset;
+ std::unique_ptr<weld::HexColorControl> m_xHexcustom;
+ std::unique_ptr<weld::Widget> m_xCMYKcustom;
+ std::unique_ptr<weld::Widget> m_xCMYKpreset;
+ std::unique_ptr<weld::Entry> m_xCpreset;
+ std::unique_ptr<weld::Entry> m_xYpreset;
+ std::unique_ptr<weld::Entry> m_xMpreset;
+ std::unique_ptr<weld::Entry> m_xKpreset;
+ std::unique_ptr<weld::MetricSpinButton> m_xCcustom;
+ std::unique_ptr<weld::MetricSpinButton> m_xYcustom;
+ std::unique_ptr<weld::MetricSpinButton> m_xMcustom;
+ std::unique_ptr<weld::MetricSpinButton> m_xKcustom;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+ std::unique_ptr<weld::Button> m_xBtnWorkOn;
+ std::unique_ptr<weld::Button> m_xMoreColors;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreviewOld;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreviewNew;
+ std::unique_ptr<weld::CustomWeld> m_xValSetColorListWin;
+ std::unique_ptr<weld::CustomWeld> m_xValSetRecentListWin;
+
+ static void ConvertColorValues (Color& rColor, ColorModel eModell);
+ static void RgbToCmyk_Impl( Color& rColor, sal_uInt16& rK );
+ static void CmykToRgb_Impl( Color& rColor, const sal_uInt16 nKey );
+ sal_uInt16 ColorToPercent_Impl( sal_uInt16 nColor );
+ sal_uInt16 PercentToColor_Impl( sal_uInt16 nPercent );
+
+ void ImpColorCountChanged();
+ void FillPaletteLB();
+
+ DECL_LINK(ClickAddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickWorkOnHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickDeleteHdl_Impl, weld::Button&, void);
+ DECL_STATIC_LINK(SvxColorTabPage, OnMoreColorsClick, weld::Button&, void);
+
+ DECL_LINK(SelectPaletteLBHdl, weld::ComboBox&, void);
+ DECL_LINK( SelectValSetHdl_Impl, ValueSet*, void );
+ DECL_LINK( SelectColorModeHdl_Impl, weld::Toggleable&, void );
+ void ChangeColor(const svx::NamedThemedColor &rNewColor, bool bUpdatePreset = true);
+ void SetColorModel(ColorModel eModel);
+ void ChangeColorModel();
+ void UpdateColorValues( bool bUpdatePreset = true );
+ DECL_LINK(SpinValueHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(MetricSpinValueHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifiedHdl_Impl, weld::Entry&, void);
+
+ void UpdateModified();
+
+ static sal_Int32 FindInCustomColors( std::u16string_view aColorName );
+ sal_Int32 FindInPalette( const Color& rColor );
+
+public:
+ SvxColorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxColorTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetPropertyList( XPropertyListType t, const XPropertyListRef &xRef );
+ void SetColorList( const XColorListRef& pColList );
+
+
+ void SetColorChgd( ChangeType* pIn ) { pnColorListState = pIn; }
+
+ void SetCtlPreviewOld( const SfxItemSet& rAttrs ) { m_aCtlPreviewOld.SetAttributes( rAttrs ); }
+
+ virtual void FillUserData() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuitabline.hxx b/cui/source/inc/cuitabline.hxx
new file mode 100644
index 000000000..7e4d7798f
--- /dev/null
+++ b/cui/source/inc/cuitabline.hxx
@@ -0,0 +1,376 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <memory>
+#include <vector>
+#include <editeng/brushitem.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/xlnasit.hxx>
+#include <svx/xtable.hxx>
+#include <svx/dlgctrl.hxx>
+#include <vcl/customweld.hxx>
+
+enum class PageType;
+class ColorListBox;
+
+class SvxLineTabDialog final : public SfxTabDialogController
+{
+ SdrModel* pDrawModel;
+ const SdrObject* pObj;
+
+ XColorListRef pColorList;
+ XColorListRef mpNewColorList;
+ XDashListRef pDashList;
+ XDashListRef pNewDashList;
+ XLineEndListRef pLineEndList;
+ XLineEndListRef pNewLineEndList;
+ bool bObjSelected;
+
+ ChangeType nLineEndListState;
+ ChangeType nDashListState;
+ ChangeType mnColorListState;
+
+ PageType nPageType;
+ sal_Int32 nPosDashLb;
+ sal_Int32 nPosLineEndLb;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+ virtual short Ok() override;
+ DECL_LINK(CancelHdlImpl, weld::Button&, void);
+ void SavePalettes();
+
+public:
+ SvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel, const SdrObject* pObj,
+ bool bHasObj);
+
+ void SetNewDashList( XDashListRef const & pInLst)
+ { pNewDashList = pInLst; }
+ const XDashListRef& GetNewDashList() const { return pNewDashList; }
+
+ void SetNewLineEndList( XLineEndListRef const & pInLst)
+ { pNewLineEndList = pInLst; }
+ const XLineEndListRef& GetNewLineEndList() const { return pNewLineEndList; }
+
+ void SetNewColorList( XColorListRef const & pColTab ) { mpNewColorList = pColTab; }
+ const XColorListRef& GetNewColorList() const { return mpNewColorList; }
+};
+
+/*************************************************************************/
+
+struct SvxBmpItemInfo
+{
+ std::unique_ptr<SvxBrushItem> pBrushItem;
+ OUString sItemId;
+};
+
+class SvxLineTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pLineRanges;
+private:
+ //#58425# symbols on a line (e. g. StarChart) ->
+ /** a list of symbols to be shown in menu. Symbol at position SID_ATTR_SYMBOLTYPE is to be shown in preview.
+ The list position is to be used cyclic. */
+ SdrObjList* m_pSymbolList;
+ bool m_bNewSize;
+ /// a graphic to be displayed in the preview in case that an automatic symbol is chosen
+ Graphic m_aAutoSymbolGraphic;
+ sal_Int32 m_nSymbolType;
+ /// attributes for the shown symbols; only necessary if not equal to line properties
+ std::unique_ptr<SfxItemSet> m_xSymbolAttr;
+
+ std::vector<OUString> m_aGrfNames;
+ std::vector< std::unique_ptr<SvxBmpItemInfo> >
+ m_aGalleryBrushItems;
+ std::vector< std::unique_ptr<SvxBmpItemInfo> >
+ m_aSymbolBrushItems;
+ bool m_bLastWidthModified;
+ Size m_aSymbolLastSize;
+ Graphic m_aSymbolGraphic;
+ Size m_aSymbolSize;
+ bool m_bSymbols;
+
+ const SfxItemSet& m_rOutAttrs;
+ bool m_bObjSelected;
+
+ XLineAttrSetItem m_aXLineAttr;
+ SfxItemSet& m_rXLSet;
+
+ XDashListRef m_pDashList;
+ XLineEndListRef m_pLineEndList;
+
+ ChangeType* m_pnLineEndListState;
+ ChangeType* m_pnDashListState;
+ ChangeType* m_pnColorListState;
+ PageType m_nPageType;
+ sal_uInt16 m_nDlgType;
+ sal_Int32* m_pPosDashLb;
+ sal_Int32* m_pPosLineEndLb;
+
+ MapUnit m_ePoolUnit;
+
+ sal_Int32 m_nActLineWidth;
+
+ SvxXLinePreview m_aCtlPreview;
+ std::unique_ptr<weld::Widget> m_xBoxColor;
+ std::unique_ptr<SvxLineLB> m_xLbLineStyle;
+ std::unique_ptr<ColorListBox> m_xLbColor;
+ std::unique_ptr<weld::Widget> m_xBoxWidth;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrLineWidth;
+ std::unique_ptr<weld::Widget> m_xBoxTransparency;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTransparent;
+ std::unique_ptr<weld::Widget> m_xFlLineEnds;
+ std::unique_ptr<weld::Widget> m_xBoxArrowStyles;
+ std::unique_ptr<SvxLineEndLB> m_xLbStartStyle;
+ std::unique_ptr<weld::Widget> m_xBoxStart;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrStartWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbCenterStart;
+ std::unique_ptr<weld::Widget> m_xBoxEnd;
+ std::unique_ptr<SvxLineEndLB> m_xLbEndStyle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrEndWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbCenterEnd;
+ std::unique_ptr<weld::CheckButton> m_xCbxSynchronize;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ std::unique_ptr<weld::Widget> m_xFLEdgeStyle;
+ std::unique_ptr<weld::Widget> m_xGridEdgeCaps;
+ std::unique_ptr<weld::ComboBox> m_xLBEdgeStyle;
+
+ // LineCaps
+ std::unique_ptr<weld::ComboBox> m_xLBCapStyle;
+
+ std::unique_ptr<weld::Widget> m_xFlSymbol;
+ std::unique_ptr<weld::Widget> m_xGridIconSize;
+ std::unique_ptr<weld::MenuButton> m_xSymbolMB;
+ std::unique_ptr<weld::Menu> m_xSymbolsMenu;
+ std::unique_ptr<weld::Menu> m_xGalleryMenu;
+ std::unique_ptr<weld::MetricSpinButton> m_xSymbolWidthMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xSymbolHeightMF;
+ std::unique_ptr<weld::CheckButton> m_xSymbolRatioCB;
+
+ // handler for gallery popup menu button + size
+ DECL_LINK(GraphicHdl_Impl, const OString&, void);
+ DECL_LINK(SizeHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(MenuCreateHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(RatioHdl_Impl, weld::Toggleable&, void);
+
+ DECL_LINK(ClickInvisibleHdl_Impl, weld::ComboBox&, void);
+ void ClickInvisibleHdl_Impl();
+ DECL_LINK(ChangeStartClickHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ChangeStartListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeEndListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeEndClickHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ChangePreviewListBoxHdl_Impl, ColorListBox&, void);
+ DECL_LINK(ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, void);
+ void ChangePreviewHdl_Impl(const weld::MetricSpinButton*);
+ DECL_LINK(ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void);
+
+ DECL_LINK(ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void);
+
+ // LineCaps
+ DECL_LINK(ChangeCapStyleHdl_Impl, weld::ComboBox&, void);
+
+ void FillXLSet_Impl();
+
+ void FillListboxes();
+public:
+
+ void ShowSymbolControls(bool bOn);
+
+ SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxLineTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pLineRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet* ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void FillUserData() override;
+
+ void SetDashList( XDashListRef const & pDshLst ) { m_pDashList = pDshLst; }
+ void SetLineEndList( XLineEndListRef const & pLneEndLst) { m_pLineEndList = pLneEndLst; }
+ void SetObjSelected( bool bHasObj ) { m_bObjSelected = bHasObj; }
+
+ void SetPageType( PageType nInType ) { m_nPageType = nInType; }
+ void SetDlgType( sal_uInt16 nInType ) { m_nDlgType = nInType; }
+ void SetPosDashLb( sal_Int32* pInPos ) { m_pPosDashLb = pInPos; }
+ void SetPosLineEndLb( sal_Int32* pInPos ) { m_pPosLineEndLb = pInPos; }
+
+ void SetLineEndChgd( ChangeType* pIn ) { m_pnLineEndListState = pIn; }
+ void SetDashChgd( ChangeType* pIn ) { m_pnDashListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/*************************************************************************/
+
+class SvxLineDefTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& rOutAttrs;
+ XDash aDash;
+
+ XLineAttrSetItem aXLineAttr;
+ SfxItemSet& rXLSet;
+
+ XDashListRef pDashList;
+
+ ChangeType* pnDashListState;
+ PageType* pPageType;
+ sal_uInt16 nDlgType;
+ sal_Int32* pPosDashLb;
+
+ MapUnit ePoolUnit;
+ FieldUnit eFUnit;
+
+ SvxXLinePreview m_aCtlPreview;
+ std::unique_ptr<SvxLineLB> m_xLbLineStyles;
+ std::unique_ptr<weld::ComboBox> m_xLbType1;
+ std::unique_ptr<weld::ComboBox> m_xLbType2;
+ std::unique_ptr<weld::SpinButton> m_xNumFldNumber1;
+ std::unique_ptr<weld::SpinButton> m_xNumFldNumber2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrLength1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrLength2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrDistance;
+ std::unique_ptr<weld::CheckButton> m_xCbxSynchronize;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+ std::unique_ptr<weld::Button> m_xBtnLoad;
+ std::unique_ptr<weld::Button> m_xBtnSave;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ void FillDash_Impl();
+ void FillDialog_Impl();
+
+ DECL_LINK(ClickAddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickModifyHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectLinestyleListBoxHdl_Impl, weld::ComboBox&, void);
+ void SelectLinestyleHdl_Impl(const weld::ComboBox*);
+ DECL_LINK(ChangePreviewHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeNumber1Hdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(ChangeNumber2Hdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(ClickLoadHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickSaveHdl_Impl, weld::Button&, void);
+ DECL_LINK(ChangeMetricHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(SelectTypeListBoxHdl_Impl, weld::ComboBox&, void);
+ void SelectTypeHdl_Impl(const weld::ComboBox*);
+ void ChangeMetricHdl_Impl(const weld::Toggleable*);
+
+ void CheckChanges_Impl();
+
+public:
+ SvxLineDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxLineDefTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetDashList( XDashListRef const & pDshLst ) { pDashList = pDshLst; }
+
+ void SetPageType( PageType* pInType ) { pPageType = pInType; }
+ void SetDlgType( sal_uInt16 nInType ) { nDlgType = nInType; }
+ void SetPosDashLb( sal_Int32* pInPos ) { pPosDashLb = pInPos; }
+
+ void SetDashChgd( ChangeType* pIn ) { pnDashListState = pIn; }
+};
+
+/*************************************************************************/
+
+class SvxLineEndDefTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& rOutAttrs;
+ const SdrObject* pPolyObj;
+
+ XLineAttrSetItem aXLineAttr;
+ SfxItemSet& rXLSet;
+
+ XLineEndListRef pLineEndList;
+
+ ChangeType* pnLineEndListState;
+ PageType* pPageType;
+ sal_uInt16 nDlgType;
+ sal_Int32* pPosLineEndLb;
+
+ SvxXLinePreview m_aCtlPreview;
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<SvxLineEndLB> m_xLbLineEnds;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+ std::unique_ptr<weld::Button> m_xBtnLoad;
+ std::unique_ptr<weld::Button> m_xBtnSave;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ DECL_LINK(ClickAddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickModifyHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickLoadHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickSaveHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectLineEndHdl_Impl, weld::ComboBox&, void);
+
+ void SelectLineEndHdl_Impl();
+ void CheckChanges_Impl();
+
+public:
+ SvxLineEndDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxLineEndDefTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetLineEndList( XLineEndListRef const & pInList ) { pLineEndList = pInList; }
+ void SetPolyObj( const SdrObject* pObj ) { pPolyObj = pObj; }
+
+ void SetPageType( PageType* pInType ) { pPageType = pInType; }
+ void SetDlgType( sal_uInt16 nInType ) { nDlgType = nInType; }
+ void SetPosLineEndLb( sal_Int32* pInPos ) { pPosLineEndLb = pInPos; }
+
+ void SetLineEndChgd( ChangeType* pIn ) { pnLineEndListState = pIn; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuitbxform.hxx b/cui/source/inc/cuitbxform.hxx
new file mode 100644
index 000000000..f5546f1cd
--- /dev/null
+++ b/cui/source/inc/cuitbxform.hxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class FmInputRecordNoDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::SpinButton> m_xRecordNo;
+
+public:
+ FmInputRecordNoDialog(weld::Window* pParent);
+ virtual ~FmInputRecordNoDialog() override;
+
+ void SetValue(int dNew) { m_xRecordNo->set_value(dNew); }
+ int GetValue() const { return m_xRecordNo->get_value(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dbregister.hxx b/cui/source/inc/dbregister.hxx
new file mode 100644
index 000000000..56c63b4c4
--- /dev/null
+++ b/cui/source/inc/dbregister.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <tools/solar.h>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+
+namespace svx
+{
+
+ class DbRegistrationOptionsPage : public SfxTabPage
+ {
+ private:
+ sal_uLong m_nOldCount;
+ bool m_bModified;
+
+ std::unique_ptr<weld::Button> m_xNew;
+ std::unique_ptr<weld::Button> m_xEdit;
+ std::unique_ptr<weld::Button> m_xDelete;
+ std::unique_ptr<weld::TreeView> m_xPathBox;
+ std::unique_ptr<weld::TreeIter> m_xIter;
+
+ DECL_LINK( NewHdl, weld::Button&, void );
+ DECL_LINK( EditHdl, weld::Button&, void );
+ DECL_LINK( DeleteHdl, weld::Button&, void );
+ DECL_LINK( PathBoxDoubleClickHdl, weld::TreeView&, bool);
+
+ DECL_LINK( PathSelect_Impl, weld::TreeView&, void);
+
+ DECL_LINK( HeaderSelect_Impl, int, void );
+ DECL_LINK( NameValidator, const OUString&, bool);
+
+ /** inserts a new entry in the tablistbox
+ @param _sName
+ The name of the entry.
+ @param _sLocation
+ The location of the file.
+ */
+ void insertNewEntry( const OUString& _sName,const OUString& _sLocation, const bool bReadOnly );
+
+ /** opens the LinkDialog to create a register pair
+ @param sOldName
+ The old name of the entry may be empty.
+ @param sOldLocation
+ The old location of the entry may be empty.
+ @param nEntry
+ The entry to remove if the entry will be changed
+ */
+ void openLinkDialog(const OUString& sOldName, const OUString& sOldLocation, int nEntry = -1);
+
+ public:
+ DbRegistrationOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~DbRegistrationOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+ };
+
+ /** helper for DatabaseRegistrationDialog
+
+ Necessary so that DatabaseRegistrationDialog is self-contained, i.e. always reflects
+ the current registration state.
+ */
+ class RegistrationItemSetHolder
+ {
+ private:
+ SfxItemSet m_aRegistrationItems;
+
+ protected:
+ RegistrationItemSetHolder( SfxItemSet _aMasterSet );
+ ~RegistrationItemSetHolder();
+
+ protected:
+ const SfxItemSet& getRegistrationItems() const { return m_aRegistrationItems; }
+ };
+
+ class DatabaseRegistrationDialog :public RegistrationItemSetHolder
+ ,public SfxSingleTabDialogController
+ {
+ public:
+ DatabaseRegistrationDialog(weld::Window* pParent, const SfxItemSet& rAttr);
+
+ virtual short run() override;
+ };
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/defdlgname.hxx b/cui/source/inc/defdlgname.hxx
new file mode 100644
index 000000000..1927e0a7f
--- /dev/null
+++ b/cui/source/inc/defdlgname.hxx
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+
+// const -----------------------------------------------------------------
+
+const short RET_BTN_1 = 100;
+const short RET_BTN_2 = 101;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dialmgr.hxx b/cui/source/inc/dialmgr.hxx
new file mode 100644
index 000000000..a26c0b25d
--- /dev/null
+++ b/cui/source/inc/dialmgr.hxx
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <unotools/resmgr.hxx>
+
+OUString CuiResId(TranslateId aKey);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dlgname.hxx b/cui/source/inc/dlgname.hxx
new file mode 100644
index 000000000..0baa56b61
--- /dev/null
+++ b/cui/source/inc/dlgname.hxx
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+/// Dialog for editing a name
+class SvxNameDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<weld::Label> m_xFtDescription;
+ std::unique_ptr<weld::Button> m_xBtnOK;
+
+ Link<SvxNameDialog&, bool> m_aCheckNameHdl;
+ Link<SvxNameDialog&, OUString> m_aCheckNameTooltipHdl;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ SvxNameDialog(weld::Window* pWindow, const OUString& rName, const OUString& rDesc);
+
+ OUString GetName() const { return m_xEdtName->get_text(); }
+
+ /** add a callback Link that is called whenever the content of the edit
+ field is changed. The Link result determines whether the OK
+ Button is enabled (> 0) or disabled (== 0).
+
+ @param rLink a Callback declared with DECL_DLLPRIVATE_LINK and implemented with
+ IMPL_LINK, that is executed on modification.
+
+ @param bCheckImmediately If true, the Link is called directly after
+ setting it. It is recommended to set this flag to true to avoid
+ an inconsistent state if the initial String (given in the CTOR)
+ does not satisfy the check condition.
+
+ @todo Remove the parameter bCheckImmediately and incorporate the 'true'
+ behaviour as default.
+ */
+ void SetCheckNameHdl(const Link<SvxNameDialog&, bool>& rLink, bool bCheckImmediately)
+ {
+ m_aCheckNameHdl = rLink;
+ if (bCheckImmediately)
+ m_xBtnOK->set_sensitive(rLink.Call(*this));
+ }
+
+ void SetCheckNameTooltipHdl(const Link<SvxNameDialog&, OUString>& rLink)
+ {
+ m_aCheckNameTooltipHdl = rLink;
+ m_xBtnOK->set_tooltip_text(rLink.Call(*this));
+ }
+
+ void SetEditHelpId(const OString& aHelpId) { m_xEdtName->set_help_id(aHelpId); }
+};
+
+/** #i68101#
+ Dialog for editing Object name
+ plus uniqueness-callback-linkHandler */
+class SvxObjectNameDialog : public weld::GenericDialogController
+{
+private:
+ // name
+ std::unique_ptr<weld::Entry> m_xEdtName;
+
+ // buttons
+ std::unique_ptr<weld::Button> m_xBtnOK;
+
+ // callback link for name uniqueness
+ Link<SvxObjectNameDialog&, bool> aCheckNameHdl;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ // constructor
+ SvxObjectNameDialog(weld::Window* pWindow, const OUString& rName);
+
+ // data access
+ OUString GetName() const { return m_xEdtName->get_text(); }
+
+ // set handler
+ void SetCheckNameHdl(const Link<SvxObjectNameDialog&, bool>& rLink) { aCheckNameHdl = rLink; }
+};
+
+/** #i68101#
+ Dialog for editing Object Title and Description */
+class SvxObjectTitleDescDialog : public weld::GenericDialogController
+{
+private:
+ // title
+ std::unique_ptr<weld::Entry> m_xEdtTitle;
+
+ // description
+ std::unique_ptr<weld::TextView> m_xEdtDescription;
+
+public:
+ // constructor
+ SvxObjectTitleDescDialog(weld::Window* pWindow, const OUString& rTitle, const OUString& rDesc);
+ // data access
+ OUString GetTitle() const { return m_xEdtTitle->get_text(); }
+ OUString GetDescription() const { return m_xEdtDescription->get_text(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/fileextcheckdlg.hxx b/cui/source/inc/fileextcheckdlg.hxx
new file mode 100644
index 000000000..968deae77
--- /dev/null
+++ b/cui/source/inc/fileextcheckdlg.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <vcl/weld.hxx>
+
+class FileExtCheckDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Label> m_pText;
+ std::unique_ptr<weld::CheckButton> m_pPerformCheck;
+ std::unique_ptr<weld::Button> m_pOk;
+
+ DECL_LINK(OnOkClick, weld::Button&, void);
+
+public:
+ FileExtCheckDialog(weld::Window* pWindow, const OUString& sTitle, const OUString& sMsg);
+ virtual ~FileExtCheckDialog() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/grfpage.hxx b/cui/source/inc/grfpage.hxx
new file mode 100644
index 000000000..adfaebc33
--- /dev/null
+++ b/cui/source/inc/grfpage.hxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/customweld.hxx>
+#include <vcl/graph.hxx>
+#include <sfx2/tabdlg.hxx>
+
+class SvxCropExample : public weld::CustomWidgetController
+{
+ MapMode m_aMapMode;
+ Size m_aFrameSize;
+ Point m_aTopLeft, m_aBottomRight;
+ Graphic m_aGrf;
+
+public:
+ SvxCropExample();
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+ virtual void Resize() override;
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+
+ void SetTop( tools::Long nVal ) { m_aTopLeft.setX(nVal); }
+ void SetBottom( tools::Long nVal ) { m_aBottomRight.setX(nVal); }
+ void SetLeft( tools::Long nVal ) { m_aTopLeft.setY(nVal); }
+ void SetRight( tools::Long nVal) { m_aBottomRight.setY(nVal); }
+ void SetFrameSize( const Size& rSz );
+ void SetGraphic( const Graphic& rGrf ) { m_aGrf = rGrf; }
+};
+
+class SvxGrfCropPage : public SfxTabPage
+{
+ friend class VclPtr<SvxGrfCropPage>;
+
+ OUString m_aGraphicName;
+ Size m_aOrigSize;
+ Size m_aOrigPixelSize;
+ Size m_aPageSize;
+ tools::Long m_nOldWidth;
+ tools::Long m_nOldHeight;
+ bool m_bSetOrigSize;
+ sal_Int32 m_aPreferredDPI;
+
+ SvxCropExample m_aExampleWN;
+
+ std::unique_ptr<weld::Widget> m_xCropFrame;
+ std::unique_ptr<weld::RadioButton> m_xZoomConstRB;
+ std::unique_ptr<weld::RadioButton> m_xSizeConstRB;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xBottomMF;
+
+ std::unique_ptr<weld::Widget> m_xScaleFrame;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthZoomMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightZoomMF;
+
+ std::unique_ptr<weld::Widget> m_xSizeFrame;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightMF;
+
+ std::unique_ptr<weld::Widget> m_xOrigSizeGrid;
+ std::unique_ptr<weld::Label> m_xOrigSizeFT;
+ std::unique_ptr<weld::Button> m_xOrigSizePB;
+
+ // Example
+ std::unique_ptr<weld::CustomWeld> m_xExampleWN;
+
+ DECL_LINK(ZoomHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(SizeHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(CropModifyHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(OrigSizeHdl, weld::Button&, void);
+
+ void CalcZoom();
+ void CalcMinMaxBorder();
+ void GraphicHasChanged(bool bFound);
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+
+ Size GetGrfOrigSize(const Graphic& rGraphic);
+public:
+ SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet );
+ virtual ~SvxGrfCropPage() override;
+
+ virtual bool FillItemSet( SfxItemSet *rSet ) override;
+ virtual void Reset( const SfxItemSet *rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet *pSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hangulhanjadlg.hxx b/cui/source/inc/hangulhanjadlg.hxx
new file mode 100644
index 000000000..57c3284d6
--- /dev/null
+++ b/cui/source/inc/hangulhanjadlg.hxx
@@ -0,0 +1,301 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/customweld.hxx>
+#include <vcl/event.hxx>
+#include <vcl/weld.hxx>
+#include <editeng/hangulhanja.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/linguistic2/XConversionDictionaryList.hpp>
+#include <svtools/valueset.hxx>
+
+#include <vector>
+#include <memory>
+
+namespace svx
+{
+
+ class SuggestionSet : public ValueSet
+ {
+ public:
+ SuggestionSet(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow);
+
+ virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
+ };
+
+ class SuggestionDisplay
+ {
+ public:
+ SuggestionDisplay(weld::Builder& rBuilder);
+
+ void DisplayListBox( bool bDisplayListBox );
+
+ void SetSelectHdl( const Link<SuggestionDisplay&,void>& rLink );
+
+ void Clear();
+ void InsertEntry( const OUString& rStr );
+ void SelectEntryPos( sal_uInt16 nPos );
+
+ sal_uInt16 GetEntryCount() const;
+
+ OUString GetEntry( sal_uInt16 nPos ) const;
+ OUString GetSelectedEntry() const;
+
+ DECL_LINK( SelectSuggestionListBoxHdl, weld::TreeView&, void );
+ DECL_LINK( SelectSuggestionValueSetHdl, ValueSet*, void );
+ void SelectSuggestionHdl(bool bListBox);
+
+ void SetHelpIds();
+
+ void set_size_request(int nWidth, int nHeight)
+ {
+ m_xValueSetWin->set_size_request(nWidth, nHeight);
+ m_xListBox->set_size_request(nWidth, nHeight);
+ }
+
+ private:
+ void implUpdateDisplay();
+ weld::Widget& implGetCurrentControl();
+
+ private:
+ bool m_bDisplayListBox; //otherwise ValueSet
+ bool m_bInSelectionUpdate;
+ Link<SuggestionDisplay&,void> m_aSelectLink;
+
+ std::unique_ptr<SuggestionSet> m_xValueSet;
+ std::unique_ptr<weld::CustomWeld> m_xValueSetWin;
+ std::unique_ptr<weld::TreeView> m_xListBox;
+ };
+
+ class RubyRadioButton;
+
+ class HangulHanjaConversionDialog : public weld::GenericDialogController
+ {
+ private:
+ /** are we working for a document? This is normally true, but in case
+ the user uses the "find" functionality, we switch to working
+ with what the user entered, which then does not have any relation to
+ the document anymore. Some functionality must be disabled then */
+ bool m_bDocumentMode;
+
+ Link<LinkParamNone*,void> m_aOptionsChangedLink;
+ Link<weld::Toggleable&,void> m_aClickByCharacterLink;
+
+ std::unique_ptr<weld::Button> m_xFind;
+ std::unique_ptr<weld::Button> m_xIgnore;
+ std::unique_ptr<weld::Button> m_xIgnoreAll;
+ std::unique_ptr<weld::Button> m_xReplace;
+ std::unique_ptr<weld::Button> m_xReplaceAll;
+ std::unique_ptr<weld::Button> m_xOptions;
+ std::unique_ptr<SuggestionDisplay> m_xSuggestions;
+ std::unique_ptr<weld::RadioButton> m_xSimpleConversion;
+ std::unique_ptr<weld::RadioButton> m_xHangulBracketed;
+ std::unique_ptr<weld::RadioButton> m_xHanjaBracketed;
+ std::unique_ptr<weld::Entry> m_xWordInput;
+ std::unique_ptr<weld::Label> m_xOriginalWord;
+ std::unique_ptr<RubyRadioButton> m_xHanjaAbove;
+ std::unique_ptr<RubyRadioButton> m_xHanjaBelow;
+ std::unique_ptr<RubyRadioButton> m_xHangulAbove;
+ std::unique_ptr<RubyRadioButton> m_xHangulBelow;
+ std::unique_ptr<weld::CheckButton> m_xHangulOnly;
+ std::unique_ptr<weld::CheckButton> m_xHanjaOnly;
+ std::unique_ptr<weld::CheckButton> m_xReplaceByChar;
+ public:
+ HangulHanjaConversionDialog(weld::Widget* pParent);
+ virtual ~HangulHanjaConversionDialog() override;
+
+ public:
+ void SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl );
+ void SetIgnoreHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetIgnoreAllHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetChangeHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetChangeAllHdl( const Link<weld::Button&,void>& _rHdl );
+
+ void SetClickByCharacterHdl( const Link<weld::Toggleable&,void>& _rHdl );
+ void SetConversionFormatChangedHdl( const Link<weld::Toggleable&,void>& _rHdl );
+ void SetFindHdl( const Link<weld::Button&,void>& _rHdl );
+
+ OUString GetCurrentString( ) const;
+ void SetCurrentString(
+ const OUString& _rNewString,
+ const css::uno::Sequence< OUString >& _rSuggestions,
+ bool _bOriginatesFromDocument
+ );
+
+ void FocusSuggestion( );
+
+ /// retrieves the current suggestion
+ OUString GetCurrentSuggestion( ) const;
+
+ void SetConversionFormat( editeng::HangulHanjaConversion::ConversionFormat _eType );
+ editeng::HangulHanjaConversion::ConversionFormat GetConversionFormat( ) const;
+
+ void SetByCharacter( bool _bByCharacter );
+ void SetConversionDirectionState( bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection );
+
+ /// should text which does not match the primary conversion direction be ignored?
+ bool GetUseBothDirections( ) const;
+
+ /** get current conversion direction to use
+ (return argument if GetUseBothDirections is true) */
+ editeng::HangulHanjaConversion::ConversionDirection GetDirection( editeng::HangulHanjaConversion::ConversionDirection eDefaultDirection ) const;
+
+ /// enables or disables the checkboxes for ruby formatted replacements
+ void EnableRubySupport( bool bVal );
+
+ private:
+ DECL_LINK( OnOption, weld::Button&, void );
+ DECL_LINK( OnSuggestionModified, weld::Entry&, void );
+ DECL_LINK( OnSuggestionSelected, SuggestionDisplay&, void );
+ DECL_LINK( OnConversionDirectionClicked, weld::Toggleable&, void );
+ DECL_LINK( ClickByCharacterHdl, weld::Toggleable&, void );
+
+ /// fill the suggestion list box with suggestions for the actual input
+ void FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions );
+ };
+
+
+ typedef std::vector< css::uno::Reference< css::linguistic2::XConversionDictionary > > HHDictList;
+
+ class HangulHanjaOptionsDialog : public weld::GenericDialogController
+ {
+ private:
+ HHDictList m_aDictList;
+ css::uno::Reference< css::linguistic2::XConversionDictionaryList > m_xConversionDictionaryList;
+
+ std::unique_ptr<weld::TreeView> m_xDictsLB;
+ std::unique_ptr<weld::CheckButton> m_xIgnorepostCB;
+ std::unique_ptr<weld::CheckButton> m_xShowrecentlyfirstCB;
+ std::unique_ptr<weld::CheckButton> m_xAutoreplaceuniqueCB;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xEditPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<weld::Button> m_xOkPB;
+
+ DECL_LINK( OkHdl, weld::Button&, void );
+ DECL_LINK( DictsLB_SelectHdl, weld::TreeView&, void );
+ DECL_LINK( NewDictHdl, weld::Button&, void );
+ DECL_LINK( EditDictHdl, weld::Button&, void );
+ DECL_LINK( DeleteDictHdl, weld::Button&, void );
+
+ void Init(); ///< reads settings from core and init controls
+ public:
+ HangulHanjaOptionsDialog(weld::Window* pParent);
+ virtual ~HangulHanjaOptionsDialog() override;
+
+ void AddDict( const OUString& _rName, bool _bChecked );
+ };
+
+ class HangulHanjaNewDictDialog : public weld::GenericDialogController
+ {
+ private:
+ bool m_bEntered;
+
+ std::unique_ptr<weld::Button> m_xOkBtn;
+ std::unique_ptr<weld::Entry> m_xDictNameED;
+
+ DECL_LINK(OKHdl, weld::Button&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ public:
+ HangulHanjaNewDictDialog(weld::Window* pParent);
+ virtual ~HangulHanjaNewDictDialog() override;
+
+ bool GetName( OUString& _rRetName ) const;
+ };
+
+ class SuggestionList;
+ class HangulHanjaEditDictDialog;
+
+ class SuggestionEdit
+ {
+ private:
+ HangulHanjaEditDictDialog* m_pParent;
+ SuggestionEdit* m_pPrev;
+ SuggestionEdit* m_pNext;
+ weld::ScrolledWindow* m_pScrollBar;
+ std::unique_ptr<weld::Entry> m_xEntry;
+
+ bool ShouldScroll( bool _bUp ) const;
+ void DoJump( bool _bUp );
+ public:
+ SuggestionEdit(std::unique_ptr<weld::Entry> xEntry, HangulHanjaEditDictDialog* pParent);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ void init(weld::ScrolledWindow* pScrollBar, SuggestionEdit* pPrev, SuggestionEdit* pNext);
+
+ void grab_focus() { m_xEntry->grab_focus(); }
+ void set_text(const OUString& rText) { m_xEntry->set_text(rText); }
+ void connect_changed(const Link<weld::Entry&, void>& rLink) { m_xEntry->connect_changed(rLink); }
+ };
+
+ class HangulHanjaEditDictDialog : public weld::GenericDialogController
+ {
+ private:
+ const OUString m_aEditHintText;
+ HHDictList& m_rDictList;
+ sal_uInt32 m_nCurrentDict;
+
+ OUString m_aOriginal;
+ std::unique_ptr<SuggestionList> m_xSuggestions;
+
+ sal_uInt16 m_nTopPos;
+ bool m_bModifiedSuggestions;
+ bool m_bModifiedOriginal;
+
+ std::unique_ptr<weld::ComboBox> m_xBookLB;
+ std::unique_ptr<weld::ComboBox> m_xOriginalLB;
+ std::unique_ptr<SuggestionEdit> m_xEdit1;
+ std::unique_ptr<SuggestionEdit> m_xEdit2;
+ std::unique_ptr<SuggestionEdit> m_xEdit3;
+ std::unique_ptr<SuggestionEdit> m_xEdit4;
+ std::unique_ptr<weld::Widget> m_xContents;
+ std::unique_ptr<weld::ScrolledWindow> m_xScrollSB;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+
+ DECL_LINK( OriginalModifyHdl, weld::ComboBox&, void );
+ DECL_LINK( ScrollHdl, weld::ScrolledWindow&, void );
+ DECL_LINK( EditModifyHdl1, weld::Entry&, void );
+ DECL_LINK( EditModifyHdl2, weld::Entry&, void );
+ DECL_LINK( EditModifyHdl3, weld::Entry&, void );
+ DECL_LINK( EditModifyHdl4, weld::Entry&, void );
+
+ DECL_LINK( BookLBSelectHdl, weld::ComboBox&, void );
+ DECL_LINK( NewPBPushHdl, weld::Button&, void );
+ DECL_LINK( DeletePBPushHdl, weld::Button&, void );
+
+ void InitEditDictDialog(sal_uInt32 nSelDict);
+ void UpdateOriginalLB();
+ void UpdateSuggestions();
+ void UpdateButtonStates();
+
+ void SetEditText( SuggestionEdit& rEdit, sal_uInt16 nEntryNum );
+ void EditModify( const weld::Entry* pEdit, sal_uInt8 nEntryOffset );
+
+ bool DeleteEntryFromDictionary( const css::uno::Reference< css::linguistic2::XConversionDictionary >& xDict );
+
+ public:
+ HangulHanjaEditDictDialog(weld::Window* pParent, HHDictList& rDictList, sal_uInt32 nSelDict);
+ virtual ~HangulHanjaEditDictDialog() override;
+
+ void UpdateScrollbar();
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/headertablistbox.hxx b/cui/source/inc/headertablistbox.hxx
new file mode 100644
index 000000000..a87bb1460
--- /dev/null
+++ b/cui/source/inc/headertablistbox.hxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class MacroEventListBox final
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+
+public:
+ MacroEventListBox(std::unique_ptr<weld::TreeView> xTreeView);
+ void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
+ void show() { m_xTreeView->show(); }
+
+ weld::TreeView& GetListBox() { return *m_xTreeView; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/helpids.h b/cui/source/inc/helpids.h
new file mode 100644
index 000000000..f82e0a1c8
--- /dev/null
+++ b/cui/source/inc/helpids.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <rtl/string.hxx>
+
+inline constexpr OStringLiteral HID_OPTIONS_COLORCONFIG_SAVE_SCHEME
+ = "CUI_HID_OPTIONS_COLORCONFIG_SAVE_SCHEME";
+inline constexpr OStringLiteral HID_OFA_FONT_SUBST_CLB = "CUI_HID_OFA_FONT_SUBST_CLB";
+inline constexpr OStringLiteral HID_DBPATH_CTL_PATH = "CUI_HID_DBPATH_CTL_PATH";
+#define HID_DBPATH_HEADERBAR "CUI_HID_DBPATH_HEADERBAR"
+inline constexpr OStringLiteral HID_OFADLG_TREELISTBOX = "CUI_HID_OFADLG_TREELISTBOX";
+inline constexpr OStringLiteral HID_SVX_CONFIG_TOOLBAR = "CUI_HID_SVX_CONFIG_TOOLBAR";
+inline constexpr OStringLiteral HID_SVX_CONFIG_TOOLBAR_CONTENTS
+ = "CUI_HID_SVX_CONFIG_TOOLBAR_CONTENTS";
+inline constexpr OStringLiteral HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS
+ = "CUI_HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS";
+inline constexpr OStringLiteral HID_HANGULDLG_SUGGESTIONS_GRID
+ = "CUI_HID_HANGULDLG_SUGGESTIONS_GRID";
+inline constexpr OStringLiteral HID_HANGULDLG_SUGGESTIONS_LIST
+ = "CUI_HID_HANGULDLG_SUGGESTIONS_LIST";
+inline constexpr OStringLiteral HID_SVX_CONFIG_NAME_SUBMENU = "CUI_HID_SVX_CONFIG_NAME_SUBMENU";
+inline constexpr OStringLiteral HID_SVX_CONFIG_RENAME_MENU = "CUI_HID_SVX_CONFIG_RENAME_MENU";
+inline constexpr OStringLiteral HID_SVX_CONFIG_RENAME_MENU_ITEM
+ = "CUI_HID_SVX_CONFIG_RENAME_MENU_ITEM";
+inline constexpr OStringLiteral HID_SVX_CONFIG_RENAME_TOOLBAR = "CUI_HID_SVX_CONFIG_RENAME_TOOLBAR";
+inline constexpr OStringLiteral HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM
+ = "CUI_HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM";
+inline constexpr OStringLiteral HID_SVX_UP_TOOLBAR_ITEM = "CUI_HID_SVX_UP_TOOLBAR_ITEM";
+inline constexpr OStringLiteral HID_SVX_DOWN_TOOLBAR_ITEM = "CUI_HID_SVX_DOWN_TOOLBAR_ITEM";
+inline constexpr OStringLiteral HID_SVX_SAVE_IN = "CUI_HID_SVX_SAVE_IN";
+inline constexpr OStringLiteral HID_SVX_TOPLEVELLISTBOX = "CUI_HID_SVX_TOPLEVELLISTBOX";
+inline constexpr OStringLiteral HID_SVX_DESCFIELD = "CUI_HID_SVX_DESCFIELD";
+inline constexpr OStringLiteral HID_MACRO_HEADERTABLISTBOX = "CUI_HID_MACRO_HEADERTABLISTBOX";
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hldocntp.hxx b/cui/source/inc/hldocntp.hxx
new file mode 100644
index 000000000..6cd6de54d
--- /dev/null
+++ b/cui/source/inc/hldocntp.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - New Document
+|*
+\************************************************************************/
+class SvxHyperlinkNewDocTp : public SvxHyperlinkTabPageBase
+{
+private:
+ std::unique_ptr<weld::RadioButton> m_xRbtEditNow;
+ std::unique_ptr<weld::RadioButton> m_xRbtEditLater;
+ std::unique_ptr<SvxHyperURLBox> m_xCbbPath;
+ std::unique_ptr<weld::Button> m_xBtCreate;
+ std::unique_ptr<weld::TreeView> m_xLbDocTypes;
+
+ bool ImplGetURLObject( const OUString& rPath, std::u16string_view rBase, INetURLObject& aURLObject ) const;
+ void FillDocumentList ();
+
+ DECL_LINK (ClickNewHdl_Impl, weld::Button&, void );
+ DECL_STATIC_LINK(SvxHyperlinkNewDocTp, DispatchDocument, void*, void);
+
+protected:
+ void FillDlgFields(const OUString& rStrURL) override;
+ void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+
+public:
+ SvxHyperlinkNewDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkNewDocTp () override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void DoApply () override;
+
+ virtual void SetInitFocus() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hldoctp.hxx b/cui/source/inc/hldoctp.hxx
new file mode 100644
index 000000000..c55c1cd20
--- /dev/null
+++ b/cui/source/inc/hldoctp.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - Document
+|*
+\************************************************************************/
+class SvxHyperlinkDocTp final : public SvxHyperlinkTabPageBase
+{
+private:
+ std::unique_ptr<SvxHyperURLBox> m_xCbbPath;
+ std::unique_ptr<weld::Button> m_xBtFileopen;
+ std::unique_ptr<weld::Entry> m_xEdTarget;
+ std::unique_ptr<weld::Label> m_xFtFullURL;
+ std::unique_ptr<weld::Button> m_xBtBrowse;
+
+ OUString maStrURL;
+
+ bool m_bMarkWndOpen;
+
+ DECL_LINK (ClickFileopenHdl_Impl, weld::Button&, void );
+ DECL_LINK (ClickTargetHdl_Impl, weld::Button&, void );
+
+ DECL_LINK (ModifiedPathHdl_Impl, weld::ComboBox&, void ); ///< Contents of combobox "Path" modified
+ DECL_LINK (ModifiedTargetHdl_Impl, weld::Entry&, void ); ///< Contents of editfield "Target" modified
+
+ DECL_LINK( LostFocusPathHdl_Impl, weld::Widget&, void ); ///< Combobox "path" lost its focus
+
+ DECL_LINK( TimeoutHdl_Impl, Timer *, void ); ///< Handler for timer -timeout
+
+ enum class EPathType { Invalid, ExistsFile };
+ static EPathType GetPathType ( std::u16string_view rStrPath );
+
+ void FillDlgFields(const OUString& rStrURL) override;
+ void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+ virtual bool ShouldOpenMarkWnd () override {return m_bMarkWndOpen;}
+ virtual void SetMarkWndShouldOpen (bool bOpen) override {m_bMarkWndOpen=bOpen;}
+ OUString GetCurrentURL() const;
+
+public:
+ SvxHyperlinkDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkDocTp() override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void SetMarkStr ( const OUString& aStrMark ) override;
+
+ virtual void SetInitFocus() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlinettp.hxx b/cui/source/inc/hlinettp.hxx
new file mode 100644
index 000000000..c2340fdde
--- /dev/null
+++ b/cui/source/inc/hlinettp.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "cuihyperdlg.hxx"
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - Internet
+|*
+\************************************************************************/
+
+class SvxHyperlinkInternetTp : public SvxHyperlinkTabPageBase
+{
+private:
+ OUString maStrOldUser;
+ OUString maStrOldPassword;
+
+ bool m_bMarkWndOpen;
+
+ std::unique_ptr<weld::RadioButton> m_xRbtLinktypInternet;
+ std::unique_ptr<weld::RadioButton> m_xRbtLinktypFTP;
+ std::unique_ptr<SvxHyperURLBox> m_xCbbTarget;
+ std::unique_ptr<weld::Label> m_xFtTarget;
+ std::unique_ptr<weld::Label> m_xFtLogin;
+ std::unique_ptr<weld::Entry> m_xEdLogin;
+ std::unique_ptr<weld::Label> m_xFtPassword;
+ std::unique_ptr<weld::Entry> m_xEdPassword;
+ std::unique_ptr<weld::CheckButton> m_xCbAnonymous;
+
+ DECL_LINK( Click_SmartProtocol_Impl, weld::Toggleable&, void ); ///< Radiobutton toggled: Type HTTP or FTP
+ DECL_LINK( ClickAnonymousHdl_Impl, weld::Toggleable&, void ); ///< Checkbox : Anonymous User
+ DECL_LINK( ModifiedLoginHdl_Impl, weld::Entry&, void ); ///< Contents of editfield "Login" modified
+ DECL_LINK( LostFocusTargetHdl_Impl, weld::Widget&, void ); ///< Combobox "Target" lost its focus
+ DECL_LINK( ModifiedTargetHdl_Impl, weld::ComboBox&, void ); ///< Contents of editfield "Target" modified
+
+ DECL_LINK( TimeoutHdl_Impl, Timer *, void); ///< Handler for timer -timeout
+
+
+ void SetScheme(std::u16string_view rScheme);
+ void RemoveImproperProtocol(std::u16string_view rProperScheme);
+ OUString GetSchemeFromButtons() const;
+ INetProtocol GetSmartProtocolFromButtons() const;
+
+ OUString CreateAbsoluteURL() const;
+
+ void setAnonymousFTPUser();
+ void setFTPUser(const OUString& rUser, const OUString& rPassword);
+ void RefreshMarkWindow();
+
+protected:
+ virtual void FillDlgFields(const OUString& rStrURL) override;
+ virtual void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+ virtual bool ShouldOpenMarkWnd () override {return ( m_bMarkWndOpen && m_xRbtLinktypInternet->get_active() );}
+ virtual void SetMarkWndShouldOpen (bool bOpen) override {m_bMarkWndOpen=bOpen;}
+
+public:
+ SvxHyperlinkInternetTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkInternetTp() override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void SetMarkStr ( const OUString& aStrMark ) override;
+
+ virtual void SetInitFocus() override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlmailtp.hxx b/cui/source/inc/hlmailtp.hxx
new file mode 100644
index 000000000..8b8bc39d8
--- /dev/null
+++ b/cui/source/inc/hlmailtp.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - Mail
+|*
+\************************************************************************/
+
+class SvxHyperlinkMailTp : public SvxHyperlinkTabPageBase
+{
+private:
+ std::unique_ptr<SvxHyperURLBox> m_xCbbReceiver;
+ std::unique_ptr<weld::Button> m_xBtAdrBook;
+ std::unique_ptr<weld::Label> m_xFtSubject;
+ std::unique_ptr<weld::Entry> m_xEdSubject;
+
+ DECL_STATIC_LINK(SvxHyperlinkMailTp, ClickAdrBookHdl_Impl, weld::Button&, void);
+ ///< Button : Address book
+ DECL_LINK (ModifiedReceiverHdl_Impl, weld::ComboBox&, void ); ///< Combobox "receiver" modified
+
+ void SetScheme(std::u16string_view rScheme);
+ void RemoveImproperProtocol(std::u16string_view aProperScheme);
+
+ OUString CreateAbsoluteURL() const;
+
+protected:
+ virtual void FillDlgFields(const OUString& rStrURL) override;
+ virtual void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+
+public:
+ SvxHyperlinkMailTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkMailTp() override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void SetInitFocus() override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlmarkwn.hxx b/cui/source/inc/hlmarkwn.hxx
new file mode 100644
index 000000000..d88dddab2
--- /dev/null
+++ b/cui/source/inc/hlmarkwn.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <vcl/weld.hxx>
+
+class SvxHyperlinkTabPageBase;
+
+//# #
+//# Window-Class #
+//# #
+class SvxHlinkDlgMarkWnd : public weld::GenericDialogController
+{
+private:
+ SvxHyperlinkTabPageBase* mpParent;
+
+ sal_uInt16 mnError;
+
+ std::unique_ptr<weld::Button> mxBtApply;
+ std::unique_ptr<weld::Button> mxBtClose;
+ std::unique_ptr<weld::TreeView> mxLbTree;
+ std::unique_ptr<weld::Label> mxError;
+
+ void ErrorChanged();
+
+protected:
+ bool RefreshFromDoc( const OUString& aURL );
+ void RestoreLastSelection();
+
+ std::unique_ptr<weld::TreeIter> FindEntry(std::u16string_view aStrName);
+ void ClearTree();
+ int FillTree( const css::uno::Reference< css::container::XNameAccess >& xLinks, const weld::TreeIter* pParentEntry =nullptr );
+
+ DECL_LINK( ClickApplyHdl_Impl, weld::Button&, void );
+ DECL_LINK( DoubleClickApplyHdl_Impl, weld::TreeView&, bool );
+ DECL_LINK( ClickCloseHdl_Impl, weld::Button&, void );
+
+public:
+ SvxHlinkDlgMarkWnd(weld::Window* pParentDialog, SvxHyperlinkTabPageBase *pParentPage);
+ virtual ~SvxHlinkDlgMarkWnd() override;
+
+ void MoveTo(const Point& rNewPos);
+ void RefreshTree(const OUString& aStrURL);
+ bool SelectEntry(std::u16string_view aStrMark);
+
+ sal_uInt16 SetError( sal_uInt16 nError);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlmarkwn_def.hxx b/cui/source/inc/hlmarkwn_def.hxx
new file mode 100644
index 000000000..34cd741fe
--- /dev/null
+++ b/cui/source/inc/hlmarkwn_def.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#define LERR_NOERROR 0
+#define LERR_NOENTRIES 1
+#define LERR_DOCNOTOPEN 2
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hltpbase.hxx b/cui/source/inc/hltpbase.hxx
new file mode 100644
index 000000000..e3c399bd4
--- /dev/null
+++ b/cui/source/inc/hltpbase.hxx
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svtools/inettbc.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/locktoplevels.hxx>
+
+#include <com/sun/star/frame/XFrame.hpp>
+#include <svx/hlnkitem.hxx>
+
+#include "hlmarkwn.hxx"
+#include "iconcdlg.hxx"
+
+/// ComboBox-Control for URL's with History and Autocompletion
+class SvxHyperURLBox : public SvtURLBox, public DropTargetHelper
+{
+protected:
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
+
+public:
+ SvxHyperURLBox(std::unique_ptr<weld::ComboBox> xWidget);
+};
+
+/// Tabpage : Basisclass
+class SvxHyperlinkTabPageBase : public IconChoicePage
+{
+private:
+ std::unique_ptr<weld::ComboBox> mxCbbFrame;
+ std::unique_ptr<weld::ComboBox> mxLbForm;
+ std::unique_ptr<weld::Entry> mxEdIndication;
+ std::unique_ptr<weld::Entry> mxEdText;
+ std::unique_ptr<weld::Button> mxBtScript;
+ std::unique_ptr<weld::Label> mxFormLabel;
+ std::unique_ptr<weld::Label> mxFrameLabel;
+
+ bool mbIsCloseDisabled;
+
+ css::uno::Reference< css::frame::XFrame >
+ mxDocumentFrame;
+
+protected:
+ SvxHpLinkDlg* mpDialog;
+
+ bool mbStdControlsInit;
+
+ OUString maStrInitURL;
+
+ Timer maTimer;
+
+ TopLevelWindowLocker maBusy;
+
+ std::shared_ptr<SvxHlinkDlgMarkWnd> mxMarkWnd;
+
+ void InitStdControls ();
+ void FillStandardDlgFields ( const SvxHyperlinkItem* pHyperlinkItem );
+ virtual void FillDlgFields(const OUString& rStrURL) = 0;
+ virtual void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) = 0;
+
+ void GetDataFromCommonFields( OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode );
+
+ DECL_LINK (ClickScriptHdl_Impl, weld::Button&, void ); ///< Button : Script
+
+ static OUString GetSchemeFromURL( const OUString& rStrURL );
+
+ void DisableClose( bool _bDisable );
+
+public:
+ SvxHyperlinkTabPageBase (
+ weld::Container* pParent,
+ SvxHpLinkDlg* pDlg,
+ const OUString& rUIXMLDescription,
+ const OString& rID,
+ const SfxItemSet* pItemSet
+ );
+ virtual ~SvxHyperlinkTabPageBase () override;
+
+ void SetDocumentFrame(
+ const css::uno::Reference< css::frame::XFrame >& rxDocumentFrame )
+ {
+ mxDocumentFrame = rxDocumentFrame;
+ }
+
+ virtual void DoApply ();
+ virtual void SetInitFocus();
+ virtual void SetMarkStr ( const OUString& aStrMark );
+ virtual void Reset( const SfxItemSet& ) override;
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void ActivatePage( const SfxItemSet& rItemSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ bool IsMarkWndVisible() const { return static_cast<bool>(mxMarkWnd); }
+ void MoveToExtraWnd ( Point aNewPos );
+
+ virtual bool QueryClose() override;
+
+protected:
+ virtual bool ShouldOpenMarkWnd();
+ virtual void SetMarkWndShouldOpen(bool bOpen);
+
+ void ShowMarkWnd();
+ void HideMarkWnd();
+
+ SfxDispatcher* GetDispatcher() const;
+
+ HyperDialogEvent GetMacroEvents() const;
+ SvxMacroTableDtor* GetMacroTable();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hyphen.hxx b/cui/source/inc/hyphen.hxx
new file mode 100644
index 000000000..0b304e943
--- /dev/null
+++ b/cui/source/inc/hyphen.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+
+#include <vcl/weld.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <com/sun/star/linguistic2/XPossibleHyphens.hpp>
+
+class SvxSpellWrapper;
+
+class SvxHyphenWordDialog : public SfxDialogController
+{
+ OUString m_aLabel;
+ SvxSpellWrapper *const m_pHyphWrapper;
+ css::uno::Reference< css::linguistic2::XHyphenator > m_xHyphenator;
+ css::uno::Reference< css::linguistic2::XPossibleHyphens > m_xPossHyph;
+ OUString m_aEditWord; // aEditWord and aWordEdit.GetText() differ only by the character for the current selected hyphenation position
+ OUString m_aActWord; // actual word to be hyphenated
+ LanguageType m_nActLanguage; // and its language
+ sal_Int16 m_nMaxHyphenationPos; // right most valid hyphenation pos
+ sal_Int32 m_nOldPos;
+ sal_Int32 m_nHyphenationPositionsOffset;
+ int m_nWordEditWidth;
+ bool m_bBusy;
+
+ std::unique_ptr<weld::Entry> m_xWordEdit;
+ std::unique_ptr<weld::Button> m_xLeftBtn;
+ std::unique_ptr<weld::Button> m_xRightBtn;
+ std::unique_ptr<weld::Button> m_xOkBtn;
+ std::unique_ptr<weld::Button> m_xContBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+ std::unique_ptr<weld::Button> m_xHyphAll;
+ std::unique_ptr<weld::Button> m_xCloseBtn;
+
+ void EnableLRBtn_Impl();
+ OUString EraseUnusableHyphens_Impl();
+
+ void InitControls_Impl();
+ void ContinueHyph_Impl( sal_Int32 nInsPos = -1 ); // continue by default
+
+ void select_region(int nStart, int nEnd);
+
+ DECL_LINK(Left_Impl, weld::Button&, void);
+ DECL_LINK(Right_Impl, weld::Button&, void);
+ DECL_LINK(CutHdl_Impl, weld::Button&, void);
+ DECL_LINK(ContinueHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(HyphenateAllHdl_Impl, weld::Button&, void);
+ DECL_LINK(CancelHdl_Impl, weld::Button&, void);
+ DECL_LINK(GetFocusHdl_Impl, weld::Widget&, void);
+ DECL_LINK(CursorChangeHdl_Impl, weld::Entry&, void);
+
+public:
+ SvxHyphenWordDialog(OUString aWord, LanguageType nLang,
+ weld::Widget* pParent,
+ css::uno::Reference<css::linguistic2::XHyphenator> const &xHyphen,
+ SvxSpellWrapper* pWrapper);
+ virtual ~SvxHyphenWordDialog() override;
+
+ void SetWindowTitle( LanguageType nLang );
+ bool SelLeft();
+ bool SelRight();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/iconcdlg.hxx b/cui/source/inc/iconcdlg.hxx
new file mode 100644
index 000000000..1803a9a63
--- /dev/null
+++ b/cui/source/inc/iconcdlg.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <utility>
+
+// forward-declarations
+struct IconChoicePageData;
+class SvxHpLinkDlg;
+class IconChoicePage;
+class SfxItemPool;
+class SfxItemSet;
+
+// Create-Function
+typedef std::unique_ptr<IconChoicePage> (*CreatePage)(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pAttrSet);
+
+/// Data-structure for pages in dialog
+struct IconChoicePageData
+{
+ OString sId;
+ std::unique_ptr<IconChoicePage> xPage; ///< the TabPage itself
+ bool bRefresh; ///< Flag: page has to be newly initialized
+
+ // constructor
+ IconChoicePageData(OString aId, std::unique_ptr<IconChoicePage> xInPage)
+ : sId(std::move(aId))
+ , xPage(std::move(xInPage))
+ , bRefresh(false)
+ {}
+};
+
+class IconChoicePage
+{
+protected:
+ std::unique_ptr<weld::Builder> xBuilder;
+ std::unique_ptr<weld::Container> xContainer;
+
+private:
+ const SfxItemSet* pSet;
+ bool bHasExchangeSupport;
+
+protected:
+
+ IconChoicePage(weld::Container* pParent, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet* pItemSet);
+
+public:
+ virtual ~IconChoicePage();
+
+ OString GetHelpId() const { return xContainer->get_help_id(); }
+
+ const SfxItemSet& GetItemSet() const { return *pSet; }
+
+ virtual bool FillItemSet( SfxItemSet* ) = 0;
+ virtual void Reset( const SfxItemSet& ) = 0;
+
+ bool HasExchangeSupport() const { return bHasExchangeSupport; }
+ void SetExchangeSupport() { bHasExchangeSupport = true; }
+
+ virtual void ActivatePage( const SfxItemSet& );
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet );
+ virtual bool QueryClose();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/insdlg.hxx b/cui/source/inc/insdlg.hxx
new file mode 100644
index 000000000..4938314a3
--- /dev/null
+++ b/cui/source/inc/insdlg.hxx
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <svtools/insdlg.hxx>
+#include <vcl/weld.hxx>
+#include <comphelper/embeddedobjectcontainer.hxx>
+
+class INetURLObject;
+
+class InsertObjectDialog_Impl : public weld::GenericDialogController
+{
+protected:
+ css::uno::Reference < css::embed::XEmbeddedObject > m_xObj;
+ const css::uno::Reference < css::embed::XStorage > m_xStorage;
+ comphelper::EmbeddedObjectContainer aCnt;
+
+ InsertObjectDialog_Impl(weld::Window * pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ css::uno::Reference < css::embed::XStorage > xStorage);
+public:
+ const css::uno::Reference<css::embed::XEmbeddedObject>& GetObject() const { return m_xObj; }
+ virtual css::uno::Reference<css::io::XInputStream> GetIconIfIconified(OUString* pGraphicMediaType);
+ void SetHelpId(const OString& rHelpId) { m_xDialog->set_help_id(rHelpId); }
+ virtual bool IsCreateNew() const;
+};
+
+class SvInsertOleDlg : public InsertObjectDialog_Impl
+{
+ const SvObjectServerList* m_pServers;
+
+ css::uno::Sequence< sal_Int8 > m_aIconMetaFile;
+ OUString m_aIconMediaType;
+
+ std::unique_ptr<weld::RadioButton> m_xRbNewObject;
+ std::unique_ptr<weld::RadioButton> m_xRbObjectFromfile;
+ std::unique_ptr<weld::Frame> m_xObjectTypeFrame;
+ std::unique_ptr<weld::TreeView> m_xLbObjecttype;
+ std::unique_ptr<weld::Frame> m_xFileFrame;
+ std::unique_ptr<weld::Entry> m_xEdFilepath;
+ std::unique_ptr<weld::Button> m_xBtnFilepath;
+ std::unique_ptr<weld::CheckButton> m_xCbFilelink;
+ std::unique_ptr<weld::CheckButton> m_xCbAsIcon;
+
+ DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(BrowseHdl, weld::Button&, void);
+ DECL_LINK(RadioHdl, weld::Toggleable&, void);
+ bool IsCreateNew() const override { return m_xRbNewObject->get_active(); }
+
+public:
+ SvInsertOleDlg(weld::Window* pParent,
+ const css::uno::Reference < css::embed::XStorage >& xStorage,
+ const SvObjectServerList* pServers );
+ virtual short run() override;
+
+ /// get replacement for the iconified embedded object and the mediatype of the replacement
+ css::uno::Reference< css::io::XInputStream > GetIconIfIconified( OUString* pGraphicMediaType ) override;
+};
+
+class SfxInsertFloatingFrameDialog : public InsertObjectDialog_Impl
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEDName;
+ std::unique_ptr<weld::Entry> m_xEDURL;
+ std::unique_ptr<weld::Button> m_xBTOpen;
+
+ std::unique_ptr<weld::RadioButton> m_xRBScrollingOn;
+ std::unique_ptr<weld::RadioButton> m_xRBScrollingOff;
+ std::unique_ptr<weld::RadioButton> m_xRBScrollingAuto;
+
+ std::unique_ptr<weld::RadioButton> m_xRBFrameBorderOn;
+ std::unique_ptr<weld::RadioButton> m_xRBFrameBorderOff;
+
+ std::unique_ptr<weld::Label> m_xFTMarginWidth;
+ std::unique_ptr<weld::SpinButton> m_xNMMarginWidth;
+ std::unique_ptr<weld::CheckButton> m_xCBMarginWidthDefault;
+ std::unique_ptr<weld::Label> m_xFTMarginHeight;
+ std::unique_ptr<weld::SpinButton> m_xNMMarginHeight;
+ std::unique_ptr<weld::CheckButton> m_xCBMarginHeightDefault;
+
+ DECL_LINK(OpenHdl, weld::Button&, void);
+ DECL_LINK(CheckHdl, weld::Toggleable&, void);
+
+ void Init();
+
+public:
+ SfxInsertFloatingFrameDialog(weld::Window *pParent,
+ const css::uno::Reference<css::embed::XStorage>& xStorage);
+ SfxInsertFloatingFrameDialog(weld::Window* pParent,
+ const css::uno::Reference<css::embed::XEmbeddedObject>& xObj);
+ virtual short run() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/insrc.hxx b/cui/source/inc/insrc.hxx
new file mode 100644
index 000000000..e00379538
--- /dev/null
+++ b/cui/source/inc/insrc.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <rtl/string.hxx>
+#include <svx/svxdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxInsRowColDlg : public SvxAbstractInsRowColDlg, public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> m_xCountEdit;
+ std::unique_ptr<weld::RadioButton> m_xBeforeBtn;
+ std::unique_ptr<weld::RadioButton> m_xAfterBtn;
+
+public:
+ SvxInsRowColDlg(weld::Window* pParent, bool bCol, const OString& rHelpId);
+
+ virtual short Execute() override;
+
+ virtual bool isInsertBefore() const override;
+ virtual sal_uInt16 getInsertCount() const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/labdlg.hxx b/cui/source/inc/labdlg.hxx
new file mode 100644
index 000000000..8146ec388
--- /dev/null
+++ b/cui/source/inc/labdlg.hxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svtools/valueset.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/sxctitm.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svx/anchorid.hxx>
+#include <vcl/image.hxx>
+
+class SdrView;
+
+// class SvxCaptionTabPage -----------------------------------------------
+
+const sal_uInt16 CAPTYPE_BITMAPS_COUNT = 3;
+
+class SvxCaptionTabPage : public SfxTabPage
+{
+private:
+ static const WhichRangesContainer pCaptionRanges;
+
+ Image m_aBmpCapTypes[CAPTYPE_BITMAPS_COUNT];
+
+ std::vector<OUString> m_aStrHorzList;
+ std::vector<OUString> m_aStrVertList;
+
+ SdrCaptionType nCaptionType;
+ sal_Int32 nGap;
+ SdrCaptionEscDir nEscDir;
+ bool bEscRel;
+ sal_Int32 nEscAbs;
+ sal_Int32 nEscRel;
+ sal_Int32 nLineLen;
+ bool bFitLineLen;
+
+ sal_uInt16 nPosition;
+ sal_uInt16 nExtension;
+
+ const SfxItemSet& rOutAttrs;
+ const SdrView* pView;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xMF_SPACING;
+ std::unique_ptr<weld::ComboBox> m_xLB_EXTENSION;
+ std::unique_ptr<weld::Label> m_xFT_BYFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xMF_BY;
+ std::unique_ptr<weld::Label> m_xFT_POSITIONFT;
+ std::unique_ptr<weld::ComboBox> m_xLB_POSITION;
+ std::unique_ptr<weld::ComboBox> m_xLineTypes;
+ std::unique_ptr<weld::Label> m_xFT_LENGTHFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xMF_LENGTH;
+ std::unique_ptr<weld::CheckButton> m_xCB_OPTIMAL;
+ std::unique_ptr<ValueSet> m_xCT_CAPTTYPE;
+ std::unique_ptr<weld::CustomWeld> m_xCT_CAPTTYPEWin;
+
+ void SetupExtension_Impl( sal_uInt16 nType );
+ void SetupType_Impl( SdrCaptionType nType );
+ DECL_LINK(ExtensionSelectHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PositionSelectHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(LineOptHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(SelectCaptTypeHdl_Impl, ValueSet*, void);
+
+public:
+ SvxCaptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxCaptionTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pCaptionRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ void Construct();
+ void SetView( const SdrView* pSdrView )
+ { pView = pSdrView; }
+
+ void FillValueSet();
+};
+
+// class SvxCaptionTabDialog ---------------------------------------------
+struct SvxSwFrameValidation;
+class SvxCaptionTabDialog : public SfxTabDialogController
+{
+private:
+ const SdrView* pView;
+ SvxAnchorIds nAnchorCtrls;
+
+ Link<SvxSwFrameValidation&,void> aValidateLink;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ SvxCaptionTabDialog(weld::Window* pParent, const SdrView* pView,
+ SvxAnchorIds nAnchorTypes);
+
+ /// link for the Writer to validate positions
+ void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink );
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/linkdlg.hxx b/cui/source/inc/linkdlg.hxx
new file mode 100644
index 000000000..1e54954ec
--- /dev/null
+++ b/cui/source/inc/linkdlg.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/idle.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+
+/********************** SvUpdateLinksDialog ******************************
+*************************************************************************/
+namespace sfx2
+{
+class LinkManager;
+class SvBaseLink;
+}
+
+enum class SfxLinkUpdateMode;
+
+class SvBaseLinksDlg : public weld::GenericDialogController
+{
+ OUString aStrAutolink;
+ OUString aStrManuallink;
+ OUString aStrBrokenlink;
+ OUString aStrCloselinkmsg;
+ OUString aStrCloselinkmsgMulti;
+ OUString aStrWaitinglink;
+ sfx2::LinkManager* pLinkMgr;
+ Idle aUpdateIdle;
+
+ std::unique_ptr<weld::TreeView> m_xTbLinks;
+ std::unique_ptr<weld::LinkButton> m_xFtFullFileName;
+ std::unique_ptr<weld::Label> m_xFtFullSourceName;
+ std::unique_ptr<weld::Label> m_xFtFullTypeName;
+ std::unique_ptr<weld::RadioButton> m_xRbAutomatic;
+ std::unique_ptr<weld::RadioButton> m_xRbManual;
+ std::unique_ptr<weld::Button> m_xPbUpdateNow;
+ std::unique_ptr<weld::Button> m_xPbChangeSource;
+ std::unique_ptr<weld::Button> m_xPbBreakLink;
+
+ ScopedVclPtr<VirtualDevice> m_xVirDev;
+
+ DECL_LINK(LinksSelectHdl, weld::TreeView&, void);
+ DECL_LINK(LinksDoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(ToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(UpdateNowClickHdl, weld::Button&, void);
+ DECL_LINK(ChangeSourceClickHdl, weld::Button&, void);
+ DECL_LINK(BreakLinkClickHdl, weld::Button&, void);
+ DECL_LINK(UpdateWaitingHdl, Timer*, void);
+ DECL_LINK(EndEditHdl, sfx2::SvBaseLink&, void);
+ void LinksSelectHdl(weld::TreeView* pTreeView);
+ sfx2::SvBaseLink* GetSelEntry(int* pPos);
+ OUString ImplGetStateStr(const sfx2::SvBaseLink&);
+ void SetType(sfx2::SvBaseLink& rLink, int nPos, SfxLinkUpdateMode nType);
+ void InsertEntry(const sfx2::SvBaseLink& rLink, int nPos = -1, bool bSelect = false);
+
+ void SetManager(sfx2::LinkManager*);
+
+public:
+ SvBaseLinksDlg(weld::Window* pParent, sfx2::LinkManager*, bool bHtml);
+ virtual ~SvBaseLinksDlg() override;
+ void SetActLink(sfx2::SvBaseLink const* pLink);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/macroass.hxx b/cui/source/inc/macroass.hxx
new file mode 100644
index 000000000..ba3c1de11
--- /dev/null
+++ b/cui/source/inc/macroass.hxx
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svl/macitem.hxx>
+#include <vcl/weld.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <memory>
+
+class SfxMacroTabPage_;
+class SfxMacroTabPage_Impl;
+class Timer;
+
+class SfxMacroTabPage final : public SfxTabPage
+{
+ SvxMacroTableDtor aTbl;
+ DECL_LINK(SelectEvent_Impl, weld::TreeView&, void);
+ DECL_LINK(SelectGroup_Impl, weld::TreeView&, void);
+ DECL_LINK(SelectMacro_Impl, weld::TreeView&, void);
+
+ DECL_LINK(AssignDeleteHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(AssignDeleteClickHdl_Impl, weld::Button&, void);
+ void AssignDeleteHdl(const weld::Widget*);
+ DECL_LINK( TimeOut_Impl, Timer*, void );
+
+ std::unique_ptr<SfxMacroTabPage_Impl> mpImpl;
+
+ void InitAndSetHandler();
+ void FillEvents();
+ void EnableButtons();
+
+public:
+ SfxMacroTabPage(
+ weld::Container* pPage, weld::DialogController* pController,
+ const css::uno::Reference< css::frame::XFrame >& rxDocumentFrame,
+ const SfxItemSet& rSet
+ );
+
+ virtual ~SfxMacroTabPage() override;
+
+ void AddEvent( const OUString & rEventName, SvMacroItemId nEventId );
+
+ void ScriptChanged();
+ virtual void PageCreated (const SfxAllItemSet& aSet) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ void LaunchFillGroup();
+
+ // --------- inherit from the base -------------
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ bool IsReadOnly() const override;
+
+ // --------- inherit from the base -------------
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+};
+
+class SfxMacroAssignDlg : public SfxSingleTabDialogController
+{
+public:
+ SfxMacroAssignDlg(weld::Widget* pParent,
+ const css::uno::Reference< css::frame::XFrame >& rxDocumentFrame,
+ const SfxItemSet& rSet);
+ SfxMacroTabPage* GetTabPage()
+ {
+ return static_cast<SfxMacroTabPage*>(m_xSfxPage.get());
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/macropg.hxx b/cui/source/inc/macropg.hxx
new file mode 100644
index 000000000..39e4ef284
--- /dev/null
+++ b/cui/source/inc/macropg.hxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ustring.hxx>
+#include <unotools/resmgr.hxx>
+
+#include <unordered_map>
+#include <vector>
+
+typedef std::unordered_map< OUString, std::pair< OUString, OUString > > EventsHash;
+
+struct EventDisplayName
+{
+ const char* pAsciiEventName;
+ TranslateId pEventResourceID;
+ EventDisplayName(const char* pAsciiName, TranslateId pResId)
+ : pAsciiEventName(pAsciiName)
+ , pEventResourceID(pResId)
+ {
+ }
+};
+
+class SvxMacroTabPage_;
+class SvTabListBox;
+
+class SvxMacroTabPage_Impl;
+
+
+class SvxMacroTabPage_ : public SfxTabPage
+{
+ DECL_LINK( SelectEvent_Impl, weld::TreeView&, void );
+ DECL_LINK( AssignDeleteHdl_Impl, weld::Button&, void );
+ DECL_LINK( DoubleClickHdl_Impl, weld::TreeView&, bool );
+
+ static void GenericHandler_Impl( SvxMacroTabPage_* pThis, const weld::Button* pBtn );
+
+ css::uno::Reference< css::container::XNameReplace > m_xAppEvents;
+protected:
+ std::unique_ptr<SvxMacroTabPage_Impl> mpImpl;
+ css::uno::Reference< css::container::XNameReplace > m_xDocEvents;
+ css::uno::Reference< css::util::XModifiable > m_xModifiable;
+ EventsHash m_appEventsHash;
+ EventsHash m_docEventsHash;
+ bool bDocModified, bAppEvents, bInitialized;
+ std::vector< EventDisplayName > aDisplayNames;
+
+ SvxMacroTabPage_(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rItemSet);
+
+ void EnableButtons();
+ static css::uno::Any GetPropsByName( const OUString& eventName, EventsHash& eventsHash );
+ static std::pair< OUString, OUString > GetPairFromAny( const css::uno::Any& aAny );
+
+public:
+
+ virtual ~SvxMacroTabPage_() override;
+ void InitResources();
+
+ void InitAndSetHandler( const css::uno::Reference< css::container::XNameReplace >& xAppEvents, const css::uno::Reference< css::container::XNameReplace >& xDocEvents, const css::uno::Reference< css::util::XModifiable >& xModifiable );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+ virtual void Reset( const SfxItemSet* ) override;
+
+ void DisplayAppEvents( bool appEvents);
+ void SetReadOnly( bool bSet );
+ bool IsReadOnly() const override;
+};
+
+class SvxMacroTabPage : public SvxMacroTabPage_
+{
+public:
+ SvxMacroTabPage(
+ weld::Container* pPage, weld::DialogController* pController,
+ const css::uno::Reference< css::frame::XFrame >& _rxDocumentFrame,
+ const SfxItemSet& rSet,
+ css::uno::Reference< css::container::XNameReplace > const & xNameReplace,
+ sal_uInt16 nSelectedIndex
+ );
+};
+
+// class SvxMacroAssignDlg --------------------------------------------------
+
+typedef WhichRangesContainer (*GetTabPageRanges)(); // gives international Which-values
+
+class SvxMacroAssignSingleTabDialog : public SfxSingleTabDialogController
+{
+public:
+ SvxMacroAssignSingleTabDialog(weld::Window* pParent, const SfxItemSet& rOptionsSet);
+
+private:
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+};
+
+class SvxMacroAssignDlg : public SvxMacroAssignSingleTabDialog
+{
+public:
+ SvxMacroAssignDlg(
+ weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& _rxDocumentFrame,
+ const SfxItemSet& rSet,
+ const css::uno::Reference< css::container::XNameReplace >& xNameReplace,
+ sal_uInt16 nSelectedIndex
+ );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/measure.hxx b/cui/source/inc/measure.hxx
new file mode 100644
index 000000000..7e18c6485
--- /dev/null
+++ b/cui/source/inc/measure.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/basedlgs.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/measctrl.hxx>
+
+class SdrView;
+
+/// Dialog for changing TextAttributes
+class SvxMeasurePage : public SvxTabPage
+{
+private:
+ static const WhichRangesContainer pRanges;
+
+ const SfxItemSet& rOutAttrs;
+ SfxItemSet aAttrSet;
+ const SdrView* pView;
+ MapUnit eUnit;
+
+ bool bPositionModified;
+
+ SvxRectCtl m_aCtlPosition;
+ SvxXMeasurePreview m_aCtlPreview;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLineDist;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelplineOverhang;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelplineDist;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelpline1Len;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelpline2Len;
+ std::unique_ptr<weld::CheckButton> m_xTsbBelowRefEdge;
+ std::unique_ptr<weld::SpinButton> m_xMtrFldDecimalPlaces;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoPosV;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoPosH;
+ std::unique_ptr<weld::CheckButton> m_xTsbShowUnit;
+ std::unique_ptr<weld::ComboBox> m_xLbUnit;
+ std::unique_ptr<weld::CheckButton> m_xTsbParallel;
+ std::unique_ptr<weld::Label> m_xFtAutomatic;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPosition;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ void FillUnitLB();
+
+ DECL_LINK(ClickAutoPosHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeAttrSpinHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeAttrClickHdl_Impl, weld::Toggleable&, void);
+ void ChangeAttrHdl_Impl(void const *);
+
+public:
+
+ SvxMeasurePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxMeasurePage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+
+};
+
+/* Derived from SfxSingleTabDialogController, in order to be able to be
+ informed about virtual methods by the control. */
+class SvxMeasureDialog : public SfxSingleTabDialogController
+{
+public:
+ SvxMeasureDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ const SdrView* pView);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/multipat.hxx b/cui/source/inc/multipat.hxx
new file mode 100644
index 000000000..258e446e8
--- /dev/null
+++ b/cui/source/inc/multipat.hxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class SvxMultiPathDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xRadioLB;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+
+ void AppendEntry(const OUString& rText, const OUString& rId);
+ void HandleEntryChecked(int nRow);
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(CheckHdl_Impl, const weld::TreeView::iter_col&, void);
+
+public:
+ SvxMultiPathDialog(weld::Window* pParent);
+ virtual ~SvxMultiPathDialog() override;
+
+ OUString GetPath() const;
+ void SetPath(std::u16string_view rPath);
+ void SetTitle(const OUString& rTitle) { m_xDialog->set_title(rTitle); }
+};
+
+class SvxPathSelectDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xPathLB;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+
+public:
+ SvxPathSelectDialog(weld::Window* pParent);
+
+ OUString GetPath() const;
+ void SetPath( std::u16string_view rPath );
+ void SetTitle(const OUString& rTitle) { m_xDialog->set_title(rTitle); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/newtabledlg.hxx b/cui/source/inc/newtabledlg.hxx
new file mode 100644
index 000000000..b62e1199e
--- /dev/null
+++ b/cui/source/inc/newtabledlg.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svx/svxdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxNewTableDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> mxNumColumns;
+ std::unique_ptr<weld::SpinButton> mxNumRows;
+
+public:
+ SvxNewTableDialog(weld::Window* pParent);
+
+ sal_Int32 getRows() const;
+ sal_Int32 getColumns() const;
+};
+
+class SvxNewTableDialogWrapper : public SvxAbstractNewTableDialog
+{
+private:
+ std::shared_ptr<weld::DialogController> m_xDlg;
+
+public:
+ SvxNewTableDialogWrapper(weld::Window* pParent)
+ : m_xDlg(std::make_shared<SvxNewTableDialog>(pParent))
+ {
+ }
+
+ virtual std::shared_ptr<weld::DialogController> getDialogController() override
+ {
+ return m_xDlg;
+ }
+
+ virtual sal_Int32 getRows() const override
+ {
+ SvxNewTableDialog* pDlg = dynamic_cast<SvxNewTableDialog*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->getRows();
+
+ return 0;
+ }
+
+ virtual sal_Int32 getColumns() const override
+ {
+ SvxNewTableDialog* pDlg = dynamic_cast<SvxNewTableDialog*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->getColumns();
+
+ return 0;
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/numfmt.hxx b/cui/source/inc/numfmt.hxx
new file mode 100644
index 000000000..13f1a88e9
--- /dev/null
+++ b/cui/source/inc/numfmt.hxx
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+
+#include <rtl/ustring.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+#include <tools/color.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+
+class SvxNumberFormatShell;
+class SvxNumberInfoItem;
+class vector;
+
+
+class SvxNumberPreview : public weld::CustomWidgetController
+{
+private:
+ OUString aPrevStr;
+ Color aPrevCol;
+ sal_Int32 mnPos;
+ sal_Unicode mnChar;
+
+protected:
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+
+public:
+ SvxNumberPreview();
+
+ void NotifyChange( const OUString& rPrevStr, const Color* pColor = nullptr );
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(-1, pDrawingArea->get_text_height() * 3);
+ }
+};
+
+class SvxNumberFormatTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pRanges;
+
+public:
+ SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+ virtual ~SvxNumberFormatTabPage() override;
+ // Returns area information.
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual DeactivateRC DeactivatePage ( SfxItemSet* pSet ) override;
+
+ void HideLanguage(bool bFlag=true);
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+
+private:
+ std::unique_ptr<SvxNumberInfoItem> pNumItem;
+ std::unique_ptr<SvxNumberFormatShell> pNumFmtShell;
+ sal_uInt32 nInitFormat;
+ short m_nLbFormatSelPosEdComment;
+
+ bool bNumItemFlag; ///< for handling with DocShell
+ bool bOneAreaFlag;
+ bool bLegacyAutomaticCurrency;
+ short nFixedCategory;
+
+ OUString sAutomaticLangEntry;
+ OUString sAutomaticCurrencyEntry;
+
+ SvxNumberPreview m_aWndPreview;
+ std::unique_ptr<weld::Label> m_xFtCategory;
+ std::unique_ptr<weld::TreeView> m_xLbCategory;
+ std::unique_ptr<weld::Label> m_xFtFormat;
+ std::unique_ptr<weld::ComboBox> m_xLbCurrency;
+ std::unique_ptr<weld::TreeView> m_xLbFormat;
+ std::unique_ptr<weld::Label> m_xFtLanguage;
+ std::unique_ptr<weld::CheckButton> m_xCbSourceFormat;
+ std::unique_ptr<weld::Label> m_xFtOptions;
+ std::unique_ptr<weld::Label> m_xFtDecimals;
+ std::unique_ptr<weld::SpinButton> m_xEdDecimals;
+ std::unique_ptr<weld::Label> m_xFtDenominator;
+ std::unique_ptr<weld::SpinButton> m_xEdDenominator;
+ std::unique_ptr<weld::CheckButton> m_xBtnNegRed;
+ std::unique_ptr<weld::Label> m_xFtLeadZeroes;
+ std::unique_ptr<weld::SpinButton> m_xEdLeadZeroes;
+ std::unique_ptr<weld::CheckButton> m_xBtnThousand;
+ std::unique_ptr<weld::CheckButton> m_xBtnEngineering;
+ std::unique_ptr<weld::Widget> m_xFormatCodeFrame;
+ std::unique_ptr<weld::Entry> m_xEdFormat;
+ std::unique_ptr<weld::Button> m_xIbAdd;
+ std::unique_ptr<weld::Button> m_xIbInfo;
+ std::unique_ptr<weld::Button> m_xIbRemove;
+ std::unique_ptr<weld::Label> m_xFtComment;
+ std::unique_ptr<weld::Entry> m_xEdComment;
+ std::unique_ptr<SvxLanguageBox> m_xLbLanguage;
+ std::unique_ptr<weld::CustomWeld> m_xWndPreview;
+
+ void Init_Impl();
+ void FillCurrencyBox();
+ void FillFormatListBox_Impl( std::vector<OUString>& rEntries );
+ void UpdateOptions_Impl( bool bCheckCatChange );
+ void UpdateFormatListBox_Impl( bool bCat, bool bUpdateEdit );
+ void UpdateThousandEngineeringCheckBox();
+ void UpdateDecimalsDenominatorEditBox();
+ void Obstructing();
+ void EnableBySourceFormat_Impl();
+ void SetCategory( sal_uInt16 nPos );
+ OUString GetExpColorString( const Color*& rpPreviewColor, const OUString& aFormatStr, short nTmpCatPos );
+ void MakePreviewText( const OUString& rFormat );
+ void ChangePreviewText( sal_uInt16 nPos );
+ void AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect);
+ bool Click_Impl(const weld::Button& rIB);
+ // Handler
+ DECL_LINK(LostFocusHdl_Impl, weld::Widget&, void);
+ DECL_LINK(DoubleClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(SelFormatListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SelFormatTreeListBoxHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(SelFormatClickHdl_Impl, weld::Toggleable&, void);
+ void SelFormatHdl_Impl(weld::Widget*);
+ DECL_LINK(ClickHdl_Impl, weld::Button&, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(OptEditHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(OptClickHdl_Impl, weld::Toggleable&, void);
+ void EditHdl_Impl(const weld::Entry*);
+ void OptHdl_Impl(const weld::Widget*);
+
+ // set and get currency, taking into account if the legacy
+ // automatic currency entry exists
+ void set_active_currency(sal_Int32 nCurCurrencyEntryPos);
+ sal_uInt32 get_active_currency() const;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/numpages.hxx b/cui/source/inc/numpages.hxx
new file mode 100644
index 000000000..8f554722f
--- /dev/null
+++ b/cui/source/inc/numpages.hxx
@@ -0,0 +1,384 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vector>
+#include <memory>
+
+#include <sfx2/tabdlg.hxx>
+#include <editeng/numdef.hxx>
+#include <editeng/svxenum.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/timer.hxx>
+#include <cui/numberingpreview.hxx>
+
+#define MN_GALLERY_ENTRY 100
+
+class ColorListBox;
+class SvxNumValueSet;
+class SvxNumRule;
+class SvxBmpNumValueSet;
+class SvxBrushItem;
+struct ImplSVEvent;
+
+struct SvxNumSettings_Impl
+{
+ SvxNumType nNumberType;
+ short nParentNumbering;
+ OUString sPrefix;
+ OUString sSuffix;
+ OUString sBulletChar;
+ OUString sBulletFont;
+ SvxNumSettings_Impl() :
+ nNumberType(SVX_NUM_CHARS_UPPER_LETTER),
+ nParentNumbering(0)
+ {}
+};
+
+typedef std::vector<std::unique_ptr<SvxNumSettings_Impl> > SvxNumSettingsArr_Impl;
+
+
+class SvxSingleNumPickTabPage final : public SfxTabPage
+{
+ SvxNumSettingsArr_Impl aNumSettingsArr;
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ bool bModified : 1;
+ bool bPreset : 1;
+ TypedWhichId<SvxNumBulletItem> nNumItemId;
+
+ std::unique_ptr<SvxNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+
+public:
+ SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxSingleNumPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvxBulletPickTabPage final : public SfxTabPage
+{
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ bool bModified : 1;
+ bool bPreset : 1;
+ TypedWhichId<SvxNumBulletItem> nNumItemId;
+
+ OUString sBulletCharFormatName;
+
+ std::unique_ptr<SvxNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+public:
+ SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBulletPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#define NUM_VALUSET_COUNT 16
+
+/// TabPage for complete numeration
+class SvxNumPickTabPage final : public SfxTabPage
+{
+ OUString sNumCharFmtName;
+ OUString sBulletCharFormatName;
+
+ SvxNumSettingsArr_Impl aNumSettingsArrays[NUM_VALUSET_COUNT]; // is initialized with the five formats
+
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ TypedWhichId<SvxNumBulletItem> nNumItemId;
+ bool bModified : 1;
+ bool bPreset : 1;
+
+ std::unique_ptr<SvxNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+
+public:
+ SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxNumPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void SetCharFormatNames(const OUString& rCharName, const OUString& rBulName)
+ { sNumCharFmtName = rCharName;
+ sBulletCharFormatName = rBulName;}
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+class SvxBitmapPickTabPage final : public SfxTabPage
+{
+ std::vector<OUString> aGrfNames;
+
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ TypedWhichId<SvxNumBulletItem> nNumItemId;
+ MapUnit eCoreUnit;
+ bool bModified : 1;
+ bool bPreset : 1;
+
+ std::unique_ptr<weld::Label> m_xErrorText;
+ std::unique_ptr<weld::Button> m_xBtBrowseFile;
+ std::unique_ptr<SvxBmpNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+ DECL_LINK(ClickAddBrowseHdl_Impl, weld::Button&, void);
+
+public:
+ SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBitmapPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvxNumOptionsTabPage : public SfxTabPage
+{
+ OUString m_sNumCharFmtName;
+ OUString m_sBulletCharFormatName;
+
+ Timer aInvalidateTimer;
+
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+
+ Size aInitSize[SVX_MAX_NUM];
+
+ ImplSVEvent* m_pLevelHdlEvent;
+
+ bool bLastWidthModified : 1;
+ bool bModified : 1;
+ bool bPreset : 1;
+ bool bAutomaticCharStyles: 1;
+ bool bHTMLMode : 1;
+
+ std::vector<OUString> aGrfNames;
+ vcl::Font aActBulletFont;
+
+ sal_uInt8 nBullet;
+ sal_uInt16 nActNumLvl;
+ TypedWhichId<SvxNumBulletItem> nNumItemId;
+ MapUnit eCoreUnit;
+
+ SvxNumberingPreview m_aPreviewWIN;
+ std::unique_ptr<weld::Widget> m_xGrid;
+ std::unique_ptr<weld::TreeView> m_xLevelLB;
+ std::unique_ptr<weld::ComboBox> m_xFmtLB;
+ std::unique_ptr<weld::Label> m_xSeparatorFT;
+ std::unique_ptr<weld::Label> m_xPrefixFT;
+ std::unique_ptr<weld::Entry> m_xPrefixED;
+ std::unique_ptr<weld::Label> m_xSuffixFT;
+ std::unique_ptr<weld::Entry> m_xSuffixED;
+ std::unique_ptr<weld::Label> m_xCharFmtFT;
+ std::unique_ptr<weld::ComboBox> m_xCharFmtLB;
+ std::unique_ptr<weld::Label> m_xBulColorFT;
+ std::unique_ptr<ColorListBox> m_xBulColLB;
+ std::unique_ptr<weld::Label> m_xBulRelSizeFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xBulRelSizeMF;
+ std::unique_ptr<weld::Label> m_xAllLevelFT;
+ std::unique_ptr<weld::SpinButton> m_xAllLevelNF;
+ std::unique_ptr<weld::Label> m_xStartFT;
+ std::unique_ptr<weld::SpinButton> m_xStartED;
+ std::unique_ptr<weld::Label> m_xBulletFT;
+ std::unique_ptr<weld::Button> m_xBulletPB;
+ std::unique_ptr<weld::Label> m_xBitmapFT;
+ std::unique_ptr<weld::MenuButton> m_xBitmapMB;
+ std::unique_ptr<weld::Label> m_xWidthFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthMF;
+ std::unique_ptr<weld::Label> m_xHeightFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightMF;
+ std::unique_ptr<weld::CheckButton> m_xRatioCB;
+ std::unique_ptr<weld::Label> m_xOrientFT;
+ std::unique_ptr<weld::ComboBox> m_xOrientLB;
+ std::unique_ptr<weld::Widget> m_xAllLevelsFrame;
+ std::unique_ptr<weld::Menu> m_xGalleryMenu;
+ std::unique_ptr<weld::CheckButton> m_xSameLevelCB;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+
+ void InitControls();
+ /** To switch between the numbering type
+ 0 - Number;
+ 1 - Bullet;
+ 2 - Bitmap; */
+ void SwitchNumberType( sal_uInt8 nType );
+ void CheckForStartValue_Impl(sal_uInt16 nNumberingType);
+
+ DECL_LINK(NumberTypeSelectHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(LevelHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(LevelHdl, void *, void);
+ DECL_LINK(PopupActivateHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(GraphicHdl_Impl, const OString&, void);
+ DECL_LINK(BulletHdl_Impl, weld::Button&, void);
+ DECL_LINK(SizeHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(RatioHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(CharFmtHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(SpinModifyHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(AllLevelHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(OrientHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SameLevelHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(BulColorHdl_Impl, ColorListBox&, void);
+ DECL_LINK(BulRelSizeHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(PreviewInvalidateHdl_Impl, Timer*, void);
+ void EditModifyHdl_Impl(const weld::Entry*);
+
+public:
+ SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxNumOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void SetCharFmts(const OUString& rNumName, const OUString& rBulletName)
+ {
+ m_sNumCharFmtName = rNumName;
+ m_sBulletCharFormatName = rBulletName;
+ }
+ void SetMetric(FieldUnit eSet);
+
+ void SetModified(bool bRepaint = true);
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+
+class SvxNumPositionTabPage : public SfxTabPage
+{
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+
+ ImplSVEvent* m_pLevelHdlEvent;
+ sal_uInt16 nActNumLvl;
+ TypedWhichId<SvxNumBulletItem> nNumItemId;
+ MapUnit eCoreUnit;
+
+ bool bModified : 1;
+ bool bPreset : 1;
+ bool bInInintControl : 1; // workaround for Modify-error, is said to be corrected from 391 on
+ bool bLabelAlignmentPosAndSpaceModeActive;
+
+ SvxNumberingPreview m_aPreviewWIN;
+ std::unique_ptr<weld::TreeView> m_xLevelLB;
+ // former set of controls shown for numbering rules containing list level
+ // attributes in SvxNumberFormat::SvxNumPositionAndSpaceMode == LABEL_WIDTH_AND_POSITION
+ std::unique_ptr<weld::Label> m_xDistBorderFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xDistBorderMF;
+ std::unique_ptr<weld::CheckButton> m_xRelativeCB;
+ std::unique_ptr<weld::Label> m_xIndentFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xIndentMF;
+ std::unique_ptr<weld::Label> m_xDistNumFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xDistNumMF;
+ std::unique_ptr<weld::Label> m_xAlignFT;
+ std::unique_ptr<weld::ComboBox> m_xAlignLB;
+ // new set of controls shown for numbering rules containing list level
+ // attributes in SvxNumberFormat::SvxNumPositionAndSpaceMode == LABEL_ALIGNMENT
+ std::unique_ptr<weld::Label> m_xLabelFollowedByFT;
+ std::unique_ptr<weld::ComboBox> m_xLabelFollowedByLB;
+ std::unique_ptr<weld::Label> m_xListtabFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xListtabMF;
+ std::unique_ptr<weld::Label>m_xAlign2FT;
+ std::unique_ptr<weld::ComboBox> m_xAlign2LB;
+ std::unique_ptr<weld::Label> m_xAlignedAtFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xAlignedAtMF;
+ std::unique_ptr<weld::Label> m_xIndentAtFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xIndentAtMF;
+ std::unique_ptr<weld::Button> m_xStandardPB;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+
+ void InitControls();
+
+ DECL_LINK(LevelHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(LevelHdl, void *, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(DistanceHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(RelativeHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+
+ void InitPosAndSpaceMode();
+ void ShowControlsDependingOnPosAndSpaceMode();
+
+ DECL_LINK(LabelFollowedByHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ListtabPosHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(AlignAtHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(IndentAtHdl_Impl, weld::MetricSpinButton&, void);
+
+public:
+ SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxNumPositionTabPage() override;
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ void SetMetric(FieldUnit eSet);
+ void SetModified();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optasian.hxx b/cui/source/inc/optasian.hxx
new file mode 100644
index 000000000..9d9815ea4
--- /dev/null
+++ b/cui/source/inc/optasian.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+
+struct SvxAsianLayoutPage_Impl;
+class SvxAsianLayoutPage : public SfxTabPage
+{
+ std::unique_ptr<SvxAsianLayoutPage_Impl> pImpl;
+
+ std::unique_ptr<weld::RadioButton> m_xCharKerningRB;
+ std::unique_ptr<weld::RadioButton> m_xCharPunctKerningRB;
+ std::unique_ptr<weld::RadioButton> m_xNoCompressionRB;
+ std::unique_ptr<weld::RadioButton> m_xPunctCompressionRB;
+ std::unique_ptr<weld::RadioButton> m_xPunctKanaCompressionRB;
+ std::unique_ptr<weld::Label> m_xLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xStandardCB;
+ std::unique_ptr<weld::Label> m_xStartFT;
+ std::unique_ptr<weld::Entry> m_xStartED;
+ std::unique_ptr<weld::Label> m_xEndFT;
+ std::unique_ptr<weld::Entry> m_xEndED;
+ std::unique_ptr<weld::Label> m_xHintFT;
+
+ DECL_LINK(LanguageHdl, weld::ComboBox&, void);
+ DECL_LINK(ChangeStandardHdl, weld::Toggleable&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ SvxAsianLayoutPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SvxAsianLayoutPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ static WhichRangesContainer GetRanges();
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optdict.hxx b/cui/source/inc/optdict.hxx
new file mode 100644
index 000000000..e2dcf5595
--- /dev/null
+++ b/cui/source/inc/optdict.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <svx/langbox.hxx>
+
+namespace com::sun::star{
+ namespace linguistic2{
+ class XDictionary;
+ class XSpellChecker1;
+ }
+}
+
+// forward ---------------------------------------------------------------
+
+
+// class SvxNewDictionaryDialog ------------------------------------------
+
+class SvxNewDictionaryDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xNameEdit;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xExceptBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ css::uno::Reference<css::linguistic2::XDictionary> m_xNewDic;
+
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+
+public:
+ SvxNewDictionaryDialog(weld::Window* pParent);
+
+ const css::uno::Reference<css::linguistic2::XDictionary>& GetNewDictionary() const { return m_xNewDic; }
+};
+
+// class SvxEditDictionaryDialog -----------------------------------------
+
+class SvxEditDictionaryDialog : public weld::GenericDialogController
+{
+private:
+ OUString sModify;
+ OUString sNew;
+ OUString sReplaceFT_Text;
+
+ css::uno::Sequence<
+ css::uno::Reference<
+ css::linguistic2::XDictionary > > aDics; //! snapshot copy to work on
+
+ bool bFirstSelect;
+ bool bDoNothing;
+ bool bDicIsReadonly;
+
+ weld::TreeView* m_pWordsLB;
+ std::unique_ptr<weld::ComboBox> m_xAllDictsLB;
+ std::unique_ptr<weld::Label> m_xLangFT;
+ std::unique_ptr<SvxLanguageBox> m_xLangLB;
+ std::unique_ptr<weld::Entry> m_xWordED;
+ std::unique_ptr<weld::Label> m_xReplaceFT;
+ std::unique_ptr<weld::Entry> m_xReplaceED;
+ std::unique_ptr<weld::TreeView> m_xSingleColumnLB;
+ std::unique_ptr<weld::TreeView> m_xDoubleColumnLB;
+ std::unique_ptr<weld::Button> m_xNewReplacePB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+
+ DECL_LINK(SelectBookHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SelectLangHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(NewDelButtonHdl, weld::Button&, void);
+ DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ DECL_LINK(EntrySizeAllocHdl, const Size&, void);
+ DECL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString&, bool);
+ bool NewDelHdl(const weld::Widget*);
+
+ void ShowWords_Impl( sal_uInt16 nId );
+ void SetLanguage_Impl( LanguageType nLanguage );
+ bool IsDicReadonly_Impl() const { return bDicIsReadonly; }
+ void SetDicReadonly_Impl( css::uno::Reference<
+ css::linguistic2::XDictionary > const &xDic );
+
+ void RemoveDictEntry(int nEntry);
+ int GetLBInsertPos(std::u16string_view rDicWord);
+
+public:
+ SvxEditDictionaryDialog(weld::Window* pParent, std::u16string_view rName);
+ virtual ~SvxEditDictionaryDialog() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optlingu.hxx b/cui/source/inc/optlingu.hxx
new file mode 100644
index 000000000..365acfbbb
--- /dev/null
+++ b/cui/source/inc/optlingu.hxx
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace com::sun::star{
+ namespace beans{
+ class XPropertySet;
+ }
+ namespace linguistic2{
+ class XDictionary;
+ class XDictionaryList;
+ class XLinguProperties;
+ }
+}
+
+class SvxLinguData_Impl;
+
+// define ----------------------------------------------------------------
+
+#define GROUP_MODULES (sal_uInt16(0x0008))
+
+// forward ---------------------------------------------------------------
+
+class SvxEditModulesDlg : public weld::GenericDialogController
+{
+ OUString sSpell;
+ OUString sHyph;
+ OUString sThes;
+ OUString sGrammar;
+
+ std::unique_ptr<SvxLinguData_Impl> pDefaultLinguData;
+ SvxLinguData_Impl& rLinguData;
+
+ std::unique_ptr<weld::TreeView> m_xModulesCLB;
+ std::unique_ptr<weld::Button> m_xPrioUpPB;
+ std::unique_ptr<weld::Button> m_xPrioDownPB;
+ std::unique_ptr<weld::Button> m_xBackPB;
+ std::unique_ptr<weld::LinkButton> m_xMoreDictsLink;
+ std::unique_ptr<weld::Button> m_xClosePB;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+
+ DECL_LINK( SelectHdl_Impl, weld::TreeView&, void );
+ DECL_LINK( UpDownHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickHdl_Impl, weld::Button&, void );
+ DECL_LINK( BackHdl_Impl, weld::Button&, void );
+ DECL_LINK( LangSelectListBoxHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( BoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, void );
+ DECL_STATIC_LINK( SvxEditModulesDlg, OnLinkClick, weld::LinkButton&, bool);
+ void LangSelectHdl_Impl(const SvxLanguageBox* pBox);
+
+public:
+ SvxEditModulesDlg(weld::Window* pParent, SvxLinguData_Impl& rData);
+ virtual ~SvxEditModulesDlg() override;
+};
+
+struct ImplSVEvent;
+
+// class SvxLinguTabPage -------------------------------------------------
+class SvxLinguTabPage : public SfxTabPage
+{
+private:
+ OUString sCapitalWords;
+ OUString sWordsWithDigits;
+ OUString sSpellSpecial;
+ OUString sSpellAuto;
+ OUString sGrammarAuto;
+ OUString sNumMinWordlen;
+ OUString sNumPreBreak;
+ OUString sNumPostBreak;
+ OUString sHyphAuto;
+ OUString sHyphSpecial;
+
+ int nUPN_HYPH_MIN_WORD_LENGTH;
+ int nUPN_HYPH_MIN_LEADING;
+ int nUPN_HYPH_MIN_TRAILING;
+
+ ImplSVEvent* m_nDlbClickEventId;
+
+ css::uno::Reference<
+ css::linguistic2::XLinguProperties > xProp;
+
+ css::uno::Reference<
+ css::linguistic2::XDictionaryList > xDicList;
+ css::uno::Sequence<
+ css::uno::Reference<
+ css::linguistic2::XDictionary > > aDics;
+
+ std::unique_ptr<SvxLinguData_Impl> pLinguData;
+
+ std::unique_ptr<weld::Label> m_xLinguModulesFT;
+ std::unique_ptr<weld::TreeView> m_xLinguModulesCLB;
+ std::unique_ptr<weld::Button> m_xLinguModulesEditPB;
+ std::unique_ptr<weld::Label> m_xLinguDicsFT;
+ std::unique_ptr<weld::TreeView> m_xLinguDicsCLB;
+ std::unique_ptr<weld::Button> m_xLinguDicsNewPB;
+ std::unique_ptr<weld::Button> m_xLinguDicsEditPB;
+ std::unique_ptr<weld::Button> m_xLinguDicsDelPB;
+ std::unique_ptr<weld::TreeView> m_xLinguOptionsCLB;
+ std::unique_ptr<weld::Button> m_xLinguOptionsEditPB;
+ std::unique_ptr<weld::LinkButton> m_xMoreDictsLink;
+
+ void AddDicBoxEntry( const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx );
+ static sal_uInt32 GetDicUserData( const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx );
+
+ DECL_LINK( SelectHdl_Impl, weld::TreeView&, void );
+ DECL_LINK( ClickHdl_Impl, weld::Button&, void );
+ DECL_LINK( BoxDoubleClickHdl_Impl, weld::TreeView&, bool );
+ DECL_LINK( ModulesBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, void );
+ DECL_LINK( DicsBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, void );
+ DECL_LINK( PostDblClickHdl_Impl, void *, void);
+ DECL_STATIC_LINK( SvxLinguTabPage, OnLinkClick, weld::LinkButton&, bool);
+
+ void UpdateModulesBox_Impl();
+ void UpdateDicBox_Impl();
+
+public:
+ SvxLinguTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxLinguTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void HideGroups( sal_uInt16 nGrp );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optpath.hxx b/cui/source/inc/optpath.hxx
new file mode 100644
index 000000000..acc769652
--- /dev/null
+++ b/cui/source/inc/optpath.hxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+#include <unotools/pathoptions.hxx>
+
+// forward ---------------------------------------------------------------
+struct OptPath_Impl;
+class SvxPathTabPage;
+
+// class SvxPathTabPage --------------------------------------------------
+class SvxPathTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<OptPath_Impl> pImpl;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ std::unique_ptr<weld::Button> m_xStandardBtn;
+ std::unique_ptr<weld::Button> m_xPathBtn;
+ std::unique_ptr<weld::TreeView> m_xPathBox;
+
+ void ChangeCurrentEntry( const OUString& _rFolder );
+
+ DECL_LINK(PathHdl_Impl, weld::Button&, void);
+ DECL_LINK(DoubleClickPathHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+
+ DECL_LINK(PathSelect_Impl, weld::TreeView&, void);
+ DECL_LINK(HeaderBarClick, int, void);
+
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+ void GetPathList( SvtPathOptions::Paths _nPathHandle, OUString& _rInternalPath,
+ OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly );
+ void SetPathList( SvtPathOptions::Paths _nPathHandle,
+ std::u16string_view _rUserPath, const OUString& _rWritablePath );
+
+public:
+ SvxPathTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxPathTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/page.hxx b/cui/source/inc/page.hxx
new file mode 100644
index 000000000..02af8079a
--- /dev/null
+++ b/cui/source/inc/page.hxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/pagectrl.hxx>
+#include <svx/pagenumberlistbox.hxx>
+#include <svx/papersizelistbox.hxx>
+#include <svx/frmdirlbox.hxx>
+#include <i18nutil/paper.hxx>
+#include <svx/flagsdef.hxx>
+#include <vcl/print.hxx>
+
+// class SvxPageDescPage -------------------------------------------------
+/*
+ [Description]
+ TabPage for page settings (size, margins, ...)
+
+ [Items]
+ <SvxPageItem>: <SID_ATTR_PAGE>
+ <SvxSizeItem>: <SID_ATTR_SIZE>
+ <SvxSizeItem>: <SID_ATTR_MAXSIZE>
+ <SvxULSpaceItem>: <SID_ATTR_LRSPACE>
+ <SvxLRSpaceItem>: <SID_ATTR_ULSPACE>
+ <SfxAllEnumItem>: <SID_ATTR_PAPERTRAY>
+ <SvxPaperBinItem>: <SID_ATTR_PAPERBIN>
+ <SvxBoolItem>: <SID_ATTR_EXT1>
+ <SvxBoolItem>: <SID_ATTR_EXT2>
+
+ <SfxSetItem>: <SID_ATTR_HEADERSET>
+ <SfxBoolItem>: <SID_ATTR_ON>
+ <SfxBoolItem>: <SID_ATTR_DYNAMIC>
+ <SfxBoolItem>: <SID_ATTR_SHARED>
+ <SvxSizeItem>: <SID_ATTR_SIZE>
+ <SvxULSpaceItem>: <SID_ATTR_ULSPACE>
+ <SvxLRSpaceItem>: <SID_ATTR_LRSPACE>
+
+ <SfxSetItem>: <SID_ATTR_FOOTERSET>
+ <SfxBoolItem>: <SID_ATTR_ON>
+ <SfxBoolItem>: <SID_ATTR_DYNAMIC>
+ <SfxBoolItem>: <SID_ATTR_SHARED>
+ <SvxSizeItem>: <SID_ATTR_SIZE>
+ <SvxULSpaceItem>: <SID_ATTR_ULSPACE>
+ <SvxLRSpaceItem>: <SID_ATTR_LRSPACE>
+*/
+
+typedef sal_uInt16 MarginPosition;
+
+class SvxPageDescPage : public SfxTabPage
+{
+ static const WhichRangesContainer pRanges;
+private:
+ OUString sStandardRegister;
+ tools::Long nFirstLeftMargin;
+ tools::Long nFirstRightMargin;
+ tools::Long nFirstTopMargin;
+ tools::Long nFirstBottomMargin;
+ tools::Long nLastLeftMargin;
+ tools::Long nLastRightMargin;
+ tools::Long nLastTopMargin;
+ tools::Long nLastBottomMargin;
+
+ bool bLandscape;
+ bool bBorderModified;
+ SvxModeType eMode;
+ Paper ePaperStart;
+
+ MarginPosition m_nPos;
+ VclPtr<Printer> mpDefPrinter;
+
+ bool mbDelPrinter : 1;
+ bool mbEnableDrawingLayerFillStyles : 1;
+
+ SvxPageWindow m_aBspWin;
+
+ // paper format
+ std::unique_ptr<SvxPaperSizeListBox> m_xPaperSizeBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xPaperWidthEdit;
+ std::unique_ptr<weld::MetricSpinButton> m_xPaperHeightEdit;
+ std::unique_ptr<weld::Label> m_xOrientationFT;
+ std::unique_ptr<weld::RadioButton> m_xPortraitBtn;
+ std::unique_ptr<weld::RadioButton> m_xLandscapeBtn;
+ std::unique_ptr<weld::Label> m_xTextFlowLbl;
+ std::unique_ptr<svx::FrameDirectionListBox> m_xTextFlowBox;
+ std::unique_ptr<weld::ComboBox> m_xPaperTrayBox;
+ // Margins
+ std::unique_ptr<weld::Label> m_xLeftMarginLbl;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMarginEdit;
+ std::unique_ptr<weld::Label> m_xRightMarginLbl;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightMarginEdit;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMarginEdit;
+ std::unique_ptr<weld::MetricSpinButton> m_xBottomMarginEdit;
+ std::unique_ptr<weld::Label> m_xGutterMarginLbl;
+ std::unique_ptr<weld::MetricSpinButton> m_xGutterMarginEdit;
+ // layout settings
+ std::unique_ptr<weld::Label> m_xPageText;
+ std::unique_ptr<weld::ComboBox> m_xLayoutBox;
+ std::unique_ptr<weld::Label> m_xNumberFormatText;
+ std::unique_ptr<SvxPageNumberListBox> m_xNumberFormatBox;
+ //Extras Calc
+ std::unique_ptr<weld::Label> m_xTblAlignFT;
+ std::unique_ptr<weld::CheckButton> m_xHorzBox;
+ std::unique_ptr<weld::CheckButton> m_xVertBox;
+ // Impress and Draw
+ std::unique_ptr<weld::CheckButton> m_xAdaptBox;
+ //Register Writer
+ std::unique_ptr<weld::CheckButton> m_xRegisterCB;
+ std::unique_ptr<weld::Label> m_xRegisterFT;
+ std::unique_ptr<weld::ComboBox> m_xRegisterLB;
+ std::unique_ptr<weld::Label> m_xGutterPositionFT;
+ std::unique_ptr<weld::ComboBox> m_xGutterPositionLB;
+ std::unique_ptr<weld::CheckButton> m_xRtlGutterCB;
+ std::unique_ptr<weld::CheckButton> m_xBackgroundFullSizeCB;
+ std::unique_ptr<weld::Label> m_xInsideLbl;
+ std::unique_ptr<weld::Label> m_xOutsideLbl;
+ std::unique_ptr<weld::Label> m_xPrintRangeQueryText;
+ std::unique_ptr<weld::CustomWeld> m_xBspWin;
+
+ void Init_Impl();
+ DECL_LINK(LayoutHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(GutterPositionHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PaperBinHdl_Impl, weld::Widget&, void);
+ DECL_LINK(SwapOrientation_Impl, weld::Toggleable&, void);
+ void SwapFirstValues_Impl( bool bSet );
+ DECL_LINK(BorderModify_Impl, weld::MetricSpinButton&, void);
+ void InitHeadFoot_Impl( const SfxItemSet& rSet );
+ DECL_LINK(CenterHdl_Impl, weld::Toggleable&, void);
+ void UpdateExample_Impl( bool bResetbackground = false );
+
+ DECL_LINK(PaperSizeSelect_Impl, weld::ComboBox&, void );
+ DECL_LINK(PaperSizeModify_Impl, weld::MetricSpinButton&, void);
+
+ DECL_LINK(FrameDirectionModify_Impl, weld::ComboBox&, void );
+
+ void ResetBackground_Impl( const SfxItemSet& rSet );
+
+ void RangeHdl_Impl();
+ void CalcMargin_Impl();
+
+ DECL_LINK(RegisterModify, weld::Toggleable&, void);
+
+ // page direction
+ /** Disables vertical page direction entries in the text flow listbox. */
+ void DisableVerticalPageDir();
+
+ bool IsPrinterRangeOverflow(weld::MetricSpinButton& rField, tools::Long nFirstMargin,
+ tools::Long nLastMargin, MarginPosition nPos);
+ void CheckMarginEdits( bool _bClear );
+ bool IsMarginOutOfRange() const;
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxPageDescPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxPageDescPage() override;
+
+ // returns the range of the Which values
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rOutSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+
+ void SetPaperFormatRanges( Paper eStart )
+ { ePaperStart = eStart; }
+
+ void SetCollectionList(const std::vector<OUString> &aList);
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx
new file mode 100644
index 000000000..991641e3b
--- /dev/null
+++ b/cui/source/inc/paragrph.hxx
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/relfld.hxx>
+#include <svx/paraprev.hxx>
+#include <svx/frmdirlbox.hxx>
+
+class SvxLineSpacingItem;
+
+// class SvxStdParagraphTabPage ------------------------------------------
+/*
+ [Description]
+ With this TabPage standard attributes of a paragraph can be set
+ (indention, distance, alignment, line spacing).
+
+ [Items]
+ <SvxAdjustItem><SID_ATTR_PARA_ADJUST>
+ <SvxLineSpacingItem><SID_ATTR_PARA_LINESPACE>
+ <SvxULSpaceItem><SID_ATTR_ULSPACE>
+ <SvxLRSpaceItem><SID_ATTR_LRSPACE>
+*/
+
+class SvxStdParagraphTabPage: public SfxTabPage
+{
+ static const WhichRangesContainer pStdRanges;
+
+private:
+ tools::Long nWidth;
+ tools::Long nMinFixDist;
+ bool bRelativeMode;
+ OUString sAbsDist;
+
+ SvxParaPrevWindow m_aExampleWin;
+
+ // indention
+ std::unique_ptr<SvxRelativeField> m_xLeftIndent;
+
+ std::unique_ptr<weld::Label> m_xRightLabel;
+ std::unique_ptr<SvxRelativeField> m_xRightIndent;
+
+ std::unique_ptr<weld::Label> m_xFLineLabel;
+ std::unique_ptr<SvxRelativeField> m_xFLineIndent;
+ std::unique_ptr<weld::CheckButton> m_xAutoCB;
+
+ // distance
+ std::unique_ptr<SvxRelativeField> m_xTopDist;
+ std::unique_ptr<SvxRelativeField> m_xBottomDist;
+ std::unique_ptr<weld::CheckButton> m_xContextualCB;
+
+ // line spacing
+ std::unique_ptr<weld::ComboBox> m_xLineDist;
+ std::unique_ptr<weld::MetricSpinButton> m_xLineDistAtPercentBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xLineDistAtMetricBox;
+ std::unique_ptr<weld::Label> m_xLineDistAtLabel;
+ std::unique_ptr<weld::Label> m_xAbsDist;
+
+ // only writer
+ std::unique_ptr<weld::CheckButton> m_xRegisterCB;
+
+ // preview
+ std::unique_ptr<weld::CustomWeld> m_xExampleWin;
+
+ void SetLineSpacing_Impl( const SvxLineSpacingItem& rAttr );
+ void Init_Impl();
+ void UpdateExample_Impl();
+ void ELRLoseFocus();
+
+ DECL_LINK(LineDistPopupHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(LineDistHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(AutoHdl_Impl, weld::Toggleable&, void);
+
+ bool m_bLineDistToggled = false;
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+
+public:
+ SvxStdParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxStdParagraphTabPage() override;
+
+ DECL_LINK(ELRLoseFocusHdl, weld::MetricSpinButton&, void);
+
+ static WhichRangesContainer GetRanges() { return pStdRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void EnableRelativeMode();
+ void EnableRegisterMode();
+ void EnableContextualMode();
+ void EnableAutoFirstLine();
+ void EnableAbsLineDist(tools::Long nMinTwip);
+ void EnableNegativeMode();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxParaAlignTabPage ------------------------------------------------
+
+class SvxParaAlignTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pAlignRanges;
+
+ SvxParaPrevWindow m_aExampleWin;
+
+ // alignment
+ std::unique_ptr<weld::RadioButton> m_xLeft;
+ std::unique_ptr<weld::RadioButton> m_xRight;
+ std::unique_ptr<weld::RadioButton> m_xCenter;
+ std::unique_ptr<weld::RadioButton> m_xJustify;
+ std::unique_ptr<weld::Label> m_xLeftBottom;
+ std::unique_ptr<weld::Label> m_xRightTop;
+
+ std::unique_ptr<weld::Label> m_xLastLineFT;
+ std::unique_ptr<weld::ComboBox> m_xLastLineLB;
+ std::unique_ptr<weld::CheckButton> m_xExpandCB;
+
+ std::unique_ptr<weld::CheckButton> m_xSnapToGridCB;
+
+ //preview
+ std::unique_ptr<weld::CustomWeld> m_xExampleWin;
+ //vertical alignment
+ std::unique_ptr<weld::Widget> m_xVertAlignFL;
+ std::unique_ptr<weld::ComboBox> m_xVertAlignLB;
+
+ std::unique_ptr<weld::Widget> m_xPropertiesFL;
+ std::unique_ptr<svx::FrameDirectionListBox> m_xTextDirectionLB;
+
+ DECL_LINK(AlignHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(LastLineHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(TextDirectionHdl_Impl, weld::ComboBox&, void);
+
+ void UpdateExample_Impl();
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxParaAlignTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxParaAlignTabPage() override;
+
+ static WhichRangesContainer GetRanges() { return pAlignRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void EnableJustifyExt();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxExtParagraphTabPage ------------------------------------------
+/*
+ [Description]
+ With this TabPage special attributes of a paragraph can be set
+ (hyphenation, pagebreak, orphan, widow, ...).
+
+ [Items]
+ <SvxHyphenZoneItem><SID_ATTR_PARA_HYPHENZONE>
+ <SvxFormatBreakItem><SID_ATTR_PARA_PAGEBREAK>
+ <SvxFormatSplitItem><SID_ATTR_PARA_SPLIT>
+ <SvxWidowsItem><SID_ATTR_PARA_WIDOWS>
+ <SvxOrphansItem><SID_ATTR_PARA_ORPHANS>
+*/
+
+class SvxExtParagraphTabPage: public SfxTabPage
+{
+ static const WhichRangesContainer pExtRanges;
+
+public:
+ SvxExtParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet );
+ virtual ~SvxExtParagraphTabPage() override;
+
+ static WhichRangesContainer GetRanges() { return pExtRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void DisablePageBreak();
+
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ weld::TriStateEnabled aHyphenState;
+ weld::TriStateEnabled aPageBreakState;
+ weld::TriStateEnabled aApplyCollState;
+ weld::TriStateEnabled aPageNumState;
+ weld::TriStateEnabled aKeepTogetherState;
+ weld::TriStateEnabled aKeepParaState;
+ weld::TriStateEnabled aOrphanState;
+ weld::TriStateEnabled aWidowState;
+
+ bool bPageBreak;
+ bool bHtmlMode;
+ sal_uInt16 nStdPos;
+
+ // hyphenation
+ std::unique_ptr<weld::CheckButton> m_xHyphenBox;
+ std::unique_ptr<weld::CheckButton> m_xHyphenNoCapsBox;
+ std::unique_ptr<weld::CheckButton> m_xHyphenNoLastWordBox;
+ std::unique_ptr<weld::Label> m_xBeforeText;
+ std::unique_ptr<weld::SpinButton> m_xExtHyphenBeforeBox;
+ std::unique_ptr<weld::Label> m_xAfterText;
+ std::unique_ptr<weld::SpinButton> m_xExtHyphenAfterBox;
+ std::unique_ptr<weld::Label> m_xMaxHyphenLabel;
+ std::unique_ptr<weld::SpinButton> m_xMaxHyphenEdit;
+ std::unique_ptr<weld::Label> m_xMinWordLabel;
+ std::unique_ptr<weld::SpinButton> m_xMinWordLength;
+ std::unique_ptr<weld::Label> m_xHyphenZoneLabel;
+ std::unique_ptr<SvxRelativeField> m_xHyphenZone;
+
+ // pagebreak
+ std::unique_ptr<weld::CheckButton> m_xPageBreakBox;
+ std::unique_ptr<weld::Label> m_xBreakTypeFT;
+ std::unique_ptr<weld::ComboBox> m_xBreakTypeLB;
+ std::unique_ptr<weld::Label> m_xBreakPositionFT;
+ std::unique_ptr<weld::ComboBox> m_xBreakPositionLB;
+ std::unique_ptr<weld::CheckButton> m_xApplyCollBtn;
+ std::unique_ptr<weld::ComboBox> m_xApplyCollBox;
+ std::unique_ptr<weld::CheckButton> m_xPageNumBox;
+ std::unique_ptr<weld::SpinButton> m_xPagenumEdit;
+
+ // paragraph division
+ std::unique_ptr<weld::CheckButton> m_xKeepTogetherBox;
+ std::unique_ptr<weld::CheckButton> m_xKeepParaBox;
+
+ // orphan/widow
+ std::unique_ptr<weld::CheckButton> m_xOrphanBox;
+ std::unique_ptr<weld::SpinButton> m_xOrphanRowNo;
+ std::unique_ptr<weld::Label> m_xOrphanRowLabel;
+
+ std::unique_ptr<weld::CheckButton> m_xWidowBox;
+ std::unique_ptr<weld::SpinButton> m_xWidowRowNo;
+ std::unique_ptr<weld::Label> m_xWidowRowLabel;
+
+ void HyphenClickHdl();
+ void PageNumBoxClickHdl();
+ void ApplyCollClickHdl();
+ void PageBreakHdl();
+ void KeepTogetherHdl();
+ void OrphanHdl();
+ void WidowHdl();
+
+ DECL_LINK(PageBreakHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(KeepTogetherHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(WidowHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(OrphanHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(HyphenClickHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ApplyCollClickHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(PageBreakPosHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PageBreakTypeHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PageNumBoxClickHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(KeepParaBoxClickHdl_Impl, weld::Toggleable&, void);
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+class SvxAsianTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xForbiddenRulesCB;
+ std::unique_ptr<weld::CheckButton> m_xHangingPunctCB;
+ std::unique_ptr<weld::CheckButton> m_xScriptSpaceCB;
+
+public:
+ SvxAsianTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+ virtual ~SvxAsianTabPage() override;
+
+ static WhichRangesContainer GetRanges();
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/passwdomdlg.hxx b/cui/source/inc/passwdomdlg.hxx
new file mode 100644
index 000000000..2e13cc1b6
--- /dev/null
+++ b/cui/source/inc/passwdomdlg.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/basedlgs.hxx>
+#include <memory>
+
+class PasswordToOpenModifyDialog : public SfxDialogController
+{
+ std::unique_ptr<weld::Entry> m_xPasswdToOpenED;
+ std::unique_ptr<weld::Label> m_xPasswdToOpenInd;
+ std::unique_ptr<weld::Entry> m_xReenterPasswdToOpenED;
+ std::unique_ptr<weld::Label> m_xReenterPasswdToOpenInd;
+ std::unique_ptr<weld::Expander> m_xOptionsExpander;
+ std::unique_ptr<weld::Button> m_xOk;
+ std::unique_ptr<weld::CheckButton> m_xOpenReadonlyCB;
+ std::unique_ptr<weld::Label> m_xPasswdToModifyFT;
+ std::unique_ptr<weld::Entry> m_xPasswdToModifyED;
+ std::unique_ptr<weld::Label> m_xPasswdToModifyInd;
+ std::unique_ptr<weld::Label> m_xReenterPasswdToModifyFT;
+ std::unique_ptr<weld::Entry> m_xReenterPasswdToModifyED;
+ std::unique_ptr<weld::Label> m_xReenterPasswdToModifyInd;
+
+ OUString m_aOneMismatch;
+ OUString m_aTwoMismatch;
+ OUString m_aInvalidStateForOkButton;
+ OUString m_aInvalidStateForOkButton_v2;
+
+ int m_nMaxPasswdLen;
+ bool m_bIsPasswordToModify;
+
+
+ DECL_LINK(OkBtnClickHdl, weld::Button&, void);
+ DECL_LINK(ReadonlyOnOffHdl, weld::Toggleable&, void);
+ DECL_LINK(ChangeHdl, weld::Entry&, void);
+
+ PasswordToOpenModifyDialog( const PasswordToOpenModifyDialog & ) = delete;
+ PasswordToOpenModifyDialog & operator = ( const PasswordToOpenModifyDialog & ) = delete;
+
+public:
+ PasswordToOpenModifyDialog(weld::Window* pParent,
+ sal_uInt16 nMaxPasswdLen /* 0 -> no max len enforced */,
+ bool bIsPasswordToModify );
+
+ // AbstractPasswordToOpenModifyDialog
+ OUString GetPasswordToOpen() const;
+ OUString GetPasswordToModify() const;
+ bool IsRecommendToOpenReadonly() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/pastedlg.hxx b/cui/source/inc/pastedlg.hxx
new file mode 100644
index 000000000..72f7911f2
--- /dev/null
+++ b/cui/source/inc/pastedlg.hxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <map>
+#include <sot/formats.hxx>
+#include <tools/globname.hxx>
+#include <vcl/transfer.hxx>
+#include <vcl/weld.hxx>
+
+struct TransferableObjectDescriptor;
+class TransferableDataHelper;
+
+class SvPasteObjectDialog : public weld::GenericDialogController
+{
+ std::map< SotClipboardFormatId, OUString > aSupplementMap;
+ // Additional UNO command to be displayed along the supported paste formats
+ std::pair<OUString, OUString> aExtraCommand;
+ SvGlobalName aObjClassName;
+ OUString aObjName;
+
+ std::unique_ptr<weld::Label> m_xFtObjectSource;
+ std::unique_ptr<weld::TreeView> m_xLbInsertList;
+ std::unique_ptr<weld::Button> m_xOKButton;
+
+ weld::TreeView& ObjectLB() { return *m_xLbInsertList; }
+
+ void SelectObject();
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
+
+public:
+ SvPasteObjectDialog(weld::Window* pParent);
+
+ void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName );
+ void InsertUno( const OUString& sUnoCmd, const OUString& sLabel);
+ void SetObjName( const SvGlobalName & rClass, const OUString & rObjName );
+ /**
+ * @brief PreGetFormat Prepares the dialog for running to get format of paste as a SotClipboardFormatId value by calling GetFormatOnly()
+ * @param aHelper
+ */
+ void PreGetFormat( const TransferableDataHelper& aHelper);
+ /**
+ * @brief GetFormatOnly Returns a SotClipboardFormatId value. Should be called after actually running the dialog.
+ * @return
+ */
+ SotClipboardFormatId GetFormatOnly();
+ /**
+ * @brief GetFormat Prepares and runs the dialog, and returns a SotClipboardFormatId depending on the RET_OK result
+ * @param aHelper TransferableDataHelper containing the data to be pasted
+ * @return a SotClipboardFormatId value depending on the result of running the dialog
+ */
+ SotClipboardFormatId GetFormat( const TransferableDataHelper& aHelper);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/postdlg.hxx b/cui/source/inc/postdlg.hxx
new file mode 100644
index 000000000..66fd07af6
--- /dev/null
+++ b/cui/source/inc/postdlg.hxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <sfx2/basedlgs.hxx>
+
+// class SvxPostItDialog -------------------------------------------------
+/*
+ [Description]
+ In this dialog a note can be created or edited. If the
+ application holds a list of notes, it can be iterated
+ over this list with links.
+
+ [Items]
+ <SvxPostItAuthorItem><SID_ATTR_POSTIT_AUTHOR>
+ <SvxPostItDateItem><SID_ATTR_POSTIT_DATE>
+ <SvxPostItTextItem><SID_ATTR_POSTIT_TEXT>
+*/
+
+class SvxPostItDialog : public SfxDialogController
+{
+public:
+ SvxPostItDialog(weld::Widget* pParent, const SfxItemSet& rCoreSet,
+ bool bPrevNext);
+ virtual ~SvxPostItDialog() override;
+
+ static WhichRangesContainer GetRanges();
+ const SfxItemSet* GetOutputItemSet() const { return m_xOutSet.get(); }
+
+ void SetPrevHdl( const Link<SvxPostItDialog&,void>& rLink )
+ { m_aPrevHdlLink = rLink; }
+ void SetNextHdl( const Link<SvxPostItDialog&,void>& rLink )
+ { m_aNextHdlLink = rLink; }
+
+ void EnableTravel(bool bNext, bool bPrev);
+ OUString GetNote() const
+ {
+ return m_xEditED->get_text();
+ }
+ void SetNote(const OUString& rTxt)
+ {
+ m_xEditED->set_text(rTxt);
+ }
+ void ShowLastAuthor(std::u16string_view rAuthor, std::u16string_view rDate);
+ void DontChangeAuthor()
+ {
+ m_xAuthorBtn->set_sensitive(false);
+ }
+ void HideAuthor()
+ {
+ m_xInsertAuthor->hide();
+ }
+ void set_title(const OUString& rTitle)
+ {
+ m_xDialog->set_title(rTitle);
+ }
+ std::shared_ptr<weld::Dialog> const & GetDialog() const
+ {
+ return m_xDialog;
+ }
+
+private:
+ const SfxItemSet& m_rSet;
+ std::unique_ptr<SfxItemSet> m_xOutSet;
+
+ Link<SvxPostItDialog&,void> m_aPrevHdlLink;
+ Link<SvxPostItDialog&,void> m_aNextHdlLink;
+
+ std::unique_ptr<weld::Label> m_xLastEditFT;
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<weld::TextView> m_xEditED;
+ std::unique_ptr<weld::Widget> m_xInsertAuthor;
+ std::unique_ptr<weld::Button> m_xAuthorBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::Button> m_xPrevBtn;
+ std::unique_ptr<weld::Button> m_xNextBtn;
+
+ DECL_LINK(Stamp, weld::Button&, void);
+ DECL_LINK(OKHdl, weld::Button&, void);
+ DECL_LINK(PrevHdl, weld::Button&, void);
+ DECL_LINK(NextHdl, weld::Button&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/screenshotannotationdlg.hxx b/cui/source/inc/screenshotannotationdlg.hxx
new file mode 100644
index 000000000..1e41810a0
--- /dev/null
+++ b/cui/source/inc/screenshotannotationdlg.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <memory>
+
+class ScreenshotAnnotationDlg_Impl;
+
+class ScreenshotAnnotationDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<ScreenshotAnnotationDlg_Impl> m_pImpl;
+
+ ScreenshotAnnotationDlg(const ScreenshotAnnotationDlg&) = delete;
+ ScreenshotAnnotationDlg& operator=(const ScreenshotAnnotationDlg&) = delete;
+
+public:
+ ScreenshotAnnotationDlg(weld::Dialog& rParentDialog);
+ virtual ~ScreenshotAnnotationDlg() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/scriptdlg.hxx b/cui/source/inc/scriptdlg.hxx
new file mode 100644
index 000000000..0644ea442
--- /dev/null
+++ b/cui/source/inc/scriptdlg.hxx
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <memory>
+#include <sfx2/basedlgs.hxx>
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <unordered_map>
+
+#define OBJTYPE_METHOD 2L
+#define OBJTYPE_SCRIPTCONTAINER 3L
+#define OBJTYPE_SFROOT 4L
+
+typedef std::unordered_map < OUString, OUString > Selection_hash;
+
+class SFEntry;
+
+enum class InputDialogMode {
+ NEWLIB = 1,
+ NEWMACRO = 2,
+ RENAME = 3,
+};
+
+class CuiInputDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdit;
+public:
+ CuiInputDialog(weld::Window * pParent, InputDialogMode nMode);
+ OUString GetObjectName() const { return m_xEdit->get_text(); }
+ void SetObjectName(const OUString& rName)
+ {
+ m_xEdit->set_text(rName);
+ m_xEdit->select_region(0, -1);
+ }
+};
+
+class SFEntry final
+{
+private:
+ bool loaded;
+ css::uno::Reference< css::script::browse::XBrowseNode > nodes;
+ css::uno::Reference< css::frame::XModel > model;
+public:
+ SFEntry( const css::uno::Reference< css::script::browse::XBrowseNode >& entryNodes ,
+ const css::uno::Reference< css::frame::XModel >& entryModel) { nodes = entryNodes; loaded=false; model = entryModel; }
+ SFEntry( const SFEntry& r ) { nodes = r.nodes; loaded = r.loaded; }
+ const css::uno::Reference< css::script::browse::XBrowseNode >& GetNode() const { return nodes ;}
+ const css::uno::Reference< css::frame::XModel >& GetModel() const { return model ;};
+ bool isLoaded() const { return loaded; }
+ void setLoaded() { loaded=true; }
+};
+
+class SvxScriptOrgDialog : public SfxDialogController
+{
+protected:
+ weld::Window* m_pParent;
+ OUString m_sLanguage;
+ static Selection_hash m_lastSelection;
+ const OUString m_delErrStr;
+ const OUString m_delErrTitleStr;
+ const OUString m_delQueryStr;
+ const OUString m_delQueryTitleStr;
+ const OUString m_createErrStr;
+ const OUString m_createDupStr;
+ const OUString m_createErrTitleStr;
+ const OUString m_renameErrStr;
+ const OUString m_renameErrTitleStr;
+ const OUString m_sMyMacros;
+ const OUString m_sProdMacros;
+
+ std::unique_ptr<weld::TreeView> m_xScriptsBox;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+ std::unique_ptr<weld::Button> m_xRunButton;
+ std::unique_ptr<weld::Button> m_xCloseButton;
+ std::unique_ptr<weld::Button> m_xCreateButton;
+ std::unique_ptr<weld::Button> m_xEditButton;
+ std::unique_ptr<weld::Button> m_xRenameButton;
+ std::unique_ptr<weld::Button> m_xDelButton;
+
+ DECL_LINK( ScriptSelectHdl, weld::TreeView&, void );
+ DECL_LINK( ExpandingHdl, const weld::TreeIter&, bool );
+ DECL_LINK( ButtonHdl, weld::Button&, void );
+ static bool getBoolProperty( css::uno::Reference< css::beans::XPropertySet > const & xProps, OUString const & propName );
+ void CheckButtons( css::uno::Reference< css::script::browse::XBrowseNode > const & node );
+
+ void createEntry(const weld::TreeIter& rEntry);
+ void renameEntry(const weld::TreeIter& rEntry);
+ void deleteEntry(const weld::TreeIter& rEntry);
+ css::uno::Reference<css::script::browse::XBrowseNode> getBrowseNode(const weld::TreeIter& rEntry);
+ css::uno::Reference<css::frame::XModel> getModel(const weld::TreeIter& rEntry);
+ OUString getListOfChildren( const css::uno::Reference< css::script::browse::XBrowseNode >& node, int depth );
+ void StoreCurrentSelection();
+ void RestorePreviousSelection();
+
+ void Init(std::u16string_view language);
+ void delUserData(const weld::TreeIter& rIter);
+ void deleteTree(const weld::TreeIter& rIter);
+ void deleteAllTree();
+ void insertEntry(OUString const & rText, OUString const & rBitmap,
+ const weld::TreeIter* pParent,
+ bool bChildrenOnDemand,
+ std::unique_ptr< SFEntry > && aUserData,
+ std::u16string_view factoryURL, bool bSelect);
+ void insertEntry(OUString const & rText, OUString const & rBitmap,
+ const weld::TreeIter* pParent,
+ bool bChildrenOnDemand,
+ std::unique_ptr< SFEntry > && aUserData,
+ bool bSelect);
+
+ void RequestSubEntries(const weld::TreeIter& rRootEntry,
+ css::uno::Reference< css::script::browse::XBrowseNode > const & node,
+ css::uno::Reference< css::frame::XModel>& model);
+
+ static css::uno::Reference< css::script::browse::XBrowseNode >
+ getLangNodeFromRootNode( css::uno::Reference< css::script::browse::XBrowseNode > const & root, std::u16string_view language );
+
+ static css::uno::Reference< css::uno::XInterface > getDocumentModel( css::uno::Reference< css::uno::XComponentContext > const & xCtx, std::u16string_view docName );
+
+public:
+ // prob need another arg in the ctor
+ // to specify the language or provider
+ SvxScriptOrgDialog(weld::Window* pParent, OUString language);
+ virtual ~SvxScriptOrgDialog() override;
+
+ virtual short run() override;
+};
+
+class SvxScriptErrorDialog
+{
+private:
+ struct DialogData {
+ weld::Window* pParent;
+ OUString sMessage;
+ };
+
+ DECL_STATIC_LINK( SvxScriptErrorDialog, ShowDialog, void*, void );
+
+public:
+
+ static void ShowAsyncErrorDialog( weld::Window* pParent, css::uno::Any const & aException );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/sdrcelldlg.hxx b/cui/source/inc/sdrcelldlg.hxx
new file mode 100644
index 000000000..5b7e9ca71
--- /dev/null
+++ b/cui/source/inc/sdrcelldlg.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/xtable.hxx>
+#include <svx/tabarea.hxx>
+
+class SdrModel;
+class SvxFormatCellsDialog : public SfxTabDialogController
+{
+private:
+ const SfxItemSet& mrOutAttrs;
+
+ XColorListRef mpColorTab;
+ ChangeType mnColorTabState;
+ XGradientListRef mpGradientList;
+ XHatchListRef mpHatchingList;
+ XBitmapListRef mpBitmapList;
+ XPatternListRef mpPatternList;
+
+public:
+ SvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel);
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/showcols.hxx b/cui/source/inc/showcols.hxx
new file mode 100644
index 000000000..e378c5e19
--- /dev/null
+++ b/cui/source/inc/showcols.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <vcl/weld.hxx>
+
+// FmShowColsDialog
+
+class FmShowColsDialog final : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::TreeView> m_xList;
+ std::unique_ptr<weld::Button> m_xOK;
+
+ css::uno::Reference<css::container::XIndexAccess> m_xColumns;
+
+public:
+ FmShowColsDialog(weld::Window* pParent);
+ virtual ~FmShowColsDialog() override;
+
+ void SetColumns(const css::uno::Reference<css::container::XIndexContainer>& xCols);
+
+private:
+ DECL_LINK(OnClickedOk, weld::Button&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/splitcelldlg.hxx b/cui/source/inc/splitcelldlg.hxx
new file mode 100644
index 000000000..ce14e0714
--- /dev/null
+++ b/cui/source/inc/splitcelldlg.hxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svx/svxdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxSplitTableDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> m_xCountEdit;
+ std::unique_ptr<weld::RadioButton> m_xHorzBox;
+ std::unique_ptr<weld::RadioButton> m_xVertBox;
+ std::unique_ptr<weld::CheckButton> m_xPropCB;
+
+ tools::Long mnMaxVertical;
+ tools::Long mnMaxHorizontal;
+
+public:
+ SvxSplitTableDlg(weld::Window *pParent, bool bIsTableVertical, tools::Long nMaxVertical, tools::Long nMaxHorizontal);
+
+ DECL_LINK(ToggleHdl, weld::Toggleable&, void);
+
+ bool IsHorizontal() const;
+ bool IsProportional() const;
+ tools::Long GetCount() const;
+
+ void SetSplitVerticalByDefault();
+};
+
+class SvxAbstractSplitTableDialog_Impl : public SvxAbstractSplitTableDialog
+{
+ std::shared_ptr<SvxSplitTableDlg> m_xDlg;
+
+public:
+ SvxAbstractSplitTableDialog_Impl(std::shared_ptr<SvxSplitTableDlg> pDlg) : m_xDlg(std::move(pDlg)) {}
+
+ virtual bool IsHorizontal() const override;
+ virtual bool IsProportional() const override;
+ virtual tools::Long GetCount() const override;
+
+ virtual void SetSplitVerticalByDefault() override;
+
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext& rContext) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/srchxtra.hxx b/cui/source/inc/srchxtra.hxx
new file mode 100644
index 000000000..e95fccd41
--- /dev/null
+++ b/cui/source/inc/srchxtra.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svx/srchdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxSearchFormatDialog : public SfxTabDialogController
+{
+public:
+ SvxSearchFormatDialog(weld::Window* pParent, const SfxItemSet& rSet);
+ virtual ~SvxSearchFormatDialog() override;
+
+protected:
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+private:
+ std::unique_ptr<FontList> m_pFontList;
+};
+
+// class SvxSearchFormatDialog -------------------------------------------
+
+class SvxSearchAttributeDialog : public weld::GenericDialogController
+{
+public:
+ SvxSearchAttributeDialog(weld::Window* pParent, SearchAttrItemList& rLst,
+ const WhichRangesContainer& pWhRanges);
+ virtual ~SvxSearchAttributeDialog() override;
+
+private:
+ SearchAttrItemList& rList;
+
+ std::unique_ptr<weld::TreeView> m_xAttrLB;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+
+ DECL_LINK(OKHdl, weld::Button&, void);
+};
+
+// class SvxSearchSimilarityDialog ---------------------------------------
+
+class SvxSearchSimilarityDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> m_xOtherFld;
+ std::unique_ptr<weld::SpinButton> m_xLongerFld;
+ std::unique_ptr<weld::SpinButton> m_xShorterFld;
+ std::unique_ptr<weld::CheckButton> m_xRelaxBox;
+
+public:
+ SvxSearchSimilarityDialog(weld::Window* pParent,
+ bool bRelax,
+ sal_uInt16 nOther,
+ sal_uInt16 nShorter,
+ sal_uInt16 nLonger);
+ virtual ~SvxSearchSimilarityDialog() override;
+
+ sal_uInt16 GetOther() const { return static_cast<sal_uInt16>(m_xOtherFld->get_value()); }
+ sal_uInt16 GetShorter() const { return static_cast<sal_uInt16>(m_xShorterFld->get_value()); }
+ sal_uInt16 GetLonger() const { return static_cast<sal_uInt16>(m_xLongerFld->get_value()); }
+ bool IsRelaxed() const { return m_xRelaxBox->get_active(); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/swpossizetabpage.hxx b/cui/source/inc/swpossizetabpage.hxx
new file mode 100644
index 000000000..eb7319698
--- /dev/null
+++ b/cui/source/inc/swpossizetabpage.hxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/swframeexample.hxx>
+#include <vcl/weld.hxx>
+
+// SvxSwPosSizeTabPage - position and size page for Writer drawing objects
+struct FrmMap;
+class SdrView;
+struct SvxSwFrameValidation;
+enum class SvxAnchorIds;
+
+class SvxSwPosSizeTabPage : public SfxTabPage
+{
+ Link<SvxSwFrameValidation&,void> m_aValidateLink;
+
+ ::tools::Rectangle m_aRect; //size of all selected objects
+ ::tools::Rectangle m_aWorkArea;
+ Point m_aAnchorPos;
+
+ FrmMap const * m_pVMap;
+ FrmMap const * m_pHMap;
+ const SdrView* m_pSdrView;
+
+ // initial values
+ short m_nOldH;
+ short m_nOldHRel;
+ short m_nOldV;
+ short m_nOldVRel;
+
+ double m_fWidthHeightRatio; //width-to-height ratio to support the KeepRatio button
+ bool m_bHtmlMode;
+ bool m_bIsVerticalFrame;
+ bool m_bPositioningDisabled;
+ bool m_bIsMultiSelection;
+ bool m_bIsInRightToLeft;
+ TriState m_nProtectSizeState;
+
+ SwFrameExample m_aExampleWN;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightMF;
+ std::unique_ptr<weld::CheckButton> m_xKeepRatioCB;
+ std::unique_ptr<weld::RadioButton> m_xToPageRB;
+ std::unique_ptr<weld::RadioButton> m_xToParaRB;
+ std::unique_ptr<weld::RadioButton> m_xToCharRB;
+ std::unique_ptr<weld::RadioButton> m_xAsCharRB;
+ std::unique_ptr<weld::RadioButton> m_xToFrameRB;
+ std::unique_ptr<weld::CheckButton> m_xPositionCB;
+ std::unique_ptr<weld::CheckButton> m_xSizeCB;
+ std::unique_ptr<weld::Widget> m_xPosFrame;
+ std::unique_ptr<weld::Label> m_xHoriFT;
+ std::unique_ptr<weld::ComboBox> m_xHoriLB;
+ std::unique_ptr<weld::Label> m_xHoriByFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xHoriByMF;
+ std::unique_ptr<weld::Label> m_xHoriToFT;
+ std::unique_ptr<weld::ComboBox> m_xHoriToLB;
+ std::unique_ptr<weld::CheckButton> m_xHoriMirrorCB;
+ std::unique_ptr<weld::Label> m_xVertFT;
+ std::unique_ptr<weld::ComboBox> m_xVertLB;
+ std::unique_ptr<weld::Label> m_xVertByFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xVertByMF;
+ std::unique_ptr<weld::Label> m_xVertToFT;
+ std::unique_ptr<weld::ComboBox> m_xVertToLB;
+ std::unique_ptr<weld::CheckButton> m_xFollowCB;
+ std::unique_ptr<weld::CustomWeld> m_xExampleWN;
+
+ DECL_LINK(RangeModifyHdl, weld::Widget&, void);
+ DECL_LINK(RangeModifyClickHdl, weld::Toggleable&, void);
+ DECL_LINK(AnchorTypeHdl, weld::Toggleable&, void);
+ DECL_LINK(PosHdl, weld::ComboBox&, void);
+ DECL_LINK(RelHdl, weld::ComboBox&, void);
+ DECL_LINK(MirrorHdl, weld::Toggleable&, void);
+ DECL_LINK(ModifyHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(ProtectHdl, weld::Toggleable&, void);
+
+ void InitPos(RndStdIds nAnchorType, sal_uInt16 nH, sal_uInt16 nHRel,
+ sal_uInt16 nV, sal_uInt16 nVRel,
+ tools::Long nX, tools::Long nY);
+ static sal_uInt16 GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB);
+ static short GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB);
+ static short GetRelation(const weld::ComboBox& rRelationLB);
+ RndStdIds GetAnchorType(bool* pbHasChanged = nullptr);
+ void FillRelLB(FrmMap const *pMap, sal_uInt16 nLBSelPos, sal_uInt16 nAlign, sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT);
+ sal_uInt16 FillPosLB(FrmMap const *pMap, sal_uInt16 nAlign, const sal_uInt16 _nRel, weld::ComboBox& rLB);
+
+ void UpdateExample();
+
+ void setOptimalFrmWidth();
+ void setOptimalRelWidth();
+
+public:
+ SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual ~SvxSwPosSizeTabPage() override;
+
+ static WhichRangesContainer GetRanges();
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void EnableAnchorTypes(SvxAnchorIds nAnchorEnable);
+
+ void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+ {m_aValidateLink = rLink;}
+
+ void SetView( const SdrView* pSdrView );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/tabstpge.hxx b/cui/source/inc/tabstpge.hxx
new file mode 100644
index 000000000..207b8b705
--- /dev/null
+++ b/cui/source/inc/tabstpge.hxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/tabdlg.hxx>
+
+#include <editeng/tstpitem.hxx>
+#include <svx/flagsdef.hxx>
+
+class SvxTabulatorTabPage;
+
+// class TabWin_Impl -----------------------------------------------------
+
+class TabWin_Impl : public weld::CustomWidgetController
+{
+private:
+ sal_uInt16 nTabStyle;
+
+public:
+
+ TabWin_Impl() : nTabStyle(0)
+ {
+ }
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+
+ void SetTabStyle(sal_uInt16 nStyle) {nTabStyle = nStyle; }
+};
+
+// class SvxTabulatorTabPage ---------------------------------------------
+/*
+ [Description]
+ In this TabPage tabulators are managed.
+
+ [Items]
+ <SvxTabStopItem><SID_ATTR_TABSTOP>
+ <SfxUInt16Item><SID_ATTR_TABSTOP_DEFAULTS>
+ <SfxUInt16Item><SID_ATTR_TABSTOP_POS>
+ <SfxInt32Item><SID_ATTR_TABSTOP_OFFSET>
+*/
+
+class SvxTabulatorTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pRanges;
+
+public:
+ SvxTabulatorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxTabulatorTabPage() override;
+
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void DisableControls( const TabulatorDisableFlags nFlag );
+
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ // local variables, internal functions
+ SvxTabStop aCurrentTab;
+ std::unique_ptr<SvxTabStopItem> aNewTabs;
+ tools::Long nDefDist;
+
+ TabWin_Impl m_aLeftWin;
+ TabWin_Impl m_aRightWin;
+ TabWin_Impl m_aCenterWin;
+ TabWin_Impl m_aDezWin;
+
+ // just to format the numbers, not shown
+ std::unique_ptr<weld::MetricSpinButton> m_xTabSpin;
+ // tabulators and positions
+ std::unique_ptr<weld::EntryTreeView> m_xTabBox;
+ // TabType
+ std::unique_ptr<weld::RadioButton> m_xLeftTab;
+ std::unique_ptr<weld::RadioButton> m_xRightTab;
+ std::unique_ptr<weld::RadioButton> m_xCenterTab;
+ std::unique_ptr<weld::RadioButton> m_xDezTab;
+
+ std::unique_ptr<weld::Entry> m_xDezChar;
+ std::unique_ptr<weld::Label> m_xDezCharLabel;
+
+ std::unique_ptr<weld::RadioButton> m_xNoFillChar;
+ std::unique_ptr<weld::RadioButton> m_xFillPoints;
+ std::unique_ptr<weld::RadioButton> m_xFillDashLine ;
+ std::unique_ptr<weld::RadioButton> m_xFillSolidLine;
+ std::unique_ptr<weld::RadioButton> m_xFillSpecial;
+ std::unique_ptr<weld::Entry> m_xFillChar;
+
+ std::unique_ptr<weld::Button> m_xNewBtn;
+ std::unique_ptr<weld::Button> m_xDelAllBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+
+ std::unique_ptr<weld::Container> m_xTypeFrame;
+ std::unique_ptr<weld::Container> m_xFillFrame;
+
+ std::unique_ptr<weld::CustomWeld> m_xLeftWin;
+ std::unique_ptr<weld::CustomWeld> m_xRightWin;
+ std::unique_ptr<weld::CustomWeld> m_xCenterWin;
+ std::unique_ptr<weld::CustomWeld> m_xDezWin;
+
+ void InitTabPos_Impl( sal_uInt16 nPos = 0 );
+ void SetFillAndTabType_Impl();
+ void NewHdl_Impl(const weld::Button*);
+
+ OUString FormatTab();
+
+ // Handler
+ DECL_LINK(NewHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelAllHdl_Impl, weld::Button&, void);
+
+ DECL_LINK(FillTypeCheckHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(TabTypeCheckHdl_Impl, weld::Toggleable&, void);
+
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(ModifyHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ReformatHdl_Impl, weld::Widget&, void);
+ DECL_LINK(GetFillCharHdl_Impl, weld::Widget&, void);
+ DECL_LINK(GetDezCharHdl_Impl, weld::Widget&, void);
+
+ int FindCurrentTab();
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/textanim.hxx b/cui/source/inc/textanim.hxx
new file mode 100644
index 000000000..8f4767e22
--- /dev/null
+++ b/cui/source/inc/textanim.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/sdtakitm.hxx>
+#include <svx/sdtaditm.hxx>
+#include <vcl/weld.hxx>
+
+class SdrView;
+
+/*************************************************************************
+|*
+|* Page for changing TextAnimations (running text etc.)
+|*
+\************************************************************************/
+
+class SvxTextAnimationPage : public SfxTabPage
+{
+private:
+ static const WhichRangesContainer pRanges;
+
+ SdrTextAniKind eAniKind;
+ FieldUnit eFUnit;
+ MapUnit eUnit;
+
+ TriState m_aUpState;
+ TriState m_aLeftState;
+ TriState m_aRightState;
+ TriState m_aDownState;
+
+ std::unique_ptr<weld::ComboBox> m_xLbEffect;
+ std::unique_ptr<weld::Widget> m_xBoxDirection;
+ std::unique_ptr<weld::ToggleButton> m_xBtnUp;
+ std::unique_ptr<weld::ToggleButton> m_xBtnLeft;
+ std::unique_ptr<weld::ToggleButton> m_xBtnRight;
+ std::unique_ptr<weld::ToggleButton> m_xBtnDown;
+
+ std::unique_ptr<weld::Frame> m_xFlProperties;
+ std::unique_ptr<weld::CheckButton> m_xTsbStartInside;
+ std::unique_ptr<weld::CheckButton> m_xTsbStopInside;
+
+ std::unique_ptr<weld::Widget> m_xBoxCount;
+ std::unique_ptr<weld::CheckButton> m_xTsbEndless;
+ std::unique_ptr<weld::SpinButton> m_xNumFldCount;
+
+ std::unique_ptr<weld::CheckButton> m_xTsbPixel;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldAmount;
+
+ std::unique_ptr<weld::CheckButton> m_xTsbAuto;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldDelay;
+
+ DECL_LINK( SelectEffectHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( ClickEndlessHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK( ClickAutoHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK( ClickPixelHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK( ClickDirectionHdl_Impl, weld::Button&, void );
+
+ void SelectDirection( SdrTextAniDirection nValue );
+ sal_uInt16 GetSelectedDirection() const;
+
+public:
+ SvxTextAnimationPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxTextAnimationPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+};
+
+/*************************************************************************
+|*
+|* Text-Tab-Dialog
+|*
+\************************************************************************/
+class SvxTextTabDialog : public SfxTabDialogController
+{
+private:
+ const SdrView* pView;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrView* pView);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/textattr.hxx b/cui/source/inc/textattr.hxx
new file mode 100644
index 000000000..a6a7f2bd6
--- /dev/null
+++ b/cui/source/inc/textattr.hxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svx/dlgctrl.hxx>
+#include <svx/svdobjkind.hxx>
+
+class SdrView;
+
+/*************************************************************************
+|*
+|* Dialog for changing TextAttributes
+|*
+\************************************************************************/
+
+class SvxTextAttrPage : public SvxTabPage
+{
+private:
+ static const WhichRangesContainer pRanges;
+
+ const SfxItemSet& rOutAttrs;
+ SdrObjKind m_eObjKind;
+
+ bool bAutoGrowSizeEnabled;
+ bool bContourEnabled;
+ bool bAutoGrowWidthEnabled;
+ bool bAutoGrowHeightEnabled;
+ bool bWordWrapTextEnabled;
+ bool bFitToSizeEnabled;
+
+ SvxRectCtl m_aCtlPosition;
+
+ std::unique_ptr<weld::Widget> m_xDrawingText;
+ std::unique_ptr<weld::Widget> m_xCustomShapeText;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowHeight;
+ std::unique_ptr<weld::CheckButton> m_xTsbFitToSize;
+ std::unique_ptr<weld::CheckButton> m_xTsbContour;
+ std::unique_ptr<weld::CheckButton> m_xTsbWordWrapText;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowSize;
+ std::unique_ptr<weld::Frame> m_xFlDistance;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLeft;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldRight;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldTop;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldBottom;
+ std::unique_ptr<weld::Frame> m_xFlPosition;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPosition;
+ std::unique_ptr<weld::CheckButton> m_xTsbFullWidth;
+
+ DECL_LINK(ClickFullWidthHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ClickHdl_Impl, weld::Toggleable&, void);
+
+ /** Return whether the text direction is from left to right (</sal_True>) or
+ top to bottom (</sal_False>).
+ */
+ bool IsTextDirectionLeftToRight() const;
+
+public:
+
+ SvxTextAttrPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxTextAttrPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override;
+
+ void Construct();
+ void SetObjKind(SdrObjKind eObjKind) { m_eObjKind = eObjKind; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/themepage.hxx b/cui/source/inc/themepage.hxx
new file mode 100644
index 000000000..894a09c93
--- /dev/null
+++ b/cui/source/inc/themepage.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <sfx2/tabdlg.hxx>
+
+#include <memory>
+
+class ColorListBox;
+
+/// Tab page for themes
+class SvxThemePage : public SfxTabPage
+{
+ static const WhichRangesContainer m_pRanges;
+
+ std::unique_ptr<weld::Entry> m_xThemeName;
+ std::unique_ptr<weld::Entry> m_xColorSetName;
+ std::unique_ptr<ColorListBox> m_xDk1;
+ std::unique_ptr<ColorListBox> m_xLt1;
+ std::unique_ptr<ColorListBox> m_xDk2;
+ std::unique_ptr<ColorListBox> m_xLt2;
+ std::unique_ptr<ColorListBox> m_xAccent1;
+ std::unique_ptr<ColorListBox> m_xAccent2;
+ std::unique_ptr<ColorListBox> m_xAccent3;
+ std::unique_ptr<ColorListBox> m_xAccent4;
+ std::unique_ptr<ColorListBox> m_xAccent5;
+ std::unique_ptr<ColorListBox> m_xAccent6;
+ std::unique_ptr<ColorListBox> m_xHlink;
+ std::unique_ptr<ColorListBox> m_xFolHlink;
+
+public:
+ SvxThemePage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+ virtual ~SvxThemePage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet*);
+ static WhichRangesContainer GetRanges() { return m_pRanges; }
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/thesdlg.hxx b/cui/source/inc/thesdlg.hxx
new file mode 100644
index 000000000..05865d68d
--- /dev/null
+++ b/cui/source/inc/thesdlg.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include <vcl/idle.hxx>
+#include <sfx2/basedlgs.hxx>
+
+#include <memory>
+#include <stack>
+
+struct ImplSVEvent;
+
+class SvxThesaurusDialog : public SfxDialogController
+{
+ Idle m_aModifyIdle;
+
+ css::uno::Reference< css::linguistic2::XThesaurus > xThesaurus;
+ OUString aLookUpText;
+ LanguageType nLookUpLanguage;
+ std::stack< OUString > aLookUpHistory;
+ bool m_bWordFound;
+
+ std::unique_ptr<weld::Button> m_xLeftBtn;
+ std::unique_ptr<weld::ComboBox> m_xWordCB;
+ std::unique_ptr<weld::TreeView> m_xAlternativesCT;
+ std::unique_ptr<weld::Label> m_xNotFound;
+ std::unique_ptr<weld::Entry> m_xReplaceEdit;
+ std::unique_ptr<weld::ComboBox> m_xLangLB;
+ std::unique_ptr<weld::Button> m_xReplaceBtn;
+ ImplSVEvent* m_nSelectFirstEvent;
+
+public:
+ virtual ~SvxThesaurusDialog() override;
+
+ // Handler
+ DECL_LINK( ReplaceBtnHdl_Impl, weld::Button&, void );
+ DECL_LINK( LeftBtnHdl_Impl, weld::Button&, void );
+ DECL_LINK( LanguageHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( WordSelectHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( AlternativesSelectHdl_Impl, weld::TreeView&, void );
+ DECL_LINK( AlternativesDoubleClickHdl_Impl, weld::TreeView&, bool );
+ DECL_LINK( SelectFirstHdl_Impl, void*, void );
+ DECL_LINK( ReplaceEditHdl_Impl, weld::Entry&, void );
+ DECL_LINK( ModifyTimer_Hdl, Timer *, void );
+ DECL_LINK( KeyInputHdl, const KeyEvent&, bool );
+
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ css::uno::Sequence< css::uno::Reference< css::linguistic2::XMeaning > >
+ queryMeanings_Impl( OUString& rTerm, const css::lang::Locale& rLocale, const css::beans::PropertyValues& rProperties );
+
+ bool UpdateAlternativesBox_Impl();
+ void LookUp( const OUString &rText );
+ void LookUp_Impl();
+
+public:
+ SvxThesaurusDialog(weld::Widget* pParent,
+ css::uno::Reference< css::linguistic2::XThesaurus > const & xThesaurus,
+ const OUString &rWord, LanguageType nLanguage);
+ void SetWindowTitle( LanguageType nLanguage );
+ OUString GetWord() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/tipofthedaydlg.hxx b/cui/source/inc/tipofthedaydlg.hxx
new file mode 100644
index 000000000..69af1996e
--- /dev/null
+++ b/cui/source/inc/tipofthedaydlg.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+#include "cuigrfflt.hxx"
+
+class VclWindowEvent;
+
+class TipOfTheDayDialog : public weld::GenericDialogController
+{
+private:
+ CuiGraphicPreviewWindow m_aPreview;
+ weld::Window* m_pParent;
+
+ std::unique_ptr<weld::Label> m_pText;
+ std::unique_ptr<weld::CheckButton> m_pShowTip;
+ std::unique_ptr<weld::Button> m_pNext;
+ std::unique_ptr<weld::LinkButton> m_pLink;
+ std::unique_ptr<weld::CustomWeld> m_pPreview;
+
+ sal_Int32 m_nCurrentTip;
+ void UpdateTip();
+ DECL_LINK(OnNextClick, weld::Button&, void);
+ DECL_LINK(OnLinkClick, weld::LinkButton&, bool);
+
+public:
+ TipOfTheDayDialog(weld::Window* pWindow);
+ virtual ~TipOfTheDayDialog() override;
+
+ DECL_LINK(Terminated, VclWindowEvent&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/toolbarmodedlg.hxx b/cui/source/inc/toolbarmodedlg.hxx
new file mode 100644
index 000000000..5965aa759
--- /dev/null
+++ b/cui/source/inc/toolbarmodedlg.hxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <vcl/weld.hxx>
+
+class ToolbarmodeDialog : public weld::GenericDialogController
+{
+public:
+ ToolbarmodeDialog(weld::Window* pWindow);
+ virtual ~ToolbarmodeDialog() override;
+
+private:
+ std::unique_ptr<weld::Image> m_pImage;
+ std::unique_ptr<weld::Button> m_pApply;
+ std::unique_ptr<weld::Button> m_pApplyAll;
+ std::unique_ptr<weld::RadioButton> m_pRadioButtons[9];
+ std::unique_ptr<weld::Label> m_pInfoLabel;
+
+ void UpdateImage(std::u16string_view sFileName);
+ int GetActiveRadioButton();
+ DECL_LINK(SelectToolbarmode, weld::Toggleable&, void);
+ DECL_LINK(OnApplyClick, weld::Button&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/transfrm.hxx b/cui/source/inc/transfrm.hxx
new file mode 100644
index 000000000..30b789dc7
--- /dev/null
+++ b/cui/source/inc/transfrm.hxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <svx/dlgctrl.hxx>
+#include <svx/dialcontrol.hxx>
+#include <svx/anchorid.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+// predefines
+class SdrView;
+
+/*************************************************************************
+|*
+|* Transform-Tab-Dialog
+|*
+\************************************************************************/
+
+struct SvxSwFrameValidation;
+class SvxTransformTabDialog : public SfxTabDialogController
+{
+private:
+ const SdrView* pView;
+
+ SvxAnchorIds nAnchorCtrls;
+ Link<SvxSwFrameValidation&,void> aValidateLink;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ SvxTransformTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes);
+
+ //link for the Writer to validate positions
+ void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink );
+};
+
+/*************************************************************************
+|*
+|* position and size tab page
+|*
+\************************************************************************/
+
+class SvxPositionSizeTabPage : public SvxTabPage
+{
+ static const WhichRangesContainer pPosSizeRanges;
+
+private:
+ const SfxItemSet& mrOutAttrs;
+
+ const SdrView* mpView;
+
+ // #i75273#
+ basegfx::B2DRange maRange;
+ basegfx::B2DRange maWorkRange;
+ basegfx::B2DPoint maAnchor;
+
+ MapUnit mePoolUnit;
+ FieldUnit meDlgUnit;
+ TriState mnProtectSizeState;
+ bool mbPageDisabled;
+ bool mbProtectDisabled;
+ bool mbSizeDisabled;
+ bool mbAdjustDisabled;
+ bool mbIgnoreAutoGrowWidth;
+ bool mbIgnoreAutoGrowHeight;
+
+ // from size
+ // #i75273#
+ double mfOldWidth;
+ double mfOldHeight;
+ RectPoint meRP;
+
+ SvxRectCtl m_aCtlPos;
+ SvxRectCtl m_aCtlSize;
+
+ // position
+ std::unique_ptr<weld::Widget> m_xFlPosition;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosY;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPos;
+
+ // size
+ std::unique_ptr<weld::Widget> m_xFlSize;
+ std::unique_ptr<weld::Label> m_xFtWidth;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrWidth;
+ std::unique_ptr<weld::Label> m_xFtHeight;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrHeight;
+ std::unique_ptr<weld::CheckButton> m_xCbxScale;
+ std::unique_ptr<weld::CustomWeld> m_xCtlSize;
+
+ // protect
+ std::unique_ptr<weld::Widget> m_xFlProtect;
+ std::unique_ptr<weld::CheckButton> m_xTsbPosProtect;
+ std::unique_ptr<weld::CheckButton> m_xTsbSizeProtect;
+
+ // adjust
+ std::unique_ptr<weld::Widget> m_xFlAdjust;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowHeight;
+
+ DECL_LINK(ChangePosProtectHdl, weld::Toggleable&, void);
+ DECL_LINK(ChangeSizeProtectHdl, weld::Toggleable&, void);
+
+ void SetMinMaxPosition();
+ void GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange);
+
+ DECL_LINK( ChangeWidthHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ChangeHeightHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ClickSizeProtectHdl, weld::Toggleable&, void );
+ DECL_LINK( ClickAutoHdl, weld::Toggleable&, void );
+
+public:
+ SvxPositionSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxPositionSizeTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pPosSizeRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void PointChanged(weld::DrawingArea* pWindow, RectPoint eRP) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { mpView = pSdrView; }
+
+ virtual void FillUserData() override;
+
+ void DisableResize();
+ void DisableProtect();
+
+ void UpdateControlStates();
+};
+
+/*************************************************************************
+|*
+|* rotation angle tab page
+|*
+\************************************************************************/
+class SvxAngleTabPage : public SvxTabPage
+{
+ static const WhichRangesContainer pAngleRanges;
+
+private:
+ const SdrView* pView;
+
+ // #i75273#
+ basegfx::B2DRange maRange;
+ basegfx::B2DPoint maAnchor;
+
+ MapUnit ePoolUnit;
+ FieldUnit eDlgUnit;
+
+ SvxRectCtl m_aCtlRect;
+
+ std::unique_ptr<weld::Widget> m_xFlPosition;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosY;
+ std::unique_ptr<weld::CustomWeld> m_xCtlRect;
+ std::unique_ptr<weld::Widget> m_xFlAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xNfAngle;
+ std::unique_ptr<svx::DialControl> m_xCtlAngle;
+ std::unique_ptr<weld::CustomWeld> m_xCtlAngleWin;
+
+public:
+ SvxAngleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxAngleTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pAngleRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void PointChanged(weld::DrawingArea* pWindow, RectPoint eRP) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+};
+
+/*************************************************************************
+|*
+|* slant/corner radius tab page
+|*
+\************************************************************************/
+class SvxSlantTabPage : public SfxTabPage
+{
+ static const WhichRangesContainer pSlantRanges;
+
+private:
+ const SdrView* pView;
+
+ MapUnit ePoolUnit;
+ FieldUnit eDlgUnit;
+
+ std::unique_ptr<weld::Widget> m_xFlRadius;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrRadius;
+ std::unique_ptr<weld::Widget> m_xFlAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrAngle;
+ std::unique_ptr<weld::Widget> m_aControlGroups[2];
+ std::unique_ptr<weld::Widget> m_aControlGroupX[2];
+ std::unique_ptr<weld::MetricSpinButton> m_aControlX[2];
+ std::unique_ptr<weld::Widget> m_aControlGroupY[2];
+ std::unique_ptr<weld::MetricSpinButton> m_aControlY[2];
+
+public:
+ SvxSlantTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxSlantTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static WhichRangesContainer GetRanges() { return pSlantRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/treeopt.hxx b/cui/source/inc/treeopt.hxx
new file mode 100644
index 000000000..a4d90e6e9
--- /dev/null
+++ b/cui/source/inc/treeopt.hxx
@@ -0,0 +1,239 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <sfx2/basedlgs.hxx>
+#include <svtools/restartdialog.hxx>
+#include <utility>
+
+class SfxModule;
+class SfxShell;
+
+// struct OrderedEntry ---------------------------------------------------
+
+struct OrderedEntry
+{
+ sal_Int32 m_nIndex;
+ OUString m_sId;
+
+ OrderedEntry( sal_Int32 nIndex, OUString aId ) :
+ m_nIndex( nIndex ), m_sId(std::move( aId )) {}
+};
+
+
+// struct Module ---------------------------------------------------------
+
+struct Module
+{
+ bool m_bActive;
+ std::vector< std::unique_ptr<OrderedEntry> > m_aNodeList;
+
+ Module() : m_bActive( false ) {}
+};
+
+// struct OptionsLeaf ----------------------------------------------------
+
+struct OptionsLeaf
+{
+ OUString m_sLabel;
+ OUString m_sPageURL;
+ OUString m_sEventHdl;
+ OUString m_sGroupId;
+ sal_Int32 m_nGroupIndex;
+
+ OptionsLeaf( OUString aLabel,
+ OUString aPageURL,
+ OUString aEventHdl,
+ OUString aGroupId,
+ sal_Int32 nGroupIndex ) :
+ m_sLabel(std::move( aLabel )),
+ m_sPageURL(std::move( aPageURL )),
+ m_sEventHdl(std::move( aEventHdl )),
+ m_sGroupId(std::move( aGroupId )),
+ m_nGroupIndex( nGroupIndex ) {}
+};
+
+// struct OptionsNode ----------------------------------------------------
+
+struct OptionsNode
+{
+ OUString m_sId;
+ OUString m_sLabel;
+ bool m_bAllModules;
+ std::vector< std::unique_ptr<OptionsLeaf> > m_aLeaves;
+ std::vector< std::vector< std::unique_ptr<OptionsLeaf> > >
+ m_aGroupedLeaves;
+
+ OptionsNode( OUString aId,
+ OUString aLabel,
+ bool bAllModules ) :
+ m_sId(std::move( aId )),
+ m_sLabel(std::move( aLabel )),
+ m_bAllModules( bAllModules ) {}
+};
+
+typedef std::vector< std::unique_ptr<OptionsNode> > VectorOfNodes;
+
+struct LastPageSaver
+{
+ sal_uInt16 m_nLastPageId;
+ OUString m_sLastPageURL_Tools;
+ OUString m_sLastPageURL_ExtMgr;
+
+ LastPageSaver() : m_nLastPageId( USHRT_MAX ) {}
+};
+
+// class OfaTreeOptionsDialog --------------------------------------------
+
+namespace com::sun::star::frame { class XFrame; }
+namespace com::sun::star::awt { class XContainerWindowProvider; }
+
+struct OptionsPageInfo;
+struct Module;
+class ExtensionsTabPage;
+class SvxColorTabPage;
+struct OptionsGroupInfo;
+
+class OfaTreeOptionsDialog final: public SfxOkDialogController
+{
+private:
+ std::unique_ptr<weld::Button> xOkPB;
+ std::unique_ptr<weld::Button> xApplyPB;
+ std::unique_ptr<weld::Button> xBackPB;
+
+ std::unique_ptr<weld::TreeView> xTreeLB;
+ std::unique_ptr<weld::Container> xTabBox;
+
+ weld::Window* m_pParent;
+
+ std::unique_ptr<weld::TreeIter> xCurrentPageEntry;
+
+ OUString sTitle;
+
+ bool bForgetSelection;
+ bool bIsFromExtensionManager;
+
+ // check "for the current document only" and set focus to "Western" languages box
+ bool bIsForSetDocumentLanguage;
+
+ bool bNeedsRestart;
+ svtools::RestartReason eRestartReason;
+
+ css::uno::Reference < css::awt::XContainerWindowProvider >
+ m_xContainerWinProvider;
+
+ static LastPageSaver* pLastPageSaver;
+
+ std::optional<SfxItemSet> CreateItemSet( sal_uInt16 nId );
+ static void ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet );
+ void InitTreeAndHandler();
+ void Initialize( const css::uno::Reference< css::frame::XFrame >& _xFrame );
+ void InitWidgets();
+
+ void LoadExtensionOptions( std::u16string_view rExtensionId );
+ static OUString GetModuleIdentifier( const css::uno::Reference<
+ css::frame::XFrame >& xFrame );
+ static std::unique_ptr<Module> LoadModule( std::u16string_view rModuleIdentifier );
+ static VectorOfNodes LoadNodes( Module* pModule, std::u16string_view rExtensionId );
+ void InsertNodes( const VectorOfNodes& rNodeList );
+
+ void ApplyOptions();
+
+ DECL_LINK(ShowPageHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(BackHdl_Impl, weld::Button&, void);
+ DECL_LINK(ApplyHdl_Impl, weld::Button&, void);
+ DECL_LINK(HelpHdl_Impl, weld::Widget&, bool);
+ void ResetCurrentPageFromConfig();
+ void SelectHdl_Impl();
+
+ void InitItemSets(OptionsGroupInfo& rGroupInfo);
+
+ virtual short run() override;
+
+ virtual weld::Button& GetOKButton() const override { return *xOkPB; }
+ virtual const SfxItemSet* GetExampleSet() const override { return nullptr; }
+
+public:
+ OfaTreeOptionsDialog(weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& _xFrame,
+ bool bActivateLastSelection);
+ OfaTreeOptionsDialog(weld::Window* pParent, std::u16string_view rExtensionId);
+ virtual ~OfaTreeOptionsDialog() override;
+
+ OptionsPageInfo* AddTabPage( sal_uInt16 nId, const OUString& rPageName, sal_uInt16 nGroup );
+ sal_uInt16 AddGroup( const OUString& rGroupName, SfxShell* pCreateShell,
+ SfxModule* pCreateModule, sal_uInt16 nDialogId );
+
+ void ActivateLastSelection();
+ void ActivatePage( sal_uInt16 nResId );
+ void ActivatePage( const OUString& rPageURL );
+ void ApplyItemSets();
+
+ // helper functions to call the language settings TabPage from the SpellDialog
+ static void ApplyLanguageOptions(const SfxItemSet& rSet);
+
+ void SetNeedsRestart( svtools::RestartReason eReason );
+};
+
+// class ExtensionsTabPage -----------------------------------------------
+
+namespace com::sun::star::awt { class XWindow; }
+namespace com::sun::star::awt { class XContainerWindowEventHandler; }
+
+class ExtensionsTabPage
+{
+private:
+ weld::Container* m_pContainer;
+ OUString m_sPageURL;
+ css::uno::Reference<css::awt::XWindow> m_xPageParent;
+ css::uno::Reference<css::awt::XWindow> m_xPage;
+ OUString m_sEventHdl;
+ css::uno::Reference< css::awt::XContainerWindowEventHandler >
+ m_xEventHdl;
+ css::uno::Reference< css::awt::XContainerWindowProvider >
+ m_xWinProvider;
+
+ void CreateDialogWithHandler();
+ bool DispatchAction( const OUString& rAction );
+
+public:
+ ExtensionsTabPage(
+ weld::Container* pParent,
+ OUString rPageURL, OUString aEvtHdl,
+ const css::uno::Reference<
+ css::awt::XContainerWindowProvider >& rProvider );
+
+ ~ExtensionsTabPage();
+
+ void Show();
+ void Hide();
+
+ void ActivatePage();
+ void DeactivatePage();
+
+ void ResetPage();
+ void SavePage();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/zoom.hxx b/cui/source/inc/zoom.hxx
new file mode 100644
index 000000000..f44998378
--- /dev/null
+++ b/cui/source/inc/zoom.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/basedlgs.hxx>
+#include <svl/itemset.hxx>
+#include <svx/zoom_def.hxx>
+#include <vcl/weld.hxx>
+
+class SvxZoomDialog : public SfxDialogController
+{
+private:
+ const SfxItemSet& m_rSet;
+ std::unique_ptr<SfxItemSet> m_pOutSet;
+ bool m_bModified;
+
+ std::unique_ptr<weld::RadioButton> m_xOptimalBtn;
+ std::unique_ptr<weld::RadioButton> m_xWholePageBtn;
+ std::unique_ptr<weld::RadioButton> m_xPageWidthBtn;
+ std::unique_ptr<weld::RadioButton> m_x100Btn;
+ std::unique_ptr<weld::RadioButton> m_xUserBtn;
+ std::unique_ptr<weld::MetricSpinButton> m_xUserEdit;
+ std::unique_ptr<weld::Widget> m_xViewFrame;
+ std::unique_ptr<weld::RadioButton> m_xAutomaticBtn;
+ std::unique_ptr<weld::RadioButton> m_xSingleBtn;
+ std::unique_ptr<weld::RadioButton> m_xColumnsBtn;
+ std::unique_ptr<weld::SpinButton> m_xColumnsEdit;
+ std::unique_ptr<weld::CheckButton> m_xBookModeChk;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+
+ DECL_LINK(UserHdl, weld::Toggleable&, void);
+ DECL_LINK(SpinHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(ViewLayoutUserHdl, weld::Toggleable&, void);
+ DECL_LINK(ViewLayoutSpinHdl, weld::SpinButton&, void);
+ DECL_LINK(ViewLayoutCheckHdl, weld::Toggleable&, void);
+ DECL_LINK(OKHdl, weld::Button&, void);
+
+public:
+ SvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet);
+
+ const SfxItemSet* GetOutputItemSet() const;
+
+ sal_uInt16 GetFactor() const;
+ void SetFactor(sal_uInt16 nNewFactor, ZoomButtonId nButtonId = ZoomButtonId::NONE);
+
+ void HideButton(ZoomButtonId nButtonId);
+ void SetLimits(sal_uInt16 nMin, sal_uInt16 nMax);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/certpath.cxx b/cui/source/options/certpath.cxx
new file mode 100644
index 000000000..3aff94b32
--- /dev/null
+++ b/cui/source/options/certpath.cxx
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <tools/diagnose_ex.h>
+#include "certpath.hxx"
+
+#include <com/sun/star/xml/crypto/NSSInitializer.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <comphelper/processfactory.hxx>
+
+using namespace ::com::sun::star;
+
+CertPathDialog::CertPathDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/certdialog.ui", "CertDialog")
+ , m_xManualButton(m_xBuilder->weld_button("add"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xCertPathList(m_xBuilder->weld_tree_view("paths"))
+ , m_sAddDialogText(m_xBuilder->weld_label("certdir")->get_label())
+ , m_sManualLabel(m_xBuilder->weld_label("manual")->get_label())
+{
+ m_xCertPathList->set_size_request(m_xCertPathList->get_approximate_digit_width() * 70,
+ m_xCertPathList->get_height_rows(6));
+
+ m_xCertPathList->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ m_xCertPathList->connect_toggled(LINK(this, CertPathDialog, CheckHdl_Impl));
+
+ m_xManualButton->connect_clicked( LINK( this, CertPathDialog, ManualHdl_Impl ) );
+ m_xOKButton->connect_clicked( LINK( this, CertPathDialog, OKHdl_Impl ) );
+}
+
+void CertPathDialog::Init()
+{
+ m_xCertPathList->clear();
+ m_xCertPathList->set_sensitive(true);
+
+ try
+ {
+ uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
+
+ OUString sActivePath = xCipherContextSupplier->getNSSPath();
+ auto aProductList = xCipherContextSupplier->getNSSProfiles();
+
+ // these map to the integer values of mozilla::MozillaProductType
+ const char* const productNames[4] = {
+ "",
+ "mozilla",
+ "firefox",
+ "thunderbird"
+ };
+
+ for (const auto& rNSSProfile : std::as_const(aProductList))
+ {
+ if (rNSSProfile.Type == mozilla::MozillaProductType_Default)
+ {
+ if (rNSSProfile.Name == "MOZILLA_CERTIFICATE_FOLDER" && !rNSSProfile.Path.isEmpty())
+ {
+ AddCertPath("$MOZILLA_CERTIFICATE_FOLDER", rNSSProfile.Path);
+ m_xCertPathList->set_sensitive(false);
+ }
+ else if (rNSSProfile.Name == "MANUAL")
+ AddManualCertPath(rNSSProfile.Path);
+ }
+ else
+ {
+ OUString sEntry = OUString::createFromAscii(
+ productNames[static_cast<int>(rNSSProfile.Type)]) + ":" + rNSSProfile.Name;
+ AddCertPath(sEntry, rNSSProfile.Path, rNSSProfile.Path == sActivePath);
+ }
+ }
+
+ OUString sManualCertPath = officecfg::Office::Common::Security::Scripting::ManualCertDir::get();
+ if (!sManualCertPath.isEmpty())
+ AddManualCertPath(sManualCertPath, false);
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+void CertPathDialog::AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect)
+{
+ if (sUserSetCertPath.isEmpty())
+ return;
+
+ ::osl::DirectoryItem aUserPathItem;
+ OUString sUserSetCertURLPath;
+ osl::FileBase::getFileURLFromSystemPath(sUserSetCertPath, sUserSetCertURLPath);
+ if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sUserSetCertURLPath, aUserPathItem))
+ {
+ ::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
+ if (::osl::FileBase::E_None == aUserPathItem.getFileStatus(aStatus))
+ // the cert path exists
+ AddCertPath(m_sManualLabel, sUserSetCertPath, bSelect);
+ }
+}
+
+IMPL_LINK_NOARG(CertPathDialog, OKHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ const int nEntry = m_xCertPathList->get_selected_index();
+ officecfg::Office::Common::Security::Scripting::CertDir::set(
+ nEntry == -1 ? OUString() : m_xCertPathList->get_id(nEntry), batch);
+ officecfg::Office::Common::Security::Scripting::ManualCertDir::set(m_sManualPath, batch);
+ batch->commit();
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::OKHdl_Impl()");
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+bool CertPathDialog::isActiveServicePath() const
+{
+ int nEntry = m_xCertPathList->get_selected_index();
+ if (nEntry == -1)
+ return true;
+
+ try
+ {
+ uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
+
+ if (!xCipherContextSupplier->getIsNSSinitialized())
+ return true;
+ return (xCipherContextSupplier->getNSSPath() == m_xCertPathList->get_id(nEntry));
+ }
+ catch (const uno::Exception&)
+ {
+ return false;
+ }
+}
+
+CertPathDialog::~CertPathDialog()
+{
+}
+
+IMPL_LINK(CertPathDialog, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ HandleEntryChecked(m_xCertPathList->get_iter_index_in_parent(rRowCol.first));
+}
+
+void CertPathDialog::HandleEntryChecked(int nRow)
+{
+ const bool bChecked = m_xCertPathList->get_toggle(nRow) == TRISTATE_TRUE;
+ if (bChecked)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ m_xCertPathList->select(nRow);
+ const int nCount = m_xCertPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (i != nRow)
+ m_xCertPathList->set_toggle(i, TRISTATE_FALSE);
+ }
+ }
+}
+
+void CertPathDialog::AddCertPath(const OUString &rProfile, const OUString &rPath, const bool bSelect)
+{
+ int nRow = -1;
+ for (int i = 0, nCount = m_xCertPathList->n_children(); i < nCount; ++i)
+ {
+ OUString sCertPath = m_xCertPathList->get_id(i);
+ //already exists, just select the original one
+ if (sCertPath == rPath)
+ {
+ const bool bWantSelected = bSelect || m_xCertPathList->get_toggle(i);
+ m_xCertPathList->set_toggle(i, bWantSelected ? TRISTATE_TRUE : TRISTATE_FALSE);
+ HandleEntryChecked(i);
+ return;
+ }
+ else if (m_xCertPathList->get_text(i, 0) == rProfile)
+ nRow = i;
+ }
+
+ if (m_sManualLabel == rProfile)
+ m_sManualPath = rPath;
+
+ if (nRow < 0)
+ {
+ m_xCertPathList->append();
+ nRow = m_xCertPathList->n_children() - 1;
+ }
+ m_xCertPathList->set_toggle(nRow, bSelect ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCertPathList->set_text(nRow, rProfile, 0);
+ m_xCertPathList->set_text(nRow, rPath, 1);
+ m_xCertPathList->set_id(nRow, rPath);
+ HandleEntryChecked(nRow);
+}
+
+IMPL_LINK_NOARG(CertPathDialog, ManualHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
+ comphelper::getProcessComponentContext(), m_xDialog.get());
+
+ OUString sURL;
+ if (!m_sManualPath.isEmpty())
+ osl::FileBase::getFileURLFromSystemPath(m_sManualPath, sURL);
+ if (sURL.isEmpty())
+ osl::Security().getHomeDir(sURL);
+ xFolderPicker->setDisplayDirectory(sURL);
+ xFolderPicker->setDescription(m_sAddDialogText);
+
+ if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ sURL = xFolderPicker->getDirectory();
+ OUString aPath;
+ if (osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sURL, aPath))
+ AddCertPath(m_sManualLabel, aPath);
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/certpath.hxx b/cui/source/options/certpath.hxx
new file mode 100644
index 000000000..50addc1e8
--- /dev/null
+++ b/cui/source/options/certpath.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class CertPathDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Button> m_xManualButton;
+ std::unique_ptr<weld::Button> m_xOKButton;
+ std::unique_ptr<weld::TreeView> m_xCertPathList;
+ OUString m_sAddDialogText;
+ OUString m_sManualLabel;
+ OUString m_sManualPath;
+
+ DECL_LINK(CheckHdl_Impl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(ManualHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+
+ void HandleEntryChecked(int nRow);
+ void AddCertPath(const OUString& rProfile, const OUString& rPath, bool bSelect = true);
+ void AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect = true);
+
+public:
+ explicit CertPathDialog(weld::Window* pParent);
+ virtual ~CertPathDialog() override;
+
+ void Init();
+
+ // returns true, if the service currently uses the selected path or is not initialized
+ // yet and therefore has no active NSS path.
+ bool isActiveServicePath() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cfgchart.cxx b/cui/source/options/cfgchart.cxx
new file mode 100644
index 000000000..13ed520d0
--- /dev/null
+++ b/cui/source/options/cfgchart.cxx
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/debug.hxx>
+#include <sal/log.hxx>
+#include "cfgchart.hxx"
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <utility>
+
+#define ROW_COLOR_COUNT 12
+
+using namespace com::sun::star;
+
+// accessors
+size_t SvxChartColorTable::size() const
+{
+ return m_aColorEntries.size();
+}
+
+const XColorEntry & SvxChartColorTable::operator[]( size_t _nIndex ) const
+{
+ if ( _nIndex >= m_aColorEntries.size() )
+ {
+ SAL_WARN( "cui.options", "SvxChartColorTable::[] invalid index" );
+ return m_aColorEntries[ 0 ];
+ }
+
+ return m_aColorEntries[ _nIndex ];
+}
+
+Color SvxChartColorTable::getColor( size_t _nIndex ) const
+{
+ if ( _nIndex >= m_aColorEntries.size() )
+ {
+ SAL_WARN( "cui.options", "SvxChartColorTable::getColorData invalid index" );
+ return COL_BLACK;
+ }
+
+ return m_aColorEntries[ _nIndex ].GetColor().GetRGBColor();
+}
+
+// mutators
+void SvxChartColorTable::clear()
+{
+ m_aColorEntries.clear();
+}
+
+void SvxChartColorTable::append( const XColorEntry & _rEntry )
+{
+ m_aColorEntries.push_back( _rEntry );
+}
+
+void SvxChartColorTable::remove( size_t _nIndex )
+{
+ if (!m_aColorEntries.empty())
+ m_aColorEntries.erase( m_aColorEntries.begin() + _nIndex);
+
+ for (size_t i=0 ; i<m_aColorEntries.size(); i++)
+ {
+ m_aColorEntries[ i ].SetName( getDefaultName( i ) );
+ }
+}
+
+void SvxChartColorTable::replace( size_t _nIndex, const XColorEntry & _rEntry )
+{
+ DBG_ASSERT( _nIndex <= m_aColorEntries.size(),
+ "SvxChartColorTable::replace invalid index" );
+
+ m_aColorEntries[ _nIndex ] = _rEntry;
+}
+
+void SvxChartColorTable::useDefault()
+{
+ static const Color aColors[] = {
+ Color( 0x00, 0x45, 0x86 ),
+ Color( 0xff, 0x42, 0x0e ),
+ Color( 0xff, 0xd3, 0x20 ),
+ Color( 0x57, 0x9d, 0x1c ),
+ Color( 0x7e, 0x00, 0x21 ),
+ Color( 0x83, 0xca, 0xff ),
+ Color( 0x31, 0x40, 0x04 ),
+ Color( 0xae, 0xcf, 0x00 ),
+ Color( 0x4b, 0x1f, 0x6f ),
+ Color( 0xff, 0x95, 0x0e ),
+ Color( 0xc5, 0x00, 0x0b ),
+ Color( 0x00, 0x84, 0xd1 )
+ };
+
+ clear();
+
+ for( sal_Int32 i=0; i<ROW_COLOR_COUNT; i++ )
+ {
+ append( XColorEntry( aColors[ i % sizeof( aColors ) ], getDefaultName( i ) ));
+ }
+}
+
+OUString SvxChartColorTable::getDefaultName( size_t _nIndex )
+{
+ OUString aName;
+
+ std::u16string_view sDefaultNamePrefix;
+ std::u16string_view sDefaultNamePostfix;
+ OUString aResName( CuiResId( RID_CUISTR_DIAGRAM_ROW ) );
+ sal_Int32 nPos = aResName.indexOf( "$(ROW)" );
+ if( nPos != -1 )
+ {
+ sDefaultNamePrefix = aResName.subView( 0, nPos );
+ sDefaultNamePostfix = aResName.subView( nPos + sizeof( "$(ROW)" ) - 1 );
+ }
+ else
+ {
+ sDefaultNamePrefix = aResName;
+ }
+
+ aName = sDefaultNamePrefix + OUString::number(_nIndex + 1) + sDefaultNamePostfix;
+
+ return aName;
+}
+
+// comparison
+bool SvxChartColorTable::operator==( const SvxChartColorTable & _rOther ) const
+{
+ // note: XColorEntry has no operator ==
+ bool bEqual = ( m_aColorEntries.size() == _rOther.m_aColorEntries.size() );
+
+ if( bEqual )
+ {
+ for( size_t i = 0; i < m_aColorEntries.size(); ++i )
+ {
+ if( getColor( i ) != _rOther.getColor( i ))
+ {
+ bEqual = false;
+ break;
+ }
+ }
+ }
+
+ return bEqual;
+}
+
+
+
+
+SvxChartOptions::SvxChartOptions() :
+ ::utl::ConfigItem( "Office.Chart" ),
+ mbIsInitialized( false ),
+ maPropertyNames{ "DefaultColor/Series" }
+{
+}
+
+SvxChartOptions::~SvxChartOptions()
+{
+}
+
+const SvxChartColorTable& SvxChartOptions::GetDefaultColors()
+{
+ if ( !mbIsInitialized )
+ mbIsInitialized = RetrieveOptions();
+ return maDefColors;
+}
+
+void SvxChartOptions::SetDefaultColors( const SvxChartColorTable& aCol )
+{
+ maDefColors = aCol;
+ SetModified();
+}
+
+bool SvxChartOptions::RetrieveOptions()
+{
+ // get sequence containing all properties
+
+ uno::Sequence< OUString > aNames = GetPropertyNames();
+ uno::Sequence< uno::Any > aProperties( aNames.getLength());
+ aProperties = GetProperties( aNames );
+
+ if( aProperties.getLength() != aNames.getLength())
+ return false;
+
+ // 1. default colors for series
+ maDefColors.clear();
+ uno::Sequence< sal_Int64 > aColorSeq;
+ aProperties[ 0 ] >>= aColorSeq;
+
+ sal_Int32 nCount = aColorSeq.getLength();
+ Color aCol;
+
+ // create strings for entry names
+ OUString aResName( CuiResId( RID_CUISTR_DIAGRAM_ROW ) );
+ std::u16string_view aPrefix, aPostfix;
+ OUString aName;
+ sal_Int32 nPos = aResName.indexOf( "$(ROW)" );
+ if( nPos != -1 )
+ {
+ aPrefix = aResName.subView( 0, nPos );
+ sal_Int32 idx = nPos + sizeof( "$(ROW)" ) - 1;
+ aPostfix = aResName.subView( idx );
+ }
+ else
+ aPrefix = aResName;
+
+ // set color values
+ for( sal_Int32 i=0; i < nCount; i++ )
+ {
+ aCol = Color(ColorTransparency, aColorSeq[ i ]);
+
+ aName = aPrefix + OUString::number(i + 1) + aPostfix;
+
+ maDefColors.append( XColorEntry( aCol, aName ));
+ }
+ return true;
+}
+
+void SvxChartOptions::ImplCommit()
+{
+ uno::Sequence< OUString > aNames = GetPropertyNames();
+ uno::Sequence< uno::Any > aValues( aNames.getLength());
+
+ if( aValues.hasElements() )
+ {
+ // 1. default colors for series
+ // convert list to sequence
+ const size_t nCount = maDefColors.size();
+ uno::Sequence< sal_Int64 > aColors( nCount );
+ auto aColorsRange = asNonConstRange(aColors);
+ for( size_t i=0; i < nCount; i++ )
+ {
+ Color aData = maDefColors.getColor( i );
+ aColorsRange[ i ] = sal_uInt32(aData);
+ }
+
+ aValues.getArray()[0] <<= aColors;
+ }
+
+ PutProperties( aNames, aValues );
+}
+
+void SvxChartOptions::Notify( const css::uno::Sequence< OUString >& )
+{
+}
+
+
+
+
+SvxChartColorTableItem::SvxChartColorTableItem( sal_uInt16 nWhich_, SvxChartColorTable aTable ) :
+ SfxPoolItem( nWhich_ ),
+ m_aColorTable(std::move( aTable ))
+{
+}
+
+SvxChartColorTableItem* SvxChartColorTableItem::Clone( SfxItemPool * ) const
+{
+ return new SvxChartColorTableItem( *this );
+}
+
+bool SvxChartColorTableItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ assert(SfxPoolItem::operator==(rAttr));
+
+ return static_cast<const SvxChartColorTableItem & >( rAttr ).m_aColorTable == m_aColorTable;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cfgchart.hxx b/cui/source/options/cfgchart.hxx
new file mode 100644
index 000000000..8e49e190d
--- /dev/null
+++ b/cui/source/options/cfgchart.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <unotools/configitem.hxx>
+#include <svl/poolitem.hxx>
+#include <svx/xtable.hxx>
+
+#include <vector>
+
+class SvxChartColorTable
+{
+private:
+ std::vector< XColorEntry > m_aColorEntries;
+
+public:
+ // accessors
+ size_t size() const;
+ const XColorEntry & operator[]( size_t _nIndex ) const;
+ Color getColor( size_t _nIndex ) const;
+
+ // mutators
+ void clear();
+ void append( const XColorEntry & _rEntry );
+ void remove( size_t _nIndex );
+ void replace( size_t _nIndex, const XColorEntry & _rEntry );
+ void useDefault();
+ static OUString getDefaultName(size_t _nIndex);
+
+ // comparison
+ bool operator==( const SvxChartColorTable & _rOther ) const;
+};
+
+
+// all options
+
+class SvxChartOptions : public ::utl::ConfigItem
+{
+private:
+ SvxChartColorTable maDefColors;
+ bool mbIsInitialized;
+
+ css::uno::Sequence< OUString >
+ maPropertyNames;
+
+ const css::uno::Sequence< OUString >& GetPropertyNames() const
+ { return maPropertyNames; }
+ bool RetrieveOptions();
+
+ virtual void ImplCommit() override;
+
+public:
+ SvxChartOptions();
+ virtual ~SvxChartOptions() override;
+
+ const SvxChartColorTable& GetDefaultColors();
+ void SetDefaultColors( const SvxChartColorTable& aCol );
+
+ virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override;
+};
+
+
+// items
+// Make Item read-only (no non-const access methods). Two reasons:
+// (1) Preparation for Item refactor
+// (2) Dangerous due to SfxItem may not be what you expect (e.g. when
+// ::Set in SfxItemSet, not your instance may be used there, no control
+// about what will happen without deep knowledge about SfxItems/SfxItemSets)
+class SvxChartColorTableItem : public SfxPoolItem
+{
+public:
+ SvxChartColorTableItem( sal_uInt16 nWhich, SvxChartColorTable );
+
+ virtual SvxChartColorTableItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+ virtual bool operator==( const SfxPoolItem& ) const override;
+
+ const SvxChartColorTable & GetColorList() const { return m_aColorTable;}
+
+private:
+ SvxChartColorTable m_aColorTable;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolconfig.cxx b/cui/source/options/connpoolconfig.cxx
new file mode 100644
index 000000000..8bf95ee0d
--- /dev/null
+++ b/cui/source/options/connpoolconfig.cxx
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "connpoolconfig.hxx"
+#include "connpoolsettings.hxx"
+
+#include <svl/itemset.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <unotools/confignode.hxx>
+#include <svl/eitem.hxx>
+#include <comphelper/processfactory.hxx>
+#include "sdbcdriverenum.hxx"
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace offapp
+{
+
+
+ using namespace ::utl;
+ using namespace ::com::sun::star::uno;
+
+
+ static OUString getConnectionPoolNodeName()
+ {
+ return "org.openoffice.Office.DataAccess/ConnectionPool";
+ }
+
+
+ static OUString getEnablePoolingNodeName()
+ {
+ return "EnablePooling";
+ }
+
+
+ static OUString getDriverSettingsNodeName()
+ {
+ return "DriverSettings";
+ }
+
+
+ static OUString getDriverNameNodeName()
+ {
+ return "DriverName";
+ }
+
+
+ static OUString getEnableNodeName()
+ {
+ return "Enable";
+ }
+
+
+ static OUString getTimeoutNodeName()
+ {
+ return "Timeout";
+ }
+
+ void ConnectionPoolConfig::GetOptions(SfxItemSet& _rFillItems)
+ {
+ // the config node where all pooling relevant info are stored under
+ OConfigurationTreeRoot aConnectionPoolRoot = OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(), getConnectionPoolNodeName(), -1, OConfigurationTreeRoot::CM_READONLY);
+
+ // the global "enabled" flag
+ Any aEnabled = aConnectionPoolRoot.getNodeValue(getEnablePoolingNodeName());
+ bool bEnabled = true;
+ aEnabled >>= bEnabled;
+ _rFillItems.Put(SfxBoolItem(SID_SB_POOLING_ENABLED, bEnabled));
+
+ // the settings for the single drivers
+ DriverPoolingSettings aSettings;
+ // first get all the drivers register at the driver manager
+ ODriverEnumeration aEnumDrivers;
+ for (auto const& elem : aEnumDrivers)
+ {
+ aSettings.push_back(DriverPooling(elem));
+ }
+
+ // then look for which of them settings are stored in the configuration
+ OConfigurationNode aDriverSettings = aConnectionPoolRoot.openNode(getDriverSettingsNodeName());
+
+ Sequence< OUString > aDriverKeys = aDriverSettings.getNodeNames();
+ const OUString* pDriverKeys = aDriverKeys.getConstArray();
+ const OUString* pDriverKeysEnd = pDriverKeys + aDriverKeys.getLength();
+ for (;pDriverKeys != pDriverKeysEnd; ++pDriverKeys)
+ {
+ // the name of the driver in this round
+ OConfigurationNode aThisDriverSettings = aDriverSettings.openNode(*pDriverKeys);
+ OUString sThisDriverName;
+ aThisDriverSettings.getNodeValue(getDriverNameNodeName()) >>= sThisDriverName;
+
+ // look if we (resp. the driver manager) know this driver
+ // doing O(n) search here, which is expensive, but this doesn't matter in this small case ...
+ DriverPoolingSettings::iterator aLookup;
+ for ( aLookup = aSettings.begin();
+ aLookup != aSettings.end();
+ ++aLookup
+ )
+ if (sThisDriverName == aLookup->sName)
+ break;
+
+ if (aLookup == aSettings.end())
+ { // do not know the driver - add it
+ aSettings.push_back(DriverPooling(sThisDriverName));
+
+ // and the position of the new entry
+ aLookup = aSettings.end();
+ --aLookup;
+ }
+
+ // now fill this entry with the settings from the configuration
+ aThisDriverSettings.getNodeValue(getEnableNodeName()) >>= aLookup->bEnabled;
+ aThisDriverSettings.getNodeValue(getTimeoutNodeName()) >>= aLookup->nTimeoutSeconds;
+ }
+
+ _rFillItems.Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, aSettings));
+ }
+
+
+ void ConnectionPoolConfig::SetOptions(const SfxItemSet& _rSourceItems)
+ {
+ // the config node where all pooling relevant info are stored under
+ OConfigurationTreeRoot aConnectionPoolRoot = OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(), getConnectionPoolNodeName());
+
+ if (!aConnectionPoolRoot.isValid())
+ // already asserted by the OConfigurationTreeRoot
+ return;
+
+ bool bNeedCommit = false;
+
+ // the global "enabled" flag
+ const SfxBoolItem* pEnabled = _rSourceItems.GetItem<SfxBoolItem>(SID_SB_POOLING_ENABLED);
+ if (pEnabled)
+ {
+ bool bEnabled = pEnabled->GetValue();
+ aConnectionPoolRoot.setNodeValue(getEnablePoolingNodeName(), Any(bEnabled));
+ bNeedCommit = true;
+ }
+
+ // the settings for the single drivers
+ const DriverPoolingSettingsItem* pDriverSettings = _rSourceItems.GetItem<DriverPoolingSettingsItem>(SID_SB_DRIVER_TIMEOUTS);
+ if (pDriverSettings)
+ {
+ OConfigurationNode aDriverSettings = aConnectionPoolRoot.openNode(getDriverSettingsNodeName());
+ if (!aDriverSettings.isValid())
+ return;
+
+ OUString sThisDriverName;
+ OConfigurationNode aThisDriverSettings;
+
+ const DriverPoolingSettings& rNewSettings = pDriverSettings->getSettings();
+ for (auto const& newSetting : rNewSettings)
+ {
+ // need the name as OUString
+ sThisDriverName = newSetting.sName;
+
+ // the sub-node for this driver
+ if (aDriverSettings.hasByName(newSetting.sName))
+ aThisDriverSettings = aDriverSettings.openNode(newSetting.sName);
+ else
+ aThisDriverSettings = aDriverSettings.createNode(newSetting.sName);
+
+ // set the values
+ aThisDriverSettings.setNodeValue(getDriverNameNodeName(), Any(sThisDriverName));
+ aThisDriverSettings.setNodeValue(getEnableNodeName(), Any(newSetting.bEnabled));
+ aThisDriverSettings.setNodeValue(getTimeoutNodeName(), Any(newSetting.nTimeoutSeconds));
+ }
+ bNeedCommit = true;
+ }
+ if (bNeedCommit)
+ aConnectionPoolRoot.commit();
+ }
+
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolconfig.hxx b/cui/source/options/connpoolconfig.hxx
new file mode 100644
index 000000000..41ec88d5b
--- /dev/null
+++ b/cui/source/options/connpoolconfig.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SfxItemSet;
+
+namespace offapp
+{
+
+ class ConnectionPoolConfig
+ {
+
+ public:
+ static void GetOptions(SfxItemSet& _rFillItems);
+ static void SetOptions(const SfxItemSet& _rSourceItems);
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpooloptions.cxx b/cui/source/options/connpooloptions.cxx
new file mode 100644
index 000000000..c067af0c3
--- /dev/null
+++ b/cui/source/options/connpooloptions.cxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include "connpooloptions.hxx"
+#include "connpoolsettings.hxx"
+#include <svl/eitem.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+namespace offapp
+{
+ bool ConnectionPoolOptionsPage::isModifiedDriverList() const
+ {
+ if (m_aSettings.size() != m_aSavedSettings.size())
+ return true;
+
+ DriverPoolingSettings::const_iterator aSaved = m_aSavedSettings.begin();
+ for (auto const& currentSetting : m_aSettings)
+ {
+ if (currentSetting != *aSaved)
+ return true;
+ ++aSaved;
+ }
+
+ return false;
+ }
+
+ ConnectionPoolOptionsPage::ConnectionPoolOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ : SfxTabPage(pPage, pController, "cui/ui/connpooloptions.ui", "ConnPoolPage", &_rAttrSet)
+ , m_sYes(CuiResId(RID_CUISTR_YES))
+ , m_sNo(CuiResId(RID_CUISTR_NO))
+ , m_xEnablePooling(m_xBuilder->weld_check_button("connectionpooling"))
+ , m_xDriversLabel(m_xBuilder->weld_label("driverslabel"))
+ , m_xDriverList(m_xBuilder->weld_tree_view("driverlist"))
+ , m_xDriverLabel(m_xBuilder->weld_label("driverlabel"))
+ , m_xDriver(m_xBuilder->weld_label("driver"))
+ , m_xDriverPoolingEnabled(m_xBuilder->weld_check_button("enablepooling"))
+ , m_xTimeoutLabel(m_xBuilder->weld_label("timeoutlabel"))
+ , m_xTimeout(m_xBuilder->weld_spin_button("timeout"))
+ {
+ m_xDriverList->set_size_request(m_xDriverList->get_approximate_digit_width() * 60,
+ m_xDriverList->get_height_rows(15));
+ m_xDriverList->show();
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xDriverList->get_approximate_digit_width() * 50),
+ o3tl::narrowing<int>(m_xDriverList->get_approximate_digit_width() * 8)
+ };
+ m_xDriverList->set_column_fixed_widths(aWidths);
+
+ m_xEnablePooling->connect_toggled( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
+ m_xDriverPoolingEnabled->connect_toggled( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
+
+ m_xDriverList->connect_changed(LINK(this, ConnectionPoolOptionsPage, OnDriverRowChanged));
+ m_xTimeout->connect_value_changed(LINK(this, ConnectionPoolOptionsPage, OnSpinValueChanged));
+ }
+
+ void ConnectionPoolOptionsPage::updateRow(size_t nRow)
+ {
+ auto const& currentSetting = m_aSettings[nRow];
+ m_xDriverList->set_text(nRow, currentSetting.sName, 0);
+ if (currentSetting.bEnabled)
+ {
+ m_xDriverList->set_text(nRow, m_sYes, 1);
+ m_xDriverList->set_text(nRow, OUString::number(currentSetting.nTimeoutSeconds), 2);
+ }
+ else
+ {
+ m_xDriverList->set_text(nRow, m_sNo, 1);
+ m_xDriverList->set_text(nRow, "-", 2);
+ }
+ }
+
+ void ConnectionPoolOptionsPage::updateCurrentRow()
+ {
+ int nRow = m_xDriverList->get_selected_index();
+ if (nRow == -1)
+ return;
+ updateRow(nRow);
+ }
+
+ void ConnectionPoolOptionsPage::UpdateDriverList(const DriverPoolingSettings& _rSettings)
+ {
+ m_aSettings = _rSettings;
+
+ m_xDriverList->freeze();
+ m_xDriverList->clear();
+
+ for (size_t i = 0; i < m_aSettings.size(); ++i)
+ {
+ m_xDriverList->append();
+ updateRow(i);
+ }
+
+ m_xDriverList->thaw();
+
+ if (!m_aSettings.empty())
+ {
+ m_xDriverList->select(0);
+ OnDriverRowChanged(*m_xDriverList);
+ }
+ }
+
+ ConnectionPoolOptionsPage::~ConnectionPoolOptionsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ConnectionPoolOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<ConnectionPoolOptionsPage>(pPage, pController, *_rAttrSet);
+ }
+
+ void ConnectionPoolOptionsPage::implInitControls(const SfxItemSet& _rSet)
+ {
+ // the enabled flag
+ const SfxBoolItem* pEnabled = _rSet.GetItem<SfxBoolItem>(SID_SB_POOLING_ENABLED);
+ OSL_ENSURE(pEnabled, "ConnectionPoolOptionsPage::implInitControls: missing the Enabled item!");
+ m_xEnablePooling->set_active(pEnabled == nullptr || pEnabled->GetValue());
+
+ m_xEnablePooling->save_state();
+
+ // the settings for the single drivers
+ const DriverPoolingSettingsItem* pDriverSettings = _rSet.GetItem<DriverPoolingSettingsItem>(SID_SB_DRIVER_TIMEOUTS);
+ if (pDriverSettings)
+ UpdateDriverList(pDriverSettings->getSettings());
+ else
+ {
+ OSL_FAIL("ConnectionPoolOptionsPage::implInitControls: missing the DriverTimeouts item!");
+ UpdateDriverList(DriverPoolingSettings());
+ }
+ saveDriverList();
+
+ // reflect the new settings
+ OnEnabledDisabled(*m_xEnablePooling);
+ }
+
+ IMPL_LINK_NOARG(ConnectionPoolOptionsPage, OnSpinValueChanged, weld::SpinButton&, void)
+ {
+ commitTimeoutField();
+ }
+
+ bool ConnectionPoolOptionsPage::FillItemSet(SfxItemSet* _rSet)
+ {
+ commitTimeoutField();
+
+ bool bModified = false;
+ // the enabled flag
+ if (m_xEnablePooling->get_state_changed_from_saved())
+ {
+ _rSet->Put(SfxBoolItem(SID_SB_POOLING_ENABLED, m_xEnablePooling->get_active()));
+ bModified = true;
+ }
+
+ // the settings for the single drivers
+ if (isModifiedDriverList())
+ {
+ _rSet->Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, m_aSettings));
+ bModified = true;
+ }
+
+ return bModified;
+ }
+
+ void ConnectionPoolOptionsPage::ActivatePage( const SfxItemSet& _rSet)
+ {
+ SfxTabPage::ActivatePage(_rSet);
+ implInitControls(_rSet);
+ }
+
+ void ConnectionPoolOptionsPage::Reset(const SfxItemSet* _rSet)
+ {
+ implInitControls(*_rSet);
+ }
+
+ IMPL_LINK_NOARG(ConnectionPoolOptionsPage, OnDriverRowChanged, weld::TreeView&, void)
+ {
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ bool bValidRow = (nDriverPos != -1);
+ m_xDriverPoolingEnabled->set_sensitive(bValidRow && m_xEnablePooling->get_active());
+ m_xTimeoutLabel->set_sensitive(bValidRow);
+ m_xTimeout->set_sensitive(bValidRow);
+
+ if (!bValidRow)
+ { // positioned on an invalid row
+ m_xDriver->set_label(OUString());
+ }
+ else
+ {
+ auto const& currentSetting = m_aSettings[nDriverPos];
+ m_xDriver->set_label(currentSetting.sName);
+ m_xDriverPoolingEnabled->set_active(currentSetting.bEnabled);
+ m_xTimeout->set_value(currentSetting.nTimeoutSeconds);
+
+ OnEnabledDisabled(*m_xDriverPoolingEnabled);
+ }
+ }
+
+ void ConnectionPoolOptionsPage::commitTimeoutField()
+ {
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ if (nDriverPos == -1)
+ return;
+ m_aSettings[nDriverPos].nTimeoutSeconds = m_xTimeout->get_value();
+ updateCurrentRow();
+ }
+
+ IMPL_LINK( ConnectionPoolOptionsPage, OnEnabledDisabled, weld::Toggleable&, rCheckBox, void )
+ {
+ bool bGloballyEnabled = m_xEnablePooling->get_active();
+ bool bLocalDriverChanged = m_xDriverPoolingEnabled.get() == &rCheckBox;
+
+ if (m_xEnablePooling.get() == &rCheckBox)
+ {
+ m_xDriversLabel->set_sensitive(bGloballyEnabled);
+ m_xDriverList->set_sensitive(bGloballyEnabled);
+ if (!bGloballyEnabled)
+ m_xDriverList->select(-1);
+ m_xDriverLabel->set_sensitive(bGloballyEnabled);
+ m_xDriver->set_sensitive(bGloballyEnabled);
+ m_xDriverPoolingEnabled->set_sensitive(bGloballyEnabled);
+ }
+ else
+ OSL_ENSURE(bLocalDriverChanged, "ConnectionPoolOptionsPage::OnEnabledDisabled: where did this come from?");
+
+ m_xTimeoutLabel->set_sensitive(bGloballyEnabled && m_xDriverPoolingEnabled->get_active());
+ m_xTimeout->set_sensitive(bGloballyEnabled && m_xDriverPoolingEnabled->get_active());
+
+ if (bLocalDriverChanged)
+ {
+ // update the list
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ if (nDriverPos == -1)
+ return;
+ m_aSettings[nDriverPos].bEnabled = m_xDriverPoolingEnabled->get_active();
+ updateCurrentRow();
+ }
+ }
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpooloptions.hxx b/cui/source/options/connpooloptions.hxx
new file mode 100644
index 000000000..549448e21
--- /dev/null
+++ b/cui/source/options/connpooloptions.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+#include "connpoolsettings.hxx"
+
+namespace offapp
+{
+ class ConnectionPoolOptionsPage final : public SfxTabPage
+ {
+ OUString m_sYes;
+ OUString m_sNo;
+ DriverPoolingSettings m_aSettings;
+ DriverPoolingSettings m_aSavedSettings;
+
+ std::unique_ptr<weld::CheckButton> m_xEnablePooling;
+ std::unique_ptr<weld::Label> m_xDriversLabel;
+ std::unique_ptr<weld::TreeView> m_xDriverList;
+ std::unique_ptr<weld::Label> m_xDriverLabel;
+ std::unique_ptr<weld::Label> m_xDriver;
+ std::unique_ptr<weld::CheckButton> m_xDriverPoolingEnabled;
+ std::unique_ptr<weld::Label> m_xTimeoutLabel;
+ std::unique_ptr<weld::SpinButton> m_xTimeout;
+
+ public:
+ ConnectionPoolOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ virtual ~ConnectionPoolOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet);
+
+ private:
+ virtual bool FillItemSet(SfxItemSet* _rSet) override;
+ virtual void Reset(const SfxItemSet* _rSet) override;
+ virtual void ActivatePage( const SfxItemSet& _rSet) override;
+
+ void updateRow(size_t nRow);
+ void updateCurrentRow();
+ void UpdateDriverList(const DriverPoolingSettings& _rSettings);
+ bool isModifiedDriverList() const;
+ void saveDriverList() { m_aSavedSettings = m_aSettings; }
+
+ DECL_LINK(OnEnabledDisabled, weld::Toggleable&, void);
+ DECL_LINK(OnSpinValueChanged, weld::SpinButton&, void);
+ DECL_LINK(OnDriverRowChanged, weld::TreeView&, void);
+
+ void implInitControls(const SfxItemSet& _rSet);
+
+ void commitTimeoutField();
+ };
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolsettings.cxx b/cui/source/options/connpoolsettings.cxx
new file mode 100644
index 000000000..e92b26da5
--- /dev/null
+++ b/cui/source/options/connpoolsettings.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <utility>
+
+#include "connpoolsettings.hxx"
+
+
+namespace offapp
+{
+
+ DriverPooling::DriverPooling( OUString _aName )
+ :sName(std::move(_aName))
+ ,bEnabled(false)
+ ,nTimeoutSeconds(120)
+ {
+ }
+
+
+ bool DriverPooling::operator == (const DriverPooling& _rR) const
+ {
+ return (sName == _rR.sName)
+ && (bEnabled == _rR.bEnabled)
+ && (nTimeoutSeconds == _rR.nTimeoutSeconds);
+ }
+
+ DriverPoolingSettings::DriverPoolingSettings()
+ {
+ }
+
+
+ DriverPoolingSettingsItem::DriverPoolingSettingsItem( sal_uInt16 _nId, DriverPoolingSettings _aSettings )
+ :SfxPoolItem(_nId)
+ ,m_aSettings(std::move(_aSettings))
+ {
+ }
+
+
+ bool DriverPoolingSettingsItem::operator==( const SfxPoolItem& _rCompare ) const
+ {
+ assert(SfxPoolItem::operator==(_rCompare));
+ const DriverPoolingSettingsItem* pItem = static_cast<const DriverPoolingSettingsItem*>( &_rCompare );
+
+ if (m_aSettings.size() != pItem->m_aSettings.size())
+ return false;
+
+ DriverPoolingSettings::const_iterator aForeign = pItem->m_aSettings.begin();
+ for (auto const& ownSetting : m_aSettings)
+ {
+ if (ownSetting != *aForeign)
+ return false;
+
+ ++aForeign;
+ }
+
+ return true;
+ }
+
+ DriverPoolingSettingsItem* DriverPoolingSettingsItem::Clone( SfxItemPool * ) const
+ {
+ return new DriverPoolingSettingsItem(*this);
+ }
+
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolsettings.hxx b/cui/source/options/connpoolsettings.hxx
new file mode 100644
index 000000000..1e2404b88
--- /dev/null
+++ b/cui/source/options/connpoolsettings.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <vector>
+
+#include <rtl/ustring.hxx>
+#include <svl/poolitem.hxx>
+
+
+namespace offapp
+{
+
+ struct DriverPooling
+ {
+ OUString sName;
+ bool bEnabled;
+ sal_Int32 nTimeoutSeconds;
+
+ explicit DriverPooling( OUString _aName );
+
+ bool operator == (const DriverPooling& _rR) const;
+ bool operator != (const DriverPooling& _rR) const { return !operator ==(_rR); }
+ };
+
+ class DriverPoolingSettings final
+ {
+ typedef std::vector<DriverPooling> DriverSettings;
+ DriverSettings m_aDrivers;
+
+ public:
+ typedef DriverSettings::const_iterator const_iterator;
+ typedef DriverSettings::iterator iterator;
+
+ DriverPoolingSettings();
+
+ size_t size() const { return m_aDrivers.size(); }
+ DriverPooling& operator[]( size_t nPos ) { return m_aDrivers[nPos]; }
+ bool empty() const { return m_aDrivers.empty(); }
+
+ const_iterator begin() const { return m_aDrivers.begin(); }
+ const_iterator end() const { return m_aDrivers.end(); }
+
+ iterator begin() { return m_aDrivers.begin(); }
+ iterator end() { return m_aDrivers.end(); }
+
+ void push_back(const DriverPooling& _rElement) { m_aDrivers.push_back(_rElement); }
+ };
+
+ class DriverPoolingSettingsItem final : public SfxPoolItem
+ {
+ DriverPoolingSettings m_aSettings;
+
+ public:
+
+ DriverPoolingSettingsItem( sal_uInt16 _nId, DriverPoolingSettings _aSettings );
+
+ virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual DriverPoolingSettingsItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+
+ const DriverPoolingSettings& getSettings() const { return m_aSettings; }
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cuisrchdlg.cxx b/cui/source/options/cuisrchdlg.cxx
new file mode 100644
index 000000000..f58985d90
--- /dev/null
+++ b/cui/source/options/cuisrchdlg.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/basedlgs.hxx>
+
+#include <cuisrchdlg.hxx>
+
+#include "optjsearch.hxx"
+
+
+// class SvxJSearchOptionsDialog -----------------------------------------
+
+SvxJSearchOptionsDialog::SvxJSearchOptionsDialog(weld::Window *pParent,
+ const SfxItemSet& rOptionsSet, TransliterationFlags nInitialFlags)
+ : SfxSingleTabDialogController(pParent, &rOptionsSet)
+{
+ // m_xPage will be implicitly destroyed by the
+ // SfxSingleTabDialog destructor
+ SetTabPage(SvxJSearchOptionsPage::Create(get_content_area(), this, &rOptionsSet)); //! implicitly calls m_xPage->Reset(...)!
+ m_pPage = static_cast<SvxJSearchOptionsPage*>(GetTabPage());
+ m_pPage->EnableSaveOptions(false);
+ m_pPage->SetTransliterationFlags(nInitialFlags);
+}
+
+SvxJSearchOptionsDialog::~SvxJSearchOptionsDialog()
+{
+}
+
+TransliterationFlags SvxJSearchOptionsDialog::GetTransliterationFlags() const
+{
+ return m_pPage->GetTransliterationFlags();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregister.cxx b/cui/source/options/dbregister.cxx
new file mode 100644
index 000000000..143112c58
--- /dev/null
+++ b/cui/source/options/dbregister.cxx
@@ -0,0 +1,315 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <dbregister.hxx>
+#include "dbregistersettings.hxx"
+#include <o3tl/safeint.hxx>
+#include <svl/filenotation.hxx>
+#include <helpids.h>
+#include <tools/debug.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/itemset.hxx>
+#include "doclinkdialog.hxx"
+#include <dialmgr.hxx>
+#include "dbregisterednamesconfig.hxx"
+#include <svx/databaseregistrationui.hxx>
+#include <o3tl/string_view.hxx>
+
+#define COL_TYPE 0
+
+namespace svx
+{
+
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+using namespace ::svt;
+
+// class RegistrationItemSetHolder -------------------------------------------------
+
+RegistrationItemSetHolder::RegistrationItemSetHolder( SfxItemSet _aMasterSet )
+ :m_aRegistrationItems(std::move( _aMasterSet ))
+{
+ DbRegisteredNamesConfig::GetOptions( m_aRegistrationItems );
+}
+
+RegistrationItemSetHolder::~RegistrationItemSetHolder()
+{
+}
+
+// class DatabaseRegistrationDialog ------------------------------------------------
+
+DatabaseRegistrationDialog::DatabaseRegistrationDialog(weld::Window* pParent, const SfxItemSet& rInAttrs)
+ : RegistrationItemSetHolder(rInAttrs)
+ , SfxSingleTabDialogController(pParent, &getRegistrationItems())
+{
+ SetTabPage(DbRegistrationOptionsPage::Create(get_content_area(), this, &getRegistrationItems()));
+ m_xDialog->set_title(CuiResId(RID_CUISTR_REGISTERED_DATABASES));
+}
+
+short DatabaseRegistrationDialog::run()
+{
+ short result = SfxSingleTabDialogController::run();
+ if (result == RET_OK)
+ {
+ DBG_ASSERT( GetOutputItemSet(), "DatabaseRegistrationDialog::Execute: no output items!" );
+ if ( GetOutputItemSet() )
+ DbRegisteredNamesConfig::SetOptions( *GetOutputItemSet() );
+ }
+ return result;
+}
+
+// class DbRegistrationOptionsPage --------------------------------------------------
+
+DbRegistrationOptionsPage::DbRegistrationOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/dbregisterpage.ui", "DbRegisterPage", &rSet)
+ , m_nOldCount(0)
+ , m_bModified(false)
+ , m_xNew(m_xBuilder->weld_button("new"))
+ , m_xEdit(m_xBuilder->weld_button("edit"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xPathBox(m_xBuilder->weld_tree_view("pathctrl"))
+ , m_xIter(m_xPathBox->make_iterator())
+{
+ Size aControlSize(m_xPathBox->get_approximate_digit_width() * 60,
+ m_xPathBox->get_height_rows(12));
+ m_xPathBox->set_size_request(aControlSize.Width(), aControlSize.Height());
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xPathBox->get_approximate_digit_width() * 20)
+ };
+ m_xPathBox->set_column_fixed_widths(aWidths);
+
+ m_xNew->connect_clicked( LINK( this, DbRegistrationOptionsPage, NewHdl ) );
+ m_xEdit->connect_clicked( LINK( this, DbRegistrationOptionsPage, EditHdl ) );
+ m_xDelete->connect_clicked( LINK( this, DbRegistrationOptionsPage, DeleteHdl ) );
+
+ m_xPathBox->connect_column_clicked(LINK(this, DbRegistrationOptionsPage, HeaderSelect_Impl));
+
+ m_xPathBox->make_sorted();
+ m_xPathBox->connect_row_activated( LINK( this, DbRegistrationOptionsPage, PathBoxDoubleClickHdl ) );
+ m_xPathBox->connect_changed( LINK( this, DbRegistrationOptionsPage, PathSelect_Impl ) );
+
+ m_xPathBox->set_help_id(HID_DBPATH_CTL_PATH);
+}
+
+DbRegistrationOptionsPage::~DbRegistrationOptionsPage()
+{
+ for (int i = 0, nCount = m_xPathBox->n_children(); i < nCount; ++i )
+ delete weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(i));
+}
+
+std::unique_ptr<SfxTabPage> DbRegistrationOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<DbRegistrationOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool DbRegistrationOptionsPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ // the settings for the single drivers
+ bool bModified = false;
+ DatabaseRegistrations aRegistrations;
+ int nCount = m_xPathBox->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ DatabaseRegistration* pRegistration = weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(i));
+ if ( pRegistration && !pRegistration->sLocation.isEmpty() )
+ {
+ OUString sName(m_xPathBox->get_text(i, 0));
+ OFileNotation aTransformer( pRegistration->sLocation );
+ aRegistrations[ sName ] = DatabaseRegistration( aTransformer.get( OFileNotation::N_URL ), pRegistration->bReadOnly );
+ }
+ }
+ if ( m_nOldCount != aRegistrations.size() || m_bModified )
+ {
+ rCoreSet->Put(DatabaseMapItem( SID_SB_DB_REGISTER, std::move(aRegistrations) ));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void DbRegistrationOptionsPage::Reset( const SfxItemSet* rSet )
+{
+ // the settings for the single drivers
+ const DatabaseMapItem* pRegistrations = rSet->GetItem<DatabaseMapItem>(SID_SB_DB_REGISTER);
+ if ( !pRegistrations )
+ return;
+
+ m_xPathBox->clear();
+
+ const DatabaseRegistrations& rRegistrations = pRegistrations->getRegistrations();
+ m_nOldCount = rRegistrations.size();
+ for (auto const& elem : rRegistrations)
+ {
+ OFileNotation aTransformer( elem.second.sLocation );
+ insertNewEntry( elem.first, aTransformer.get( OFileNotation::N_SYSTEM ), elem.second.bReadOnly );
+ }
+
+ OUString aUserData = GetUserData();
+ if ( aUserData.isEmpty() )
+ return;
+
+ sal_Int32 nIdx {0};
+ // restore column width
+ std::vector<int> aWidths
+ {
+ o3tl::toInt32(o3tl::getToken(aUserData, 0, ';', nIdx))
+ };
+ m_xPathBox->set_column_fixed_widths(aWidths);
+ // restore sort direction
+ bool bUp = o3tl::toInt32(o3tl::getToken(aUserData, 0, ';', nIdx)) != 0;
+ m_xPathBox->set_sort_order(bUp);
+ m_xPathBox->set_sort_indicator(bUp ? TRISTATE_TRUE : TRISTATE_FALSE, COL_TYPE);
+}
+
+void DbRegistrationOptionsPage::FillUserData()
+{
+ OUString aUserData = OUString::number( m_xPathBox->get_column_width(COL_TYPE) ) + ";";
+ bool bUp = m_xPathBox->get_sort_order();
+ aUserData += (bUp ? std::u16string_view(u"1") : std::u16string_view(u"0"));
+ SetUserData( aUserData );
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, DeleteHdl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry != -1)
+ {
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo, CuiResId(RID_CUISTR_QUERY_DELETE_CONFIRM)));
+ if (xQuery->run() == RET_YES)
+ m_xPathBox->remove(nEntry);
+ }
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, NewHdl, weld::Button&, void)
+{
+ openLinkDialog(OUString(),OUString());
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, PathBoxDoubleClickHdl, weld::TreeView&, bool)
+{
+ EditHdl(*m_xEdit);
+ return true;
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, EditHdl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ DatabaseRegistration* pOldRegistration = weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(nEntry));
+ if (!pOldRegistration || pOldRegistration->bReadOnly)
+ return;
+
+ OUString sOldName = m_xPathBox->get_text(nEntry, 0);
+ openLinkDialog(sOldName, pOldRegistration->sLocation, nEntry);
+}
+
+IMPL_LINK( DbRegistrationOptionsPage, HeaderSelect_Impl, int, nCol, void )
+{
+ if (nCol != COL_TYPE)
+ return;
+
+ bool bSortMode = m_xPathBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ bSortMode = !bSortMode;
+ m_xPathBox->set_sort_order(bSortMode);
+
+ //sort lists
+ m_xPathBox->set_sort_indicator(bSortMode ? TRISTATE_TRUE : TRISTATE_FALSE, nCol);
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, PathSelect_Impl, weld::TreeView&, void)
+{
+ DatabaseRegistration* pRegistration = weld::fromId<DatabaseRegistration*>(m_xPathBox->get_selected_id());
+
+ bool bReadOnly = true;
+ if (pRegistration)
+ {
+ bReadOnly = pRegistration->bReadOnly;
+ }
+
+ m_xEdit->set_sensitive( !bReadOnly );
+ m_xDelete->set_sensitive( !bReadOnly );
+}
+
+void DbRegistrationOptionsPage::insertNewEntry(const OUString& _sName,const OUString& _sLocation, const bool _bReadOnly)
+{
+ OUString sId(weld::toId(new DatabaseRegistration(_sLocation, _bReadOnly)));
+ m_xPathBox->insert(nullptr, -1, &_sName, &sId, nullptr, nullptr, false, m_xIter.get());
+
+ if (_bReadOnly)
+ m_xPathBox->set_image(*m_xIter, RID_SVXBMP_LOCK);
+
+ m_xPathBox->set_text(*m_xIter, _sLocation, 1);
+}
+
+void DbRegistrationOptionsPage::openLinkDialog(const OUString& sOldName, const OUString& sOldLocation, int nEntry)
+{
+ ODocumentLinkDialog aDlg(GetFrameWeld(), nEntry == -1);
+
+ aDlg.setLink(sOldName, sOldLocation);
+ aDlg.setNameValidator(LINK( this, DbRegistrationOptionsPage, NameValidator ) );
+
+ if (aDlg.run() != RET_OK)
+ return;
+
+ OUString sNewName,sNewLocation;
+ aDlg.getLink(sNewName,sNewLocation);
+ if ( nEntry == -1 || sNewName != sOldName || sNewLocation != sOldLocation )
+ {
+ if (nEntry != -1)
+ {
+ delete weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(nEntry));
+ m_xPathBox->remove(nEntry);
+ }
+ insertNewEntry( sNewName, sNewLocation, false );
+ m_bModified = true;
+ }
+}
+
+IMPL_LINK( DbRegistrationOptionsPage, NameValidator, const OUString&, _rName, bool )
+{
+ int nCount = m_xPathBox->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (m_xPathBox->get_text(i, 0) == _rName)
+ return false;
+ }
+ return true;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregisterednamesconfig.cxx b/cui/source/options/dbregisterednamesconfig.cxx
new file mode 100644
index 000000000..b33e9ded6
--- /dev/null
+++ b/cui/source/options/dbregisterednamesconfig.cxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbregisterednamesconfig.hxx"
+#include "dbregistersettings.hxx"
+#include <svx/databaseregistrationui.hxx>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <comphelper/processfactory.hxx>
+#include <svl/itemset.hxx>
+#include <tools/diagnose_ex.h>
+
+
+namespace svx
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::container;
+
+ void DbRegisteredNamesConfig::GetOptions( SfxItemSet& _rFillItems )
+ {
+ DatabaseRegistrations aSettings;
+
+ try
+ {
+ Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XDatabaseContext > xRegistrations(
+ DatabaseContext::create(xContext) );
+
+ Sequence< OUString > aRegistrationNames( xRegistrations->getRegistrationNames() );
+ const OUString* pRegistrationName = aRegistrationNames.getConstArray();
+ const OUString* pRegistrationNamesEnd = pRegistrationName + aRegistrationNames.getLength();
+ for ( ; pRegistrationName != pRegistrationNamesEnd; ++pRegistrationName )
+ {
+ OUString sLocation( xRegistrations->getDatabaseLocation( *pRegistrationName ) );
+ aSettings[ *pRegistrationName ] =
+ DatabaseRegistration( sLocation, xRegistrations->isDatabaseRegistrationReadOnly( *pRegistrationName ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.options");
+ }
+
+ _rFillItems.Put( DatabaseMapItem( SID_SB_DB_REGISTER, std::move(aSettings) ) );
+ }
+
+
+ void DbRegisteredNamesConfig::SetOptions(const SfxItemSet& _rSourceItems)
+ {
+ // the settings for the single drivers
+ const DatabaseMapItem* pRegistrations = _rSourceItems.GetItem<DatabaseMapItem>(SID_SB_DB_REGISTER);
+ if ( !pRegistrations )
+ return;
+
+ try
+ {
+ Reference< XDatabaseContext > xRegistrations(
+ DatabaseContext::create(
+ comphelper::getProcessComponentContext()));
+
+ const DatabaseRegistrations& rNewRegistrations = pRegistrations->getRegistrations();
+ for ( DatabaseRegistrations::const_iterator reg = rNewRegistrations.begin();
+ reg != rNewRegistrations.end();
+ ++reg
+ )
+ {
+ const OUString sName = reg->first;
+ const OUString sLocation = reg->second.sLocation;
+
+ if ( xRegistrations->hasRegisteredDatabase( sName ) )
+ {
+ if ( !xRegistrations->isDatabaseRegistrationReadOnly( sName ) )
+ xRegistrations->changeDatabaseLocation( sName, sLocation );
+ else
+ {
+ OSL_ENSURE( xRegistrations->getDatabaseLocation( sName ) == sLocation,
+ "DbRegisteredNamesConfig::SetOptions: somebody changed a read-only registration. How unrespectful." );
+ }
+ }
+ else
+ xRegistrations->registerDatabaseLocation( sName, sLocation );
+ }
+
+ // delete unused entries
+ Sequence< OUString > aRegistrationNames = xRegistrations->getRegistrationNames();
+ const OUString* pRegistrationName = aRegistrationNames.getConstArray();
+ const OUString* pRegistrationNamesEnd = pRegistrationName + aRegistrationNames.getLength();
+ for ( ; pRegistrationName != pRegistrationNamesEnd; ++pRegistrationName )
+ {
+ if ( rNewRegistrations.find( *pRegistrationName ) == rNewRegistrations.end() )
+ xRegistrations->revokeDatabaseLocation( *pRegistrationName );
+ }
+ }
+ catch( const Exception& )
+ {
+ //DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregisterednamesconfig.hxx b/cui/source/options/dbregisterednamesconfig.hxx
new file mode 100644
index 000000000..9decf7e11
--- /dev/null
+++ b/cui/source/options/dbregisterednamesconfig.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SfxItemSet;
+
+namespace svx
+{
+
+ class DbRegisteredNamesConfig
+ {
+
+ public:
+ static void GetOptions(SfxItemSet& _rFillItems);
+ static void SetOptions(const SfxItemSet& _rSourceItems);
+ };
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregistersettings.cxx b/cui/source/options/dbregistersettings.cxx
new file mode 100644
index 000000000..c544e1111
--- /dev/null
+++ b/cui/source/options/dbregistersettings.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbregistersettings.hxx"
+
+#include <rtl/ustring.hxx>
+
+
+namespace svx
+{
+
+ DatabaseMapItem::DatabaseMapItem( sal_uInt16 _nId, DatabaseRegistrations&& _rRegistrations )
+ :SfxPoolItem( _nId )
+ ,m_aRegistrations( std::move(_rRegistrations) )
+ {
+ }
+
+ bool DatabaseMapItem::operator==( const SfxPoolItem& _rCompare ) const
+ {
+ if (!SfxPoolItem::operator==(_rCompare))
+ return false;
+ const DatabaseMapItem* pItem = static_cast<const DatabaseMapItem*>( &_rCompare );
+ if ( !pItem )
+ return false;
+
+ if ( m_aRegistrations.size() != pItem->m_aRegistrations.size() )
+ return false;
+
+ return m_aRegistrations == pItem->m_aRegistrations;
+ }
+
+ DatabaseMapItem* DatabaseMapItem::Clone( SfxItemPool* ) const
+ {
+ return new DatabaseMapItem( *this );
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregistersettings.hxx b/cui/source/options/dbregistersettings.hxx
new file mode 100644
index 000000000..b1db16542
--- /dev/null
+++ b/cui/source/options/dbregistersettings.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <map>
+
+#include <svl/poolitem.hxx>
+#include <utility>
+
+
+namespace svx
+{
+
+
+ struct DatabaseRegistration
+ {
+ OUString sLocation;
+ bool bReadOnly;
+
+ DatabaseRegistration()
+ :sLocation()
+ ,bReadOnly( true )
+ {
+ }
+
+ DatabaseRegistration( OUString _aLocation, const bool _bReadOnly )
+ :sLocation(std::move( _aLocation ))
+ ,bReadOnly( _bReadOnly )
+ {
+ }
+
+ bool operator==( const DatabaseRegistration& _rhs ) const
+ {
+ return ( sLocation == _rhs.sLocation );
+ // do not take the read-only-ness into account, this is not maintained everywhere, but only
+ // properly set when filling the struct from the XDatabaseRegistrations data
+ }
+
+ };
+
+ typedef std::map< OUString, DatabaseRegistration > DatabaseRegistrations;
+
+ class DatabaseMapItem final : public SfxPoolItem
+ {
+ DatabaseRegistrations m_aRegistrations;
+
+ public:
+
+ DatabaseMapItem( sal_uInt16 _nId, DatabaseRegistrations&& _rRegistrations );
+
+ virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual DatabaseMapItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+
+ const DatabaseRegistrations&
+ getRegistrations() const { return m_aRegistrations; }
+ };
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/doclinkdialog.cxx b/cui/source/options/doclinkdialog.cxx
new file mode 100644
index 000000000..4218a18a1
--- /dev/null
+++ b/cui/source/options/doclinkdialog.cxx
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "doclinkdialog.hxx"
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <comphelper/processfactory.hxx>
+#include <strings.hrc>
+#include <svl/filenotation.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <ucbhelper/content.hxx>
+#include <dialmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docfilt.hxx>
+
+namespace svx
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::svt;
+
+ ODocumentLinkDialog::ODocumentLinkDialog(weld::Window* pParent, bool _bCreateNew)
+ : GenericDialogController(pParent, "cui/ui/databaselinkdialog.ui", "DatabaseLinkDialog")
+ , m_xBrowseFile(m_xBuilder->weld_button("browse"))
+ , m_xName(m_xBuilder->weld_entry("name"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
+ , m_xURL(new SvtURLBox(m_xBuilder->weld_combo_box("url")))
+ {
+ if (!_bCreateNew)
+ m_xDialog->set_title(m_xAltTitle->get_label());
+
+ m_xURL->SetSmartProtocol(INetProtocol::File);
+ m_xURL->DisableHistory();
+ m_xURL->SetFilter("*.odb");
+
+ m_xName->connect_changed( LINK(this, ODocumentLinkDialog, OnEntryModified) );
+ m_xURL->connect_changed( LINK(this, ODocumentLinkDialog, OnComboBoxModified) );
+ m_xBrowseFile->connect_clicked( LINK(this, ODocumentLinkDialog, OnBrowseFile) );
+ m_xOK->connect_clicked( LINK(this, ODocumentLinkDialog, OnOk) );
+
+ validate();
+ }
+
+ ODocumentLinkDialog::~ODocumentLinkDialog()
+ {
+ }
+
+ void ODocumentLinkDialog::setLink(const OUString& rName, const OUString& rURL)
+ {
+ m_xName->set_text(rName);
+ m_xURL->set_entry_text(rURL);
+ validate();
+ }
+
+ void ODocumentLinkDialog::getLink(OUString& rName, OUString& rURL) const
+ {
+ rName = m_xName->get_text();
+ rURL = m_xURL->get_active_text();
+ }
+
+ void ODocumentLinkDialog::validate( )
+ {
+ m_xOK->set_sensitive((!m_xName->get_text().isEmpty()) && (!m_xURL->get_active_text().isEmpty()));
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnOk, weld::Button&, void)
+ {
+ // get the current URL
+ OUString sURL = m_xURL->get_active_text();
+ OFileNotation aTransformer(sURL);
+ sURL = aTransformer.get(OFileNotation::N_URL);
+
+ // check for the existence of the selected file
+ bool bFileExists = false;
+ try
+ {
+ ::ucbhelper::Content aFile(sURL, Reference< XCommandEnvironment >(), comphelper::getProcessComponentContext());
+ if (aFile.isDocument())
+ bFileExists = true;
+ }
+ catch(Exception&)
+ {
+ }
+
+ if (!bFileExists)
+ {
+ OUString sMsg = CuiResId(STR_LINKEDDOC_DOESNOTEXIST);
+ sMsg = sMsg.replaceFirst("$file$", m_xURL->get_active_text());
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+ return;
+ } // if (!bFileExists)
+ INetURLObject aURL( sURL );
+ if ( aURL.GetProtocol() != INetProtocol::File )
+ {
+ OUString sMsg = CuiResId(STR_LINKEDDOC_NO_SYSTEM_FILE);
+ sMsg = sMsg.replaceFirst("$file$", m_xURL->get_active_text());
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+ return;
+ }
+
+ OUString sCurrentText = m_xName->get_text();
+ if ( m_aNameValidator.IsSet() )
+ {
+ if ( !m_aNameValidator.Call( sCurrentText ) )
+ {
+ OUString sMsg = CuiResId(STR_NAME_CONFLICT);
+ sMsg = sMsg.replaceFirst("$file$", sCurrentText);
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+
+ m_xName->select_region(0, -1);
+ m_xName->grab_focus();
+ return;
+ }
+ }
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnBrowseFile, weld::Button&, void)
+ {
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION, FileDialogFlags::NONE, m_xDialog.get());
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetFilterByName("StarOffice XML (Base)");
+ if ( pFilter )
+ {
+ aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
+ aFileDlg.SetCurrentFilter(pFilter->GetUIName());
+ }
+
+ OUString sPath = m_xURL->get_active_text();
+ if (!sPath.isEmpty())
+ {
+ OFileNotation aTransformer( sPath, OFileNotation::N_SYSTEM );
+ aFileDlg.SetDisplayDirectory( aTransformer.get( OFileNotation::N_URL ) );
+ }
+
+ if (ERRCODE_NONE != aFileDlg.Execute())
+ return;
+
+ if (m_xName->get_text().isEmpty())
+ { // default the name to the base of the chosen URL
+ INetURLObject aParser;
+
+ aParser.SetSmartProtocol(INetProtocol::File);
+ aParser.SetSmartURL(aFileDlg.GetPath());
+
+ m_xName->set_text(aParser.getBase(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset));
+
+ m_xName->select_region(0, -1);
+ m_xName->grab_focus();
+ }
+ else
+ m_xURL->grab_focus();
+
+ // get the path in system notation
+ OFileNotation aTransformer(aFileDlg.GetPath(), OFileNotation::N_URL);
+ m_xURL->set_entry_text(aTransformer.get(OFileNotation::N_SYSTEM));
+
+ validate();
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnEntryModified, weld::Entry&, void)
+ {
+ validate();
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnComboBoxModified, weld::ComboBox&, void)
+ {
+ validate();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/doclinkdialog.hxx b/cui/source/options/doclinkdialog.hxx
new file mode 100644
index 000000000..371dc6504
--- /dev/null
+++ b/cui/source/options/doclinkdialog.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <svtools/inettbc.hxx>
+
+namespace svx
+{
+ /** dialog for editing document links associated with data sources
+ */
+ class ODocumentLinkDialog final : public weld::GenericDialogController
+ {
+ Link<const OUString&,bool> m_aNameValidator;
+
+ std::unique_ptr<weld::Button> m_xBrowseFile;
+ std::unique_ptr<weld::Entry> m_xName;
+ std::unique_ptr<weld::Button> m_xOK;
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<SvtURLBox> m_xURL;
+
+ public:
+ ODocumentLinkDialog(weld::Window* pParent, bool bCreateNew);
+ virtual ~ODocumentLinkDialog() override;
+
+ // name validation has to be done by an external instance
+ // the validator link gets a pointer to a String, and should return 0 if the string is not
+ // acceptable
+ void setNameValidator( const Link<const OUString&,bool>& _rValidator ) { m_aNameValidator = _rValidator; }
+
+ void setLink( const OUString& _rName, const OUString& _rURL );
+ void getLink( OUString& _rName, OUString& _rURL ) const;
+
+ private:
+ DECL_LINK( OnEntryModified, weld::Entry&, void );
+ DECL_LINK( OnComboBoxModified, weld::ComboBox&, void );
+ DECL_LINK( OnBrowseFile, weld::Button&, void );
+ DECL_LINK( OnOk, weld::Button&, void );
+
+ void validate();
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/fontsubs.cxx b/cui/source/options/fontsubs.cxx
new file mode 100644
index 000000000..93c8b03d9
--- /dev/null
+++ b/cui/source/options/fontsubs.cxx
@@ -0,0 +1,405 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <officecfg/Office/Common.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/fontsubstconfig.hxx>
+#include "fontsubs.hxx"
+#include <helpids.h>
+
+/*********************************************************************/
+/* */
+/* TabPage font replacement */
+/* */
+/*********************************************************************/
+
+SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet)
+ , m_xUseTableCB(m_xBuilder->weld_check_button("usetable"))
+ , m_xFont1CB(m_xBuilder->weld_combo_box("font1"))
+ , m_xFont2CB(m_xBuilder->weld_combo_box("font2"))
+ , m_xApply(m_xBuilder->weld_button("apply"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklb"))
+ , m_xFontNameLB(m_xBuilder->weld_combo_box("fontname"))
+ , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button("nonpropfontonly"))
+ , m_xFontHeightLB(m_xBuilder->weld_combo_box("fontheight"))
+{
+ m_xFont1CB->make_sorted();
+ m_xFont1CB->set_size_request(1, -1);
+ m_xFont2CB->make_sorted();
+ m_xFont2CB->set_size_request(1, -1);
+ m_sAutomatic = m_xFontNameLB->get_text(0);
+ assert(!m_sAutomatic.isEmpty());
+
+ m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 60,
+ m_xCheckLB->get_height_rows(8));
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
+ m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
+
+ setColSizes(m_xCheckLB->get_size_request());
+ m_xCheckLB->connect_size_allocate(LINK(this, SvxFontSubstTabPage, ResizeHdl));
+
+ m_xCheckLB->set_centered_column(0);
+ m_xCheckLB->set_centered_column(1);
+
+ Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
+ Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
+
+ m_xCheckLB->connect_changed(LINK(this, SvxFontSubstTabPage, TreeListBoxSelectHdl));
+ m_xCheckLB->connect_column_clicked(LINK(this, SvxFontSubstTabPage, HeaderBarClick));
+ m_xUseTableCB->connect_toggled(LINK(this, SvxFontSubstTabPage, ToggleHdl));
+ m_xFont1CB->connect_changed(aLink2);
+ m_xFont2CB->connect_changed(aLink2);
+ m_xApply->connect_clicked(aClickLink);
+ m_xDelete->connect_clicked(aClickLink);
+
+ m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
+
+ sal_uInt16 nHeight;
+ for(nHeight = 6; nHeight <= 16; nHeight++)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 18; nHeight <= 28; nHeight+= 2)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 32; nHeight <= 48; nHeight+= 4)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 54; nHeight <= 72; nHeight+= 6)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 80; nHeight <= 96; nHeight+= 8)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+}
+
+IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = m_xCheckLB->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xCheckLB->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xCheckLB->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
+ m_xCheckLB->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+void SvxFontSubstTabPage::setColSizes(const Size& rSize)
+{
+ int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(2)).Width();
+ int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
+ int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
+ int nMin = m_xCheckLB->get_checkbox_column_width();
+ nMax = std::max(nMax, nMin);
+ const int nDoubleMax = 2*nMax;
+ const int nRest = rSize.Width() - nDoubleMax;
+ std::vector<int> aWidths { nMax, nMax, nRest/2 };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ResizeHdl, const Size&, rSize, void)
+{
+ setColSizes(rSize);
+}
+
+SvxFontSubstTabPage::~SvxFontSubstTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxFontSubstTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* )
+{
+ std::vector<SubstitutionStruct> aNewFontSubs;
+
+ m_xCheckLB->all_foreach([this, &aNewFontSubs](weld::TreeIter& rIter) {
+ SubstitutionStruct aAdd;
+ aAdd.sFont = m_xCheckLB->get_text(rIter, 2);
+ aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 3);
+ aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 0);
+ aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 1);
+ aNewFontSubs.push_back(aAdd);
+ return false;
+ });
+
+ svtools::SetFontSubstitutions(m_xUseTableCB->get_active(), aNewFontSubs);
+ svtools::ApplyFontSubstitutionsToVcl();
+
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ if (m_xFontHeightLB->get_value_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
+ static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
+ batch);
+ if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::set(
+ m_xNonPropFontsOnlyCB->get_active(), batch);
+ //font name changes cannot be detected by saved values
+ OUString sFontName;
+ if (m_xFontNameLB->get_active() != -1)
+ sFontName = m_xFontNameLB->get_active_text();
+ officecfg::Office::Common::Font::SourceViewFont::FontName::set(
+ std::optional< OUString >(sFontName), batch);
+ batch->commit();
+
+ return false;
+}
+
+void SvxFontSubstTabPage::Reset( const SfxItemSet* )
+{
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ m_xFont1CB->freeze();
+ m_xFont1CB->clear();
+ m_xFont2CB->freeze();
+ m_xFont2CB->clear();
+
+ FontList aFntLst(Application::GetDefaultDevice());
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName(i);
+ m_xFont1CB->append_text(rFontMetric.GetFamilyName());
+ m_xFont2CB->append_text(rFontMetric.GetFamilyName());
+ }
+
+ m_xFont2CB->thaw();
+ m_xFont1CB->thaw();
+
+ m_xUseTableCB->set_active(svtools::IsFontSubstitutionsEnabled());
+
+ std::vector<SubstitutionStruct> aFontSubs = svtools::GetFontSubstitutions();
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ for (auto const & sub: aFontSubs)
+ {
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, sub.bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xCheckLB->set_toggle(*xIter, sub.bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(*xIter, sub.sFont, 2);
+ m_xCheckLB->set_text(*xIter, sub.sReplaceBy, 3);
+ }
+
+ m_xCheckLB->thaw();
+
+ m_xCheckLB->make_sorted();
+ m_xCheckLB->set_sort_column(2);
+ m_xCheckLB->set_sort_indicator(TRISTATE_TRUE, 2);
+
+ SelectHdl(m_xFont1CB.get());
+
+ //fill font name box first
+ m_xNonPropFontsOnlyCB->set_active(
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::get());
+ NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
+ OUString sFontName(
+ officecfg::Office::Common::Font::SourceViewFont::FontName::get().
+ value_or(OUString()));
+ if(!sFontName.isEmpty())
+ m_xFontNameLB->set_active_text(sFontName);
+ else
+ m_xFontNameLB->set_active(0);
+ m_xFontHeightLB->set_active_text(
+ OUString::number(
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::
+ get()));
+ m_xNonPropFontsOnlyCB->save_state();
+ m_xFontHeightLB->save_value();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
+{
+ SelectHdl(&rBox);
+}
+
+namespace
+{
+ // search in the "font" column
+ int findText(const weld::TreeView& rTreeView, std::u16string_view rCol)
+ {
+ for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
+ {
+ if (rTreeView.get_text(i, 2) == rCol)
+ return i;
+ }
+ return -1;
+ }
+
+ bool findRow(const weld::TreeView& rTreeView, std::u16string_view rCol1, std::u16string_view rCol2)
+ {
+ int nRow = findText(rTreeView, rCol1);
+ if (nRow == -1)
+ return false;
+ return rTreeView.get_text(nRow, 3) == rCol2;
+ }
+}
+
+void SvxFontSubstTabPage::SelectHdl(const weld::Widget* pWin)
+{
+ if (pWin == m_xApply.get() || pWin == m_xDelete.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+ if (pWin == m_xApply.get())
+ {
+ m_xCheckLB->unselect_all();
+ if (nPos != -1)
+ {
+ // change entry
+ m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 3);
+ m_xCheckLB->select(nPos);
+ }
+ else
+ {
+ // new entry
+ OUString sFont1 = m_xFont1CB->get_active_text();
+ OUString sFont2 = m_xFont2CB->get_active_text();
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 0);
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(*xIter, sFont1, 2);
+ m_xCheckLB->set_text(*xIter, sFont2, 3);
+ m_xCheckLB->select(*xIter);
+ }
+ }
+ else if (pWin == m_xDelete.get())
+ {
+ m_xCheckLB->remove_selection();
+ }
+ }
+
+ if (pWin == m_xCheckLB.get())
+ {
+ const int nSelectedRowCount = m_xCheckLB->count_selected_rows();
+ if (nSelectedRowCount == 1)
+ {
+ int nRow = m_xCheckLB->get_selected_index();
+ m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 2));
+ m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
+ }
+ else if (nSelectedRowCount > 1)
+ {
+ m_xFont1CB->set_entry_text(OUString());
+ m_xFont2CB->set_entry_text(OUString());
+ }
+ }
+
+ if (pWin == m_xFont1CB.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+
+ if (nPos != -1)
+ {
+ int nSelectedRow = m_xCheckLB->get_selected_index();
+ if (nPos != nSelectedRow)
+ {
+ m_xCheckLB->unselect_all();
+ m_xCheckLB->select(nPos);
+ }
+ }
+ else
+ m_xCheckLB->unselect_all();
+ }
+
+ CheckEnable();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::Toggleable&, rBox, void)
+{
+ OUString sFontName = m_xFontNameLB->get_active_text();
+ bool bNonPropOnly = rBox.get_active();
+ m_xFontNameLB->clear();
+ FontList aFntLst( Application::GetDefaultDevice() );
+ m_xFontNameLB->append_text(m_sAutomatic);
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
+ if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
+ m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
+ }
+ m_xFontNameLB->set_active_text(sFontName);
+}
+
+void SvxFontSubstTabPage::CheckEnable()
+{
+ bool bEnableAll = m_xUseTableCB->get_active();
+ m_xCheckLB->set_sensitive(bEnableAll);
+ m_xFont1CB->set_sensitive(bEnableAll);
+ m_xFont2CB->set_sensitive(bEnableAll);
+
+ bool bApply = bEnableAll, bDelete = bEnableAll;
+
+ if (bEnableAll)
+ {
+ int nEntry = m_xCheckLB->get_selected_index();
+
+ if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
+ bApply = false;
+ else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
+ bApply = false;
+ else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
+ bApply = false;
+ else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
+ bApply = false;
+ else
+ bApply = true;
+
+ bDelete = nEntry != -1;
+ }
+
+ m_xApply->set_sensitive(bApply);
+ m_xDelete->set_sensitive(bDelete);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/fontsubs.hxx b/cui/source/options/fontsubs.hxx
new file mode 100644
index 000000000..dc55d9434
--- /dev/null
+++ b/cui/source/options/fontsubs.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+// class SvxFontSubstTabPage ----------------------------------------------------
+class SvtFontSubstConfig;
+class SvxFontSubstTabPage : public SfxTabPage
+{
+ OUString m_sAutomatic;
+
+ std::unique_ptr<weld::CheckButton> m_xUseTableCB;
+ std::unique_ptr<weld::ComboBox> m_xFont1CB;
+ std::unique_ptr<weld::ComboBox> m_xFont2CB;
+ std::unique_ptr<weld::Button> m_xApply;
+ std::unique_ptr<weld::Button> m_xDelete;
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::ComboBox> m_xFontNameLB;
+ std::unique_ptr<weld::CheckButton> m_xNonPropFontsOnlyCB;
+ std::unique_ptr<weld::ComboBox> m_xFontHeightLB;
+
+ DECL_LINK(SelectComboBoxHdl, weld::ComboBox&, void);
+ DECL_LINK(ToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(ClickHdl, weld::Button&, void);
+ DECL_LINK(TreeListBoxSelectHdl, weld::TreeView&, void);
+ DECL_LINK(NonPropFontsHdl, weld::Toggleable&, void);
+ DECL_LINK(HeaderBarClick, int, void);
+ DECL_LINK(ResizeHdl, const Size&, void);
+
+ void SelectHdl(const weld::Widget* pWidget);
+
+ void CheckEnable();
+ void setColSizes(const Size& rSize);
+
+public:
+ SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ virtual ~SvxFontSubstTabPage() override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaboutconfig.cxx b/cui/source/options/optaboutconfig.cxx
new file mode 100644
index 000000000..c4dafaf5c
--- /dev/null
+++ b/cui/source/options/optaboutconfig.cxx
@@ -0,0 +1,965 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include "optaboutconfig.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <cppu/unotype.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/textsearch.hxx>
+#include <utility>
+#include <vcl/event.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+
+#define SHORT_LEN_LIMIT 7
+#define LONG_LEN_LIMIT 11
+#define HYPER_LEN_LIMIT 20
+
+struct Prop_Impl
+{
+ OUString Name;
+ OUString Property;
+ Any Value;
+
+ Prop_Impl( OUString sName, OUString sProperty, Any aValue )
+ : Name(std::move( sName ))
+ , Property(std::move( sProperty ))
+ , Value(std::move( aValue ))
+ {}
+};
+
+struct UserData
+{
+ bool bIsPropertyPath;
+ OUString sPropertyPath;
+ int aLineage;
+ Reference<XNameAccess> aXNameAccess;
+
+ explicit UserData( OUString aPropertyPath )
+ : bIsPropertyPath( true )
+ , sPropertyPath(std::move(aPropertyPath))
+ , aLineage(0)
+ {}
+
+ explicit UserData( Reference<XNameAccess> const & rXNameAccess, int rIndex )
+ : bIsPropertyPath( false )
+ , aLineage(rIndex)
+ , aXNameAccess( rXNameAccess )
+ {}
+};
+
+IMPL_LINK(CuiAboutConfigValueDialog, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ bool bValid = false;
+ bool bNonSpace = rKeyEvent.GetKeyCode().GetCode() != KEY_SPACE;
+ if (m_bNumericOnly && bNonSpace )
+ {
+ const vcl::KeyCode& rKeyCode = rKeyEvent.GetKeyCode();
+ sal_uInt16 nGroup = rKeyCode.GetGroup();
+ sal_uInt16 nKey = rKeyCode.GetCode();
+
+ switch ( nGroup ) {
+ case KEYGROUP_NUM :
+ case KEYGROUP_CURSOR :
+ {
+ bValid = true;
+ break;
+ }
+
+ case KEYGROUP_MISC :
+ {
+ switch ( nKey ) {
+ case KEY_SUBTRACT :
+ case KEY_COMMA :
+ case KEY_POINT :
+ {
+ bValid = true;
+ break;
+ }
+
+ default :
+ {
+ if( nKey < KEY_ADD || nKey > KEY_EQUAL )
+ bValid = true;
+ break;
+ }
+ }
+ break;
+ }
+
+ default :
+ {
+ bValid = false;
+ break;
+ }
+ }
+
+ //Select all, Copy, Paste, Cut, Undo Keys
+ if ( !bValid && ( rKeyCode.IsMod1() && (
+ KEY_A == nKey || KEY_C == nKey || KEY_V == nKey || KEY_X == nKey || KEY_Z == nKey ) ) )
+ bValid = true;
+ }
+ else
+ bValid = true;
+
+ //if value return true to claim that it has been handled
+ return !bValid;
+}
+
+CuiAboutConfigTabPage::CuiAboutConfigTabPage(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/aboutconfigdialog.ui", "AboutConfig")
+ , m_xResetBtn(m_xBuilder->weld_button("reset"))
+ , m_xEditBtn(m_xBuilder->weld_button("edit"))
+ , m_xSearchBtn(m_xBuilder->weld_button("searchButton"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xPrefBox(m_xBuilder->weld_tree_view("preferences"))
+ , m_xScratchIter(m_xPrefBox->make_iterator())
+ , m_bSorted(false)
+{
+ m_xPrefBox->set_size_request(m_xPrefBox->get_approximate_digit_width() * 100,
+ m_xPrefBox->get_height_rows(23));
+ m_xPrefBox->connect_column_clicked(LINK(this, CuiAboutConfigTabPage, HeaderBarClick));
+
+ m_xEditBtn->connect_clicked(LINK( this, CuiAboutConfigTabPage, StandardHdl_Impl));
+ m_xResetBtn->connect_clicked(LINK( this, CuiAboutConfigTabPage, ResetBtnHdl_Impl));
+ m_xPrefBox->connect_row_activated(LINK(this, CuiAboutConfigTabPage, DoubleClickHdl_Impl));
+ m_xPrefBox->connect_expanding(LINK(this, CuiAboutConfigTabPage, ExpandingHdl_Impl));
+ m_xSearchBtn->connect_clicked(LINK(this, CuiAboutConfigTabPage, SearchHdl_Impl));
+
+ m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+ m_options.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_options.searchFlag |= (util::SearchFlags::REG_NOT_BEGINOFLINE |
+ util::SearchFlags::REG_NOT_ENDOFLINE);
+
+ float fWidth = m_xPrefBox->get_approximate_digit_width();
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(fWidth * 65),
+ o3tl::narrowing<int>(fWidth * 20),
+ o3tl::narrowing<int>(fWidth * 8)
+ };
+ m_xPrefBox->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(CuiAboutConfigTabPage, HeaderBarClick, int, nColumn, void)
+{
+ if (!m_bSorted)
+ {
+ m_xPrefBox->make_sorted();
+ m_bSorted = true;
+ }
+
+ bool bSortAtoZ = m_xPrefBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xPrefBox->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xPrefBox->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ int nOldSortColumn = m_xPrefBox->get_sort_column();
+ if (nOldSortColumn != -1)
+ m_xPrefBox->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
+ m_xPrefBox->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xPrefBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+CuiAboutConfigTabPage::~CuiAboutConfigTabPage()
+{
+}
+
+void CuiAboutConfigTabPage::InsertEntry(const OUString& rPropertyPath, const OUString& rProp, const OUString& rStatus,
+ const OUString& rType, const OUString& rValue, const weld::TreeIter* pParentEntry,
+ bool bInsertToPrefBox)
+{
+ m_vectorUserData.push_back(std::make_unique<UserData>(rPropertyPath));
+ if (bInsertToPrefBox)
+ {
+ OUString sId(weld::toId(m_vectorUserData.back().get()));
+ m_xPrefBox->insert(pParentEntry, -1, &rProp, &sId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rValue, 3);
+ }
+ else
+ {
+ m_prefBoxEntries.push_back({rProp, rStatus, rType, rValue, m_vectorUserData.back().get()});
+ }
+}
+
+void CuiAboutConfigTabPage::Reset()
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xPrefBox->clear();
+ m_vectorOfModified.clear();
+ if (m_bSorted)
+ {
+ m_xPrefBox->set_sort_indicator(TRISTATE_INDET, m_xPrefBox->get_sort_column());
+ m_xPrefBox->make_unsorted();
+ m_bSorted = false;
+ }
+ m_prefBoxEntries.clear();
+ m_modifiedPrefBoxEntries.clear();
+
+ m_xPrefBox->freeze();
+ Reference< XNameAccess > xConfigAccess = getConfigAccess( "/", false );
+ //Load all XNameAccess to m_prefBoxEntries
+ FillItems( xConfigAccess, nullptr, 0, true );
+ //Load xConfigAccess' children to m_prefBox
+ FillItems( xConfigAccess );
+ m_xPrefBox->thaw();
+}
+
+void CuiAboutConfigTabPage::FillItemSet()
+{
+ std::vector< std::shared_ptr< Prop_Impl > >::iterator pIter;
+ for( pIter = m_vectorOfModified.begin() ; pIter != m_vectorOfModified.end(); ++pIter )
+ {
+ Reference< XNameAccess > xUpdateAccess = getConfigAccess( (*pIter)->Name , true );
+ Reference< XNameReplace > xNameReplace( xUpdateAccess, UNO_QUERY_THROW );
+
+ xNameReplace->replaceByName( (*pIter)->Property, (*pIter)->Value );
+
+ Reference< util::XChangesBatch > xChangesBatch( xUpdateAccess, UNO_QUERY_THROW );
+ xChangesBatch->commitChanges();
+ }
+}
+
+void CuiAboutConfigTabPage::FillItems(const Reference< XNameAccess >& xNameAccess, const weld::TreeIter* pParentEntry,
+ int lineage, bool bLoadAll)
+{
+ OUString sPath = Reference< XHierarchicalName >(
+ xNameAccess, uno::UNO_QUERY_THROW )->getHierarchicalName();
+ const uno::Sequence< OUString > seqItems = xNameAccess->getElementNames();
+ for( const OUString& item : seqItems )
+ {
+ Any aNode = xNameAccess->getByName( item );
+
+ bool bNotLeaf = false;
+
+ Reference< XNameAccess > xNextNameAccess;
+ try
+ {
+ xNextNameAccess.set(aNode, uno::UNO_QUERY);
+ bNotLeaf = xNextNameAccess.is();
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "CuiAboutConfigTabPage");
+ }
+
+ if (bNotLeaf)
+ {
+ if(bLoadAll)
+ FillItems(xNextNameAccess, nullptr, lineage + 1, true);
+ else
+ {
+ // not leaf node
+ m_vectorUserData.push_back(std::make_unique<UserData>(xNextNameAccess, lineage + 1));
+ OUString sId(weld::toId(m_vectorUserData.back().get()));
+
+ m_xPrefBox->insert(pParentEntry, -1, &item, &sId, nullptr, nullptr, true, m_xScratchIter.get());
+ // Necessary, without this the selection line will be truncated.
+ m_xPrefBox->set_text(*m_xScratchIter, "", 1);
+ m_xPrefBox->set_text(*m_xScratchIter, "", 2);
+ m_xPrefBox->set_text(*m_xScratchIter, "", 3);
+ }
+ }
+ else
+ {
+ // leaf node
+ OUString sPropertyName = item;
+ auto it = std::find_if(m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
+ [&sPath, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == sPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+
+ OUString sType = aNode.getValueTypeName();
+ OUStringBuffer sValue;
+
+ if (it != m_modifiedPrefBoxEntries.end())
+ sValue = it->sValue;
+ else
+ {
+ switch( aNode.getValueType().getTypeClass() )
+ {
+ case css::uno::TypeClass_VOID:
+ break;
+
+ case css::uno::TypeClass_BOOLEAN:
+ sValue = OUString::boolean( aNode.get<bool>() );
+ break;
+
+ case css::uno::TypeClass_SHORT:
+ case css::uno::TypeClass_LONG:
+ case css::uno::TypeClass_HYPER:
+ sValue = OUString::number( aNode.get<sal_Int64>() );
+ break;
+
+ case css::uno::TypeClass_DOUBLE:
+ sValue = OUString::number( aNode.get<double>() );
+ break;
+
+ case css::uno::TypeClass_STRING:
+ sValue = aNode.get<OUString>();
+ break;
+
+ case css::uno::TypeClass_SEQUENCE:
+ if( sType == "[]boolean" )
+ {
+ uno::Sequence<sal_Bool> seq = aNode.get< uno::Sequence<sal_Bool> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::boolean( seq[j] ));
+ }
+ }
+ else if( sType == "[]byte" )
+ {
+ const uno::Sequence<sal_Int8> seq = aNode.get< uno::Sequence<sal_Int8> >();
+ for( sal_Int8 j : seq )
+ {
+ OUString s = OUString::number(
+ static_cast<sal_uInt8>(j), 16 );
+ if( s.getLength() == 1 )
+ {
+ sValue.append("0");
+ }
+ sValue.append(s.toAsciiUpperCase());
+ }
+ }
+ else if( sType == "[][]byte" )
+ {
+ const uno::Sequence< uno::Sequence<sal_Int8> > seq = aNode.get< uno::Sequence< uno::Sequence<sal_Int8> > >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ for( sal_Int8 k : seq[j] )
+ {
+ OUString s = OUString::number(
+ static_cast<sal_uInt8>(k), 16 );
+ if( s.getLength() == 1 )
+ {
+ sValue.append("0");
+ }
+ sValue.append(s.toAsciiUpperCase());
+ }
+ }
+ }
+ else if( sType == "[]short" )
+ {
+ uno::Sequence<sal_Int16> seq = aNode.get< uno::Sequence<sal_Int16> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( static_cast<sal_Int32>(seq[j]) );
+ }
+ }
+ else if( sType == "[]long" )
+ {
+ uno::Sequence<sal_Int32> seq = aNode.get< uno::Sequence<sal_Int32> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( seq[j] );
+ }
+ }
+ else if( sType == "[]hyper" )
+ {
+ uno::Sequence<sal_Int64> seq = aNode.get< uno::Sequence<sal_Int64> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( seq[j] );
+ }
+ }
+ else if( sType == "[]double" )
+ {
+ uno::Sequence<double> seq = aNode.get< uno::Sequence<double> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( seq[j] );
+ }
+ }
+ else if( sType == "[]string" )
+ {
+ uno::Sequence<OUString> seq = aNode.get< uno::Sequence<OUString> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(seq[j]);
+ }
+ }
+ else
+ {
+ SAL_WARN(
+ "cui.options",
+ "path \"" << sPath << "\" member " << item
+ << " of unsupported type " << sType);
+ }
+ break;
+
+ default:
+ SAL_WARN(
+ "cui.options",
+ "path \"" << sPath << "\" member " << item
+ << " of unsupported type " << sType);
+ break;
+ }
+ }
+
+ //Short name
+ int index = 0;
+ for(int j = 1; j < lineage; ++j)
+ index = sPath.indexOf("/", index + 1);
+
+ InsertEntry(sPath, sPath.copy(index+1), item, sType, sValue.makeStringAndClear(), pParentEntry, !bLoadAll);
+ }
+ }
+}
+
+Reference< XNameAccess > CuiAboutConfigTabPage::getConfigAccess( const OUString& sNodePath, bool bUpdate )
+{
+ uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ css::configuration::theDefaultProvider::get( xContext ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= sNodePath;
+
+ uno::Sequence< uno::Any > aArgumentList{ uno::Any(aProperty) };
+
+ OUString sAccessString;
+
+ if( bUpdate )
+ sAccessString = "com.sun.star.configuration.ConfigurationUpdateAccess";
+ else
+ sAccessString = "com.sun.star.configuration.ConfigurationAccess";
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ sAccessString, aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ return xNameAccess;
+}
+
+void CuiAboutConfigTabPage::AddToModifiedVector( const std::shared_ptr< Prop_Impl >& rProp )
+{
+ bool isModifiedBefore = false;
+ //Check if value modified before
+ for(std::shared_ptr<Prop_Impl> & nInd : m_vectorOfModified)
+ {
+ if( rProp->Name == nInd->Name && rProp->Property == nInd->Property )
+ {
+ //property modified before. Assign reference to the modified value
+ //do your changes on this object. They will be saved later.
+ nInd = rProp;
+ isModifiedBefore = true;
+ break;
+ }
+ }
+
+ if( !isModifiedBefore )
+ m_vectorOfModified.push_back( rProp );
+ //property is not modified before
+}
+
+std::vector< OUString > CuiAboutConfigTabPage::commaStringToSequence( std::u16string_view rCommaSepString )
+{
+ std::vector<OUString> tempVector;
+
+ sal_Int32 index = 0;
+ do
+ {
+ OUString word( o3tl::getToken(rCommaSepString, 0, u',', index) );
+ word = word.trim();
+ if( !word.isEmpty())
+ tempVector.push_back(word);
+ }while( index >= 0 );
+ return tempVector;
+}
+
+CuiAboutConfigValueDialog::CuiAboutConfigValueDialog(weld::Window* pWindow,
+ const OUString& rValue,
+ int limit)
+ : GenericDialogController(pWindow, "cui/ui/aboutconfigvaluedialog.ui", "AboutConfigValueDialog")
+ , m_bNumericOnly(limit != 0)
+ , m_xEDValue(m_xBuilder->weld_entry("valuebox"))
+{
+ if (limit)
+ m_xEDValue->set_max_length(limit);
+ m_xEDValue->set_text(rValue);
+ m_xEDValue->connect_key_press(LINK(this, CuiAboutConfigValueDialog, KeyInputHdl));
+}
+
+CuiAboutConfigValueDialog::~CuiAboutConfigValueDialog()
+{
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, ResetBtnHdl_Impl, weld::Button&, void )
+{
+ Reset();
+}
+
+IMPL_LINK_NOARG(CuiAboutConfigTabPage, DoubleClickHdl_Impl, weld::TreeView&, bool)
+{
+ StandardHdl_Impl(*m_xEditBtn);
+ return true;
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, StandardHdl_Impl, weld::Button&, void )
+{
+ if (!m_xPrefBox->get_selected(m_xScratchIter.get()))
+ return;
+
+ UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(*m_xScratchIter));
+ if (!(pUserData && pUserData->bIsPropertyPath))
+ return;
+
+ //if selection is a node
+ OUString sPropertyName = m_xPrefBox->get_text(*m_xScratchIter, 1);
+ OUString sPropertyType = m_xPrefBox->get_text(*m_xScratchIter, 2);
+ OUString sPropertyValue = m_xPrefBox->get_text(*m_xScratchIter, 3);
+
+ // If the configuration property has a nil value, determine its static type:
+ if (sPropertyType == "void")
+ {
+ css::uno::Reference<css::beans::XPropertySetInfo> info(
+ CuiAboutConfigTabPage::getConfigAccess(pUserData->sPropertyPath, false),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Type t;
+ try {
+ t = info->getPropertyByName(sPropertyName).Type;
+ } catch (css::beans::UnknownPropertyException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", pUserData->sPropertyPath << " " << sPropertyName);
+ }
+ // If the configuration property is of type any (or an UnknownPropertyException was caught
+ // above), stick to "void" for now (ideally, properties of type any would allow setting
+ // values of arbitrary type, regardless of their current value, in this dialog anyway):
+ if (t != cppu::UnoType<void>::get()) {
+ sPropertyType = t.getTypeName();
+ switch (t.getTypeClass()) {
+ case css::uno::TypeClass_BOOLEAN:
+ sPropertyValue = "false";
+ break;
+ case css::uno::TypeClass_SHORT:
+ case css::uno::TypeClass_LONG:
+ case css::uno::TypeClass_HYPER:
+ case css::uno::TypeClass_DOUBLE:
+ sPropertyValue = "0";
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ auto pProperty = std::make_shared<Prop_Impl>( pUserData->sPropertyPath, sPropertyName, Any( sPropertyValue ) );
+ bool bSaveChanges = false;
+
+ bool bOpenDialog = true;
+ OUString sDialogValue;
+
+ if( sPropertyType == "boolean" )
+ {
+ bool bValue;
+ if( sPropertyValue == "true" )
+ {
+ sDialogValue = "false";
+ bValue = false;
+ }
+ else
+ {
+ sDialogValue = "true";
+ bValue = true;
+ }
+
+ pProperty->Value <<= bValue;
+ bOpenDialog = false;
+ bSaveChanges = true;
+ }
+ else if ( sPropertyType == "void" )
+ {
+ bOpenDialog = false;
+ }
+ else
+ {
+ sDialogValue = sPropertyValue;
+ bOpenDialog = true;
+ }
+
+ try
+ {
+ if( bOpenDialog )
+ {
+ //Cosmetic length limit for integer values.
+ int limit=0;
+ if( sPropertyType == "short" )
+ limit = SHORT_LEN_LIMIT;
+ else if( sPropertyType == "long" )
+ limit = LONG_LEN_LIMIT;
+ else if( sPropertyType == "hyper" )
+ limit = HYPER_LEN_LIMIT;
+
+ CuiAboutConfigValueDialog aValueDialog(m_xDialog.get(), sDialogValue, limit);
+
+ if (aValueDialog.run() == RET_OK )
+ {
+ OUString sNewValue = aValueDialog.getValue();
+ bSaveChanges = true;
+ if ( sPropertyType == "short")
+ {
+ sal_Int16 nShort;
+ sal_Int32 nNumb = sNewValue.toInt32();
+
+ //if the value is 0 and length is not 1, there is something wrong
+ if( ( nNumb==0 && sNewValue.getLength()!=1 ) || nNumb > SAL_MAX_INT16 || nNumb < SAL_MIN_INT16)
+ throw uno::Exception("out of range short", nullptr);
+ nShort = static_cast<sal_Int16>(nNumb);
+ pProperty->Value <<= nShort;
+ }
+ else if( sPropertyType == "long" )
+ {
+ sal_Int32 nLong = sNewValue.toInt32();
+ if( nLong==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range long", nullptr);
+ pProperty->Value <<= nLong;
+ }
+ else if( sPropertyType == "hyper")
+ {
+ sal_Int64 nHyper = sNewValue.toInt64();
+ if( nHyper==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range hyper", nullptr);
+ pProperty->Value <<= nHyper;
+ }
+ else if( sPropertyType == "double")
+ {
+ double nDoub = sNewValue.toDouble();
+ if( nDoub ==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range double", nullptr);
+ pProperty->Value <<= nDoub;
+ }
+ else if( sPropertyType == "float")
+ {
+ float nFloat = sNewValue.toFloat();
+ if( nFloat ==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range float", nullptr);
+ pProperty->Value <<= nFloat;
+ }
+ else if( sPropertyType == "string" )
+ {
+ pProperty->Value <<= sNewValue;
+ }
+ else if( sPropertyType == "[]short" )
+ {
+ //create string sequence from comma separated string
+ //uno::Sequence< OUString > seqStr;
+ std::vector< OUString > seqStr = commaStringToSequence( sNewValue );
+
+ //create appropriate sequence with same size as string sequence
+ uno::Sequence< sal_Int16 > seqShort( seqStr.size() );
+ //convert all strings to appropriate type
+ std::transform(seqStr.begin(), seqStr.end(), seqShort.getArray(),
+ [](const auto& str)
+ { return static_cast<sal_Int16>(str.toInt32()); });
+ pProperty->Value <<= seqShort;
+ }
+ else if( sPropertyType == "[]long" )
+ {
+ std::vector< OUString > seqStrLong = commaStringToSequence( sNewValue );
+
+ uno::Sequence< sal_Int32 > seqLong( seqStrLong.size() );
+ std::transform(seqStrLong.begin(), seqStrLong.end(), seqLong.getArray(),
+ [](const auto& str) { return str.toInt32(); });
+ pProperty->Value <<= seqLong;
+ }
+ else if( sPropertyType == "[]hyper" )
+ {
+ std::vector< OUString > seqStrHyper = commaStringToSequence( sNewValue );
+ uno::Sequence< sal_Int64 > seqHyper( seqStrHyper.size() );
+ std::transform(seqStrHyper.begin(), seqStrHyper.end(), seqHyper.getArray(),
+ [](const auto& str) { return str.toInt64(); });
+ pProperty->Value <<= seqHyper;
+ }
+ else if( sPropertyType == "[]double" )
+ {
+ std::vector< OUString > seqStrDoub = commaStringToSequence( sNewValue );
+ uno::Sequence< double > seqDoub( seqStrDoub.size() );
+ std::transform(seqStrDoub.begin(), seqStrDoub.end(), seqDoub.getArray(),
+ [](const auto& str) { return str.toDouble(); });
+ pProperty->Value <<= seqDoub;
+ }
+ else if( sPropertyType == "[]float" )
+ {
+ std::vector< OUString > seqStrFloat = commaStringToSequence( sNewValue );
+ uno::Sequence< sal_Int16 > seqFloat( seqStrFloat.size() );
+ std::transform(seqStrFloat.begin(), seqStrFloat.end(), seqFloat.getArray(),
+ [](const auto& str) { return str.toFloat(); });
+ pProperty->Value <<= seqFloat;
+ }
+ else if( sPropertyType == "[]string" )
+ {
+ pProperty->Value <<= comphelper::containerToSequence( commaStringToSequence( sNewValue ));
+ }
+ else //unknown
+ throw uno::Exception("unknown property type " + sPropertyType, nullptr);
+
+ sDialogValue = sNewValue;
+ }
+ }
+
+ if(bSaveChanges)
+ {
+ AddToModifiedVector( pProperty );
+
+ //update listbox value.
+ m_xPrefBox->set_text(*m_xScratchIter, sPropertyType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, sDialogValue, 3);
+ //update m_prefBoxEntries
+ auto it = std::find_if(m_prefBoxEntries.begin(), m_prefBoxEntries.end(),
+ [&pUserData, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+ if (it != m_prefBoxEntries.end())
+ {
+ it->sValue = sDialogValue;
+
+ auto modifiedIt = std::find_if(
+ m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
+ [&pUserData, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+
+ if (modifiedIt != m_modifiedPrefBoxEntries.end())
+ {
+ modifiedIt->sValue = sDialogValue;
+ }
+ else
+ {
+ m_modifiedPrefBoxEntries.push_back(*it);
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, SearchHdl_Impl, weld::Button&, void)
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xPrefBox->hide();
+ m_xPrefBox->clear();
+ m_xPrefBox->freeze();
+
+ if (m_bSorted)
+ m_xPrefBox->make_unsorted();
+
+ if (m_xSearchEdit->get_text().isEmpty())
+ {
+ m_xPrefBox->clear();
+ Reference< XNameAccess > xConfigAccess = getConfigAccess( "/", false );
+ FillItems( xConfigAccess );
+ }
+ else
+ {
+ m_options.searchString = m_xSearchEdit->get_text();
+ utl::TextSearch textSearch( m_options );
+ for (auto const& it : m_prefBoxEntries)
+ {
+ sal_Int32 endPos, startPos = 0;
+
+ for(size_t i = 0; i < 5; ++i)
+ {
+ OUString scrTxt;
+
+ if (i == 0)
+ scrTxt = it.pUserData->sPropertyPath;
+ else if (i == 1)
+ scrTxt = it.sProp;
+ else if (i == 2)
+ scrTxt = it.sStatus;
+ else if (i == 3)
+ scrTxt = it.sType;
+ else if (i == 4)
+ scrTxt = it.sValue;
+
+ endPos = scrTxt.getLength();
+ if (textSearch.SearchForward(scrTxt, &startPos, &endPos))
+ {
+ InsertEntry(it);
+ break;
+ }
+ }
+ }
+ }
+
+ m_xPrefBox->thaw();
+ if (m_bSorted)
+ m_xPrefBox->make_sorted();
+
+ m_xPrefBox->all_foreach([this](weld::TreeIter& rEntry) {
+ m_xPrefBox->expand_row(rEntry);
+ return false;
+ });
+ m_xPrefBox->show();
+}
+
+void CuiAboutConfigTabPage::InsertEntry(const prefBoxEntry& rEntry)
+{
+ OUString sPathWithProperty = rEntry.pUserData->sPropertyPath;
+ sal_Int32 index = sPathWithProperty.lastIndexOf(rEntry.sProp);
+ OUString sPath = sPathWithProperty.copy(0, index);
+ index = 0;
+ std::unique_ptr<weld::TreeIter> xParentEntry(m_xPrefBox->make_iterator());
+ std::unique_ptr<weld::TreeIter> xGrandParentEntry;
+
+ do
+ {
+ int prevIndex = index;
+ index = sPath.indexOf("/", index+1);
+ // deal with no parent case (tdf#107811)
+ if (index < 0)
+ {
+ OUString sId(weld::toId(rEntry.pUserData));
+ m_xPrefBox->insert(nullptr, -1, &rEntry.sProp, &sId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sValue, 3);
+ return;
+ }
+ OUString sParentName = sPath.copy(prevIndex+1, index - prevIndex - 1);
+
+ bool hasEntry = false;
+ bool bStartOk;
+
+ if (!xGrandParentEntry)
+ bStartOk = m_xPrefBox->get_iter_first(*xParentEntry);
+ else
+ {
+ m_xPrefBox->copy_iterator(*xGrandParentEntry, *xParentEntry);
+ bStartOk = m_xPrefBox->iter_children(*xParentEntry);
+ }
+
+ if (bStartOk)
+ {
+ do
+ {
+ if (m_xPrefBox->get_text(*xParentEntry, 0) == sParentName)
+ {
+ hasEntry = true;
+ break;
+ }
+ } while (m_xPrefBox->iter_next_sibling(*xParentEntry));
+ }
+
+ if (!hasEntry)
+ {
+ m_xPrefBox->insert(xGrandParentEntry.get(), -1, &sParentName, nullptr, nullptr, nullptr, false, xParentEntry.get());
+ //It is needed, without this the selection line will be truncated.
+ m_xPrefBox->set_text(*xParentEntry, "", 1);
+ m_xPrefBox->set_text(*xParentEntry, "", 2);
+ m_xPrefBox->set_text(*xParentEntry, "", 3);
+ }
+
+ xGrandParentEntry = m_xPrefBox->make_iterator(xParentEntry.get());
+ } while(index < sPath.getLength() - 1);
+
+ OUString sId(weld::toId(rEntry.pUserData));
+ m_xPrefBox->insert(xParentEntry.get(), -1, &rEntry.sProp, &sId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sValue, 3);
+}
+
+IMPL_LINK(CuiAboutConfigTabPage, ExpandingHdl_Impl, const weld::TreeIter&, rEntry, bool)
+{
+ if (m_xPrefBox->iter_has_child(rEntry))
+ return true;
+ UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(rEntry));
+ if (pUserData && !pUserData->bIsPropertyPath)
+ {
+ assert(pUserData->aXNameAccess.is());
+ FillItems(pUserData->aXNameAccess, &rEntry, pUserData->aLineage);
+ }
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaboutconfig.hxx b/cui/source/options/optaboutconfig.hxx
new file mode 100644
index 000000000..64443bcff
--- /dev/null
+++ b/cui/source/options/optaboutconfig.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <i18nutil/searchopt.hxx>
+#include <vcl/weld.hxx>
+
+#include <vector>
+
+class CuiAboutConfigTabPage;
+class CuiAboutConfigValueDialog;
+struct Prop_Impl;
+struct UserData;
+
+struct prefBoxEntry
+{
+ OUString sProp;
+ OUString sStatus;
+ OUString sType;
+ OUString sValue;
+ UserData* pUserData;
+};
+
+class CuiAboutConfigTabPage : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Button> m_xResetBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+ std::unique_ptr<weld::Button> m_xSearchBtn;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::TreeView> m_xPrefBox;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+
+ std::vector < std::unique_ptr<UserData> > m_vectorUserData;
+
+ std::vector<prefBoxEntry> m_modifiedPrefBoxEntries;
+ std::vector< std::shared_ptr< Prop_Impl > > m_vectorOfModified;
+
+ //for search
+ i18nutil::SearchOptions2 m_options;
+ std::vector<prefBoxEntry> m_prefBoxEntries;
+
+ bool m_bSorted;
+
+ void AddToModifiedVector( const std::shared_ptr< Prop_Impl >& rProp );
+ static std::vector< OUString > commaStringToSequence( std::u16string_view rCommaSepString );
+ void InsertEntry(const prefBoxEntry& rEntry);
+
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+ DECL_LINK(DoubleClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(ResetBtnHdl_Impl, weld::Button&, void);
+ DECL_LINK(SearchHdl_Impl, weld::Button&, void);
+ DECL_LINK(ExpandingHdl_Impl, const weld::TreeIter&, bool);
+ DECL_LINK(HeaderBarClick, int, void);
+
+public:
+ explicit CuiAboutConfigTabPage(weld::Window* pParent);
+ virtual ~CuiAboutConfigTabPage() override;
+ void InsertEntry(const OUString &rPropertyPath, const OUString& rProp, const OUString& rStatus, const OUString& rType, const OUString& rValue,
+ const weld::TreeIter* pParentEntry, bool bInsertToPrefBox);
+ void Reset();
+ void FillItems(const css::uno::Reference<css::container::XNameAccess>& xNameAccess,
+ const weld::TreeIter* pParentEntry = nullptr, int lineage = 0, bool bLoadAll = false);
+ static css::uno::Reference< css::container::XNameAccess > getConfigAccess( const OUString& sNodePath, bool bUpdate );
+ void FillItemSet();
+};
+
+class CuiAboutConfigValueDialog : public weld::GenericDialogController
+{
+private:
+ bool m_bNumericOnly;
+ std::unique_ptr<weld::Entry> m_xEDValue;
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+ CuiAboutConfigValueDialog(weld::Window* pWindow, const OUString& rValue , int limit);
+ virtual ~CuiAboutConfigValueDialog() override;
+
+ OUString getValue() const
+ {
+ return m_xEDValue->get_text();
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaccessibility.cxx b/cui/source/options/optaccessibility.cxx
new file mode 100644
index 000000000..a394ff955
--- /dev/null
+++ b/cui/source/options/optaccessibility.cxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optaccessibility.hxx"
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <officecfg/Office/Common.hxx>
+
+SvxAccessibilityOptionsTabPage::SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optaccessibilitypage.ui", "OptAccessibilityPage", &rSet)
+ , m_xAccessibilityTool(m_xBuilder->weld_check_button("acctool"))
+ , m_xTextSelectionInReadonly(m_xBuilder->weld_check_button("textselinreadonly"))
+ , m_xAnimatedGraphics(m_xBuilder->weld_check_button("animatedgraphics"))
+ , m_xAnimatedTexts(m_xBuilder->weld_check_button("animatedtext"))
+ , m_xAutoDetectHC(m_xBuilder->weld_check_button("autodetecthc"))
+ , m_xAutomaticFontColor(m_xBuilder->weld_check_button("autofontcolor"))
+ , m_xPagePreviews(m_xBuilder->weld_check_button("systempagepreviewcolor"))
+{
+#ifdef UNX
+ // UNIX: read the gconf2 setting instead to use the checkbox
+ m_xAccessibilityTool->hide();
+#endif
+}
+
+SvxAccessibilityOptionsTabPage::~SvxAccessibilityOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAccessibilityOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxAccessibilityOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxAccessibilityOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch( comphelper::ConfigurationChanges::create() );
+ if ( !officecfg::Office::Common::Accessibility::IsForPagePreviews::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsForPagePreviews::set(m_xPagePreviews->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::set(m_xAnimatedGraphics->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAllowAnimatedText::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAllowAnimatedText::set(m_xAnimatedTexts->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAutomaticFontColor::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAutomaticFontColor::set(m_xAutomaticFontColor->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsSelectionInReadonly::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsSelectionInReadonly::set(m_xTextSelectionInReadonly->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::AutoDetectSystemHC::isReadOnly() )
+ officecfg::Office::Common::Accessibility::AutoDetectSystemHC::set(m_xAutoDetectHC->get_active(), batch);
+ batch->commit();
+
+ AllSettings aAllSettings = Application::GetSettings();
+ MiscSettings aMiscSettings = aAllSettings.GetMiscSettings();
+#ifndef UNX
+ aMiscSettings.SetEnableATToolSupport(m_xAccessibilityTool->get_active());
+#endif
+ aAllSettings.SetMiscSettings(aMiscSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+
+ return false;
+}
+
+void SvxAccessibilityOptionsTabPage::Reset( const SfxItemSet* )
+{
+ m_xPagePreviews->set_active( officecfg::Office::Common::Accessibility::IsForPagePreviews::get() );
+ if( officecfg::Office::Common::Accessibility::IsForPagePreviews::isReadOnly() )
+ m_xPagePreviews->set_sensitive(false);
+
+ m_xAnimatedGraphics->set_active( officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::get() );
+ if( officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::isReadOnly() )
+ m_xAnimatedGraphics->set_sensitive(false);
+
+ m_xAnimatedTexts->set_active( officecfg::Office::Common::Accessibility::IsAllowAnimatedText::get() );
+ if( officecfg::Office::Common::Accessibility::IsAllowAnimatedText::isReadOnly() )
+ m_xAnimatedTexts->set_sensitive(false);
+
+ m_xAutomaticFontColor->set_active( officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get() );
+ if( officecfg::Office::Common::Accessibility::IsAutomaticFontColor::isReadOnly() )
+ m_xAutomaticFontColor->set_sensitive(false);
+
+ m_xTextSelectionInReadonly->set_active( officecfg::Office::Common::Accessibility::IsSelectionInReadonly::get() );
+ if( officecfg::Office::Common::Accessibility::IsSelectionInReadonly::isReadOnly() )
+ m_xTextSelectionInReadonly->set_sensitive(false);
+
+ m_xAutoDetectHC->set_active( officecfg::Office::Common::Accessibility::AutoDetectSystemHC::get() );
+ if( officecfg::Office::Common::Accessibility::AutoDetectSystemHC::isReadOnly() )
+ m_xAutoDetectHC->set_sensitive(false);
+
+ AllSettings aAllSettings = Application::GetSettings();
+ const MiscSettings& aMiscSettings = aAllSettings.GetMiscSettings();
+ m_xAccessibilityTool->set_active(aMiscSettings.GetEnableATToolSupport());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaccessibility.hxx b/cui/source/options/optaccessibility.hxx
new file mode 100644
index 000000000..35d5fdefd
--- /dev/null
+++ b/cui/source/options/optaccessibility.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class SvxAccessibilityOptionsTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xAccessibilityTool;
+ std::unique_ptr<weld::CheckButton> m_xTextSelectionInReadonly;
+ std::unique_ptr<weld::CheckButton> m_xAnimatedGraphics;
+ std::unique_ptr<weld::CheckButton> m_xAnimatedTexts;
+ std::unique_ptr<weld::CheckButton> m_xAutoDetectHC;
+ std::unique_ptr<weld::CheckButton> m_xAutomaticFontColor;
+ std::unique_ptr<weld::CheckButton> m_xPagePreviews;
+
+public:
+ SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxAccessibilityOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optasian.cxx b/cui/source/options/optasian.cxx
new file mode 100644
index 000000000..84d23b42e
--- /dev/null
+++ b/cui/source/options/optasian.cxx
@@ -0,0 +1,383 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <map>
+#include <optasian.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <o3tl/any.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <svl/asiancfg.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::i18n;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+
+constexpr OUStringLiteral cIsKernAsianPunctuation = u"IsKernAsianPunctuation";
+constexpr OUStringLiteral cCharacterCompressionType = u"CharacterCompressionType";
+
+namespace {
+
+struct SvxForbiddenChars_Impl
+{
+ bool bRemoved;
+ std::unique_ptr<ForbiddenCharacters> pCharacters;
+};
+
+}
+
+struct SvxAsianLayoutPage_Impl
+{
+ SvxAsianConfig aConfig;
+ SvxAsianLayoutPage_Impl() {}
+
+ Reference< XForbiddenCharacters > xForbidden;
+ Reference< XPropertySet > xPrSet;
+ Reference< XPropertySetInfo > xPrSetInfo;
+ std::map< LanguageType, std::unique_ptr<SvxForbiddenChars_Impl> >
+ aChangedLanguagesMap;
+
+ bool hasForbiddenCharacters(LanguageType eLang);
+ SvxForbiddenChars_Impl* getForbiddenCharacters(LanguageType eLang);
+ void addForbiddenCharacters(LanguageType eLang, std::unique_ptr<ForbiddenCharacters> pForbidden);
+};
+
+bool SvxAsianLayoutPage_Impl::hasForbiddenCharacters(LanguageType eLang)
+{
+ return aChangedLanguagesMap.count( eLang );
+}
+
+SvxForbiddenChars_Impl* SvxAsianLayoutPage_Impl::getForbiddenCharacters(LanguageType eLang)
+{
+ auto it = aChangedLanguagesMap.find( eLang );
+ DBG_ASSERT( ( it != aChangedLanguagesMap.end() ), "language not available");
+ if( it != aChangedLanguagesMap.end() )
+ return it->second.get();
+ return nullptr;
+}
+
+void SvxAsianLayoutPage_Impl::addForbiddenCharacters(
+ LanguageType eLang, std::unique_ptr<ForbiddenCharacters> pForbidden)
+{
+ auto itOld = aChangedLanguagesMap.find( eLang );
+ if( itOld == aChangedLanguagesMap.end() )
+ {
+ std::unique_ptr<SvxForbiddenChars_Impl> pChar(new SvxForbiddenChars_Impl);
+ pChar->bRemoved = nullptr == pForbidden;
+ pChar->pCharacters = std::move(pForbidden);
+ aChangedLanguagesMap.emplace( eLang, std::move(pChar) );
+ }
+ else
+ {
+ itOld->second->bRemoved = nullptr == pForbidden;
+ itOld->second->pCharacters = std::move(pForbidden);
+ }
+}
+
+static LanguageType eLastUsedLanguageTypeForForbiddenCharacters(USHRT_MAX);
+
+SvxAsianLayoutPage::SvxAsianLayoutPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optasianpage.ui", "OptAsianPage", &rSet)
+ , pImpl(new SvxAsianLayoutPage_Impl)
+ , m_xCharKerningRB(m_xBuilder->weld_radio_button("charkerning"))
+ , m_xCharPunctKerningRB(m_xBuilder->weld_radio_button("charpunctkerning"))
+ , m_xNoCompressionRB(m_xBuilder->weld_radio_button("nocompression"))
+ , m_xPunctCompressionRB(m_xBuilder->weld_radio_button("punctcompression"))
+ , m_xPunctKanaCompressionRB(m_xBuilder->weld_radio_button("punctkanacompression"))
+ , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xStandardCB(m_xBuilder->weld_check_button("standard"))
+ , m_xStartFT(m_xBuilder->weld_label("startft"))
+ , m_xStartED(m_xBuilder->weld_entry("start"))
+ , m_xEndFT(m_xBuilder->weld_label("endft"))
+ , m_xEndED(m_xBuilder->weld_entry("end"))
+ , m_xHintFT(m_xBuilder->weld_label("hintft"))
+{
+ LanguageHdl(*m_xLanguageLB->get_widget());
+ m_xLanguageLB->connect_changed(LINK(this, SvxAsianLayoutPage, LanguageHdl));
+ m_xStandardCB->connect_toggled(LINK(this, SvxAsianLayoutPage, ChangeStandardHdl));
+ Link<weld::Entry&,void> aLk(LINK(this, SvxAsianLayoutPage, ModifyHdl));
+ m_xStartED->connect_changed(aLk);
+ m_xEndED->connect_changed(aLk);
+
+ m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::FBD_CHARS, false, false );
+}
+
+SvxAsianLayoutPage::~SvxAsianLayoutPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAsianLayoutPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxAsianLayoutPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxAsianLayoutPage::FillItemSet( SfxItemSet* )
+{
+ if(m_xCharKerningRB->get_state_changed_from_saved())
+ {
+ pImpl->aConfig.SetKerningWesternTextOnly(m_xCharKerningRB->get_active());
+ OUString sPunct(cIsKernAsianPunctuation);
+ if(pImpl->xPrSetInfo.is() && pImpl->xPrSetInfo->hasPropertyByName(sPunct))
+ {
+ bool bVal = !m_xCharKerningRB->get_active();
+ pImpl->xPrSet->setPropertyValue(sPunct, Any(bVal));
+ }
+ }
+
+ if(m_xNoCompressionRB->get_state_changed_from_saved() ||
+ m_xPunctCompressionRB->get_state_changed_from_saved())
+ {
+ CharCompressType nSet = m_xNoCompressionRB->get_active() ? CharCompressType::NONE :
+ m_xPunctCompressionRB->get_active() ? CharCompressType::PunctuationOnly :
+ CharCompressType::PunctuationAndKana;
+ pImpl->aConfig.SetCharDistanceCompression(nSet);
+ OUString sCompress(cCharacterCompressionType);
+ if(pImpl->xPrSetInfo.is() && pImpl->xPrSetInfo->hasPropertyByName(sCompress))
+ {
+ pImpl->xPrSet->setPropertyValue(sCompress, Any(static_cast<sal_uInt16>(nSet)));
+ }
+ }
+ pImpl->aConfig.Commit();
+ if(pImpl->xForbidden.is())
+ {
+ try
+ {
+ for (auto const& changedLanguage : pImpl->aChangedLanguagesMap)
+ {
+ Locale aLocale( LanguageTag::convertToLocale(changedLanguage.first));
+ if(changedLanguage.second->bRemoved)
+ pImpl->xForbidden->removeForbiddenCharacters( aLocale );
+ else if(changedLanguage.second->pCharacters)
+ pImpl->xForbidden->setForbiddenCharacters( aLocale, *( changedLanguage.second->pCharacters ) );
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
+ }
+ }
+ eLastUsedLanguageTypeForForbiddenCharacters = m_xLanguageLB->get_active_id();
+
+ return false;
+}
+
+void SvxAsianLayoutPage::Reset( const SfxItemSet* )
+{
+ SfxViewFrame* pCurFrm = SfxViewFrame::Current();
+ SfxObjectShell* pDocSh = pCurFrm ? pCurFrm->GetObjectShell() : nullptr;
+ Reference< XModel > xModel;
+ if(pDocSh)
+ xModel = pDocSh->GetModel();
+ Reference<XMultiServiceFactory> xFact(xModel, UNO_QUERY);
+ if(xFact.is())
+ {
+ pImpl->xPrSet.set(xFact->createInstance("com.sun.star.document.Settings"), UNO_QUERY);
+ }
+ if( pImpl->xPrSet.is() )
+ pImpl->xPrSetInfo = pImpl->xPrSet->getPropertySetInfo();
+ bool bKernWesternText = pImpl->aConfig.IsKerningWesternTextOnly();
+ CharCompressType nCompress = pImpl->aConfig.GetCharDistanceCompression();
+ if(pImpl->xPrSetInfo.is())
+ {
+ OUString sForbidden("ForbiddenCharacters");
+ if(pImpl->xPrSetInfo->hasPropertyByName(sForbidden))
+ {
+ Any aForbidden = pImpl->xPrSet->getPropertyValue(sForbidden);
+ aForbidden >>= pImpl->xForbidden;
+ }
+ OUString sCompress(cCharacterCompressionType);
+ if(pImpl->xPrSetInfo->hasPropertyByName(sCompress))
+ {
+ Any aVal = pImpl->xPrSet->getPropertyValue(sCompress);
+ sal_uInt16 nTmp;
+ if (aVal >>= nTmp)
+ nCompress = static_cast<CharCompressType>(nTmp);
+ }
+ OUString sPunct(cIsKernAsianPunctuation);
+ if(pImpl->xPrSetInfo->hasPropertyByName(sPunct))
+ {
+ Any aVal = pImpl->xPrSet->getPropertyValue(sPunct);
+ bKernWesternText = !*o3tl::doAccess<bool>(aVal);
+ }
+ }
+ else
+ {
+ m_xLanguageFT->set_sensitive(false);
+ m_xLanguageLB->set_sensitive(false);
+ m_xStandardCB->set_sensitive(false);
+ m_xStartFT->set_sensitive(false);
+ m_xStartED->set_sensitive(false);
+ m_xEndFT->set_sensitive(false);
+ m_xEndED->set_sensitive(false);
+ m_xHintFT->set_sensitive(false);
+ }
+ if(bKernWesternText)
+ m_xCharKerningRB->set_active(true);
+ else
+ m_xCharPunctKerningRB->set_active(true);
+ switch(nCompress)
+ {
+ case CharCompressType::NONE : m_xNoCompressionRB->set_active(true); break;
+ case CharCompressType::PunctuationOnly : m_xPunctCompressionRB->set_active(true); break;
+ default: m_xPunctKanaCompressionRB->set_active(true);
+ }
+ m_xCharKerningRB->save_state();
+ m_xNoCompressionRB->save_state();
+ m_xPunctCompressionRB->save_state();
+ m_xPunctKanaCompressionRB->save_state();
+
+ m_xLanguageLB->set_active(0);
+ //preselect the system language in the box - if available
+ if(LanguageType(USHRT_MAX) == eLastUsedLanguageTypeForForbiddenCharacters)
+ {
+ eLastUsedLanguageTypeForForbiddenCharacters =
+ Application::GetSettings().GetLanguageTag().getLanguageType();
+ if (MsLangId::isSimplifiedChinese(eLastUsedLanguageTypeForForbiddenCharacters))
+ eLastUsedLanguageTypeForForbiddenCharacters = LANGUAGE_CHINESE_SIMPLIFIED;
+ else if (MsLangId::isTraditionalChinese(eLastUsedLanguageTypeForForbiddenCharacters))
+ eLastUsedLanguageTypeForForbiddenCharacters = LANGUAGE_CHINESE_TRADITIONAL;
+ }
+ m_xLanguageLB->set_active_id(eLastUsedLanguageTypeForForbiddenCharacters);
+ LanguageHdl(*m_xLanguageLB->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxAsianLayoutPage, LanguageHdl, weld::ComboBox&, void)
+{
+ //set current value
+ LanguageType eSelectLanguage = m_xLanguageLB->get_active_id();
+ LanguageTag aLanguageTag( eSelectLanguage);
+ const Locale& aLocale( aLanguageTag.getLocale());
+
+ OUString sStart, sEnd;
+ bool bAvail;
+ if(pImpl->xForbidden.is())
+ {
+ bAvail = pImpl->hasForbiddenCharacters(eSelectLanguage);
+ if(bAvail)
+ {
+ SvxForbiddenChars_Impl* pElement = pImpl->getForbiddenCharacters(eSelectLanguage);
+ if(pElement->bRemoved || !pElement->pCharacters)
+ {
+ bAvail = false;
+ }
+ else
+ {
+ sStart = pElement->pCharacters->beginLine;
+ sEnd = pElement->pCharacters->endLine;
+ }
+ }
+ else
+ {
+ try
+ {
+ bAvail = pImpl->xForbidden->hasForbiddenCharacters(aLocale);
+ if(bAvail)
+ {
+ ForbiddenCharacters aForbidden = pImpl->xForbidden->getForbiddenCharacters( aLocale );
+ sStart = aForbidden.beginLine;
+ sEnd = aForbidden.endLine;
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
+ }
+ }
+ }
+ else
+ {
+ bAvail = pImpl->aConfig.GetStartEndChars( aLocale, sStart, sEnd );
+ }
+ if(!bAvail)
+ {
+ LocaleDataWrapper aWrap( std::move(aLanguageTag) );
+ ForbiddenCharacters aForbidden = aWrap.getForbiddenCharacters();
+ sStart = aForbidden.beginLine;
+ sEnd = aForbidden.endLine;
+ }
+ m_xStandardCB->set_active(!bAvail);
+ m_xStartED->set_sensitive(bAvail);
+ m_xEndED->set_sensitive(bAvail);
+ m_xStartFT->set_sensitive(bAvail);
+ m_xEndFT->set_sensitive(bAvail);
+ m_xStartED->set_text(sStart);
+ m_xEndED->set_text(sEnd);
+}
+
+IMPL_LINK(SvxAsianLayoutPage, ChangeStandardHdl, weld::Toggleable&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ m_xStartED->set_sensitive(!bCheck);
+ m_xEndED->set_sensitive(!bCheck);
+ m_xStartFT->set_sensitive(!bCheck);
+ m_xEndFT->set_sensitive(!bCheck);
+
+ ModifyHdl(*m_xStartED);
+}
+
+IMPL_LINK(SvxAsianLayoutPage, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ LanguageType eSelectLanguage = m_xLanguageLB->get_active_id();
+ Locale aLocale( LanguageTag::convertToLocale( eSelectLanguage ));
+ OUString sStart = m_xStartED->get_text();
+ OUString sEnd = m_xEndED->get_text();
+ bool bEnable = rEdit.get_sensitive();
+ if(pImpl->xForbidden.is())
+ {
+ try
+ {
+ if(bEnable)
+ {
+ std::unique_ptr<ForbiddenCharacters> pFCSet(new ForbiddenCharacters);
+ pFCSet->beginLine = sStart;
+ pFCSet->endLine = sEnd;
+ pImpl->addForbiddenCharacters(eSelectLanguage, std::move(pFCSet));
+ }
+ else
+ pImpl->addForbiddenCharacters(eSelectLanguage, nullptr);
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
+ }
+ }
+ pImpl->aConfig.SetStartEndChars( aLocale, bEnable ? &sStart : nullptr, bEnable ? &sEnd : nullptr);
+}
+
+WhichRangesContainer SvxAsianLayoutPage::GetRanges()
+{
+ //no items are used
+ return WhichRangesContainer();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optbasic.cxx b/cui/source/options/optbasic.cxx
new file mode 100644
index 000000000..c550d9440
--- /dev/null
+++ b/cui/source/options/optbasic.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optbasic.hxx"
+#include <basic/codecompletecache.hxx>
+#include <officecfg/Office/BasicIDE.hxx>
+
+SvxBasicIDEOptionsPage::SvxBasicIDEOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optbasicidepage.ui", "OptBasicIDEPage", &rSet)
+ , m_xCodeCompleteChk(m_xBuilder->weld_check_button("codecomplete_enable"))
+ , m_xAutocloseProcChk(m_xBuilder->weld_check_button("autoclose_proc"))
+ , m_xAutocloseParenChk(m_xBuilder->weld_check_button("autoclose_paren"))
+ , m_xAutocloseQuotesChk(m_xBuilder->weld_check_button("autoclose_quotes"))
+ , m_xAutoCorrectChk(m_xBuilder->weld_check_button("autocorrect"))
+ , m_xUseExtendedTypesChk(m_xBuilder->weld_check_button("extendedtypes_enable"))
+{
+ LoadConfig();
+}
+
+SvxBasicIDEOptionsPage::~SvxBasicIDEOptionsPage()
+{
+}
+
+void SvxBasicIDEOptionsPage::LoadConfig()
+{
+ m_xCodeCompleteChk->set_active( officecfg::Office::BasicIDE::Autocomplete::CodeComplete::get() );
+ m_xCodeCompleteChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::CodeComplete::isReadOnly() );
+ m_xAutocloseProcChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::get() );
+ m_xAutocloseProcChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::isReadOnly() );
+ m_xAutocloseQuotesChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::get() );
+ m_xAutocloseQuotesChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::isReadOnly() );
+ m_xAutocloseParenChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::get() );
+ m_xAutocloseParenChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::isReadOnly() );
+ m_xAutoCorrectChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::get() );
+ m_xAutoCorrectChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::isReadOnly() );
+ m_xUseExtendedTypesChk->set_active( officecfg::Office::BasicIDE::Autocomplete::UseExtended::get() );
+ m_xUseExtendedTypesChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::UseExtended::isReadOnly() );
+}
+
+bool SvxBasicIDEOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
+{
+ bool bModified = false;
+ std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
+
+ if( m_xAutocloseProcChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::set( m_xAutocloseProcChk->get_active(), batch );
+ CodeCompleteOptions::SetProcedureAutoCompleteOn( m_xAutocloseProcChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xCodeCompleteChk->get_state_changed_from_saved() )
+ {
+ //std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::BasicIDE::Autocomplete::CodeComplete::set( m_xCodeCompleteChk->get_active(), batch );
+ CodeCompleteOptions::SetCodeCompleteOn( m_xCodeCompleteChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xUseExtendedTypesChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::UseExtended::set( m_xUseExtendedTypesChk->get_active(), batch );
+ CodeCompleteOptions::SetExtendedTypeDeclaration( m_xUseExtendedTypesChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutocloseParenChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::set( m_xAutocloseParenChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCloseParenthesisOn( m_xAutocloseParenChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutocloseQuotesChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::set( m_xAutocloseQuotesChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCloseQuotesOn( m_xAutocloseQuotesChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutoCorrectChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::set( m_xAutoCorrectChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCorrectOn( m_xAutoCorrectChk->get_active() );
+ bModified = true;
+ }
+
+ if( bModified )
+ batch->commit();
+
+ return bModified;
+}
+
+void SvxBasicIDEOptionsPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ LoadConfig();
+ m_xCodeCompleteChk->save_state();
+ m_xAutocloseProcChk->save_state();
+ m_xAutocloseQuotesChk->save_state();
+ m_xAutocloseParenChk->save_state();
+ m_xAutoCorrectChk->save_state();
+ m_xUseExtendedTypesChk->save_state();
+}
+
+std::unique_ptr<SfxTabPage> SvxBasicIDEOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxBasicIDEOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBasicIDEOptionsPage::FillUserData()
+{
+ SetUserData( OUString() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optbasic.hxx b/cui/source/options/optbasic.hxx
new file mode 100644
index 000000000..990b54d4e
--- /dev/null
+++ b/cui/source/options/optbasic.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class SvxBasicIDEOptionsPage: public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xCodeCompleteChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseProcChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseParenChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseQuotesChk;
+ std::unique_ptr<weld::CheckButton> m_xAutoCorrectChk;
+ std::unique_ptr<weld::CheckButton> m_xUseExtendedTypesChk;
+
+ void LoadConfig();
+
+public:
+ SvxBasicIDEOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBasicIDEOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optchart.cxx b/cui/source/options/optchart.cxx
new file mode 100644
index 000000000..af9b92322
--- /dev/null
+++ b/cui/source/options/optchart.cxx
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optchart.hxx"
+#include <svx/SvxColorValueSet.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/svxids.hrc>
+#include <osl/diagnose.h>
+#include <officecfg/Office/Common.hxx>
+
+void SvxDefaultColorOptPage::InsertColorEntry(const XColorEntry& rEntry, sal_Int32 nPos)
+{
+ const Color& rColor = rEntry.GetColor();
+ const OUString& rStr = rEntry.GetName();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Size aImageSize = rStyleSettings.GetListBoxPreviewDefaultPixelSize();
+
+ ScopedVclPtrInstance<VirtualDevice> xDevice;
+ xDevice->SetOutputSize(aImageSize);
+ const ::tools::Rectangle aRect(Point(0, 0), aImageSize);
+ xDevice->SetFillColor(rColor);
+ xDevice->SetLineColor(rStyleSettings.GetDisableColor());
+ xDevice->DrawRect(aRect);
+
+ m_xLbChartColors->insert(nullptr, nPos, &rStr, nullptr,
+ nullptr, xDevice.get(), false, nullptr);
+
+ if (nPos == -1)
+ aColorList.push_back( rColor );
+ else
+ {
+ ImpColorList::iterator it = aColorList.begin();
+ std::advance( it, nPos );
+ aColorList.insert( it, rColor );
+ }
+}
+
+void SvxDefaultColorOptPage::RemoveColorEntry(sal_Int32 nPos)
+{
+ m_xLbChartColors->remove(nPos);
+ ImpColorList::iterator it = aColorList.begin();
+ std::advance(it, nPos);
+ aColorList.erase(it);
+}
+
+void SvxDefaultColorOptPage::ClearColorEntries()
+{
+ aColorList.clear();
+ m_xLbChartColors->clear();
+}
+
+void SvxDefaultColorOptPage::ModifyColorEntry(const XColorEntry& rEntry, sal_Int32 nPos)
+{
+ RemoveColorEntry(nPos);
+ InsertColorEntry(rEntry, nPos);
+}
+
+void SvxDefaultColorOptPage::FillBoxChartColorLB()
+{
+ if (!m_SvxChartColorTableUniquePtr)
+ return;
+
+ m_xLbChartColors->freeze();
+ ClearColorEntries();
+ const tools::Long nCount(m_SvxChartColorTableUniquePtr->size());
+ for (tools::Long i = 0; i < nCount; ++i)
+ InsertColorEntry((*m_SvxChartColorTableUniquePtr)[i]);
+ m_xLbChartColors->thaw();
+}
+
+SvxDefaultColorOptPage::SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/optchartcolorspage.ui", "OptChartColorsPage", &rInAttrs)
+ , m_xLbChartColors(m_xBuilder->weld_tree_view("colors"))
+ , m_xLbPaletteSelector(m_xBuilder->weld_combo_box("paletteselector"))
+ , m_xPBDefault(m_xBuilder->weld_button("default"))
+ , m_xPBAdd(m_xBuilder->weld_button("add"))
+ , m_xPBRemove(m_xBuilder->weld_button("delete"))
+ , m_xValSetColorBox(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("tablewin", true)))
+ , m_xValSetColorBoxWin(new weld::CustomWeld(*m_xBuilder, "table", *m_xValSetColorBox))
+{
+ m_xLbChartColors->set_size_request(-1, m_xLbChartColors->get_height_rows(16));
+
+ m_xPBDefault->connect_clicked( LINK( this, SvxDefaultColorOptPage, ResetToDefaults ) );
+ m_xPBAdd->connect_clicked( LINK( this, SvxDefaultColorOptPage, AddChartColor ) );
+ m_xPBRemove->connect_clicked( LINK( this, SvxDefaultColorOptPage, RemoveChartColor ) );
+ m_xValSetColorBox->SetSelectHdl( LINK( this, SvxDefaultColorOptPage, BoxClickedHdl ) );
+ m_xLbPaletteSelector->connect_changed( LINK( this, SvxDefaultColorOptPage, SelectPaletteLbHdl ) );
+
+ m_xValSetColorBox->SetStyle( m_xValSetColorBox->GetStyle()
+ | WB_ITEMBORDER | WB_NAMEFIELD | WB_VSCROLL );
+
+ m_SvxChartOptionsUniquePtr.reset(new SvxChartOptions);
+
+ if ( const SvxChartColorTableItem* pEditOptionsItem = rInAttrs.GetItemIfSet( SID_SCH_EDITOPTIONS, false ) )
+ {
+ m_SvxChartColorTableUniquePtr = std::make_unique<SvxChartColorTable>(
+ pEditOptionsItem->GetColorList());
+ }
+ else
+ {
+ m_SvxChartColorTableUniquePtr = std::make_unique<SvxChartColorTable>();
+ m_SvxChartColorTableUniquePtr->useDefault();
+ m_SvxChartOptionsUniquePtr->SetDefaultColors(*m_SvxChartColorTableUniquePtr);
+ }
+
+ Construct();
+}
+
+SvxDefaultColorOptPage::~SvxDefaultColorOptPage()
+{
+ m_xValSetColorBoxWin.reset();
+ m_xValSetColorBox.reset();
+}
+
+void SvxDefaultColorOptPage::Construct()
+{
+ FillBoxChartColorLB();
+ FillPaletteLB();
+
+ m_xLbChartColors->select( 0 );
+}
+
+std::unique_ptr<SfxTabPage> SvxDefaultColorOptPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs )
+{
+ return std::make_unique<SvxDefaultColorOptPage>( pPage, pController, *rAttrs );
+}
+
+bool SvxDefaultColorOptPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ rOutAttrs->Put(SvxChartColorTableItem(SID_SCH_EDITOPTIONS, *m_SvxChartColorTableUniquePtr));
+ }
+
+ return true;
+}
+
+void SvxDefaultColorOptPage::Reset( const SfxItemSet* )
+{
+ m_xLbChartColors->select( 0 );
+}
+
+void SvxDefaultColorOptPage::FillPaletteLB()
+{
+ m_xLbPaletteSelector->clear();
+ std::vector<OUString> aPaletteList = aPaletteManager.GetPaletteList();
+ for (auto const& palette : aPaletteList)
+ m_xLbPaletteSelector->append_text(palette);
+
+ OUString aPaletteName(officecfg::Office::Common::UserColors::PaletteName::get());
+ m_xLbPaletteSelector->set_active_text(aPaletteName);
+ if (m_xLbPaletteSelector->get_active() != -1)
+ SelectPaletteLbHdl( *m_xLbPaletteSelector );
+}
+
+void SvxDefaultColorOptPage::SaveChartOptions()
+{
+ if (m_SvxChartOptionsUniquePtr && m_SvxChartColorTableUniquePtr)
+ {
+ m_SvxChartOptionsUniquePtr->SetDefaultColors(*m_SvxChartColorTableUniquePtr);
+ m_SvxChartOptionsUniquePtr->Commit();
+ }
+}
+
+// event handlers
+
+
+// ResetToDefaults
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, ResetToDefaults, weld::Button&, void)
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ m_SvxChartColorTableUniquePtr->useDefault();
+
+ FillBoxChartColorLB();
+
+ m_xLbChartColors->grab_focus();
+ m_xLbChartColors->select( 0 );
+ m_xPBRemove->set_sensitive(true);
+ }
+}
+
+// AddChartColor
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, AddChartColor, weld::Button&, void)
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ Color const black( 0x00, 0x00, 0x00 );
+
+ m_SvxChartColorTableUniquePtr->append(
+ XColorEntry(black, SvxChartColorTable::getDefaultName(m_SvxChartColorTableUniquePtr->size())));
+
+ FillBoxChartColorLB();
+ m_xLbChartColors->grab_focus();
+ m_xLbChartColors->select(m_SvxChartColorTableUniquePtr->size() - 1);
+ m_xPBRemove->set_sensitive(true);
+ }
+}
+
+// RemoveChartColor
+IMPL_LINK_NOARG( SvxDefaultColorOptPage, RemoveChartColor, weld::Button&, void )
+{
+ sal_Int32 nIndex = m_xLbChartColors->get_selected_index();
+ if (nIndex == -1)
+ return;
+
+ if( !m_SvxChartColorTableUniquePtr )
+ return;
+
+ OSL_ENSURE(m_SvxChartColorTableUniquePtr->size() > 1, "don't delete the last chart color");
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletechartcolordialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteChartColorDialog"));
+
+ if (RET_YES != xQuery->run())
+ return;
+
+ m_SvxChartColorTableUniquePtr->remove(nIndex);
+
+ FillBoxChartColorLB();
+
+ m_xLbChartColors->grab_focus();
+
+ if (nIndex == m_xLbChartColors->n_children() && m_xLbChartColors->n_children() > 0)
+ m_xLbChartColors->select(m_SvxChartColorTableUniquePtr->size() - 1);
+ else if (m_xLbChartColors->n_children() > 0)
+ m_xLbChartColors->select( nIndex );
+ else
+ m_xPBRemove->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG( SvxDefaultColorOptPage, SelectPaletteLbHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = m_xLbPaletteSelector->get_active();
+ aPaletteManager.SetPalette( nPos );
+ aPaletteManager.ReloadColorSet( *m_xValSetColorBox );
+ m_xValSetColorBox->Resize();
+}
+
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, BoxClickedHdl, ValueSet*, void)
+{
+ sal_Int32 nIdx = m_xLbChartColors->get_selected_index();
+ if (nIdx != -1)
+ {
+ const XColorEntry aEntry(m_xValSetColorBox->GetItemColor(m_xValSetColorBox->GetSelectedItemId()), m_xLbChartColors->get_selected_text());
+
+ ModifyColorEntry(aEntry, nIdx);
+ m_SvxChartColorTableUniquePtr->replace(nIdx, aEntry);
+
+ m_xLbChartColors->select(nIdx); // reselect entry
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optchart.hxx b/cui/source/options/optchart.hxx
new file mode 100644
index 000000000..11221617a
--- /dev/null
+++ b/cui/source/options/optchart.hxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/valueset.hxx>
+#include <svx/xtable.hxx>
+#include <svx/PaletteManager.hxx>
+#include <vcl/customweld.hxx>
+
+#include "cfgchart.hxx"
+
+typedef std::vector<Color> ImpColorList;
+
+class SvxDefaultColorOptPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvxChartOptions> m_SvxChartOptionsUniquePtr;
+ // no reason to use a cloned SfxItem here (SvxChartColorTableItem)
+ // that just leads to non-const SfxItem and potential trouble
+ std::unique_ptr<SvxChartColorTable> m_SvxChartColorTableUniquePtr;
+
+ ImpColorList aColorList;
+ PaletteManager aPaletteManager;
+
+ std::unique_ptr<weld::TreeView> m_xLbChartColors;
+ std::unique_ptr<weld::ComboBox> m_xLbPaletteSelector;
+ std::unique_ptr<weld::Button> m_xPBDefault;
+ std::unique_ptr<weld::Button> m_xPBAdd;
+ std::unique_ptr<weld::Button> m_xPBRemove;
+ std::unique_ptr<SvxColorValueSet> m_xValSetColorBox;
+ std::unique_ptr<weld::CustomWeld> m_xValSetColorBoxWin;
+
+ DECL_LINK(ResetToDefaults, weld::Button&, void);
+ DECL_LINK(AddChartColor, weld::Button&, void);
+ DECL_LINK(RemoveChartColor, weld::Button&, void);
+ DECL_LINK(BoxClickedHdl, ValueSet*, void);
+ DECL_LINK(SelectPaletteLbHdl, weld::ComboBox&, void);
+
+ void FillPaletteLB();
+
+private:
+ void InsertColorEntry(const XColorEntry& rEntry, sal_Int32 nPos = -1);
+ void RemoveColorEntry(sal_Int32 nPos);
+ void ModifyColorEntry(const XColorEntry& rEntry, sal_Int32 nPos);
+ void ClearColorEntries();
+ void FillBoxChartColorLB();
+
+public:
+ SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxDefaultColorOptPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+
+ void SaveChartOptions();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optcolor.cxx b/cui/source/options/optcolor.cxx
new file mode 100644
index 000000000..2249b70e4
--- /dev/null
+++ b/cui/source/options/optcolor.cxx
@@ -0,0 +1,896 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <bitset>
+
+#include <tools/debug.hxx>
+#include <editeng/editids.hrc>
+#include <svtools/colorcfg.hxx>
+#include <svtools/extcolorcfg.hxx>
+#include <svx/colorbox.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svxdlg.hxx>
+#include <helpids.h>
+#include <dialmgr.hxx>
+#include "optcolor.hxx"
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::svtools;
+
+namespace
+{
+
+// list of default groups
+enum Group
+{
+ Group_General,
+ Group_Writer,
+ Group_Html,
+ Group_Calc,
+ Group_Draw,
+ Group_Basic,
+ Group_Sql,
+
+ nGroupCount
+};
+
+// group data
+struct
+{
+ // group
+ Group eGroup;
+ // .ui group name
+ const char *pGroup;
+}
+const vGroupInfo[] =
+{
+ // the groups are in the same order as in enum Group above
+ { Group_General, "general" },
+ { Group_Writer, "writer" },
+ { Group_Html, "html" },
+ { Group_Calc, "calc" },
+ { Group_Draw, "draw" },
+ { Group_Basic, "basic" },
+ { Group_Sql, "sql" }
+};
+
+// color config entry data (see ColorConfigWindow_Impl::Entry below)
+struct
+{
+ // group
+ Group eGroup;
+ //checkbox (or simple text)
+ const char *pText;
+ //color listbox
+ const char *pColor;
+ // has checkbox?
+ bool bCheckBox;
+}
+const vEntryInfo[] =
+{
+ #define IDS(Name) \
+ SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
+
+ #define IDS_CB(Name) \
+ SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
+
+ // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
+
+ { Group_General, IDS(doccolor) },
+ { Group_General, IDS_CB(docboundaries) },
+ { Group_General, IDS(appback) },
+ { Group_General, IDS_CB(objboundaries) },
+ { Group_General, IDS_CB(tblboundaries) },
+ { Group_General, IDS(font) },
+ { Group_General, IDS_CB(unvisitedlinks) },
+ { Group_General, IDS_CB(visitedlinks) },
+ { Group_General, IDS(autospellcheck) },
+ { Group_General, IDS(smarttags) },
+ { Group_General, IDS_CB(shadows) },
+
+ { Group_Writer, IDS(writergrid) },
+ { Group_Writer, IDS_CB(field) },
+ { Group_Writer, IDS_CB(index) },
+ { Group_Writer, IDS(direct) },
+ { Group_Writer, IDS(script) },
+ { Group_Writer, IDS_CB(section) },
+ { Group_Writer, IDS(hdft) },
+ { Group_Writer, IDS(pagebreak) },
+
+ { Group_Html, IDS(sgml) },
+ { Group_Html, IDS(htmlcomment) },
+ { Group_Html, IDS(htmlkeyword) },
+ { Group_Html, IDS(unknown) },
+
+ { Group_Calc, IDS(calcgrid) },
+ { Group_Calc, IDS(brk) },
+ { Group_Calc, IDS(brkmanual) },
+ { Group_Calc, IDS(brkauto) },
+ { Group_Calc, IDS_CB(hiddencolrow) },
+ { Group_Calc, IDS(det) },
+ { Group_Calc, IDS(deterror) },
+ { Group_Calc, IDS(ref) },
+ { Group_Calc, IDS(notes) },
+ { Group_Calc, IDS(values) },
+ { Group_Calc, IDS(formulas) },
+ { Group_Calc, IDS(text) },
+ { Group_Calc, IDS(protectedcells) },
+
+ { Group_Draw, IDS(drawgrid) },
+
+ { Group_Basic, IDS(basicid) },
+ { Group_Basic, IDS(basiccomment) },
+ { Group_Basic, IDS(basicnumber) },
+ { Group_Basic, IDS(basicstring) },
+ { Group_Basic, IDS(basicop) },
+ { Group_Basic, IDS(basickeyword) },
+ { Group_Basic, IDS(error) },
+
+ { Group_Sql, IDS(sqlid) },
+ { Group_Sql, IDS(sqlnumber) },
+ { Group_Sql, IDS(sqlstring) },
+ { Group_Sql, IDS(sqlop) },
+ { Group_Sql, IDS(sqlkeyword) },
+ { Group_Sql, IDS(sqlparam) },
+ { Group_Sql, IDS(sqlcomment) }
+
+ #undef IDS
+};
+
+// ColorConfigWindow_Impl
+
+class ColorConfigWindow_Impl
+{
+public:
+ explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
+
+public:
+ void SetLinks(Link<weld::Toggleable&,void> const&,
+ Link<ColorListBox&,void> const&,
+ Link<weld::Widget&,void> const&,
+ weld::ScrolledWindow& rScroll);
+ void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
+ void ClickHdl(EditableColorConfig*, const weld::Toggleable&);
+ void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
+
+ weld::Widget& GetWidget1()
+ {
+ return *m_xWidget1;
+ }
+
+ weld::Widget& GetWidget2()
+ {
+ return *m_xWidget2;
+ }
+
+ weld::Widget& GetBody()
+ {
+ return *m_xBox;
+ }
+
+ int GetLabelIndent() const
+ {
+ return m_nCheckBoxLabelOffset;
+ }
+
+private:
+ // Chapter -- horizontal group separator stripe with text
+ class Chapter
+ {
+ // text
+ std::unique_ptr<weld::Label> m_xText;
+ public:
+ Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow);
+ void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
+ };
+
+ // Entry -- a color config entry:
+ // text (checkbox) + color list box
+ class Entry
+ {
+ public:
+ Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
+ const Color& rColor, int nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
+ public:
+ void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
+ int get_height_request() const
+ {
+ return std::max(m_xText->get_preferred_size().Height(),
+ m_xColorList->get_widget().get_preferred_size().Height());
+ }
+ void Hide ();
+ public:
+ void SetLinks(Link<weld::Toggleable&,void> const&,
+ Link<ColorListBox&,void> const&,
+ Link<weld::Widget&,void> const&);
+ void Update (ColorConfigValue const&);
+ void Update (ExtendedColorConfigValue const&);
+ void ColorChanged (ColorConfigValue&);
+ void ColorChanged (ExtendedColorConfigValue&);
+ public:
+ bool Is(const weld::Toggleable* pBox) const { return m_xText.get() == pBox; }
+ bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
+ private:
+ // checkbox (CheckBox) or simple text (FixedText)
+ std::unique_ptr<weld::Widget> m_xText;
+ // color list box
+ std::unique_ptr<ColorListBox> m_xColorList;
+ // default color
+ Color m_aDefaultColor;
+ };
+
+private:
+ weld::Window* m_pTopLevel;
+ int m_nCheckBoxLabelOffset;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Box> m_xBox;
+ std::unique_ptr<weld::Widget> m_xWidget1;
+ std::unique_ptr<weld::Widget> m_xWidget2;
+
+ std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
+ std::vector<std::unique_ptr<weld::Container>> vExtContainers;
+ // vChapters -- groups (group headers)
+ std::vector<std::shared_ptr<Chapter> > vChapters;
+ // vEntries -- color options
+ std::vector<std::shared_ptr<Entry> > vEntries;
+
+ // module options
+ SvtModuleOptions aModuleOptions;
+
+ // initialization
+ void CreateEntries();
+
+private:
+
+ bool IsGroupVisible (Group) const;
+};
+
+} // namespace
+
+// ColorConfigWindow_Impl::Chapter
+
+// ctor for default groups
+// rParent: parent window (ColorConfigWindow_Impl)
+// eGroup: which group is this?
+ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow)
+ : m_xText(rBuilder.weld_label(pLabelWidget))
+{
+ if (!bShow)
+ m_xText->hide();
+}
+
+// ColorConfigWindow_Impl::Entry
+ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
+ const char* pTextWidget, const char* pColorWidget,
+ const Color& rColor,
+ int nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
+ : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), [pTopLevel]{ return pTopLevel; }))
+ , m_aDefaultColor(rColor)
+{
+ if (bCheckBox)
+ m_xText = rBuilder.weld_check_button(pTextWidget);
+ else
+ m_xText = rBuilder.weld_label(pTextWidget);
+
+ // color list
+ m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
+
+ if (!bCheckBox)
+ {
+ m_xText->set_margin_start(m_xText->get_margin_start() +
+ nCheckBoxLabelOffset);
+ }
+
+ if (!bShow)
+ Hide();
+}
+
+void ColorConfigWindow_Impl::Entry::Hide()
+{
+ m_xText->hide();
+ m_xColorList->hide();
+}
+
+// SetLinks()
+void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::Toggleable&,void> const& rCheckLink,
+ Link<ColorListBox&,void> const& rColorLink,
+ Link<weld::Widget&,void> const& rGetFocusLink)
+{
+ m_xColorList->SetSelectHdl(rColorLink);
+ m_xColorList->connect_focus_in(rGetFocusLink);
+ if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
+ {
+ pCheckBox->connect_toggled(rCheckLink);
+ pCheckBox->connect_focus_in(rGetFocusLink);
+ }
+}
+
+// updates a default color config entry
+void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
+{
+ Color aColor(rValue.nColor);
+ m_xColorList->SelectEntry(aColor);
+ if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
+ pCheckBox->set_active(rValue.bIsVisible);
+}
+
+// updates an extended color config entry
+void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
+{
+ Color aColor(rValue.getColor());
+ if (rValue.getColor() == rValue.getDefaultColor())
+ m_xColorList->SelectEntry(COL_AUTO);
+ else
+ m_xColorList->SelectEntry(aColor);
+}
+
+// color of a default entry has changed
+void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
+{
+ Color aColor = m_xColorList->GetSelectEntryColor();
+ rValue.nColor = aColor;
+}
+
+// color of an extended entry has changed
+void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
+{
+ Color aColor = m_xColorList->GetSelectEntryColor();
+ rValue.setColor(aColor);
+ if (aColor == COL_AUTO)
+ {
+ rValue.setColor(rValue.getDefaultColor());
+ }
+}
+
+// ColorConfigWindow_Impl
+ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
+ : m_pTopLevel(pTopLevel)
+ , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
+ , m_xBox(m_xBuilder->weld_box("ColorConfigWindow"))
+ , m_xWidget1(m_xBuilder->weld_widget("docboundaries"))
+ , m_xWidget2(m_xBuilder->weld_widget("docboundaries_lb"))
+{
+ CreateEntries();
+}
+
+void ColorConfigWindow_Impl::CreateEntries()
+{
+ std::bitset<nGroupCount> aModulesInstalled;
+ // creating group headers
+ vChapters.reserve(nGroupCount);
+ for (unsigned i = 0; i != nGroupCount; ++i)
+ {
+ aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
+ vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
+ }
+
+ // Here we want to get the amount to add to the position of a FixedText to
+ // get it to align its contents with that of a CheckBox
+ {
+ OUString sSampleText("XXXXXX");
+ std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
+ std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
+ OUString sOrigCheck(xCheckBox->get_label());
+ OUString sOrigFixed(xFixedText->get_label());
+ xCheckBox->set_label(sSampleText);
+ xFixedText->set_label(sSampleText);
+ Size aCheckSize(xCheckBox->get_preferred_size());
+ Size aFixedSize(xFixedText->get_preferred_size());
+ xCheckBox->set_label(sOrigCheck);
+ xFixedText->set_label(sOrigFixed);
+ m_nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
+ }
+
+ // creating entries
+ vEntries.reserve(ColorConfigEntryCount);
+ for (size_t i = 0; i < std::size(vEntryInfo); ++i)
+ {
+ vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
+ vEntryInfo[i].pText, vEntryInfo[i].pColor,
+ ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
+ m_nCheckBoxLabelOffset,
+ vEntryInfo[i].bCheckBox,
+ aModulesInstalled[vEntryInfo[i].eGroup]));
+ }
+
+ // extended entries
+ ExtendedColorConfig aExtConfig;
+ unsigned const nExtGroupCount = aExtConfig.GetComponentCount();
+ if (!nExtGroupCount)
+ return;
+
+ for (unsigned j = 0; j != nExtGroupCount; ++j)
+ {
+ vExtBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "cui/ui/chapterfragment.ui"));
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_frame("ChapterFragment"));
+
+ OUString const sComponentName = aExtConfig.GetComponentName(j);
+ vChapters.push_back(std::make_shared<Chapter>(
+ *vExtBuilders.back(), "chapter", true));
+ vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
+
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_box("contents"));
+ weld::Container* pChapterBox = vExtContainers.back().get();
+
+ unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
+ for (unsigned i = 0; i != nColorCount; ++i)
+ {
+ vExtBuilders.emplace_back(Application::CreateBuilder(pChapterBox, "cui/ui/colorfragment.ui"));
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
+
+ ExtendedColorConfigValue const aColorEntry =
+ aExtConfig.GetComponentColorConfigValue(sComponentName, i);
+ vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
+ "label", "button", aColorEntry.getDefaultColor(),
+ m_nCheckBoxLabelOffset, false, true));
+ vEntries.back()->SetText(aColorEntry.getDisplayName());
+ }
+ }
+}
+
+// SetLinks()
+void ColorConfigWindow_Impl::SetLinks(Link<weld::Toggleable&,void> const& aCheckLink,
+ Link<ColorListBox&,void> const& aColorLink,
+ Link<weld::Widget&,void> const& rGetFocusLink,
+ weld::ScrolledWindow& rScroll)
+{
+ if (vEntries.empty())
+ return;
+ for (auto const & i: vEntries)
+ i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
+ // 6 is the spacing set on ColorConfigWindow
+ rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
+}
+
+// Update()
+void ColorConfigWindow_Impl::Update (
+ EditableColorConfig const* pConfig,
+ EditableExtendedColorConfig const* pExtConfig)
+{
+ // updating default entries
+ for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
+ {
+ ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
+ vEntries[i]->Update(
+ pConfig->GetColorValue(aColorEntry)
+ );
+ }
+
+ // updating extended entries
+ decltype(vEntries)::size_type i = ColorConfigEntryCount;
+ unsigned const nExtCount = pExtConfig->GetComponentCount();
+ for (unsigned j = 0; j != nExtCount; ++j)
+ {
+ OUString sComponentName = pExtConfig->GetComponentName(j);
+ unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
+ for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
+ vEntries[i]->Update(
+ pExtConfig->GetComponentColorConfigValue(sComponentName, k)
+ );
+ }
+}
+
+// ClickHdl()
+void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, const weld::Toggleable& rBox)
+{
+ for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
+ {
+ if (vEntries[i]->Is(&rBox))
+ {
+ ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
+ ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
+ aValue.bIsVisible = rBox.get_active();
+ pConfig->SetColorValue(aEntry, aValue);
+ break;
+ }
+ }
+}
+
+// ColorHdl()
+void ColorConfigWindow_Impl::ColorHdl(
+ EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
+ const ColorListBox* pBox)
+{
+ unsigned i = 0;
+
+ // default entries
+ for ( ; i != ColorConfigEntryCount; ++i)
+ {
+ if (pBox && vEntries[i]->Is(pBox))
+ {
+ ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
+ ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
+ vEntries[i]->ColorChanged(aValue);
+ pConfig->SetColorValue(aColorEntry, aValue);
+ break;
+ }
+ }
+
+ // extended entries
+ unsigned const nExtCount = pExtConfig->GetComponentCount();
+ i = ColorConfigEntryCount;
+ for (unsigned j = 0; j != nExtCount; ++j)
+ {
+ OUString sComponentName = pExtConfig->GetComponentName(j);
+ unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
+ unsigned const nCount = vEntries.size();
+ for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
+ {
+ if (pBox && vEntries[i]->Is(pBox))
+ {
+ ExtendedColorConfigValue aValue =
+ pExtConfig->GetComponentColorConfigValue(sComponentName, k);
+ vEntries[i]->ColorChanged(aValue);
+ pExtConfig->SetColorValue(sComponentName, aValue);
+ break;
+ }
+ }
+ }
+}
+
+
+// IsGroupVisible()
+bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
+{
+ switch (eGroup)
+ {
+ case Group_Writer:
+ case Group_Html:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
+ case Group_Calc:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
+ case Group_Draw:
+ return
+ aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
+ aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
+ case Group_Sql:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
+ default:
+ return true;
+ }
+}
+
+class ColorConfigCtrl_Impl
+{
+ std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
+ std::unique_ptr<weld::Container> m_xBody;
+ std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
+
+ EditableColorConfig* pColorConfig;
+ EditableExtendedColorConfig* pExtColorConfig;
+
+ DECL_LINK(ClickHdl, weld::Toggleable&, void);
+ DECL_LINK(ColorHdl, ColorListBox&, void);
+ DECL_LINK(ControlFocusHdl, weld::Widget&, void);
+
+public:
+ explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
+
+ void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
+ void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
+ void Update();
+ tools::Long GetScrollPosition() const
+ {
+ return m_xVScroll->vadjustment_get_value();
+ }
+ void SetScrollPosition(tools::Long nSet)
+ {
+ m_xVScroll->vadjustment_set_value(nSet);
+ }
+ weld::Widget& GetWidget1()
+ {
+ return m_xScrollWindow->GetWidget1();
+ }
+ weld::Widget& GetWidget2()
+ {
+ return m_xScrollWindow->GetWidget2();
+ }
+ int GetLabelIndent() const
+ {
+ return m_xScrollWindow->GetLabelIndent();
+ }
+};
+
+ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rBuilder)
+ : m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
+ , m_xBody(rBuilder.weld_container("colorconfig"))
+ , m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
+ , pColorConfig(nullptr)
+ , pExtColorConfig(nullptr)
+{
+ m_xBody->set_stack_background();
+
+ Link<weld::Toggleable&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
+ Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
+ Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
+ m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink, *m_xVScroll);
+}
+
+void ColorConfigCtrl_Impl::Update ()
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set");
+ m_xScrollWindow->Update(pColorConfig, pExtColorConfig);
+}
+
+IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::Toggleable&, rBox, void)
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set");
+ m_xScrollWindow->ClickHdl(pColorConfig, rBox);
+}
+
+// a color list has changed
+IMPL_LINK(ColorConfigCtrl_Impl, ColorHdl, ColorListBox&, rBox, void)
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set" );
+ m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
+}
+
+IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
+{
+ // determine whether a control is completely visible
+ // and make it visible
+ unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
+
+ // calc visible area
+ auto nThumbPos = m_xVScroll->vadjustment_get_value();
+ int const nWinTop = nThumbPos;
+ int const nWinBottom = nWinTop + nWinHeight;
+
+ int x, nCtrlPosY, width, nHeight;
+ rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
+
+ int const nSelectedItemTop = nCtrlPosY;
+ int const nSelectedItemBottom = nCtrlPosY + nHeight;
+ bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
+ bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
+ bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
+
+ if (!isNeedToScroll)
+ return;
+
+ if (shouldScrollDown)
+ {
+ int nOffset = nSelectedItemBottom - nWinBottom;
+ nThumbPos += nOffset + 2;
+ }
+ else
+ {
+ int nOffset = nWinTop - nSelectedItemTop;
+ nThumbPos -= nOffset + 2;
+ if(nThumbPos < 0)
+ nThumbPos = 0;
+ }
+ m_xVScroll->vadjustment_set_value(nThumbPos);
+}
+
+// SvxColorOptionsTabPage
+SvxColorOptionsTabPage::SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
+ , bFillItemSetCalled(false)
+ , m_nSizeAllocEventId(nullptr)
+ , m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
+ , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
+ , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
+ , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
+ , m_xTable(m_xBuilder->weld_widget("table"))
+ , m_xOnFT(m_xBuilder->weld_label("on"))
+ , m_xElementFT(m_xBuilder->weld_label("uielements"))
+ , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
+ , m_rWidget1(m_xColorConfigCT->GetWidget1())
+ , m_rWidget2(m_xColorConfigCT->GetWidget2())
+{
+ m_xColorSchemeLB->make_sorted();
+ m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
+ Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
+ m_xSaveSchemePB->connect_clicked(aLk);
+ m_xDeleteSchemePB->connect_clicked(aLk);
+
+ m_rWidget1.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
+ m_rWidget2.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
+}
+
+SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
+{
+ if (pColorConfig)
+ {
+ //when the dialog is cancelled but the color scheme ListBox has been changed these
+ //changes need to be undone
+ if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
+ {
+ OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
+ if(!sOldScheme.isEmpty())
+ {
+ pColorConfig->SetCurrentSchemeName(sOldScheme);
+ pExtColorConfig->SetCurrentSchemeName(sOldScheme);
+ }
+ }
+ pColorConfig->ClearModified();
+ pColorConfig->EnableBroadcast();
+ pColorConfig.reset();
+
+ pExtColorConfig->ClearModified();
+ pExtColorConfig->EnableBroadcast();
+ pExtColorConfig.reset();
+ }
+ m_xColorConfigCT.reset();
+ if (m_nSizeAllocEventId)
+ Application::RemoveUserEvent(m_nSizeAllocEventId);
+}
+
+std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ bFillItemSetCalled = true;
+ if (m_xColorSchemeLB->get_value_changed_from_saved())
+ {
+ pColorConfig->SetModified();
+ pExtColorConfig->SetModified();
+ }
+ if (pColorConfig->IsModified())
+ pColorConfig->Commit();
+ if (pExtColorConfig->IsModified())
+ pExtColorConfig->Commit();
+ return true;
+}
+
+void SvxColorOptionsTabPage::Reset( const SfxItemSet* )
+{
+ if(pColorConfig)
+ {
+ pColorConfig->ClearModified();
+ pColorConfig->DisableBroadcast();
+ }
+ pColorConfig.reset(new EditableColorConfig);
+ m_xColorConfigCT->SetConfig(*pColorConfig);
+
+ if(pExtColorConfig)
+ {
+ pExtColorConfig->ClearModified();
+ pExtColorConfig->DisableBroadcast();
+ }
+ pExtColorConfig.reset(new EditableExtendedColorConfig);
+ m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
+
+ OUString sUser = GetUserData();
+ //has to be called always to speed up accessibility tools
+ m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
+ m_xColorSchemeLB->clear();
+ const uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
+ for(const OUString& s : aSchemes)
+ m_xColorSchemeLB->append_text(s);
+ m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
+ m_xColorSchemeLB->save_value();
+ m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
+ UpdateColorConfig();
+}
+
+DeactivateRC SvxColorOptionsTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxColorOptionsTabPage::UpdateColorConfig()
+{
+ //update the color config control
+ m_xColorConfigCT->Update();
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ pColorConfig->LoadScheme(rBox.get_active_text());
+ pExtColorConfig->LoadScheme(rBox.get_active_text());
+ UpdateColorConfig();
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
+{
+ if (m_xSaveSchemePB.get() == &rButton)
+ {
+ OUString sName;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(GetFrameWeld(),
+ sName, CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE2) ));
+ aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
+ aNameDlg->SetText(CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE1));
+ aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
+ aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
+ if(RET_OK == aNameDlg->Execute())
+ {
+ aNameDlg->GetName(sName);
+ pColorConfig->AddScheme(sName);
+ pExtColorConfig->AddScheme(sName);
+ m_xColorSchemeLB->append_text(sName);
+ m_xColorSchemeLB->set_active_text(sName);
+ SchemeChangedHdl_Impl(*m_xColorSchemeLB);
+ }
+ }
+ else
+ {
+ DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE)));
+ xQuery->set_title(CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE_TITLE));
+ if (RET_YES == xQuery->run())
+ {
+ OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
+ m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
+ m_xColorSchemeLB->set_active(0);
+ SchemeChangedHdl_Impl(*m_xColorSchemeLB);
+ //first select the new scheme and then delete the old one
+ pColorConfig->DeleteScheme(sDeleteScheme);
+ pExtColorConfig->DeleteScheme(sDeleteScheme);
+ }
+ }
+ m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
+{
+ OUString sName;
+ rDialog.GetName(sName);
+ return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
+}
+
+void SvxColorOptionsTabPage::FillUserData()
+{
+ SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
+}
+
+IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
+{
+ if (m_nSizeAllocEventId)
+ return;
+ m_nSizeAllocEventId = Application::PostUserEvent(LINK(this, SvxColorOptionsTabPage, PostAdjustHeaderBar));
+}
+
+IMPL_LINK_NOARG(SvxColorOptionsTabPage, PostAdjustHeaderBar, void*, void)
+{
+ m_nSizeAllocEventId = nullptr;
+
+ // horizontal positions
+ int nX1, nX2, nX3, y, width, height;
+ if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
+ return;
+ if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
+ return;
+ if (!m_xTable->get_extents_relative_to(*m_xTable, nX3, y, width, height))
+ return;
+
+ // 6 is the column-spacing of the parent grid of these labels
+ auto nTextWidth1 = nX1 + m_xColorConfigCT->GetLabelIndent() - 6;
+ m_xOnFT->set_size_request(nTextWidth1, -1);
+ auto nTextWidth3 = width - nX2;
+ m_xColorFT->set_size_request(nTextWidth3, -1);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optcolor.hxx b/cui/source/options/optcolor.hxx
new file mode 100644
index 000000000..ede03dc6b
--- /dev/null
+++ b/cui/source/options/optcolor.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+namespace svtools {class EditableColorConfig;class EditableExtendedColorConfig;}
+class ColorConfigCtrl_Impl;
+class AbstractSvxNameDialog;
+struct ImplSVEvent;
+
+class SvxColorOptionsTabPage : public SfxTabPage
+{
+ bool bFillItemSetCalled;
+
+ ImplSVEvent* m_nSizeAllocEventId;
+
+ std::unique_ptr<weld::ComboBox> m_xColorSchemeLB;
+ std::unique_ptr<weld::Button> m_xSaveSchemePB;
+ std::unique_ptr<weld::Button> m_xDeleteSchemePB;
+ std::unique_ptr<ColorConfigCtrl_Impl> m_xColorConfigCT;
+ std::unique_ptr<weld::Widget> m_xTable;
+ std::unique_ptr<weld::Label> m_xOnFT;
+ std::unique_ptr<weld::Label> m_xElementFT;
+ std::unique_ptr<weld::Label> m_xColorFT;
+ weld::Widget& m_rWidget1;
+ weld::Widget& m_rWidget2;
+
+ std::unique_ptr<svtools::EditableColorConfig> pColorConfig;
+ std::unique_ptr<svtools::EditableExtendedColorConfig> pExtColorConfig;
+
+ DECL_LINK(SchemeChangedHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SaveDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckNameHdl_Impl, AbstractSvxNameDialog&, bool);
+ DECL_LINK(AdjustHeaderBar, const Size&, void);
+ DECL_LINK(PostAdjustHeaderBar, void *, void);
+ void UpdateColorConfig();
+
+public:
+ SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxColorOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void FillUserData() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optctl.cxx b/cui/source/options/optctl.cxx
new file mode 100644
index 000000000..52bd18fc8
--- /dev/null
+++ b/cui/source/options/optctl.cxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optctl.hxx"
+#include <svl/ctloptions.hxx>
+#include <sal/log.hxx>
+#include <tools/debug.hxx>
+
+// class SvxCTLOptionsPage -----------------------------------------------------
+
+IMPL_LINK_NOARG(SvxCTLOptionsPage, SequenceCheckingCB_Hdl, weld::Toggleable&, void)
+{
+ bool bIsSequenceChecking = m_xSequenceCheckingCB->get_active();
+ m_xRestrictedCB->set_sensitive( bIsSequenceChecking );
+ m_xTypeReplaceCB->set_sensitive( bIsSequenceChecking );
+ // #i48117#: by default restricted and type&replace have to be switched on
+ if (bIsSequenceChecking)
+ {
+ m_xTypeReplaceCB->set_active(true);
+ m_xRestrictedCB->set_active(true);
+ }
+}
+
+SvxCTLOptionsPage::SvxCTLOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optctlpage.ui", "OptCTLPage", &rSet)
+ , m_xSequenceCheckingCB(m_xBuilder->weld_check_button("sequencechecking"))
+ , m_xRestrictedCB(m_xBuilder->weld_check_button("restricted"))
+ , m_xTypeReplaceCB(m_xBuilder->weld_check_button("typeandreplace"))
+ , m_xMovementLogicalRB(m_xBuilder->weld_radio_button("movementlogical"))
+ , m_xMovementVisualRB(m_xBuilder->weld_radio_button("movementvisual"))
+ , m_xNumeralsLB(m_xBuilder->weld_combo_box("numerals"))
+{
+ m_xSequenceCheckingCB->connect_toggled(LINK(this, SvxCTLOptionsPage, SequenceCheckingCB_Hdl));
+}
+
+SvxCTLOptionsPage::~SvxCTLOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxCTLOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxCTLOptionsPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxCTLOptionsPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ SvtCTLOptions aCTLOptions;
+
+ // Sequence checking
+ bool bChecked = m_xSequenceCheckingCB->get_active();
+ if ( m_xSequenceCheckingCB->get_state_changed_from_saved() )
+ {
+ aCTLOptions.SetCTLSequenceChecking( bChecked );
+ bModified = true;
+ }
+
+ bChecked = m_xRestrictedCB->get_active();
+ if( m_xRestrictedCB->get_state_changed_from_saved() )
+ {
+ aCTLOptions.SetCTLSequenceCheckingRestricted( bChecked );
+ bModified = true;
+ }
+ bChecked = m_xTypeReplaceCB->get_active();
+ if( m_xTypeReplaceCB->get_state_changed_from_saved())
+ {
+ aCTLOptions.SetCTLSequenceCheckingTypeAndReplace(bChecked);
+ bModified = true;
+ }
+
+ bool bLogicalChecked = m_xMovementLogicalRB->get_active();
+ if ( m_xMovementLogicalRB->get_state_changed_from_saved() ||
+ m_xMovementVisualRB->get_state_changed_from_saved() )
+ {
+ SvtCTLOptions::CursorMovement eMovement =
+ bLogicalChecked ? SvtCTLOptions::MOVEMENT_LOGICAL : SvtCTLOptions::MOVEMENT_VISUAL;
+ aCTLOptions.SetCTLCursorMovement( eMovement );
+ bModified = true;
+ }
+
+ if (m_xNumeralsLB->get_value_changed_from_saved())
+ {
+ const sal_Int32 nPos = m_xNumeralsLB->get_active();
+ aCTLOptions.SetCTLTextNumerals( static_cast<SvtCTLOptions::TextNumerals>(nPos) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxCTLOptionsPage::Reset( const SfxItemSet* )
+{
+ SvtCTLOptions aCTLOptions;
+
+ m_xSequenceCheckingCB->set_active( aCTLOptions.IsCTLSequenceChecking() );
+ m_xRestrictedCB->set_active( aCTLOptions.IsCTLSequenceCheckingRestricted() );
+ m_xTypeReplaceCB->set_active( aCTLOptions.IsCTLSequenceCheckingTypeAndReplace() );
+
+ SvtCTLOptions::CursorMovement eMovement = aCTLOptions.GetCTLCursorMovement();
+ switch ( eMovement )
+ {
+ case SvtCTLOptions::MOVEMENT_LOGICAL :
+ m_xMovementLogicalRB->set_active(true);
+ break;
+
+ case SvtCTLOptions::MOVEMENT_VISUAL :
+ m_xMovementVisualRB->set_active(true);
+ break;
+
+ default:
+ SAL_WARN( "cui.options", "SvxCTLOptionsPage::Reset(): invalid movement enum" );
+ }
+
+ sal_uInt16 nPos = static_cast<sal_uInt16>(aCTLOptions.GetCTLTextNumerals());
+ DBG_ASSERT( nPos < m_xNumeralsLB->get_count(), "SvxCTLOptionsPage::Reset(): invalid numerals enum" );
+ m_xNumeralsLB->set_active(nPos);
+
+ m_xSequenceCheckingCB->save_state();
+ m_xRestrictedCB->save_state();
+ m_xTypeReplaceCB->save_state();
+ m_xMovementLogicalRB->save_state();
+ m_xMovementVisualRB->save_state();
+ m_xNumeralsLB->save_value();
+
+ bool bIsSequenceChecking = m_xSequenceCheckingCB->get_active();
+ m_xRestrictedCB->set_sensitive( bIsSequenceChecking );
+ m_xTypeReplaceCB->set_sensitive( bIsSequenceChecking );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optctl.hxx b/cui/source/options/optctl.hxx
new file mode 100644
index 000000000..0cc24951b
--- /dev/null
+++ b/cui/source/options/optctl.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+// class SvxCTLOptionsPage -----------------------------------------------------
+
+class SvxCTLOptionsPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xSequenceCheckingCB;
+ std::unique_ptr<weld::CheckButton> m_xRestrictedCB;
+ std::unique_ptr<weld::CheckButton> m_xTypeReplaceCB;
+ std::unique_ptr<weld::RadioButton> m_xMovementLogicalRB;
+ std::unique_ptr<weld::RadioButton> m_xMovementVisualRB;
+ std::unique_ptr<weld::ComboBox> m_xNumeralsLB;
+
+ DECL_LINK( SequenceCheckingCB_Hdl, weld::Toggleable&, void );
+
+public:
+ SvxCTLOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxCTLOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optdict.cxx b/cui/source/options/optdict.cxx
new file mode 100644
index 000000000..f0efb39ca
--- /dev/null
+++ b/cui/source/options/optdict.cxx
@@ -0,0 +1,774 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <editeng/unolingu.hxx>
+#include <o3tl/safeint.hxx>
+#include <svx/dialmgr.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <comphelper/string.hxx>
+#include <tools/debug.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <linguistic/misc.hxx>
+#include <strings.hrc>
+#include <optdict.hxx>
+#include <dialmgr.hxx>
+#include <svx/svxerr.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+using namespace linguistic;
+
+// static function -------------------------------------------------------
+
+static OUString getNormDicEntry_Impl(std::u16string_view rText)
+{
+ OUString aTmp(comphelper::string::stripEnd(rText, '.'));
+ // non-standard hyphenation
+ if (aTmp.indexOf('[') > -1)
+ {
+ OUStringBuffer aTmp2 ( aTmp.getLength() );
+ bool bSkip = false;
+ for (sal_Int32 i = 0; i < aTmp.getLength(); i++)
+ {
+ sal_Unicode cTmp = aTmp[i];
+ if (cTmp == '[')
+ bSkip = true;
+ else if (!bSkip)
+ aTmp2.append( cTmp );
+ else if (cTmp == ']')
+ bSkip = false;
+ }
+ aTmp = aTmp2.makeStringAndClear();
+ }
+ return aTmp.replaceAll("=", "");
+}
+
+namespace {
+
+// Compare Dictionary Entry result
+enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
+
+}
+
+static CDE_RESULT cmpDicEntry_Impl( std::u16string_view rText1, std::u16string_view rText2 )
+{
+ CDE_RESULT eRes = CDE_DIFFERENT;
+
+ if (rText1 == rText2)
+ eRes = CDE_EQUAL;
+ else
+ { // similar = equal up to trailing '.' and hyphenation positions
+ // marked with '=' and '[' + alternative spelling pattern + ']'
+ if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
+ eRes = CDE_SIMILAR;
+ }
+
+ return eRes;
+}
+
+// class SvxNewDictionaryDialog -------------------------------------------
+
+SvxNewDictionaryDialog::SvxNewDictionaryDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/optnewdictionarydialog.ui", "OptNewDictionaryDialog")
+ , m_xNameEdit(m_xBuilder->weld_entry("nameedit"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xExceptBtn(m_xBuilder->weld_check_button("except"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ // Prevent creation of dictionary without a name.
+ m_xOKBtn->set_sensitive(false);
+
+ // install handler
+ m_xNameEdit->connect_changed(LINK(this, SvxNewDictionaryDialog, ModifyHdl_Impl));
+ m_xOKBtn->connect_clicked(LINK(this, SvxNewDictionaryDialog, OKHdl_Impl));
+
+ // display languages
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::ALL, true, true);
+ m_xLanguageLB->set_active(0);
+}
+
+IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl, weld::Button&, void)
+{
+
+ // add extension for personal dictionaries
+ OUString sDict = comphelper::string::stripEnd(m_xNameEdit->get_text(), ' ') + ".dic";
+
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+
+ Sequence< Reference< XDictionary > > aDics;
+ if (xDicList.is())
+ aDics = xDicList->getDictionaries();
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ bool bFound = false;
+ sal_Int32 i;
+ for (i = 0; !bFound && i < nCount; ++i )
+ if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
+ bFound = true;
+
+ if ( sDict.indexOf("/") != -1 || sDict.indexOf("\\") != -1 )
+ {
+ // Detected an invalid character.
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_OPT_INVALID_DICT_NAME)));
+ xInfoBox->run();
+ m_xNameEdit->grab_focus();
+ return;
+ }
+
+ if ( bFound )
+ {
+ // duplicate names?
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_OPT_DOUBLE_DICTS)));
+ xInfoBox->run();
+ m_xNameEdit->grab_focus();
+ return;
+ }
+
+ // create and add
+ LanguageType nLang = m_xLanguageLB->get_active_id();
+ try
+ {
+ // create new dictionary
+ DictionaryType eType = m_xExceptBtn->get_active() ?
+ DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
+ if (xDicList.is())
+ {
+ lang::Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) );
+ m_xNewDic = xDicList->createDictionary(sDict, aLocale, eType, aURL);
+ m_xNewDic->setActive(true);
+ }
+ DBG_ASSERT(m_xNewDic.is(), "NULL pointer");
+ }
+ catch(...)
+ {
+ m_xNewDic = nullptr;
+ // error: couldn't create new dictionary
+ SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(),
+ m_xDialog.get(), RID_SVXERRCTX, SvxResLocale() );
+ ErrorHandler::HandleError( *new StringErrorInfo(
+ ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
+ m_xDialog->response(RET_CANCEL);
+ }
+
+ if (xDicList.is() && m_xNewDic.is())
+ {
+ xDicList->addDictionary(m_xNewDic);
+
+ // refresh list of dictionaries
+ //! dictionaries may have been added/removed elsewhere too.
+ aDics = xDicList->getDictionaries();
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxNewDictionaryDialog, ModifyHdl_Impl, weld::Entry&, void)
+{
+ m_xOKBtn->set_sensitive(!m_xNameEdit->get_text().isEmpty());
+}
+
+// class SvxEditDictionaryDialog -------------------------------------------
+
+SvxEditDictionaryDialog::SvxEditDictionaryDialog(weld::Window* pParent, std::u16string_view rName)
+ : GenericDialogController(pParent, "cui/ui/editdictionarydialog.ui", "EditDictionaryDialog")
+ , sModify(CuiResId(STR_MODIFY))
+ , bFirstSelect(false)
+ , bDoNothing(false)
+ , bDicIsReadonly(false)
+ , m_xAllDictsLB(m_xBuilder->weld_combo_box("book"))
+ , m_xLangFT(m_xBuilder->weld_label("lang_label"))
+ , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+ , m_xWordED(m_xBuilder->weld_entry("word"))
+ , m_xReplaceFT(m_xBuilder->weld_label("replace_label"))
+ , m_xReplaceED(m_xBuilder->weld_entry("replace"))
+ , m_xSingleColumnLB(m_xBuilder->weld_tree_view("words"))
+ , m_xDoubleColumnLB(m_xBuilder->weld_tree_view("replaces"))
+ , m_xNewReplacePB(m_xBuilder->weld_button("newreplace"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+{
+ sReplaceFT_Text = m_xReplaceFT->get_label();
+ m_xSingleColumnLB->set_size_request(-1, m_xSingleColumnLB->get_height_rows(8));
+ m_xDoubleColumnLB->set_size_request(-1, m_xDoubleColumnLB->get_height_rows(8));
+ m_pWordsLB = m_xDoubleColumnLB.get();
+ m_xSingleColumnLB->hide();
+
+ //set to max of both sizes to avoid resizes
+ sNew = m_xNewReplacePB->get_label();
+ auto nNewWidth = m_xNewReplacePB->get_preferred_size().Width();
+ m_xNewReplacePB->set_label(sModify);
+ auto nReplaceWidth = m_xNewReplacePB->get_preferred_size().Width();
+ m_xNewReplacePB->set_label(sNew);
+ m_xNewReplacePB->set_size_request(std::max(nNewWidth, nReplaceWidth), -1);
+
+ if (LinguMgr::GetDictionaryList().is())
+ aDics = LinguMgr::GetDictionaryList()->getDictionaries();
+
+ m_xSingleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
+ m_xDoubleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xDoubleColumnLB->get_approximate_digit_width() * 22)
+ };
+ m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
+
+ // install handler
+ m_xNewReplacePB->connect_clicked(
+ LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
+ m_xDeletePB->connect_clicked(
+ LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
+
+ m_xLangLB->connect_changed(
+ LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
+ m_xAllDictsLB->connect_changed(
+ LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
+
+ m_xWordED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
+ m_xReplaceED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
+ m_xWordED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
+ m_xReplaceED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
+
+ // fill listbox with all available WB's
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ OUString aLookUpEntry;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ Reference< XDictionary > xDic = pDic[i];
+ if (xDic.is())
+ {
+ bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+ OUString aDicName( xDic->getName() );
+ const OUString aTxt( ::GetDicInfoStr( aDicName,
+ LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) );
+ m_xAllDictsLB->append_text(aTxt);
+
+ if (rName == aDicName)
+ aLookUpEntry = aTxt;
+ }
+ }
+
+ m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true );
+
+ Link<OUString&,bool> aLink = LINK(this, SvxEditDictionaryDialog, InsertTextHdl);
+ m_xReplaceED->connect_insert_text(aLink);
+ m_xWordED->connect_insert_text(aLink);
+
+ if ( nCount > 0 )
+ {
+ m_xAllDictsLB->set_active_text(aLookUpEntry);
+ int nPos = m_xAllDictsLB->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = 0;
+ m_xAllDictsLB->set_active(nPos);
+ }
+ Reference< XDictionary > xDic;
+ if (nPos != -1)
+ xDic = aDics[ nPos ];
+ if (xDic.is())
+ SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
+
+ // check if dictionary is read-only
+ SetDicReadonly_Impl(xDic);
+ bool bEnable = !IsDicReadonly_Impl();
+ m_xNewReplacePB->set_sensitive( false );
+ m_xDeletePB->set_sensitive( false );
+ m_xLangFT->set_sensitive( bEnable );
+ m_xLangLB->set_sensitive( bEnable );
+ ShowWords_Impl( nPos );
+ }
+ else
+ {
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeletePB->set_sensitive(false);
+ }
+
+ m_xWordED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
+ m_xReplaceED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, EntrySizeAllocHdl, const Size&, void)
+{
+ std::vector<int> aWidths;
+ int x, y, width, height;
+ if (m_xReplaceED->get_extents_relative_to(*m_pWordsLB, x, y, width, height))
+ {
+ aWidths.push_back(x);
+ m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
+ }
+}
+
+SvxEditDictionaryDialog::~SvxEditDictionaryDialog()
+{
+}
+
+void SvxEditDictionaryDialog::SetDicReadonly_Impl(
+ Reference< XDictionary > const &xDic )
+{
+ // enable or disable new and delete button according to file attributes
+ bDicIsReadonly = true;
+ if (xDic.is())
+ {
+ Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
+ if ( !xStor.is() // non persistent dictionary
+ || !xStor->hasLocation() // not yet persistent
+ || !xStor->isReadonly() )
+ {
+ bDicIsReadonly = false;
+ }
+ }
+}
+
+void SvxEditDictionaryDialog::SetLanguage_Impl(LanguageType nLanguage)
+{
+ // select language
+ m_xLangLB->set_active_id(nLanguage);
+}
+
+int SvxEditDictionaryDialog::GetLBInsertPos(std::u16string_view rDicWord)
+{
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ int j;
+ int nCount = m_pWordsLB->n_children();
+ for (j = 0; j < nCount; ++j)
+ {
+ OUString aNormEntry( getNormDicEntry_Impl( rDicWord ) );
+ sal_Int32 nCmpRes = pCollator->
+ compareString( aNormEntry, getNormDicEntry_Impl( m_pWordsLB->get_text(j, 0) ) );
+ if (nCmpRes < 0)
+ break;
+ }
+
+ return j;
+}
+
+void SvxEditDictionaryDialog::RemoveDictEntry(int nEntry)
+{
+ int nLBPos = m_xAllDictsLB->get_active();
+ if (nEntry != -1 && nLBPos != -1)
+ {
+ OUString sTmpShort(m_pWordsLB->get_text(nEntry, 0));
+
+ Reference<XDictionary> xDic = aDics.getConstArray()[nLBPos];
+ if (xDic->remove(sTmpShort)) // sal_True on success
+ {
+ m_pWordsLB->remove(nEntry);
+ SelectHdl(*m_pWordsLB);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectBookHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xAllDictsLB->get_active();
+ if (nPos == -1)
+ return;
+
+ m_xNewReplacePB->set_sensitive( false );
+ m_xDeletePB->set_sensitive( false );
+ // display dictionary
+ ShowWords_Impl( nPos );
+ // enable or disable new and delete button according to file attributes
+ Reference< XDictionary > const & xDic = aDics[ nPos ];
+ if (xDic.is())
+ SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
+
+ SetDicReadonly_Impl(xDic);
+ bool bEnable = !IsDicReadonly_Impl();
+ m_xLangFT->set_sensitive( bEnable );
+ m_xLangLB->set_sensitive( bEnable );
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectLangHdl_Impl, weld::ComboBox&, void)
+{
+ int nDicPos = m_xAllDictsLB->get_active();
+ LanguageType nLang = m_xLangLB->get_active_id();
+ Reference< XDictionary > const & xDic = aDics[ nDicPos ];
+ LanguageType nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType();
+
+ if ( nLang == nOldLang )
+ return;
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_CONFIRM_SET_LANGUAGE)));
+ OUString sTxt(xBox->get_primary_text());
+ sTxt = sTxt.replaceFirst("%1", m_xAllDictsLB->get_active_text());
+ xBox->set_primary_text(sTxt);
+
+ if (xBox->run() == RET_YES)
+ {
+ xDic->setLocale( LanguageTag::convertToLocale( nLang ) );
+ bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+
+ const OUString sName(
+ ::GetDicInfoStr( xDic->getName(),
+ LanguageTag( xDic->getLocale() ).getLanguageType(),
+ bNegativ ) );
+ m_xAllDictsLB->remove(nDicPos);
+ m_xAllDictsLB->insert_text(nDicPos, sName);
+ m_xAllDictsLB->set_active(nDicPos);
+ }
+ else
+ SetLanguage_Impl( nOldLang );
+}
+
+void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
+{
+ Reference< XDictionary > xDic = aDics.getConstArray()[ nId ];
+
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xWordED->set_text(OUString());
+ m_xReplaceED->set_text(OUString());
+
+ bool bIsNegative = xDic->getDictionaryType() != DictionaryType_POSITIVE;
+ bool bLangNone = LanguageTag(
+ xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE;
+
+ // The label is "Replace By" only in negative dictionaries (forbidden
+ // words), otherwise "Grammar By" in language-specific dictionaries
+ // (where the optional second word is the sample word for
+ // the Hunspell based affixation/compounding of the new dictionary word)
+ if (bIsNegative)
+ {
+ m_xReplaceFT->set_label(sReplaceFT_Text);
+ } else if (!bLangNone) {
+ m_xReplaceFT->set_label(CuiResId(RID_CUISTR_OPT_GRAMMAR_BY));
+ }
+
+ if(bIsNegative || !bLangNone)
+ {
+ // make controls for replacement text active
+ if (!m_xReplaceFT->get_visible())
+ {
+ m_xReplaceFT->show();
+ m_xReplaceED->show();
+ m_xSingleColumnLB->hide();
+ m_xDoubleColumnLB->show();
+ m_pWordsLB = m_xDoubleColumnLB.get();
+ }
+ }
+ else
+ {
+ // deactivate controls for replacement text
+ if (m_xReplaceFT->get_visible())
+ {
+ m_xReplaceFT->hide();
+ m_xReplaceED->hide();
+ m_xDoubleColumnLB->hide();
+ m_xSingleColumnLB->show();
+ m_pWordsLB = m_xSingleColumnLB.get();
+ }
+ }
+
+ m_pWordsLB->clear();
+
+ Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() );
+ const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray();
+ sal_Int32 nCount = aEntries.getLength();
+ std::vector<OUString> aSortedDicEntries;
+ aSortedDicEntries.reserve(nCount);
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ OUString aStr = pEntry[i]->getDictionaryWord();
+ if(!pEntry[i]->getReplacementText().isEmpty())
+ {
+ aStr += "\t" + pEntry[i]->getReplacementText();
+ }
+ aSortedDicEntries.push_back(aStr);
+ }
+
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ std::sort(aSortedDicEntries.begin(), aSortedDicEntries.end(),
+ [&] (OUString const & lhs, OUString const & rhs)
+ {
+ sal_Int32 nCmpRes = pCollator->
+ compareString( getNormDicEntry_Impl(lhs), getNormDicEntry_Impl( rhs ) );
+ return nCmpRes < 0;
+ });
+
+ m_pWordsLB->freeze(); // speed up insert
+ int nRow = 0;
+ for (OUString const & rStr : aSortedDicEntries)
+ {
+ m_pWordsLB->append_text(rStr.getToken(0, '\t'));
+ if (m_pWordsLB == m_xDoubleColumnLB.get())
+ {
+ OUString sReplace = rStr.getToken(1, '\t');
+ m_pWordsLB->set_text(nRow, sReplace, 1);
+ ++nRow;
+ }
+ }
+ m_pWordsLB->thaw();
+
+ if (m_pWordsLB->n_children())
+ {
+ m_pWordsLB->select(0);
+ m_pWordsLB->set_cursor(0);
+ SelectHdl(*m_pWordsLB);
+ }
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (bDoNothing)
+ return;
+
+ int nEntry = rBox.get_selected_index();
+
+ if(!bFirstSelect)
+ {
+ if (nEntry != -1)
+ {
+ OUString sTmpShort(rBox.get_text(nEntry, 0));
+ // without this the cursor is always at the beginning of a word, if the text
+ // is set over the ModifyHdl, although you're editing there at the moment
+ if (m_xWordED->get_text() != sTmpShort)
+ m_xWordED->set_text(sTmpShort);
+ if (&rBox == m_xDoubleColumnLB.get())
+ m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
+ }
+ }
+ else
+ bFirstSelect = false;
+
+ // entries in the list box should exactly correspond to those from the
+ // dictionary. Thus:
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeletePB->set_sensitive(nEntry != -1 && !IsDicReadonly_Impl());
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, NewDelActionHdl, weld::Entry&, rDictEdit, bool)
+{
+ return NewDelHdl(&rDictEdit);
+}
+
+bool SvxEditDictionaryDialog::NewDelHdl(const weld::Widget* pBtn)
+{
+ if (pBtn == m_xDeletePB.get())
+ {
+ m_xWordED->set_text("");
+ m_xReplaceED->set_text("");
+ m_xDeletePB->set_sensitive(false);
+
+ int nEntry = m_pWordsLB->get_selected_index();
+ RemoveDictEntry(nEntry); // remove entry from dic and list-box
+ }
+ if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
+ {
+ int nEntry = m_pWordsLB->get_selected_index();
+ OUString aNewWord(m_xWordED->get_text());
+ OUString sEntry(aNewWord);
+ OUString aReplaceStr(m_xReplaceED->get_text());
+
+ DictionaryError nAddRes = DictionaryError::UNKNOWN;
+ int nPos = m_xAllDictsLB->get_active();
+ if (nPos != -1 && !aNewWord.isEmpty())
+ {
+ DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
+ Reference< XDictionary > const & xDic = aDics[ nPos ];
+ if (xDic.is())
+ {
+ // make changes in dic
+
+ bool bIsNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+
+ OUString aRplcText;
+ if(!aReplaceStr.isEmpty())
+ aRplcText = aReplaceStr;
+
+ if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
+ xDic->remove(m_pWordsLB->get_text(nEntry, 0));
+ // if remove has failed the following add should fail too
+ // and thus a warning message should be triggered...
+
+ nAddRes = linguistic::AddEntryToDic( xDic,
+ aNewWord, bIsNegEntry,
+ aRplcText, false );
+ }
+ }
+ if (DictionaryError::NONE != nAddRes)
+ SvxDicError(m_xDialog.get(), nAddRes);
+
+ if (DictionaryError::NONE == nAddRes && !sEntry.isEmpty())
+ {
+ // insert new entry in list-box etc...
+ m_pWordsLB->freeze();
+
+ if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
+ {
+ m_pWordsLB->set_text(nEntry, sEntry);
+ if (!aReplaceStr.isEmpty())
+ m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
+ }
+ else
+ {
+ nEntry = GetLBInsertPos(aNewWord);
+ m_pWordsLB->insert_text(nEntry, sEntry);
+ if(!aReplaceStr.isEmpty())
+ m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
+ }
+
+ m_pWordsLB->thaw();
+ m_pWordsLB->scroll_to_row(nEntry);
+
+ // if the request came from the ReplaceEdit, give focus to the ShortEdit
+ if (m_xReplaceED->has_focus())
+ m_xWordED->grab_focus();
+ }
+ }
+ else
+ {
+ // this can only be an enter in one of the two edit fields
+ // which means EndDialog() - has to be evaluated in KeyInput
+ return false;
+ }
+ ModifyHdl(*m_xWordED);
+ return true;
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ OUString rEntry = rEdt.get_text();
+
+ sal_Int32 nWordLen = rEntry.getLength();
+ const OUString& rRepString = m_xReplaceED->get_text();
+
+ bool bEnableNewReplace = false;
+ bool bEnableDelete = false;
+ OUString aNewReplaceText = sNew;
+
+ if (&rEdt == m_xWordED.get())
+ {
+ if(nWordLen>0)
+ {
+ bool bFound = false;
+ bool bTmpSelEntry=false;
+ CDE_RESULT eCmpRes = CDE_DIFFERENT;
+
+ bool bDoubleColumn = m_pWordsLB == m_xDoubleColumnLB.get();
+
+ for (int i = 0, nCount = m_pWordsLB->n_children(); i < nCount; ++i)
+ {
+ OUString aTestStr(m_pWordsLB->get_text(i, 0));
+ eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
+ if(CDE_DIFFERENT != eCmpRes)
+ {
+ if(!rRepString.isEmpty())
+ bFirstSelect = true;
+ bDoNothing=true;
+ m_pWordsLB->set_cursor(i);
+ bDoNothing=false;
+ if (bDoubleColumn)
+ m_xReplaceED->set_text(m_pWordsLB->get_text(i, 1));
+
+ if (CDE_SIMILAR == eCmpRes)
+ {
+ aNewReplaceText = sModify;
+ bEnableNewReplace = true;
+ }
+ bFound= true;
+ break;
+ }
+ else if(getNormDicEntry_Impl(aTestStr).indexOf(
+ getNormDicEntry_Impl( rEntry ) ) == 0
+ && !bTmpSelEntry)
+ {
+ bDoNothing=true;
+ m_pWordsLB->scroll_to_row(i);
+ bDoNothing=false;
+ bTmpSelEntry=true;
+
+ aNewReplaceText = sNew;
+ bEnableNewReplace = true;
+ }
+ }
+
+ if(!bFound)
+ {
+ m_pWordsLB->unselect_all();
+ aNewReplaceText = sNew;
+ bEnableNewReplace = true;
+ }
+ bEnableDelete = CDE_DIFFERENT != eCmpRes;
+ }
+ else if (m_pWordsLB->n_children() > 0)
+ {
+ bDoNothing=true;
+ m_pWordsLB->scroll_to_row(0);
+ bDoNothing=false;
+ }
+ }
+ else if(&rEdt == m_xReplaceED.get())
+ {
+ OUString aReplaceText;
+ OUString aWordText;
+ int nFirstSel = m_pWordsLB->get_selected_index();
+ if (nFirstSel != -1) // a m_pWordsLB entry is selected
+ {
+ aWordText = m_pWordsLB->get_text(nFirstSel, 0);
+ aReplaceText = m_pWordsLB->get_text(nFirstSel, 1);
+
+ aNewReplaceText = sModify;
+ bEnableDelete = true;
+ }
+ bool bIsChange =
+ CDE_EQUAL != cmpDicEntry_Impl(m_xWordED->get_text(), aWordText)
+ || CDE_EQUAL != cmpDicEntry_Impl(m_xReplaceED->get_text(), aReplaceText);
+ if (!m_xWordED->get_text().isEmpty() && bIsChange)
+ bEnableNewReplace = true;
+ }
+
+ m_xNewReplacePB->set_label(aNewReplaceText);
+ m_xNewReplacePB->set_sensitive(bEnableNewReplace && !IsDicReadonly_Impl());
+ m_xDeletePB->set_sensitive(bEnableDelete && !IsDicReadonly_Impl());
+}
+
+IMPL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString&, rText, bool)
+{
+ rText = rText.replaceAll(" ", "");
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optfltr.cxx b/cui/source/options/optfltr.cxx
new file mode 100644
index 000000000..48840b17e
--- /dev/null
+++ b/cui/source/options/optfltr.cxx
@@ -0,0 +1,346 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/moduleoptions.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <officecfg/Office/Common.hxx>
+#include "optfltr.hxx"
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+enum class MSFltrPg2_CheckBoxEntries {
+ Math,
+ Writer,
+ Calc,
+ Impress,
+ SmartArt,
+ Visio,
+ PDF,
+ InvalidCBEntry
+};
+
+
+OfaMSFilterTabPage::OfaMSFilterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfltrpage.ui", "OptFltrPage", &rSet)
+ , m_xWBasicCodeCB(m_xBuilder->weld_check_button("wo_basic"))
+ , m_xWBasicWbctblCB(m_xBuilder->weld_check_button("wo_exec"))
+ , m_xWBasicStgCB(m_xBuilder->weld_check_button("wo_saveorig"))
+ , m_xEBasicCodeCB(m_xBuilder->weld_check_button("ex_basic"))
+ , m_xEBasicExectblCB(m_xBuilder->weld_check_button("ex_exec"))
+ , m_xEBasicStgCB(m_xBuilder->weld_check_button("ex_saveorig"))
+ , m_xPBasicCodeCB(m_xBuilder->weld_check_button("pp_basic"))
+ , m_xPBasicStgCB(m_xBuilder->weld_check_button("pp_saveorig"))
+{
+ m_xWBasicCodeCB->connect_toggled( LINK( this, OfaMSFilterTabPage, LoadWordBasicCheckHdl_Impl ) );
+ m_xEBasicCodeCB->connect_toggled( LINK( this, OfaMSFilterTabPage, LoadExcelBasicCheckHdl_Impl ) );
+}
+
+OfaMSFilterTabPage::~OfaMSFilterTabPage()
+{
+}
+
+IMPL_LINK_NOARG(OfaMSFilterTabPage, LoadWordBasicCheckHdl_Impl, weld::Toggleable&, void)
+{
+ m_xWBasicWbctblCB->set_sensitive(m_xWBasicCodeCB->get_active());
+}
+
+IMPL_LINK_NOARG(OfaMSFilterTabPage, LoadExcelBasicCheckHdl_Impl, weld::Toggleable&, void)
+{
+ m_xEBasicExectblCB->set_sensitive(m_xEBasicCodeCB->get_active());
+}
+
+std::unique_ptr<SfxTabPage> OfaMSFilterTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMSFilterTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaMSFilterTabPage::FillItemSet( SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ if( m_xWBasicCodeCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicCode( m_xWBasicCodeCB->get_active() );
+ if( m_xWBasicWbctblCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicExecutable( m_xWBasicWbctblCB->get_active() );
+ if( m_xWBasicStgCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicStorage( m_xWBasicStgCB->get_active() );
+
+ if( m_xEBasicCodeCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicCode( m_xEBasicCodeCB->get_active() );
+ if( m_xEBasicExectblCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicExecutable( m_xEBasicExectblCB->get_active() );
+ if( m_xEBasicStgCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicStorage( m_xEBasicStgCB->get_active() );
+
+ if( m_xPBasicCodeCB->get_state_changed_from_saved())
+ rOpt.SetLoadPPointBasicCode( m_xPBasicCodeCB->get_active() );
+ if( m_xPBasicStgCB->get_state_changed_from_saved())
+ rOpt.SetLoadPPointBasicStorage( m_xPBasicStgCB->get_active() );
+
+ return false;
+}
+
+void OfaMSFilterTabPage::Reset( const SfxItemSet* )
+{
+ const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ m_xWBasicCodeCB->set_active( rOpt.IsLoadWordBasicCode() );
+ m_xWBasicCodeCB->save_state();
+ m_xWBasicWbctblCB->set_active( rOpt.IsLoadWordBasicExecutable() );
+ m_xWBasicWbctblCB->save_state();
+ m_xWBasicStgCB->set_active( rOpt.IsLoadWordBasicStorage() );
+ m_xWBasicStgCB->save_state();
+ LoadWordBasicCheckHdl_Impl( *m_xWBasicCodeCB );
+
+ m_xEBasicCodeCB->set_active( rOpt.IsLoadExcelBasicCode() );
+ m_xEBasicCodeCB->save_state();
+ m_xEBasicExectblCB->set_active( rOpt.IsLoadExcelBasicExecutable() );
+ m_xEBasicExectblCB->save_state();
+ m_xEBasicStgCB->set_active( rOpt.IsLoadExcelBasicStorage() );
+ m_xEBasicStgCB->save_state();
+ LoadExcelBasicCheckHdl_Impl( *m_xEBasicCodeCB );
+
+ m_xPBasicCodeCB->set_active( rOpt.IsLoadPPointBasicCode() );
+ m_xPBasicCodeCB->save_state();
+ m_xPBasicStgCB->set_active( rOpt.IsLoadPPointBasicStorage() );
+ m_xPBasicStgCB->save_state();
+}
+
+OfaMSFilterTabPage2::OfaMSFilterTabPage2(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfltrembedpage.ui", "OptFilterPage", &rSet)
+ , sChgToFromMath(CuiResId(RID_CUISTR_CHG_MATH))
+ , sChgToFromWriter(CuiResId(RID_CUISTR_CHG_WRITER))
+ , sChgToFromCalc(CuiResId(RID_CUISTR_CHG_CALC))
+ , sChgToFromImpress(CuiResId(RID_CUISTR_CHG_IMPRESS))
+ , sChgToFromSmartArt(CuiResId(RID_CUISTR_CHG_SMARTART))
+ , sChgToFromVisio(CuiResId(RID_CUISTR_CHG_VISIO))
+ , sChgToFromPDF(CuiResId(RID_CUISTR_CHG_PDF))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklbcontainer"))
+ , m_xHighlightingRB(m_xBuilder->weld_radio_button("highlighting"))
+ , m_xShadingRB(m_xBuilder->weld_radio_button("shading"))
+ , m_xMSOLockFileCB(m_xBuilder->weld_check_button("mso_lockfile"))
+{
+ std::vector<int> aWidths
+ {
+ m_xCheckLB->get_checkbox_column_width(),
+ m_xCheckLB->get_checkbox_column_width()
+ };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+OfaMSFilterTabPage2::~OfaMSFilterTabPage2()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaMSFilterTabPage2::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMSFilterTabPage2>( pPage, pController, *rAttrSet );
+}
+
+bool OfaMSFilterTabPage2::FillItemSet( SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ static struct ChkCBoxEntries{
+ MSFltrPg2_CheckBoxEntries eType;
+ bool (SvtFilterOptions::*FnIs)() const;
+ void (SvtFilterOptions::*FnSet)( bool bFlag );
+ } const aChkArr[] = {
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMathType2Math,
+ &SvtFilterOptions::SetMathType2Math },
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMath2MathType,
+ &SvtFilterOptions::SetMath2MathType },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWinWord2Writer,
+ &SvtFilterOptions::SetWinWord2Writer },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWriter2WinWord,
+ &SvtFilterOptions::SetWriter2WinWord },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsExcel2Calc,
+ &SvtFilterOptions::SetExcel2Calc },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsCalc2Excel,
+ &SvtFilterOptions::SetCalc2Excel },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsPowerPoint2Impress,
+ &SvtFilterOptions::SetPowerPoint2Impress },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsImpress2PowerPoint,
+ &SvtFilterOptions::SetImpress2PowerPoint },
+ { MSFltrPg2_CheckBoxEntries::SmartArt, &SvtFilterOptions::IsSmartArt2Shape,
+ &SvtFilterOptions::SetSmartArt2Shape },
+ { MSFltrPg2_CheckBoxEntries::Visio, &SvtFilterOptions::IsVisio2Draw,
+ &SvtFilterOptions::SetVisio2Draw },
+ };
+
+ bool bFirstCol = true;
+ for( const ChkCBoxEntries & rEntry : aChkArr )
+ {
+ // we loop through the list, alternating reading the first/second column,
+ // each row appears twice in the list (except for smartart and later entries, which are
+ // import only)
+ sal_uInt16 nCol = bFirstCol ? 0 : 1;
+ bFirstCol = !bFirstCol;
+ int nEntry = GetEntry4Type(rEntry.eType);
+ if (nEntry != -1)
+ {
+ bool bCheck = m_xCheckLB->get_toggle(nEntry, nCol);
+ if( bCheck != (rOpt.*rEntry.FnIs)() )
+ (rOpt.*rEntry.FnSet)( bCheck );
+ }
+ if (rEntry.eType == MSFltrPg2_CheckBoxEntries::SmartArt)
+ {
+ bFirstCol = !bFirstCol;
+ }
+ }
+ int nPDFEntry = GetEntry4Type(MSFltrPg2_CheckBoxEntries::PDF);
+ bool bPDFCheck = m_xCheckLB->get_toggle(nPDFEntry, 0);
+ if (bPDFCheck != officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get())
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::set(bPDFCheck, pBatch);
+ pBatch->commit();
+ }
+
+ if( m_xHighlightingRB->get_state_changed_from_saved() )
+ {
+ if (m_xHighlightingRB->get_active())
+ rOpt.SetCharBackground2Highlighting();
+ else
+ rOpt.SetCharBackground2Shading();
+ }
+
+ if (m_xMSOLockFileCB->get_state_changed_from_saved())
+ {
+ rOpt.EnableMSOLockFileCreation(m_xMSOLockFileCB->get_active());
+ }
+
+ return true;
+}
+
+void OfaMSFilterTabPage2::Reset( const SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ SvtModuleOptions aModuleOpt;
+
+ // int the same sequence as the enums of MSFltrPg2_CheckBoxEntries
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ InsertEntry( sChgToFromMath, MSFltrPg2_CheckBoxEntries::Math );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ InsertEntry( sChgToFromWriter, MSFltrPg2_CheckBoxEntries::Writer );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ InsertEntry( sChgToFromCalc, MSFltrPg2_CheckBoxEntries::Calc );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ InsertEntry( sChgToFromImpress, MSFltrPg2_CheckBoxEntries::Impress );
+ InsertEntry( sChgToFromSmartArt, MSFltrPg2_CheckBoxEntries::SmartArt, false );
+ if (aModuleOpt.IsModuleInstalled(SvtModuleOptions::EModule::DRAW))
+ {
+ InsertEntry(sChgToFromVisio, MSFltrPg2_CheckBoxEntries::Visio, false);
+ InsertEntry(sChgToFromPDF, MSFltrPg2_CheckBoxEntries::PDF, false);
+ }
+
+ static struct ChkCBoxEntries{
+ MSFltrPg2_CheckBoxEntries eType;
+ bool (SvtFilterOptions::*FnIs)() const;
+ } const aChkArr[] = {
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMathType2Math },
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMath2MathType },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWinWord2Writer },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWriter2WinWord },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsExcel2Calc },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsCalc2Excel },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsPowerPoint2Impress },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsImpress2PowerPoint },
+ { MSFltrPg2_CheckBoxEntries::SmartArt, &SvtFilterOptions::IsSmartArt2Shape },
+ { MSFltrPg2_CheckBoxEntries::Visio, &SvtFilterOptions::IsVisio2Draw },
+ { MSFltrPg2_CheckBoxEntries::PDF, nullptr },
+ };
+
+ bool bFirstCol = true;
+ for( const ChkCBoxEntries & rArr : aChkArr )
+ {
+ // we loop through the list, alternating reading the first/second column,
+ // each row appears twice in the list (except for smartart and later entries, which are
+ // import only)
+ sal_uInt16 nCol = bFirstCol ? 0 : 1;
+ bFirstCol = !bFirstCol;
+ int nEntry = GetEntry4Type( rArr.eType );
+ if (nEntry != -1)
+ {
+ bool bCheck = false;
+ if (rArr.eType != MSFltrPg2_CheckBoxEntries::PDF)
+ {
+ bCheck = (rOpt.*rArr.FnIs)();
+ }
+ else
+ {
+ bCheck = officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get();
+ nCol = 0;
+ }
+ m_xCheckLB->set_toggle(nEntry, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, nCol);
+ }
+ if (rArr.eType == MSFltrPg2_CheckBoxEntries::SmartArt)
+ {
+ bFirstCol = !bFirstCol;
+ }
+ }
+ m_xCheckLB->thaw();
+
+ if (rOpt.IsCharBackground2Highlighting())
+ m_xHighlightingRB->set_active(true);
+ else
+ m_xShadingRB->set_active(true);
+
+ m_xHighlightingRB->save_state();
+
+ m_xMSOLockFileCB->set_active(rOpt.IsMSOLockFileCreationIsEnabled());
+ m_xMSOLockFileCB->save_state();
+ m_xMSOLockFileCB->set_sensitive(!officecfg::Office::Common::Filter::Microsoft::Import::CreateMSOLockFiles::isReadOnly());
+}
+
+void OfaMSFilterTabPage2::InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType )
+{
+ InsertEntry( _rTxt, _nType, true );
+}
+
+void OfaMSFilterTabPage2::InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType,
+ bool saveEnabled )
+{
+ int nPos = m_xCheckLB->n_children();
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 0);
+ if (saveEnabled)
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(nPos, _rTxt, 2);
+ m_xCheckLB->set_id(nPos, OUString::number(static_cast<sal_Int32>(_nType)));
+}
+
+int OfaMSFilterTabPage2::GetEntry4Type( MSFltrPg2_CheckBoxEntries _nType ) const
+{
+ for (int i = 0, nEntryCount = m_xCheckLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (_nType == static_cast<MSFltrPg2_CheckBoxEntries>(m_xCheckLB->get_id(i).toInt32()))
+ return i;
+ }
+ return -1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optfltr.hxx b/cui/source/options/optfltr.hxx
new file mode 100644
index 000000000..f38a89366
--- /dev/null
+++ b/cui/source/options/optfltr.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class OfaMSFilterTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xWBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xWBasicWbctblCB;
+ std::unique_ptr<weld::CheckButton> m_xWBasicStgCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicExectblCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicStgCB;
+ std::unique_ptr<weld::CheckButton> m_xPBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xPBasicStgCB;
+
+ DECL_LINK(LoadWordBasicCheckHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(LoadExcelBasicCheckHdl_Impl, weld::Toggleable&, void);
+public:
+ OfaMSFilterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~OfaMSFilterTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+enum class MSFltrPg2_CheckBoxEntries;
+
+class OfaMSFilterTabPage2 : public SfxTabPage
+{
+ OUString sChgToFromMath,
+ sChgToFromWriter,
+ sChgToFromCalc,
+ sChgToFromImpress,
+ sChgToFromSmartArt,
+ sChgToFromVisio,
+ sChgToFromPDF;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::RadioButton> m_xHighlightingRB;
+ std::unique_ptr<weld::RadioButton> m_xShadingRB;
+ std::unique_ptr<weld::CheckButton> m_xMSOLockFileCB;
+
+ void InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType );
+ void InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType,
+ bool saveEnabled );
+ int GetEntry4Type( MSFltrPg2_CheckBoxEntries _nType ) const;
+
+public:
+ OfaMSFilterTabPage2(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual ~OfaMSFilterTabPage2() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
new file mode 100644
index 000000000..b9402dfb2
--- /dev/null
+++ b/cui/source/options/optgdlg.cxx
@@ -0,0 +1,1806 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/currencytable.hxx>
+#include <svtools/langhelp.hxx>
+#include <unotools/lingucfg.hxx>
+#if defined(_WIN32)
+#include <unotools/resmgr.hxx>
+#endif
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <unotools/compatibility.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <svtools/langtab.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/langitem.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <editeng/editids.hrc>
+#include <svx/svxids.hrc>
+#include <svl/intitem.hxx>
+#include <GraphicsTestsDialog.hxx>
+#include <unotools/searchopt.hxx>
+#include <sal/log.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Setup.hxx>
+#include <comphelper/configuration.hxx>
+#include <tools/diagnose_ex.h>
+#if HAVE_FEATURE_BREAKPAD
+#include <desktop/crashreport.hxx>
+#endif
+
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/office/Quickstart.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+#include <comphelper/dispatchcommand.hxx>
+
+#include <vcl/vclenum.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/window.hxx>
+#include <vcl/IconThemeInfo.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
+#include "optgdlg.hxx"
+#include <svtools/apearcfg.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <svtools/restartdialog.hxx>
+#include <svtools/imgdef.hxx>
+
+#if defined(_WIN32)
+#include <vcl/fileregistration.hxx>
+#endif
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::utl;
+
+// class OfaMiscTabPage --------------------------------------------------
+
+DeactivateRC OfaMiscTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+namespace
+{
+OUString impl_SystemFileOpenServiceName()
+{
+ #if defined(_WIN32)
+ return "com.sun.star.ui.dialogs.SystemFilePicker";
+ #elif defined MACOSX
+ return "com.sun.star.ui.dialogs.AquaFilePicker";
+ #else
+ return OUString();
+ #endif
+}
+
+bool lcl_HasSystemFilePicker()
+{
+ if( Application::hasNativeFileSelection() )
+ return true;
+
+ // Otherwise fall-back on querying services
+ bool bRet = false;
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+
+ Reference< XContentEnumerationAccess > xEnumAccess( xFactory, UNO_QUERY );
+ Reference< XSet > xSet( xFactory, UNO_QUERY );
+
+ if ( ! xEnumAccess.is() || ! xSet.is() )
+ return bRet;
+
+ try
+ {
+ OUString aFileService = impl_SystemFileOpenServiceName();
+ Reference< XEnumeration > xEnum = xEnumAccess->createContentEnumeration( aFileService );
+ if ( xEnum.is() && xEnum->hasMoreElements() )
+ bRet = true;
+ }
+ catch (const IllegalArgumentException&)
+ {
+ }
+ catch (const ElementExistException&)
+ {
+ }
+ return bRet;
+}
+}
+
+OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optgeneralpage.ui", "OptGeneralPage", &rSet)
+ , m_xExtHelpCB(m_xBuilder->weld_check_button("exthelp"))
+ , m_xPopUpNoHelpCB(m_xBuilder->weld_check_button("popupnohelp"))
+ , m_xShowTipOfTheDay(m_xBuilder->weld_check_button("cbShowTipOfTheDay"))
+ , m_xFileDlgFrame(m_xBuilder->weld_widget("filedlgframe"))
+ , m_xFileDlgROImage(m_xBuilder->weld_widget("lockimage"))
+ , m_xFileDlgCB(m_xBuilder->weld_check_button("filedlg"))
+ , m_xPrintDlgCB(m_xBuilder->weld_check_button("printdlg"))
+ , m_xDocStatusCB(m_xBuilder->weld_check_button("docstatus"))
+ , m_xYearFrame(m_xBuilder->weld_widget("yearframe"))
+ , m_xYearValueField(m_xBuilder->weld_spin_button("year"))
+ , m_xToYearFT(m_xBuilder->weld_label("toyear"))
+ , m_xCrashReport(m_xBuilder->weld_check_button("crashreport"))
+ , m_xQuickStarterFrame(m_xBuilder->weld_widget("quickstarter"))
+ , m_xHelpImproveLabel(m_xBuilder->weld_label("label7")) //"Help Improve"
+#if defined(UNX)
+ , m_xQuickLaunchCB(m_xBuilder->weld_check_button("systray"))
+#else
+ , m_xQuickLaunchCB(m_xBuilder->weld_check_button("quicklaunch"))
+#endif
+#if defined(_WIN32)
+ , m_xFileAssocFrame(m_xBuilder->weld_widget("fileassoc"))
+ , m_xFileAssocBtn(m_xBuilder->weld_button("assocfiles"))
+ , m_xPerformFileExtCheck(m_xBuilder->weld_check_button("cbPerformFileExtCheck"))
+#endif
+{
+ if (!lcl_HasSystemFilePicker())
+ m_xFileDlgFrame->hide();
+ else if (officecfg::Office::Common::Misc::UseSystemFileDialog::isReadOnly())
+ {
+ m_xFileDlgROImage->show();
+ m_xFileDlgCB->set_sensitive(false);
+ }
+
+ m_xQuickLaunchCB->show();
+
+ //Only available in Win or if building the gtk systray
+#if !defined(_WIN32)
+ m_xQuickStarterFrame->hide();
+ //Hide frame label in case of no content
+ m_xHelpImproveLabel->hide();
+#endif
+
+#if defined(_WIN32)
+ m_xFileAssocFrame->show();
+ m_xFileAssocBtn->connect_clicked(LINK(this, OfaMiscTabPage, FileAssocClick));
+#endif
+
+ m_aStrDateInfo = m_xToYearFT->get_label();
+ m_xYearValueField->connect_value_changed( LINK( this, OfaMiscTabPage, TwoFigureHdl ) );
+
+ SetExchangeSupport();
+}
+
+OfaMiscTabPage::~OfaMiscTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaMiscTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMiscTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool OfaMiscTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ if ( m_xPopUpNoHelpCB->get_state_changed_from_saved() )
+ officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::set(m_xPopUpNoHelpCB->get_active(), batch);
+
+ if ( m_xExtHelpCB->get_state_changed_from_saved() )
+ officecfg::Office::Common::Help::ExtendedTip::set(m_xExtHelpCB->get_active(), batch);
+
+ if ( m_xShowTipOfTheDay->get_state_changed_from_saved() )
+ {
+ officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_xShowTipOfTheDay->get_active(), batch);
+ bModified = true;
+ }
+
+ if ( m_xFileDlgCB->get_state_changed_from_saved() )
+ {
+ officecfg::Office::Common::Misc::UseSystemFileDialog::set( !m_xFileDlgCB->get_active(), batch );
+ bModified = true;
+ }
+
+ if (m_xDocStatusCB->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Print::PrintingModifiesDocument::set(m_xDocStatusCB->get_active(), batch);
+ bModified = true;
+ }
+
+ const SfxUInt16Item* pUInt16Item = GetOldItem( *rSet, SID_ATTR_YEAR2000 );
+ sal_uInt16 nNum = static_cast<sal_uInt16>(m_xYearValueField->get_text().toInt32());
+ if ( pUInt16Item && pUInt16Item->GetValue() != nNum )
+ {
+ bModified = true;
+ rSet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, nNum ) );
+ }
+
+#if HAVE_FEATURE_BREAKPAD
+ if (m_xCrashReport->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Misc::CrashReport::set(m_xCrashReport->get_active(), batch);
+ bModified = true;
+ }
+#endif
+
+#if defined(_WIN32)
+ if (m_xPerformFileExtCheck->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Misc::PerformFileExtCheck::set(
+ m_xPerformFileExtCheck->get_active(), batch);
+ bModified = true;
+ }
+#endif
+
+ batch->commit();
+
+ if( m_xQuickLaunchCB->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(SID_ATTR_QUICKLAUNCHER, m_xQuickLaunchCB->get_active()));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void OfaMiscTabPage::Reset( const SfxItemSet* rSet )
+{
+ m_xExtHelpCB->set_active( officecfg::Office::Common::Help::Tip::get() &&
+ officecfg::Office::Common::Help::ExtendedTip::get() );
+ m_xExtHelpCB->save_state();
+ m_xPopUpNoHelpCB->set_active( officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::get() );
+ m_xPopUpNoHelpCB->save_state();
+ m_xShowTipOfTheDay->set_active( officecfg::Office::Common::Misc::ShowTipOfTheDay::get() );
+ m_xShowTipOfTheDay->save_state();
+ m_xFileDlgCB->set_active( !officecfg::Office::Common::Misc::UseSystemFileDialog::get() );
+ m_xFileDlgCB->save_state();
+
+ m_xDocStatusCB->set_active(officecfg::Office::Common::Print::PrintingModifiesDocument::get());
+ m_xDocStatusCB->save_state();
+
+ if ( const SfxUInt16Item* pYearItem = rSet->GetItemIfSet( SID_ATTR_YEAR2000, false ) )
+ {
+ m_xYearValueField->set_value( pYearItem->GetValue() );
+ TwoFigureHdl(*m_xYearValueField);
+ }
+ else
+ m_xYearFrame->set_sensitive(false);
+
+#if HAVE_FEATURE_BREAKPAD
+ m_xCrashReport->set_active(officecfg::Office::Common::Misc::CrashReport::get() && CrashReporter::IsDumpEnable());
+ m_xCrashReport->set_sensitive(!officecfg::Office::Common::Misc::CrashReport::isReadOnly() && CrashReporter::IsDumpEnable());
+ m_xCrashReport->save_state();
+#else
+ m_xCrashReport->hide();
+#endif
+
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemState eState = rSet->GetItemState( SID_ATTR_QUICKLAUNCHER, false, &pItem );
+ if ( SfxItemState::SET == eState )
+ m_xQuickLaunchCB->set_active( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+ else if ( SfxItemState::DISABLED == eState )
+ {
+ // quickstart not installed
+ m_xQuickStarterFrame->hide();
+ }
+
+ m_xQuickLaunchCB->save_state();
+
+#if defined(_WIN32)
+ m_xPerformFileExtCheck->set_active(
+ officecfg::Office::Common::Misc::PerformFileExtCheck::get());
+ m_xPerformFileExtCheck->save_state();
+ m_xPerformFileExtCheck->set_sensitive(!officecfg::Office::Common::Misc::PerformFileExtCheck::isReadOnly());
+#endif
+}
+
+IMPL_LINK_NOARG( OfaMiscTabPage, TwoFigureHdl, weld::SpinButton&, void )
+{
+ OUString aOutput( m_aStrDateInfo );
+ OUString aStr( m_xYearValueField->get_text() );
+ sal_Int32 nNum = aStr.toInt32();
+ if ( aStr.getLength() != 4 || nNum < m_xYearValueField->get_min() || nNum > m_xYearValueField->get_max() )
+ aOutput += "????";
+ else
+ {
+ nNum += 99;
+ aOutput += OUString::number( nNum );
+ }
+ m_xToYearFT->set_label( aOutput );
+}
+
+#if defined(_WIN32)
+IMPL_STATIC_LINK_NOARG(OfaMiscTabPage, FileAssocClick, weld::Button&, void)
+{
+ vcl::fileregistration::LaunchRegistrationUI();
+}
+#endif
+
+class CanvasSettings
+{
+public:
+ CanvasSettings();
+
+ bool IsHardwareAccelerationEnabled() const;
+ bool IsHardwareAccelerationAvailable() const;
+ bool IsHardwareAccelerationRO() const;
+ void EnabledHardwareAcceleration( bool _bEnabled ) const;
+
+private:
+ typedef std::vector< std::pair<OUString,Sequence<OUString> > > ServiceVector;
+
+ Reference<XNameAccess> mxForceFlagNameAccess;
+ ServiceVector maAvailableImplementations;
+ mutable bool mbHWAccelAvailable;
+ mutable bool mbHWAccelChecked;
+};
+
+CanvasSettings::CanvasSettings() :
+ mbHWAccelAvailable(false),
+ mbHWAccelChecked(false)
+{
+ try
+ {
+ Reference<XMultiServiceFactory> xConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+
+ Sequence<Any> aArgs1(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(OUString("/org.openoffice.Office.Canvas"))}
+ }));
+ mxForceFlagNameAccess.set(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ aArgs1 ),
+ UNO_QUERY_THROW );
+
+ Sequence<Any> aArgs2(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(OUString("/org.openoffice.Office.Canvas/CanvasServiceList"))}
+ }));
+ Reference<XNameAccess> xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess",
+ aArgs2 ), UNO_QUERY_THROW );
+ Reference<XHierarchicalNameAccess> xHierarchicalNameAccess(
+ xNameAccess, UNO_QUERY_THROW);
+
+ Sequence<OUString> serviceNames = xNameAccess->getElementNames();
+ const OUString* pCurr = serviceNames.getConstArray();
+ const OUString* const pEnd = pCurr + serviceNames.getLength();
+ while( pCurr != pEnd )
+ {
+ Reference<XNameAccess> xEntryNameAccess(
+ xHierarchicalNameAccess->getByHierarchicalName(*pCurr),
+ UNO_QUERY );
+
+ if( xEntryNameAccess.is() )
+ {
+ Sequence<OUString> preferredImplementations;
+ if( xEntryNameAccess->getByName("PreferredImplementations") >>= preferredImplementations )
+ maAvailableImplementations.emplace_back(*pCurr,preferredImplementations );
+ }
+
+ ++pCurr;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+bool CanvasSettings::IsHardwareAccelerationAvailable() const
+{
+ if( !mbHWAccelChecked )
+ {
+ mbHWAccelChecked = true;
+
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+
+ // check whether any of the service lists has an
+ // implementation that presents the "HardwareAcceleration" property
+ for (auto const& availableImpl : maAvailableImplementations)
+ {
+ const OUString* pCurrImpl = availableImpl.second.getConstArray();
+ const OUString* const pEndImpl = pCurrImpl + availableImpl.second.getLength();
+
+ while( pCurrImpl != pEndImpl )
+ {
+ try
+ {
+ Reference<XPropertySet> xPropSet( xFactory->createInstance(
+ pCurrImpl->trim() ),
+ UNO_QUERY_THROW );
+ bool bHasAccel(false);
+ if( xPropSet->getPropertyValue("HardwareAcceleration") >>= bHasAccel )
+ if( bHasAccel )
+ {
+ mbHWAccelAvailable = true;
+ return mbHWAccelAvailable;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+
+ ++pCurrImpl;
+ }
+ }
+ }
+
+ return mbHWAccelAvailable;
+}
+
+bool CanvasSettings::IsHardwareAccelerationEnabled() const
+{
+ bool bForceLastEntry(false);
+ if( !mxForceFlagNameAccess.is() )
+ return true;
+
+ if( !(mxForceFlagNameAccess->getByName("ForceSafeServiceImpl") >>= bForceLastEntry) )
+ return true;
+
+ return !bForceLastEntry;
+}
+
+bool CanvasSettings::IsHardwareAccelerationRO() const
+{
+ Reference< XPropertySet > xSet(mxForceFlagNameAccess, UNO_QUERY);
+ if (!xSet.is())
+ return true;
+
+ Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
+ Property aProp = xInfo->getPropertyByName("ForceSafeServiceImpl");
+ return ((aProp.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY);
+}
+
+void CanvasSettings::EnabledHardwareAcceleration( bool _bEnabled ) const
+{
+ Reference< XNameReplace > xNameReplace(
+ mxForceFlagNameAccess, UNO_QUERY );
+
+ if( !xNameReplace.is() )
+ return;
+
+ xNameReplace->replaceByName( "ForceSafeServiceImpl", Any(!_bEnabled) );
+
+ Reference< XChangesBatch > xChangesBatch(
+ mxForceFlagNameAccess, UNO_QUERY );
+
+ if( !xChangesBatch.is() )
+ return;
+
+ xChangesBatch->commitChanges();
+}
+
+// class OfaViewTabPage --------------------------------------------------
+
+static bool DisplayNameCompareLessThan(const vcl::IconThemeInfo& rInfo1, const vcl::IconThemeInfo& rInfo2)
+{
+ return rInfo1.GetDisplayName().compareTo(rInfo2.GetDisplayName()) < 0;
+}
+
+OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optviewpage.ui", "OptViewPage", &rSet)
+ , nSizeLB_InitialSelection(0)
+ , nSidebarSizeLB_InitialSelection(0)
+ , nNotebookbarSizeLB_InitialSelection(0)
+ , nStyleLB_InitialSelection(0)
+ , pAppearanceCfg(new SvtTabAppearanceCfg)
+ , pCanvasSettings(new CanvasSettings)
+ , m_xIconSizeLB(m_xBuilder->weld_combo_box("iconsize"))
+ , m_xSidebarIconSizeLB(m_xBuilder->weld_combo_box("sidebariconsize"))
+ , m_xNotebookbarIconSizeLB(m_xBuilder->weld_combo_box("notebookbariconsize"))
+ , m_xIconStyleLB(m_xBuilder->weld_combo_box("iconstyle"))
+ , m_xFontAntiAliasing(m_xBuilder->weld_check_button("aafont"))
+ , m_xAAPointLimitLabel(m_xBuilder->weld_label("aafrom"))
+ , m_xAAPointLimit(m_xBuilder->weld_metric_spin_button("aanf", FieldUnit::PIXEL))
+ , m_xMenuIconBox(m_xBuilder->weld_widget("menuiconsbox"))
+ , m_xMenuIconsLB(m_xBuilder->weld_combo_box("menuicons"))
+ , m_xContextMenuShortcutsLB(m_xBuilder->weld_combo_box("contextmenushortcuts"))
+ , m_xFontShowCB(m_xBuilder->weld_check_button("showfontpreview"))
+ , m_xUseHardwareAccell(m_xBuilder->weld_check_button("useaccel"))
+ , m_xUseAntiAliase(m_xBuilder->weld_check_button("useaa"))
+ , m_xUseSkia(m_xBuilder->weld_check_button("useskia"))
+ , m_xForceSkiaRaster(m_xBuilder->weld_check_button("forceskiaraster"))
+ , m_xSkiaStatusEnabled(m_xBuilder->weld_label("skiaenabled"))
+ , m_xSkiaStatusDisabled(m_xBuilder->weld_label("skiadisabled"))
+ , m_xMousePosLB(m_xBuilder->weld_combo_box("mousepos"))
+ , m_xMouseMiddleLB(m_xBuilder->weld_combo_box("mousemiddle"))
+ , m_xMoreIcons(m_xBuilder->weld_button("btnMoreIcons"))
+ , m_xRunGPTests(m_xBuilder->weld_button("btn_rungptest"))
+{
+ if (Application::GetToolkitName().startsWith("gtk"))
+ m_xMenuIconBox->hide();
+
+ m_xFontAntiAliasing->connect_toggled( LINK( this, OfaViewTabPage, OnAntialiasingToggled ) );
+
+ m_xUseSkia->connect_toggled(LINK(this, OfaViewTabPage, OnUseSkiaToggled));
+
+ // Set known icon themes
+ OUString sAutoStr( m_xIconStyleLB->get_text( 0 ) );
+ m_xIconStyleLB->clear();
+ StyleSettings aStyleSettings = Application::GetSettings().GetStyleSettings();
+ mInstalledIconThemes = aStyleSettings.GetInstalledIconThemes();
+ std::sort(mInstalledIconThemes.begin(), mInstalledIconThemes.end(), DisplayNameCompareLessThan);
+
+ // Start with the automatically chosen icon theme
+ OUString autoThemeId = aStyleSettings.GetAutomaticallyChosenIconTheme();
+ const vcl::IconThemeInfo& autoIconTheme = vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, autoThemeId);
+
+ OUString entryForAuto = sAutoStr + " (" +
+ autoIconTheme.GetDisplayName() +
+ ")";
+ m_xIconStyleLB->append("auto", entryForAuto); // index 0 means choose style automatically
+
+ // separate auto and other icon themes
+ m_xIconStyleLB->append_separator("");
+
+ for (auto const& installIconTheme : mInstalledIconThemes)
+ m_xIconStyleLB->append(installIconTheme.GetThemeId(), installIconTheme.GetDisplayName());
+
+ m_xIconStyleLB->set_active(0);
+
+ m_xMoreIcons->set_from_icon_name("cmd/sc_additionsdialog.png");
+ m_xMoreIcons->connect_clicked(LINK(this, OfaViewTabPage, OnMoreIconsClick));
+ m_xRunGPTests->connect_clicked( LINK( this, OfaViewTabPage, OnRunGPTestClick));
+}
+
+OfaViewTabPage::~OfaViewTabPage()
+{
+}
+
+IMPL_LINK_NOARG(OfaViewTabPage, OnRunGPTestClick, weld::Button&, void)
+{
+ GraphicsTestsDialog m_xGraphicsTestDialog(m_xContainer.get());
+ m_xGraphicsTestDialog.run();
+}
+
+IMPL_STATIC_LINK_NOARG(OfaViewTabPage, OnMoreIconsClick, weld::Button&, void)
+{
+ css::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
+ "AdditionsTag", OUString("Icons")) };
+ comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
+}
+
+IMPL_LINK_NOARG( OfaViewTabPage, OnAntialiasingToggled, weld::Toggleable&, void )
+{
+ bool bAAEnabled = m_xFontAntiAliasing->get_active();
+
+ m_xAAPointLimitLabel->set_sensitive(bAAEnabled);
+ m_xAAPointLimit->set_sensitive(bAAEnabled);
+}
+
+IMPL_LINK_NOARG(OfaViewTabPage, OnUseSkiaToggled, weld::Toggleable&, void)
+{
+ UpdateSkiaStatus();
+}
+
+void OfaViewTabPage::HideSkiaWidgets()
+{
+ m_xUseSkia->hide();
+ m_xForceSkiaRaster->hide();
+ m_xSkiaStatusEnabled->hide();
+ m_xSkiaStatusDisabled->hide();
+}
+
+void OfaViewTabPage::UpdateSkiaStatus()
+{
+#if HAVE_FEATURE_SKIA
+ bool skiaHidden = true;
+
+ // For now Skia is used mainly on Windows, enable the controls there.
+ if (Application::GetToolkitName() == "win")
+ skiaHidden = false;
+ // It can also be used on Linux, but only with the rarely used 'gen' backend.
+ if (Application::GetToolkitName() == "x11")
+ skiaHidden = false;
+ // OSX backend has Skia support too.
+ if (Application::GetToolkitName() == "osx")
+ skiaHidden = false;
+
+ if (skiaHidden)
+ {
+ HideSkiaWidgets();
+ return;
+ }
+
+ // Easier than a custom translation string.
+ bool bEnabled = SkiaHelper::isVCLSkiaEnabled();
+ m_xSkiaStatusEnabled->set_visible(bEnabled);
+ m_xSkiaStatusDisabled->set_visible(!bEnabled);
+
+ // FIXME: should really add code to show a 'lock' icon here.
+ m_xUseSkia->set_sensitive(!officecfg::Office::Common::VCL::UseSkia::isReadOnly());
+ m_xForceSkiaRaster->set_sensitive(m_xUseSkia->get_active() && !officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly());
+
+ // Technically the 'use hardware acceleration' option could be used to mean !forceSkiaRaster, but the implementation
+ // of the option is so tied to the implementation of the canvas module that it's simpler to ignore it.
+ UpdateHardwareAccelStatus();
+#else
+ HideSkiaWidgets();
+#endif
+}
+
+std::unique_ptr<SfxTabPage> OfaViewTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaViewTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaViewTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ bool bMenuOptModified = false;
+ bool bRepaintWindows(false);
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(comphelper::ConfigurationChanges::create());
+
+ SvtMiscOptions aMiscOptions;
+ const sal_Int32 nSizeLB_NewSelection = m_xIconSizeLB->get_active();
+ if( nSizeLB_InitialSelection != nSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ sal_Int16 eSet = SFX_SYMBOLS_SIZE_AUTO;
+ switch( nSizeLB_NewSelection )
+ {
+ case 0: eSet = SFX_SYMBOLS_SIZE_AUTO; break;
+ case 1: eSet = SFX_SYMBOLS_SIZE_SMALL; break;
+ case 2: eSet = SFX_SYMBOLS_SIZE_LARGE; break;
+ case 3: eSet = SFX_SYMBOLS_SIZE_32; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xIconSizeLB should not be possible!" );
+ }
+ aMiscOptions.SetSymbolsSize( eSet );
+ }
+
+ const sal_Int32 nSidebarSizeLB_NewSelection = m_xSidebarIconSizeLB->get_active();
+ if( nSidebarSizeLB_InitialSelection != nSidebarSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ ToolBoxButtonSize eSet = ToolBoxButtonSize::DontCare;
+ switch( nSidebarSizeLB_NewSelection )
+ {
+ case 0: eSet = ToolBoxButtonSize::DontCare; break;
+ case 1: eSet = ToolBoxButtonSize::Small; break;
+ case 2: eSet = ToolBoxButtonSize::Large; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xSidebarIconSizeLB should not be possible!" );
+ }
+ officecfg::Office::Common::Misc::SidebarIconSize::set(static_cast<sal_Int16>(eSet), xChanges);
+ }
+
+ const sal_Int32 nNotebookbarSizeLB_NewSelection = m_xNotebookbarIconSizeLB->get_active();
+ if( nNotebookbarSizeLB_InitialSelection != nNotebookbarSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ ToolBoxButtonSize eSet = ToolBoxButtonSize::DontCare;
+ switch( nNotebookbarSizeLB_NewSelection )
+ {
+ case 0: eSet = ToolBoxButtonSize::DontCare; break;
+ case 1: eSet = ToolBoxButtonSize::Small; break;
+ case 2: eSet = ToolBoxButtonSize::Large; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xNotebookbarIconSizeLB should not be possible!" );
+ }
+ officecfg::Office::Common::Misc::NotebookbarIconSize::set(static_cast<sal_Int16>(eSet), xChanges);
+ }
+
+ const sal_Int32 nStyleLB_NewSelection = m_xIconStyleLB->get_active();
+ if( nStyleLB_InitialSelection != nStyleLB_NewSelection )
+ {
+ aMiscOptions.SetIconTheme(m_xIconStyleLB->get_active_id());
+ nStyleLB_InitialSelection = nStyleLB_NewSelection;
+ }
+
+ bool bAppearanceChanged = false;
+
+ // Mouse Snap Mode
+ SnapType eOldSnap = pAppearanceCfg->GetSnapMode();
+ SnapType eNewSnap = static_cast<SnapType>(m_xMousePosLB->get_active());
+ if(eNewSnap > SnapType::NONE)
+ eNewSnap = SnapType::NONE;
+
+ if ( eNewSnap != eOldSnap )
+ {
+ pAppearanceCfg->SetSnapMode(eNewSnap );
+ bAppearanceChanged = true;
+ }
+
+ // Middle Mouse Button
+ MouseMiddleButtonAction eOldMiddleMouse = pAppearanceCfg->GetMiddleMouseButton();
+ short eNewMiddleMouse = m_xMouseMiddleLB->get_active();
+ if(eNewMiddleMouse > 2)
+ eNewMiddleMouse = 2;
+
+ if ( eNewMiddleMouse != static_cast<short>(eOldMiddleMouse) )
+ {
+ pAppearanceCfg->SetMiddleMouseButton( static_cast<MouseMiddleButtonAction>(eNewMiddleMouse) );
+ bAppearanceChanged = true;
+ }
+
+ if (m_xFontAntiAliasing->get_state_changed_from_saved())
+ {
+ pAppearanceCfg->SetFontAntiAliasing(m_xFontAntiAliasing->get_active());
+ bAppearanceChanged = true;
+ }
+
+ if (m_xAAPointLimit->get_value_changed_from_saved())
+ {
+ pAppearanceCfg->SetFontAntialiasingMinPixelHeight(m_xAAPointLimit->get_value(FieldUnit::PIXEL));
+ bAppearanceChanged = true;
+ }
+
+ if (m_xFontShowCB->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::set(m_xFontShowCB->get_active(), xChanges);
+ bModified = true;
+ }
+
+ if (m_xMenuIconsLB->get_value_changed_from_saved())
+ {
+ officecfg::Office::Common::View::Menu::IsSystemIconsInMenus::set(m_xMenuIconsLB->get_active() == 0, xChanges);
+ officecfg::Office::Common::View::Menu::ShowIconsInMenues::set(m_xMenuIconsLB->get_active() == 2, xChanges);
+ bModified = true;
+ bMenuOptModified = true;
+ bAppearanceChanged = true;
+ }
+
+ if (m_xContextMenuShortcutsLB->get_value_changed_from_saved())
+ {
+ officecfg::Office::Common::View::Menu::ShortcutsInContextMenus::set(
+ m_xContextMenuShortcutsLB->get_active() == 0 ?
+ TRISTATE_INDET :
+ static_cast<TriState>(m_xContextMenuShortcutsLB->get_active() - 1),
+ xChanges);
+ bModified = true;
+ bMenuOptModified = true;
+ bAppearanceChanged = true;
+ }
+
+ // #i95644# if disabled, do not use value, see in ::Reset()
+ if (m_xUseHardwareAccell->get_sensitive())
+ {
+ if(m_xUseHardwareAccell->get_state_changed_from_saved())
+ {
+ pCanvasSettings->EnabledHardwareAcceleration(m_xUseHardwareAccell->get_active());
+ bModified = true;
+ }
+ }
+
+ // #i95644# if disabled, do not use value, see in ::Reset()
+ if (m_xUseAntiAliase->get_sensitive())
+ {
+ if (m_xUseAntiAliase->get_active() != SvtOptionsDrawinglayer::IsAntiAliasing())
+ {
+ SvtOptionsDrawinglayer::SetAntiAliasing(m_xUseAntiAliase->get_active(), /*bTemporary*/false);
+ bModified = true;
+ bRepaintWindows = true;
+ }
+ }
+
+ if (m_xUseSkia->get_state_changed_from_saved() ||
+ m_xForceSkiaRaster->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::VCL::UseSkia::set(m_xUseSkia->get_active(), xChanges);
+ officecfg::Office::Common::VCL::ForceSkiaRaster::set(m_xForceSkiaRaster->get_active(), xChanges);
+ bModified = true;
+ }
+
+ xChanges->commit();
+
+ if( bMenuOptModified )
+ {
+ // Set changed settings to the application instance
+ AllSettings aAllSettings = Application::GetSettings();
+ StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
+ aAllSettings.SetStyleSettings(aStyleSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+ }
+
+ if ( bAppearanceChanged )
+ {
+ pAppearanceCfg->Commit();
+ pAppearanceCfg->SetApplicationDefaults ( GetpApp() );
+ }
+
+ if(bRepaintWindows)
+ {
+ vcl::Window* pAppWindow = Application::GetFirstTopLevelWindow();
+
+ while(pAppWindow)
+ {
+ pAppWindow->Invalidate();
+ pAppWindow = Application::GetNextTopLevelWindow(pAppWindow);
+ }
+ }
+
+ if (m_xUseSkia->get_state_changed_from_saved() ||
+ m_xForceSkiaRaster->get_state_changed_from_saved())
+ {
+ SolarMutexGuard aGuard;
+ if( svtools::executeRestartDialog(
+ comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_SKIA))
+ GetDialogController()->response(RET_OK);
+ }
+
+ return bModified;
+}
+
+void OfaViewTabPage::Reset( const SfxItemSet* )
+{
+ SvtMiscOptions aMiscOptions;
+
+ if (aMiscOptions.GetSymbolsSize() != SFX_SYMBOLS_SIZE_AUTO)
+ {
+ nSizeLB_InitialSelection = 1;
+
+ if (aMiscOptions.GetSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE)
+ nSizeLB_InitialSelection = 2;
+ else if (aMiscOptions.GetSymbolsSize() == SFX_SYMBOLS_SIZE_32)
+ nSizeLB_InitialSelection = 3;
+ }
+ m_xIconSizeLB->set_active( nSizeLB_InitialSelection );
+ m_xIconSizeLB->save_value();
+
+ ToolBoxButtonSize eSidebarIconSize = static_cast<ToolBoxButtonSize>(officecfg::Office::Common::Misc::SidebarIconSize::get());
+ if( eSidebarIconSize == ToolBoxButtonSize::DontCare )
+ ; // do nothing
+ else if( eSidebarIconSize == ToolBoxButtonSize::Small )
+ nSidebarSizeLB_InitialSelection = 1;
+ else if( eSidebarIconSize == ToolBoxButtonSize::Large )
+ nSidebarSizeLB_InitialSelection = 2;
+ m_xSidebarIconSizeLB->set_active( nSidebarSizeLB_InitialSelection );
+ m_xSidebarIconSizeLB->save_value();
+ ToolBoxButtonSize eNotebookbarIconSize = static_cast<ToolBoxButtonSize>(officecfg::Office::Common::Misc::NotebookbarIconSize::get());
+ if( eNotebookbarIconSize == ToolBoxButtonSize::DontCare )
+ ; // do nothing
+ else if( eNotebookbarIconSize == ToolBoxButtonSize::Small )
+ nNotebookbarSizeLB_InitialSelection = 1;
+ else if( eNotebookbarIconSize == ToolBoxButtonSize::Large )
+ nNotebookbarSizeLB_InitialSelection = 2;
+ m_xNotebookbarIconSizeLB->set_active(nNotebookbarSizeLB_InitialSelection);
+ m_xNotebookbarIconSizeLB->save_value();
+
+ if (aMiscOptions.IconThemeWasSetAutomatically()) {
+ nStyleLB_InitialSelection = 0;
+ }
+ else {
+ const OUString& selected = aMiscOptions.GetIconTheme();
+ const vcl::IconThemeInfo& selectedInfo =
+ vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, selected);
+ nStyleLB_InitialSelection = m_xIconStyleLB->find_text(selectedInfo.GetDisplayName());
+ }
+
+ m_xIconStyleLB->set_active(nStyleLB_InitialSelection);
+ m_xIconStyleLB->save_value();
+
+ // Mouse Snap
+ m_xMousePosLB->set_active(static_cast<sal_Int32>(pAppearanceCfg->GetSnapMode()));
+ m_xMousePosLB->save_value();
+
+ // Mouse Snap
+ m_xMouseMiddleLB->set_active(static_cast<short>(pAppearanceCfg->GetMiddleMouseButton()));
+ m_xMouseMiddleLB->save_value();
+
+ m_xFontAntiAliasing->set_active( pAppearanceCfg->IsFontAntiAliasing() );
+ m_xAAPointLimit->set_value(pAppearanceCfg->GetFontAntialiasingMinPixelHeight(), FieldUnit::PIXEL);
+
+ // WorkingSet
+ m_xFontShowCB->set_active(officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::get());
+ bool bSystemMenuIcons = officecfg::Office::Common::View::Menu::IsSystemIconsInMenus::get();
+ bool bMenuIcons = officecfg::Office::Common::View::Menu::ShowIconsInMenues::get();
+ m_xMenuIconsLB->set_active(bSystemMenuIcons ? 0 : (bMenuIcons ? 2 : 1));
+ m_xMenuIconsLB->save_value();
+
+ TriState eContextMenuShortcuts = static_cast<TriState>(officecfg::Office::Common::View::Menu::ShortcutsInContextMenus::get());
+ bool bContextMenuShortcutsNonDefault = eContextMenuShortcuts == TRISTATE_FALSE || eContextMenuShortcuts == TRISTATE_TRUE;
+ m_xContextMenuShortcutsLB->set_active(bContextMenuShortcutsNonDefault ? eContextMenuShortcuts + 1 : 0);
+ m_xContextMenuShortcutsLB->save_value();
+
+ UpdateHardwareAccelStatus();
+ m_xUseHardwareAccell->save_state();
+
+ { // #i95644# AntiAliasing
+ if(SvtOptionsDrawinglayer::IsAAPossibleOnThisSystem())
+ {
+ m_xUseAntiAliase->set_active(SvtOptionsDrawinglayer::IsAntiAliasing());
+ }
+ else
+ {
+ m_xUseAntiAliase->set_active(false);
+ m_xUseAntiAliase->set_sensitive(false);
+ }
+
+ m_xUseAntiAliase->save_state();
+ }
+
+ m_xUseSkia->set_active(officecfg::Office::Common::VCL::UseSkia::get());
+ m_xForceSkiaRaster->set_active(officecfg::Office::Common::VCL::ForceSkiaRaster::get());
+ m_xUseSkia->save_state();
+ m_xForceSkiaRaster->save_state();
+
+ m_xFontAntiAliasing->save_state();
+ m_xAAPointLimit->save_value();
+ m_xFontShowCB->save_state();
+
+ OnAntialiasingToggled(*m_xFontAntiAliasing);
+ UpdateSkiaStatus();
+}
+
+void OfaViewTabPage::UpdateHardwareAccelStatus()
+{
+ // #i95644# HW accel (unified to disable mechanism)
+ if(pCanvasSettings->IsHardwareAccelerationAvailable())
+ {
+ m_xUseHardwareAccell->set_active(pCanvasSettings->IsHardwareAccelerationEnabled());
+ m_xUseHardwareAccell->set_sensitive(!pCanvasSettings->IsHardwareAccelerationRO());
+ }
+ else
+ {
+ m_xUseHardwareAccell->set_active(false);
+ m_xUseHardwareAccell->set_sensitive(false);
+ }
+#if HAVE_FEATURE_SKIA
+ m_xUseHardwareAccell->set_sensitive(!m_xUseSkia->get_active());
+#endif
+}
+
+struct LanguageConfig_Impl
+{
+ SvtCTLOptions aCTLLanguageOptions;
+ SvtSysLocaleOptions aSysLocaleOptions;
+ SvtLinguConfig aLinguConfig;
+};
+
+static bool bLanguageCurrentDoc_Impl = false;
+
+// some things we'll need...
+constexpr OUStringLiteral sAccessSrvc = u"com.sun.star.configuration.ConfigurationAccess";
+constexpr OUStringLiteral sAccessUpdSrvc = u"com.sun.star.configuration.ConfigurationUpdateAccess";
+constexpr OUStringLiteral sInstalledLocalesPath = u"org.openoffice.Setup/Office/InstalledLocales";
+constexpr OUStringLiteral sUserLocalePath = u"org.openoffice.Office.Linguistic/General";
+constexpr OUStringLiteral sUserLocaleKey = u"UILocale";
+static Sequence< OUString > seqInstalledLanguages;
+
+static OUString lcl_getDatePatternsConfigString( const LocaleDataWrapper& rLocaleWrapper )
+{
+ Sequence< OUString > aDateAcceptancePatterns = rLocaleWrapper.getDateAcceptancePatterns();
+ sal_Int32 nPatterns = aDateAcceptancePatterns.getLength();
+ OUStringBuffer aBuf( nPatterns * 6 ); // 6 := length of Y-M-D;
+ SAL_WARN_IF( !nPatterns, "cui.options", "No date acceptance pattern");
+ if (nPatterns)
+ {
+ const OUString* pPatterns = aDateAcceptancePatterns.getConstArray();
+ aBuf.append( pPatterns[0]);
+ for (sal_Int32 i=1; i < nPatterns; ++i)
+ aBuf.append(';').append( pPatterns[i]);
+ }
+ return aBuf.makeStringAndClear();
+}
+
+namespace
+{
+ //what ui language will be selected by default if the user override of General::UILocale is unset ?
+ LanguageTag GetInstalledLocaleForSystemUILanguage()
+ {
+ css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
+ return LanguageTag(getInstalledLocaleForSystemUILanguage(inst, false)).makeFallback();
+ }
+}
+
+OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optlanguagespage.ui", "OptLanguagesPage", &rSet)
+ , pLangConfig(new LanguageConfig_Impl)
+ , m_bDatePatternsValid(false)
+ , m_xUserInterfaceLB(m_xBuilder->weld_combo_box("userinterface"))
+ , m_xLocaleSettingFT(m_xBuilder->weld_label("localesettingFT"))
+ , m_xLocaleSettingLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("localesetting")))
+ , m_xDecimalSeparatorCB(m_xBuilder->weld_check_button("decimalseparator"))
+ , m_xCurrencyFT(m_xBuilder->weld_label("defaultcurrency"))
+ , m_xCurrencyLB(m_xBuilder->weld_combo_box("currencylb"))
+ , m_xDatePatternsFT(m_xBuilder->weld_label("dataaccpatterns"))
+ , m_xDatePatternsED(m_xBuilder->weld_entry("datepatterns"))
+ , m_xWesternLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("westernlanguage")))
+ , m_xWesternLanguageFT(m_xBuilder->weld_label("western"))
+ , m_xAsianLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("asianlanguage")))
+ , m_xComplexLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("complexlanguage")))
+ , m_xCurrentDocCB(m_xBuilder->weld_check_button("currentdoc"))
+ , m_xAsianSupportCB(m_xBuilder->weld_check_button("asiansupport"))
+ , m_xCTLSupportCB(m_xBuilder->weld_check_button("ctlsupport"))
+ , m_xIgnoreLanguageChangeCB(m_xBuilder->weld_check_button("ignorelanguagechange"))
+{
+ // tdf#125483 save original default label
+ m_sDecimalSeparatorLabel = m_xDecimalSeparatorCB->get_label();
+
+ // initialize user interface language selection
+ m_sSystemDefaultString = SvtLanguageTable::GetLanguageString( LANGUAGE_SYSTEM );
+
+ OUString aUILang = m_sSystemDefaultString +
+ " - " +
+ SvtLanguageTable::GetLanguageString(GetInstalledLocaleForSystemUILanguage().getLanguageType());
+
+ m_xUserInterfaceLB->append("0", aUILang);
+ m_xUserInterfaceLB->append_separator("");
+ try
+ {
+ Reference< XMultiServiceFactory > theConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+ // find out which locales are currently installed and add them to the listbox
+ Sequence< Any > theArgs{ Any(NamedValue("nodepath", Any(OUString(sInstalledLocalesPath)))) };
+ Reference< XNameAccess > theNameAccess(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+ seqInstalledLanguages = theNameAccess->getElementNames();
+ LanguageType aLang = LANGUAGE_DONTKNOW;
+ std::vector< std::pair<sal_Int32, OUString> > aUILanguages;
+ for (sal_Int32 i=0; i<seqInstalledLanguages.getLength(); i++)
+ {
+ aLang = LanguageTag::convertToLanguageTypeWithFallback(seqInstalledLanguages[i]);
+ if (aLang != LANGUAGE_DONTKNOW)
+ {
+ OUString aLangStr( SvtLanguageTable::GetLanguageString( aLang ) );
+ aUILanguages.emplace_back(i+1, aLangStr);
+ }
+ }
+
+ std::sort(aUILanguages.begin(), aUILanguages.end(), [](const auto& l1, const auto& l2) {
+ static const auto aSorter = comphelper::string::NaturalStringSorter(
+ comphelper::getProcessComponentContext(),
+ Application::GetSettings().GetLanguageTag().getLocale());
+ return aSorter.compare(l1.second, l2.second) < 0;
+ });
+
+ // tdf#114694: append the sorted list after the default entry and separator.
+ for (const auto & [ nGroupID, sGroupName ] : aUILanguages)
+ {
+ m_xUserInterfaceLB->append(OUString::number(nGroupID), sGroupName);
+ }
+
+ m_xUserInterfaceLB->set_active(0);
+
+ // find out whether the user has a specific locale specified
+ Sequence< Any > theArgs2{ Any(NamedValue("nodepath", Any(OUString(sUserLocalePath)))) };
+ theNameAccess.set(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs2 ), UNO_QUERY_THROW );
+ if (theNameAccess->hasByName(sUserLocaleKey))
+ theNameAccess->getByName(sUserLocaleKey) >>= m_sUserLocaleValue;
+ // select the user specified locale in the listbox
+ if (!m_sUserLocaleValue.isEmpty())
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xUserInterfaceLB->get_count(); i < nEntryCount; ++i)
+ {
+ sal_Int32 d = m_xUserInterfaceLB->get_id(i).toInt32();
+ if ( d > 0 && seqInstalledLanguages.getLength() > d-1 && seqInstalledLanguages[d-1] == m_sUserLocaleValue)
+ m_xUserInterfaceLB->set_active(i);
+ }
+ }
+
+ }
+ catch (const Exception &)
+ {
+ // we'll just leave the box in its default setting and won't
+ // even give it event handler...
+ TOOLS_WARN_EXCEPTION("cui.options", "ignoring" );
+ }
+
+ m_xWesternLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::WESTERN | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
+
+ m_xAsianLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::CJK | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
+
+ m_xComplexLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::CTL | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
+
+ m_xLocaleSettingLB->SetLanguageList(
+ SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false, false, false, true,
+ LANGUAGE_USER_SYSTEM_CONFIG, css::i18n::ScriptType::WEAK);
+
+ const NfCurrencyTable& rCurrTab = SvNumberFormatter::GetTheCurrencyTable();
+ const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry( LANGUAGE_SYSTEM );
+ // insert SYSTEM entry
+ OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
+ m_xCurrencyLB->append("default", aDefaultCurr);
+ m_xCurrencyLB->append_separator("");
+
+ assert(m_xCurrencyLB->find_id("default") != -1);
+ // all currencies
+ OUString aTwoSpace( " " );
+ sal_uInt16 nCurrCount = rCurrTab.size();
+ std::vector< const NfCurrencyEntry* > aCurrencies;
+ // first entry is SYSTEM, skip it
+ for ( sal_uInt16 j=1; j < nCurrCount; ++j )
+ {
+ aCurrencies.push_back(&rCurrTab[j]);
+ }
+ std::sort(aCurrencies.begin(), aCurrencies.end(),
+ [](const NfCurrencyEntry* c1, const NfCurrencyEntry* c2) {
+ return c1->GetBankSymbol().compareTo(c2->GetBankSymbol()) < 0;
+ });
+
+ for (auto &v : aCurrencies)
+ {
+ OUString aStr_ = v->GetBankSymbol() +
+ aTwoSpace +
+ v->GetSymbol();
+ aStr_ = ApplyLreOrRleEmbedding( aStr_ ) +
+ aTwoSpace +
+ ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( v->GetLanguage() ) );
+ m_xCurrencyLB->append(weld::toId(v), aStr_);
+ }
+
+ m_xCurrencyLB->set_active(0);
+
+ m_xLocaleSettingLB->connect_changed( LINK( this, OfaLanguagesTabPage, LocaleSettingHdl ) );
+ m_xDatePatternsED->connect_changed( LINK( this, OfaLanguagesTabPage, DatePatternsHdl ) );
+
+ Link<weld::Toggleable&,void> aLink( LINK( this, OfaLanguagesTabPage, SupportHdl ) );
+ m_xAsianSupportCB->connect_toggled( aLink );
+ m_xCTLSupportCB->connect_toggled( aLink );
+
+ m_bOldAsian = SvtCJKOptions::IsAnyEnabled();
+ m_xAsianSupportCB->set_active(m_bOldAsian);
+ m_xAsianSupportCB->save_state();
+ bool bReadonly = SvtCJKOptions::IsReadOnly(SvtCJKOptions::E_ALL);
+ m_xAsianSupportCB->set_sensitive(!bReadonly);
+ SupportHdl(*m_xAsianSupportCB);
+
+ m_bOldCtl = pLangConfig->aCTLLanguageOptions.IsCTLFontEnabled();
+ m_xCTLSupportCB->set_active(m_bOldCtl);
+ m_xCTLSupportCB->save_state();
+ bReadonly = pLangConfig->aCTLLanguageOptions.IsReadOnly(SvtCTLOptions::E_CTLFONT);
+ m_xCTLSupportCB->set_sensitive(!bReadonly);
+ SupportHdl(*m_xCTLSupportCB);
+
+ m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange() );
+}
+
+OfaLanguagesTabPage::~OfaLanguagesTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaLanguagesTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaLanguagesTabPage>(pPage, pController, *rAttrSet);
+}
+
+static void lcl_Update(std::unique_ptr<SfxVoidItem> pInvalidItems[], std::unique_ptr<SfxBoolItem> pBoolItems[], sal_uInt16 nCount)
+{
+ SfxViewFrame* pCurrentFrm = SfxViewFrame::Current();
+ SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst();
+ while(pViewFrm)
+ {
+ SfxBindings& rBind = pViewFrm->GetBindings();
+ for(sal_uInt16 i = 0; i < nCount; i++)
+ {
+ if(pCurrentFrm == pViewFrm)
+ rBind.InvalidateAll(false);
+ rBind.SetState( *pInvalidItems[i] );
+ rBind.SetState( *pBoolItems[i] );
+ }
+ pViewFrm = SfxViewFrame::GetNext(*pViewFrm);
+ }
+}
+
+bool OfaLanguagesTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ // lock configuration broadcasters so that we can coordinate the notifications
+ pLangConfig->aSysLocaleOptions.BlockBroadcasts( true );
+ pLangConfig->aCTLLanguageOptions.BlockBroadcasts( true );
+ pLangConfig->aLinguConfig.BlockBroadcasts( true );
+
+ /*
+ * Sequence checking only matters when CTL support is enabled.
+ *
+ * So we only need to check for sequence checking if
+ * a) previously it was unchecked and is now checked or
+ * b) it was already checked but the CTL language has changed
+ */
+ if (
+ m_xCTLSupportCB->get_active() &&
+ (m_xCTLSupportCB->get_saved_state() != TRISTATE_TRUE ||
+ m_xComplexLanguageLB->get_active_id_changed_from_saved())
+ )
+ {
+ //sequence checking has to be switched on depending on the selected CTL language
+ LanguageType eCTLLang = m_xComplexLanguageLB->get_active_id();
+ bool bOn = MsLangId::needsSequenceChecking( eCTLLang);
+ pLangConfig->aCTLLanguageOptions.SetCTLSequenceCheckingRestricted(bOn);
+ pLangConfig->aCTLLanguageOptions.SetCTLSequenceChecking(bOn);
+ pLangConfig->aCTLLanguageOptions.SetCTLSequenceCheckingTypeAndReplace(bOn);
+ }
+ try
+ {
+ // handle settings for UI Language
+ // a change of setting needs to bring up a warning message
+ OUString aLangString;
+ sal_Int32 d = m_xUserInterfaceLB->get_active_id().toInt32();
+ if( d > 0 && seqInstalledLanguages.getLength() > d-1)
+ aLangString = seqInstalledLanguages[d-1];
+
+ /*
+ if( m_xUserInterfaceLB->GetSelectedEntryPos() > 0)
+ aLangString = ConvertLanguageToIsoString(m_xUserInterfaceLB->get_active_id());
+ */
+ Reference< XMultiServiceFactory > theConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+ Sequence< Any > theArgs{ Any(NamedValue("nodepath", Any(OUString(sUserLocalePath)))) };
+ Reference< XPropertySet >xProp(
+ theConfigProvider->createInstanceWithArguments(sAccessUpdSrvc, theArgs ), UNO_QUERY_THROW );
+ if ( m_sUserLocaleValue != aLangString)
+ {
+ // OSL_FAIL("UserInterface language was changed, restart.");
+ // write new value
+ xProp->setPropertyValue(sUserLocaleKey, Any(aLangString));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ // display info
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(
+ comphelper::getProcessComponentContext(), GetFrameWeld(),
+ svtools::RESTART_REASON_LANGUAGE_CHANGE))
+ GetDialogController()->response(RET_OK);
+
+ // tell quickstarter to stop being a veto listener
+
+ Reference< XComponentContext > xContext(
+ comphelper::getProcessComponentContext());
+ css::office::Quickstart::createAndSetVeto(xContext, false, false, false/*DisableVeto*/);
+ }
+ }
+ catch (const Exception&)
+ {
+ // we'll just leave the box in its default setting and won't
+ // even give it event handler...
+ TOOLS_WARN_EXCEPTION("cui.options", "ignoring");
+ }
+
+ LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
+ LanguageType eOldLocale = (aLanguageTag.isSystemLocale() ? LANGUAGE_SYSTEM :
+ aLanguageTag.makeFallback().getLanguageType());
+ LanguageType eNewLocale = m_xLocaleSettingLB->get_active_id();
+
+ // If the "Default ..." entry was selected that means SYSTEM, the actual
+ // eNewLocale value is temporary for the dialog only, do not resolve to
+ // what system currently is.
+ if (eNewLocale == LANGUAGE_USER_SYSTEM_CONFIG)
+ eNewLocale = LANGUAGE_SYSTEM;
+
+ if ( eOldLocale != eNewLocale )
+ {
+ // an empty string denotes SYSTEM locale
+ OUString sNewLang;
+ if ( eNewLocale != LANGUAGE_SYSTEM )
+ sNewLang = LanguageTag::convertToBcp47( eNewLocale);
+
+ // locale nowadays get to AppSettings via notification
+ // this will happen after releasing the lock on the ConfigurationBroadcaster at
+ // the end of this method
+ pLangConfig->aSysLocaleOptions.SetLocaleConfigString( sNewLang );
+ rSet->Put( SfxBoolItem( SID_OPT_LOCALE_CHANGED, true ) );
+
+ SvtScriptType nNewType = SvtLanguageOptions::GetScriptTypeOfLanguage( eNewLocale );
+ bool bNewCJK = bool( nNewType & SvtScriptType::ASIAN );
+ SvtCompatibilityOptions aCompatOpts;
+ aCompatOpts.SetDefault( SvtCompatibilityEntry::Index::ExpandWordSpace, !bNewCJK );
+ }
+
+ if(m_xDecimalSeparatorCB->get_state_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetDecimalSeparatorAsLocale(m_xDecimalSeparatorCB->get_active());
+
+ if(m_xIgnoreLanguageChangeCB->get_state_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetIgnoreLanguageChange(m_xIgnoreLanguageChangeCB->get_active());
+
+ // Configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default.
+ OUString sOldCurr = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
+ OUString sId = m_xCurrencyLB->get_active_id();
+ const NfCurrencyEntry* pCurr = sId == "default" ? nullptr : weld::fromId<const NfCurrencyEntry*>(sId);
+ OUString sNewCurr;
+ if ( pCurr )
+ sNewCurr = SvtSysLocaleOptions::CreateCurrencyConfigString(
+ pCurr->GetBankSymbol(), pCurr->GetLanguage() );
+ if ( sOldCurr != sNewCurr )
+ pLangConfig->aSysLocaleOptions.SetCurrencyConfigString( sNewCurr );
+
+ // Configured date acceptance patterns, for example Y-M-D;M-D or empty for
+ // locale default.
+ if (m_bDatePatternsValid && m_xDatePatternsED->get_value_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetDatePatternsConfigString( m_xDatePatternsED->get_text());
+
+ SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
+ Reference< css::linguistic2::XLinguProperties > xLinguProp = LinguMgr::GetLinguPropertySet();
+ bool bCurrentDocCBChecked = m_xCurrentDocCB->get_active();
+ if (m_xCurrentDocCB->get_sensitive())
+ bLanguageCurrentDoc_Impl = bCurrentDocCBChecked;
+ bool bCurrentDocCBChanged = m_xCurrentDocCB->get_state_changed_from_saved();
+
+ bool bValChanged = m_xWesternLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xWesternLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::LATIN),
+ SID_ATTR_LANGUAGE));
+ }
+ }
+ bValChanged = m_xAsianLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xAsianLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale_CJK", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale_CJK( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::ASIAN),
+ SID_ATTR_CHAR_CJK_LANGUAGE));
+ }
+ }
+ bValChanged = m_xComplexLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xComplexLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale_CTL", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale_CTL( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::COMPLEX),
+ SID_ATTR_CHAR_CTL_LANGUAGE));
+ }
+ }
+
+ if(m_xAsianSupportCB->get_state_changed_from_saved() )
+ {
+ bool bChecked = m_xAsianSupportCB->get_active();
+ SvtCJKOptions::SetAll(bChecked);
+
+ //iterate over all bindings to invalidate vertical text direction
+ const sal_uInt16 STATE_COUNT = 2;
+
+ std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
+ pBoolItems[0].reset(new SfxBoolItem(SID_VERTICALTEXT_STATE, false));
+ pBoolItems[1].reset(new SfxBoolItem(SID_TEXT_FITTOSIZE_VERTICAL, false));
+
+ std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
+ pInvalidItems[0].reset(new SfxVoidItem(SID_VERTICALTEXT_STATE));
+ pInvalidItems[1].reset(new SfxVoidItem(SID_TEXT_FITTOSIZE_VERTICAL));
+
+ lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
+ }
+
+ if ( m_xCTLSupportCB->get_state_changed_from_saved() )
+ {
+ SvtSearchOptions aOpt;
+ aOpt.SetIgnoreDiacritics_CTL(true);
+ aOpt.SetIgnoreKashida_CTL(true);
+ aOpt.Commit();
+ pLangConfig->aCTLLanguageOptions.SetCTLFontEnabled( m_xCTLSupportCB->get_active() );
+
+ const sal_uInt16 STATE_COUNT = 1;
+ std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
+ pBoolItems[0].reset(new SfxBoolItem(SID_CTLFONT_STATE, false));
+ std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
+ pInvalidItems[0].reset(new SfxVoidItem(SID_CTLFONT_STATE));
+ lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
+ }
+
+ if ( pLangConfig->aSysLocaleOptions.IsModified() )
+ pLangConfig->aSysLocaleOptions.Commit();
+
+ // first release the lock on the ConfigurationBroadcaster for Locale changes
+ // it seems that our code relies on the fact that before other changes like e.g. currency
+ // are broadcasted locale changes have been done
+ pLangConfig->aSysLocaleOptions.BlockBroadcasts( false );
+ pLangConfig->aCTLLanguageOptions.BlockBroadcasts( false );
+ pLangConfig->aLinguConfig.BlockBroadcasts( false );
+
+ return false;
+}
+
+void OfaLanguagesTabPage::Reset( const SfxItemSet* rSet )
+{
+ LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
+ if ( aLanguageTag.isSystemLocale() )
+ m_xLocaleSettingLB->set_active_id( LANGUAGE_USER_SYSTEM_CONFIG );
+ else
+ m_xLocaleSettingLB->set_active_id( aLanguageTag.makeFallback().getLanguageType());
+ bool bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Locale);
+ m_xLocaleSettingLB->set_sensitive(!bReadonly);
+ m_xLocaleSettingFT->set_sensitive(!bReadonly);
+
+
+ m_xDecimalSeparatorCB->set_active( pLangConfig->aSysLocaleOptions.IsDecimalSeparatorAsLocale());
+ m_xDecimalSeparatorCB->save_state();
+
+ m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange());
+ m_xIgnoreLanguageChangeCB->save_state();
+
+ // let LocaleSettingHdl enable/disable checkboxes for CJK/CTL support
+ // #i15812# must be done *before* the configured currency is set
+ // and update the decimal separator used for the given locale
+ LocaleSettingHdl(*m_xLocaleSettingLB->get_widget());
+
+ // configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default
+ const NfCurrencyEntry* pCurr = nullptr;
+ OUString sCurrency = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
+ if ( !sCurrency.isEmpty() )
+ {
+ LanguageType eLang;
+ OUString aAbbrev;
+ SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( aAbbrev, eLang, sCurrency );
+ pCurr = SvNumberFormatter::GetCurrencyEntry( aAbbrev, eLang );
+ }
+ // if pCurr==nullptr the SYSTEM entry is selected
+ OUString sId = !pCurr ? OUString("default") : weld::toId(pCurr);
+ m_xCurrencyLB->set_active_id(sId);
+ bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Currency);
+ m_xCurrencyLB->set_sensitive(!bReadonly);
+ m_xCurrencyFT->set_sensitive(!bReadonly);
+
+ // date acceptance patterns
+ OUString aDatePatternsString = pLangConfig->aSysLocaleOptions.GetDatePatternsConfigString();
+ if (aDatePatternsString.isEmpty())
+ {
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aDatePatternsString = lcl_getDatePatternsConfigString( rLocaleWrapper);
+ }
+ // Let's assume patterns are valid at this point.
+ m_bDatePatternsValid = true;
+ m_xDatePatternsED->set_text(aDatePatternsString);
+ bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::DatePatterns);
+ m_xDatePatternsED->set_sensitive(!bReadonly);
+ m_xDatePatternsFT->set_sensitive(!bReadonly);
+ m_xDatePatternsED->save_value();
+
+ //western/CJK/CLK language
+ LanguageType eCurLang = LANGUAGE_NONE;
+ LanguageType eCurLangCJK = LANGUAGE_NONE;
+ LanguageType eCurLangCTL = LANGUAGE_NONE;
+ SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
+ //collect the configuration values first
+ m_xCurrentDocCB->set_sensitive(false);
+
+ Any aWestLang;
+ Any aCJKLang;
+ Any aCTLLang;
+ try
+ {
+ aWestLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale");
+ Locale aLocale;
+ aWestLang >>= aLocale;
+
+ eCurLang = LanguageTag::convertToLanguageType( aLocale, false);
+
+ aCJKLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale_CJK");
+ aLocale = Locale();
+ aCJKLang >>= aLocale;
+ eCurLangCJK = LanguageTag::convertToLanguageType( aLocale, false);
+
+ aCTLLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale_CTL");
+ aLocale = Locale();
+ aCTLLang >>= aLocale;
+ eCurLangCTL = LanguageTag::convertToLanguageType( aLocale, false);
+ }
+ catch (const Exception&)
+ {
+ }
+ //overwrite them by the values provided by the DocShell
+ if(pCurrentDocShell)
+ {
+ m_xCurrentDocCB->set_sensitive(true);
+ m_xCurrentDocCB->set_active(bLanguageCurrentDoc_Impl);
+ if( const SvxLanguageItem* pLangItem = rSet->GetItemIfSet(SID_ATTR_LANGUAGE, false))
+ {
+ LanguageType eTempCurLang = pLangItem->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLang, css::i18n::ScriptType::LATIN) != eTempCurLang)
+ eCurLang = eTempCurLang;
+ }
+
+ if( const SvxLanguageItem* pLang = rSet->GetItemIfSet(SID_ATTR_CHAR_CJK_LANGUAGE, false))
+ {
+ LanguageType eTempCurLang = pLang->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCJK, css::i18n::ScriptType::ASIAN) != eTempCurLang)
+ eCurLangCJK = eTempCurLang;
+ }
+
+ if( const SvxLanguageItem* pLang = rSet->GetItemIfSet(SID_ATTR_CHAR_CTL_LANGUAGE, false))
+ {
+ LanguageType eTempCurLang = pLang->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCTL, css::i18n::ScriptType::COMPLEX) != eTempCurLang)
+ eCurLangCTL = eTempCurLang;
+ }
+ }
+ if(LANGUAGE_NONE == eCurLang || LANGUAGE_DONTKNOW == eCurLang)
+ m_xWesternLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xWesternLanguageLB->set_active_id(eCurLang);
+
+ if(LANGUAGE_NONE == eCurLangCJK || LANGUAGE_DONTKNOW == eCurLangCJK)
+ m_xAsianLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xAsianLanguageLB->set_active_id(eCurLangCJK);
+
+ if(LANGUAGE_NONE == eCurLangCTL || LANGUAGE_DONTKNOW == eCurLangCTL)
+ m_xComplexLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xComplexLanguageLB->set_active_id(eCurLangCTL);
+
+ m_xWesternLanguageLB->save_active_id();
+ m_xAsianLanguageLB->save_active_id();
+ m_xComplexLanguageLB->save_active_id();
+ m_xIgnoreLanguageChangeCB->save_state();
+ m_xCurrentDocCB->save_state();
+
+ bool bEnable = !pLangConfig->aLinguConfig.IsReadOnly( u"DefaultLocale" );
+ m_xWesternLanguageFT->set_sensitive( bEnable );
+ m_xWesternLanguageLB->set_sensitive( bEnable );
+
+ // check the box "For the current document only"
+ // set the focus to the Western Language box
+ const SfxBoolItem* pLang = rSet->GetItemIfSet(SID_SET_DOCUMENT_LANGUAGE, false );
+ if ( pLang && pLang->GetValue() )
+ {
+ m_xWesternLanguageLB->grab_focus();
+ m_xCurrentDocCB->set_sensitive(true);
+ m_xCurrentDocCB->set_active(true);
+ }
+}
+
+IMPL_LINK(OfaLanguagesTabPage, SupportHdl, weld::Toggleable&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ if ( m_xAsianSupportCB.get() == &rBox )
+ {
+ bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly(u"DefaultLocale_CJK");
+ bCheck = ( bCheck && !bReadonly );
+ m_xAsianLanguageLB->set_sensitive( bCheck );
+ if (rBox.get_sensitive())
+ m_bOldAsian = bCheck;
+ }
+ else if ( m_xCTLSupportCB.get() == &rBox )
+ {
+ bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly(u"DefaultLocale_CTL");
+ bCheck = ( bCheck && !bReadonly );
+ m_xComplexLanguageLB->set_sensitive( bCheck );
+ if (rBox.get_sensitive())
+ m_bOldCtl = bCheck;
+ }
+ else
+ SAL_WARN( "cui.options", "OfaLanguagesTabPage::SupportHdl(): wrong rBox" );
+}
+
+namespace
+{
+ void lcl_checkLanguageCheckBox(weld::CheckButton& _rCB, bool _bNewValue, bool _bOldValue)
+ {
+ if ( _bNewValue )
+ _rCB.set_active(true);
+ else
+ _rCB.set_active( _bOldValue );
+// #i15082# do not call save_state() in running dialog...
+// _rCB.save_state();
+ _rCB.set_sensitive( !_bNewValue );
+ }
+}
+
+IMPL_LINK_NOARG(OfaLanguagesTabPage, LocaleSettingHdl, weld::ComboBox&, void)
+{
+ LanguageType eLang = m_xLocaleSettingLB->get_active_id();
+ SvtScriptType nType = SvtLanguageOptions::GetScriptTypeOfLanguage(eLang);
+ // first check if CTL must be enabled
+ // #103299# - if CTL font setting is not readonly
+ if(!pLangConfig->aCTLLanguageOptions.IsReadOnly(SvtCTLOptions::E_CTLFONT))
+ {
+ bool bIsCTLFixed = bool(nType & SvtScriptType::COMPLEX);
+ lcl_checkLanguageCheckBox(*m_xCTLSupportCB, bIsCTLFixed, m_bOldCtl);
+ SupportHdl(*m_xCTLSupportCB);
+ }
+ // second check if CJK must be enabled
+ // #103299# - if CJK support is not readonly
+ if(!SvtCJKOptions::IsReadOnly(SvtCJKOptions::E_ALL))
+ {
+ bool bIsCJKFixed = bool(nType & SvtScriptType::ASIAN);
+ lcl_checkLanguageCheckBox(*m_xAsianSupportCB, bIsCJKFixed, m_bOldAsian);
+ SupportHdl(*m_xAsianSupportCB);
+ }
+
+ const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry(
+ (eLang == LANGUAGE_USER_SYSTEM_CONFIG) ? MsLangId::getConfiguredSystemLanguage() : eLang);
+ const OUString aDefaultID = "default";
+ // Update the "Default ..." currency.
+ m_xCurrencyLB->remove_id(aDefaultID);
+ OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
+ m_xCurrencyLB->insert(0, aDefaultCurr, &aDefaultID, nullptr, nullptr);
+ assert(m_xCurrencyLB->find_id(aDefaultID) != -1);
+ m_xCurrencyLB->set_active_text(aDefaultCurr);
+
+ // obtain corresponding locale data
+ LocaleDataWrapper aLocaleWrapper(( LanguageTag(eLang) ));
+
+ // update the decimal separator key of the related CheckBox
+ OUString sTempLabel(m_sDecimalSeparatorLabel);
+ sTempLabel = sTempLabel.replaceFirst("%1", aLocaleWrapper.getNumDecimalSep() );
+ m_xDecimalSeparatorCB->set_label(sTempLabel);
+
+ // update the date acceptance patterns
+ OUString aDatePatternsString = lcl_getDatePatternsConfigString( aLocaleWrapper);
+ m_bDatePatternsValid = true;
+ m_xDatePatternsED->set_text( aDatePatternsString);
+}
+
+IMPL_LINK( OfaLanguagesTabPage, DatePatternsHdl, weld::Entry&, rEd, void )
+{
+ const OUString aPatterns(rEd.get_text());
+ OUStringBuffer aBuf( aPatterns);
+ sal_Int32 nChar = 0;
+ bool bValid = true;
+ bool bModified = false;
+ if (!aPatterns.isEmpty())
+ {
+ for (sal_Int32 nIndex=0; nIndex >= 0 && bValid; ++nChar)
+ {
+ const OUString aPat( aPatterns.getToken( 0, ';', nIndex));
+ if (aPat.isEmpty() && nIndex < 0)
+ {
+ // Indicating failure when about to append a pattern is too
+ // confusing. Empty patterns are ignored anyway when sequencing
+ // to SvtSysLocale.
+ continue; // for
+ }
+ else if (aPat.getLength() < 2)
+ bValid = false;
+ else
+ {
+ bool bY, bM, bD;
+ bY = bM = bD = false;
+ bool bSep = true;
+ if (aPat.getLength() == 3)
+ {
+ // Disallow a pattern that would match a numeric input with
+ // decimal separator, like M.D
+ const LanguageType eLang = m_xLocaleSettingLB->get_active_id();
+ const LocaleDataWrapper aLocaleWrapper(( LanguageTag(eLang)));
+ if ( aPat[1] == aLocaleWrapper.getNumDecimalSep().toChar()
+ || aPat[1] == aLocaleWrapper.getNumDecimalSepAlt().toChar())
+ {
+ bValid = false;
+ }
+ }
+ for (sal_Int32 i = 0; i < aPat.getLength() && bValid; /*nop*/)
+ {
+ const sal_Int32 j = i;
+ const sal_uInt32 c = aPat.iterateCodePoints( &i);
+ // Only one Y,M,D per pattern, separated by any character(s).
+ switch (c)
+ {
+ case 'y':
+ case 'Y':
+ if (bY || !bSep)
+ bValid = false;
+ else if (c == 'y')
+ {
+ aBuf[nChar] = 'Y';
+ bModified = true;
+ }
+ bY = true;
+ bSep = false;
+ break;
+ case 'm':
+ case 'M':
+ if (bM || !bSep)
+ bValid = false;
+ else if (c == 'm')
+ {
+ aBuf[nChar] = 'M';
+ bModified = true;
+ }
+ bM = true;
+ bSep = false;
+ break;
+ case 'd':
+ case 'D':
+ if (bD || !bSep)
+ bValid = false;
+ else if (c == 'd')
+ {
+ aBuf[nChar] = 'D';
+ bModified = true;
+ }
+ bD = true;
+ bSep = false;
+ break;
+ default:
+ // A pattern must not start with a separator (but
+ // may end with).
+ if (!(bY || bM || bD))
+ bValid = false;
+ bSep = true;
+ }
+ nChar += i-j;
+ }
+ // At least one of Y,M,D
+ bValid &= (bY || bM || bD);
+ }
+ }
+ }
+ if (bModified)
+ {
+ // gtk3 keeps the cursor position on equal length set_text() but at
+ // least the 'gen' backend does not and resets to 0.
+ const int nCursorPos = rEd.get_position();
+ rEd.set_text(aBuf.makeStringAndClear());
+ rEd.set_position(nCursorPos);
+ }
+ if (bValid)
+ rEd.set_message_type(weld::EntryMessageType::Normal);
+ else
+ rEd.set_message_type(weld::EntryMessageType::Error);
+ m_bDatePatternsValid = bValid;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
new file mode 100644
index 000000000..75f29c6c5
--- /dev/null
+++ b/cui/source/options/optgdlg.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+
+class CanvasSettings;
+
+namespace vcl {
+ class IconThemeInfo;
+}
+
+class OfaMiscTabPage : public SfxTabPage
+{
+private:
+ OUString m_aStrDateInfo;
+
+ std::unique_ptr<weld::CheckButton> m_xExtHelpCB;
+ std::unique_ptr<weld::CheckButton> m_xPopUpNoHelpCB;
+ std::unique_ptr<weld::CheckButton> m_xShowTipOfTheDay;
+ std::unique_ptr<weld::Widget> m_xFileDlgFrame;
+ std::unique_ptr<weld::Widget> m_xFileDlgROImage;
+ std::unique_ptr<weld::CheckButton> m_xFileDlgCB;
+ std::unique_ptr<weld::CheckButton> m_xPrintDlgCB;
+ std::unique_ptr<weld::CheckButton> m_xDocStatusCB;
+ std::unique_ptr<weld::Widget> m_xYearFrame;
+ std::unique_ptr<weld::SpinButton> m_xYearValueField;
+ std::unique_ptr<weld::Label> m_xToYearFT;
+ std::unique_ptr<weld::CheckButton> m_xCrashReport;
+ std::unique_ptr<weld::Widget> m_xQuickStarterFrame;
+ std::unique_ptr<weld::Label> m_xHelpImproveLabel;
+ std::unique_ptr<weld::CheckButton> m_xQuickLaunchCB;
+#if defined(_WIN32)
+ std::unique_ptr<weld::Widget> m_xFileAssocFrame;
+ std::unique_ptr<weld::Button> m_xFileAssocBtn;
+ std::unique_ptr<weld::CheckButton> m_xPerformFileExtCheck;
+#endif
+
+ DECL_LINK(TwoFigureHdl, weld::SpinButton&, void);
+#if defined(_WIN32)
+ DECL_DLLPRIVATE_STATIC_LINK(OfaMiscTabPage, FileAssocClick, weld::Button&, void);
+#endif
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaMiscTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvtTabAppearanceCfg;
+
+class OfaViewTabPage : public SfxTabPage
+{
+private:
+ sal_Int32 nSizeLB_InitialSelection;
+ sal_Int32 nSidebarSizeLB_InitialSelection;
+ sal_Int32 nNotebookbarSizeLB_InitialSelection;
+ sal_Int32 nStyleLB_InitialSelection;
+
+ std::unique_ptr<SvtTabAppearanceCfg> pAppearanceCfg;
+ std::unique_ptr<CanvasSettings> pCanvasSettings;
+
+ std::vector<vcl::IconThemeInfo> mInstalledIconThemes;
+
+ std::unique_ptr<weld::ComboBox> m_xIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xSidebarIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xNotebookbarIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xIconStyleLB;
+
+ std::unique_ptr<weld::CheckButton> m_xFontAntiAliasing;
+ std::unique_ptr<weld::Label> m_xAAPointLimitLabel;
+ std::unique_ptr<weld::MetricSpinButton> m_xAAPointLimit;
+
+ std::unique_ptr<weld::Widget> m_xMenuIconBox;
+ std::unique_ptr<weld::ComboBox> m_xMenuIconsLB;
+
+ std::unique_ptr<weld::ComboBox> m_xContextMenuShortcutsLB;
+
+ std::unique_ptr<weld::CheckButton> m_xFontShowCB;
+
+ std::unique_ptr<weld::CheckButton> m_xUseHardwareAccell;
+ std::unique_ptr<weld::CheckButton> m_xUseAntiAliase;
+ std::unique_ptr<weld::CheckButton> m_xUseSkia;
+ std::unique_ptr<weld::CheckButton> m_xForceSkiaRaster;
+
+ std::unique_ptr<weld::Label> m_xSkiaStatusEnabled;
+ std::unique_ptr<weld::Label> m_xSkiaStatusDisabled;
+
+ std::unique_ptr<weld::ComboBox> m_xMousePosLB;
+ std::unique_ptr<weld::ComboBox> m_xMouseMiddleLB;
+ std::unique_ptr<weld::Button> m_xMoreIcons;
+ std::unique_ptr<weld::Button> m_xRunGPTests;
+
+ DECL_LINK(OnAntialiasingToggled, weld::Toggleable&, void);
+ DECL_LINK(OnUseSkiaToggled, weld::Toggleable&, void);
+ DECL_STATIC_LINK(OfaViewTabPage, OnMoreIconsClick, weld::Button&, void);
+ DECL_LINK(OnRunGPTestClick, weld::Button&, void);
+ void UpdateSkiaStatus();
+ void HideSkiaWidgets();
+ void UpdateHardwareAccelStatus();
+
+public:
+ OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaViewTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+struct LanguageConfig_Impl;
+
+class OfaLanguagesTabPage : public SfxTabPage
+{
+ bool m_bOldAsian;
+ bool m_bOldCtl;
+ std::unique_ptr<LanguageConfig_Impl> pLangConfig;
+
+ OUString m_sUserLocaleValue;
+ OUString m_sSystemDefaultString;
+ OUString m_sDecimalSeparatorLabel;
+
+ bool m_bDatePatternsValid;
+
+ std::unique_ptr<weld::ComboBox> m_xUserInterfaceLB;
+ std::unique_ptr<weld::Label> m_xLocaleSettingFT;
+ std::unique_ptr<SvxLanguageBox> m_xLocaleSettingLB;
+ std::unique_ptr<weld::CheckButton> m_xDecimalSeparatorCB;
+ std::unique_ptr<weld::Label> m_xCurrencyFT;
+ std::unique_ptr<weld::ComboBox> m_xCurrencyLB;
+ std::unique_ptr<weld::Label> m_xDatePatternsFT;
+ std::unique_ptr<weld::Entry> m_xDatePatternsED;
+
+ std::unique_ptr<SvxLanguageBox> m_xWesternLanguageLB;
+ std::unique_ptr<weld::Label> m_xWesternLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xAsianLanguageLB;
+ std::unique_ptr<SvxLanguageBox> m_xComplexLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xCurrentDocCB;
+ std::unique_ptr<weld::CheckButton> m_xAsianSupportCB;
+ std::unique_ptr<weld::CheckButton> m_xCTLSupportCB;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreLanguageChangeCB;
+
+ DECL_LINK(SupportHdl, weld::Toggleable&, void);
+ DECL_LINK(LocaleSettingHdl, weld::ComboBox&, void);
+ DECL_LINK(DatePatternsHdl, weld::Entry&, void);
+
+public:
+ OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaLanguagesTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgenrl.cxx b/cui/source/options/optgenrl.cxx
new file mode 100644
index 000000000..094089421
--- /dev/null
+++ b/cui/source/options/optgenrl.cxx
@@ -0,0 +1,507 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <config_gpgme.h>
+#if HAVE_FEATURE_GPGME
+# include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
+# include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
+#endif
+
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/settings.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <unotools/useroptions.hxx>
+#include <cuioptgenrl.hxx>
+#include <svx/svxids.hrc>
+#include <svx/optgenrl.hxx>
+
+using namespace css;
+
+namespace
+{
+
+// rows
+enum RowType
+{
+ Row_Company,
+ Row_Name,
+ Row_Name_Russian,
+ Row_Name_Eastern,
+ Row_Street,
+ Row_Street_Russian,
+ Row_City,
+ Row_City_US,
+ Row_Country,
+ Row_TitlePos,
+ Row_Phone,
+ Row_FaxMail,
+
+ nRowCount
+};
+
+// language flags
+namespace Lang
+{
+ unsigned const Others = 1;
+ unsigned const Russian = 2;
+ unsigned const Eastern = 4;
+ unsigned const US = 8;
+ unsigned const All = static_cast<unsigned>(-1);
+}
+
+
+// vRowInfo[] -- rows (text + one or more edit boxes)
+// The order is the same as in RowType above, which is up to down.
+
+struct
+{
+ // id of the text
+ const char *pTextId;
+ // language flags (see Lang above):
+ // which language is this row for?
+ unsigned nLangFlags;
+}
+const vRowInfo[] =
+{
+ { "companyft", Lang::All },
+ { "nameft", Lang::All & ~Lang::Russian & ~Lang::Eastern },
+ { "rusnameft", Lang::Russian },
+ { "eastnameft", Lang::Eastern },
+ { "streetft", Lang::All & ~Lang::Russian },
+ { "russtreetft", Lang::Russian },
+ { "icityft", Lang::All & ~Lang::US },
+ { "cityft", Lang::US },
+ { "countryft", Lang::All },
+ { "titleft", Lang::All },
+ { "phoneft", Lang::All },
+ { "faxft", Lang::All },
+};
+
+
+// vFieldInfo[] -- edit boxes
+// The order is up to down, and then left to right.
+
+struct
+{
+ // in which row?
+ RowType eRow;
+ // id of the edit box
+ const char *pEditId;
+ // id for SvtUserOptions in unotools/useroptions.hxx
+ UserOptToken nUserOptionsId;
+ // id for settings the focus (defined in svx/optgenrl.hxx)
+ EditPosition nGrabFocusId;
+}
+const vFieldInfo[] =
+{
+ // Company
+ { Row_Company, "company", UserOptToken::Company, EditPosition::COMPANY },
+ // Name
+ { Row_Name, "firstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name, "lastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name, "shortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Name (russian)
+ { Row_Name_Russian, "ruslastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name_Russian, "rusfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name_Russian, "rusfathersname", UserOptToken::FathersName, EditPosition::UNKNOWN },
+ { Row_Name_Russian, "russhortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Name (eastern: reversed name ord
+ { Row_Name_Eastern, "eastlastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name_Eastern, "eastfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name_Eastern, "eastshortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Street
+ { Row_Street, "street", UserOptToken::Street, EditPosition::STREET },
+ // Street (russian)
+ { Row_Street_Russian, "russtreet", UserOptToken::Street, EditPosition::STREET },
+ { Row_Street_Russian, "apartnum", UserOptToken::Apartment, EditPosition::UNKNOWN },
+ // City
+ { Row_City, "izip", UserOptToken::Zip, EditPosition::PLZ },
+ { Row_City, "icity", UserOptToken::City, EditPosition::CITY },
+ // City (US)
+ { Row_City_US, "city", UserOptToken::City, EditPosition::CITY },
+ { Row_City_US, "state", UserOptToken::State, EditPosition::STATE },
+ { Row_City_US, "zip", UserOptToken::Zip, EditPosition::PLZ },
+ // Country
+ { Row_Country, "country", UserOptToken::Country, EditPosition::COUNTRY },
+ // Title/Position
+ { Row_TitlePos, "title", UserOptToken::Title, EditPosition::TITLE },
+ { Row_TitlePos, "position", UserOptToken::Position, EditPosition::POSITION },
+ // Phone
+ { Row_Phone, "home", UserOptToken::TelephoneHome, EditPosition::TELPRIV },
+ { Row_Phone, "work", UserOptToken::TelephoneWork, EditPosition::TELCOMPANY },
+ // Fax/Mail
+ { Row_FaxMail, "fax", UserOptToken::Fax, EditPosition::FAX },
+ { Row_FaxMail, "email", UserOptToken::Email, EditPosition::EMAIL },
+};
+
+
+} // namespace
+
+
+// Row
+
+struct SvxGeneralTabPage::Row
+{
+ // row label
+ std::unique_ptr<weld::Label> xLabel;
+ // first and last field in the row (last is exclusive)
+ unsigned nFirstField, nLastField;
+
+public:
+ explicit Row (std::unique_ptr<weld::Label> xLabel_)
+ : xLabel(std::move(xLabel_))
+ , nFirstField(0)
+ , nLastField(0)
+ {
+ xLabel->show();
+ }
+};
+
+
+// Field
+
+struct SvxGeneralTabPage::Field
+{
+ // which field is this? (in vFieldInfo[] above)
+ unsigned iField;
+ // edit box
+ std::unique_ptr<weld::Entry> xEdit;
+ std::unique_ptr<weld::Container> xParent;
+
+public:
+ Field (std::unique_ptr<weld::Entry> xEdit_, unsigned iField_)
+ : iField(iField_)
+ , xEdit(std::move(xEdit_))
+ , xParent(xEdit->weld_parent())
+ {
+ //We want all widgets inside a container, so each row of the toplevel
+ //grid has another container in it. To avoid adding spacing to these
+ //empty grids they all default to invisible, so show them if their
+ //children are visible
+ xParent->show();
+ xEdit->show();
+ }
+};
+
+SvxGeneralTabPage::SvxGeneralTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optuserpage.ui", "OptUserPage", &rCoreSet)
+ , m_xUseDataCB(m_xBuilder->weld_check_button("usefordocprop"))
+ , m_xCryptoFrame(m_xBuilder->weld_widget( "cryptography"))
+ , m_xSigningKeyLB(m_xBuilder->weld_combo_box("signingkey"))
+ , m_xEncryptionKeyLB(m_xBuilder->weld_combo_box("encryptionkey"))
+ , m_xEncryptToSelfCB(m_xBuilder->weld_check_button("encrypttoself"))
+{
+ InitControls();
+#if HAVE_FEATURE_GPGME
+ InitCryptography();
+#else
+ m_xCryptoFrame->hide();
+#endif
+
+ SetExchangeSupport(); // this page needs ExchangeSupport
+ SetLinks();
+}
+
+SvxGeneralTabPage::~SvxGeneralTabPage()
+{
+}
+
+// Initializes the titles and the edit boxes,
+// according to vRowInfo[] and vFieldInfo[] above.
+void SvxGeneralTabPage::InitControls ()
+{
+ // which language bit do we use? (see Lang and vRowInfo[] above)
+ unsigned LangBit;
+ LanguageType l = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ if (l == LANGUAGE_ENGLISH_US)
+ LangBit = Lang::US;
+ else if (l == LANGUAGE_RUSSIAN)
+ LangBit = Lang::Russian;
+ else
+ {
+ if (MsLangId::isFamilyNameFirst(l))
+ LangBit = Lang::Eastern;
+ else
+ LangBit = Lang::Others;
+ }
+
+ // creating rows
+ unsigned iField = 0;
+ for (unsigned iRow = 0; iRow != nRowCount; ++iRow)
+ {
+ RowType const eRow = static_cast<RowType>(iRow);
+ // is the row visible?
+ if (!(vRowInfo[iRow].nLangFlags & LangBit))
+ continue;
+ // creating row
+ vRows.push_back(std::make_shared<Row>(
+ m_xBuilder->weld_label(vRowInfo[iRow].pTextId)));
+ Row& rRow = *vRows.back();
+ // fields in the row
+ static unsigned const nFieldCount = std::size(vFieldInfo);
+ // skipping other (invisible) rows
+ while (iField != nFieldCount && vFieldInfo[iField].eRow != eRow)
+ ++iField;
+ // fields in the row
+ rRow.nFirstField = vFields.size();
+ for ( ; iField != nFieldCount && vFieldInfo[iField].eRow == eRow; ++iField)
+ {
+ // creating edit field
+ vFields.push_back(std::make_shared<Field>(
+ m_xBuilder->weld_entry(vFieldInfo[iField].pEditId), iField));
+ // "short name" field?
+ if (vFieldInfo[iField].nUserOptionsId == UserOptToken::ID)
+ {
+ nNameRow = vRows.size() - 1;
+ nShortNameField = vFields.size() - 1;
+ }
+ }
+ rRow.nLastField = vFields.size();
+ }
+}
+
+void SvxGeneralTabPage::InitCryptography()
+{
+#if HAVE_FEATURE_GPGME
+ m_xCryptoFrame->show();
+
+ uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
+ try
+ {
+ xSEInitializer = xml::crypto::GPGSEInitializer::create( comphelper::getProcessComponentContext() );
+ uno::Reference<xml::crypto::XXMLSecurityContext> xSC = xSEInitializer->createSecurityContext( OUString() );
+ if (xSC.is())
+ {
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSE = xSC->getSecurityEnvironment();
+ uno::Sequence<uno::Reference<security::XCertificate>> xCertificates = xSE->getPersonalCertificates();
+
+ if (xCertificates.hasElements())
+ {
+ for (auto& xCert : asNonConstRange(xCertificates))
+ {
+ m_xSigningKeyLB->append_text( xCert->getIssuerName());
+ m_xEncryptionKeyLB->append_text( xCert->getIssuerName());
+ }
+ }
+
+ //tdf#115015: wrap checkbox text and listboxes if necessary
+ int nPrefWidth(m_xEncryptToSelfCB->get_preferred_size().Width());
+ int nMaxWidth = m_xEncryptToSelfCB->get_approximate_digit_width() * 40;
+ if (nPrefWidth > nMaxWidth)
+ {
+ m_xSigningKeyLB->set_size_request(nMaxWidth, -1);
+ m_xEncryptionKeyLB->set_size_request(nMaxWidth, -1);
+ m_xEncryptToSelfCB->set_label_wrap(true);
+ m_xEncryptToSelfCB->set_size_request(nMaxWidth, -1);
+ }
+ }
+ }
+ catch ( uno::Exception const & )
+ {}
+#endif
+
+}
+
+void SvxGeneralTabPage::SetLinks ()
+{
+ // link for updating the initials
+ Link<weld::Entry&,void> aLink = LINK( this, SvxGeneralTabPage, ModifyHdl_Impl );
+ Row& rNameRow = *vRows[nNameRow];
+ for (unsigned i = rNameRow.nFirstField; i != rNameRow.nLastField - 1; ++i)
+ vFields[i]->xEdit->connect_changed(aLink);
+}
+
+
+std::unique_ptr<SfxTabPage> SvxGeneralTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxGeneralTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxGeneralTabPage::FillItemSet( SfxItemSet* )
+{
+ // remove leading and trailing whitespaces
+ for (auto const & i: vFields)
+ i->xEdit->set_text(comphelper::string::strip(i->xEdit->get_text(), ' '));
+
+ bool bModified = false;
+ bModified |= GetData_Impl();
+ if (m_xUseDataCB->get_active() != officecfg::Office::Common::Save::Document::UseUserData::get())
+ {
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Save::Document::UseUserData::set(m_xUseDataCB->get_active(), xChanges);
+ xChanges->commit();
+ bModified = true;
+ }
+ return bModified;
+}
+
+void SvxGeneralTabPage::Reset( const SfxItemSet* rSet )
+{
+ SetData_Impl();
+
+ if (rSet->GetItemState(SID_FIELD_GRABFOCUS) == SfxItemState::SET)
+ {
+ EditPosition nField = static_cast<EditPosition>(static_cast<const SfxUInt16Item&>(rSet->Get(SID_FIELD_GRABFOCUS)).GetValue());
+ if (nField != EditPosition::UNKNOWN)
+ {
+ for (auto const & i: vFields)
+ if (nField == vFieldInfo[i->iField].nGrabFocusId)
+ i->xEdit->grab_focus();
+ }
+ else
+ vFields.front()->xEdit->grab_focus();
+ }
+
+ m_xUseDataCB->set_active(officecfg::Office::Common::Save::Document::UseUserData::get());
+}
+
+
+// ModifyHdl_Impl()
+// This handler updates the initials (short name)
+// when one of the name fields was updated.
+IMPL_LINK( SvxGeneralTabPage, ModifyHdl_Impl, weld::Entry&, rEdit, void )
+{
+ // short name field and row
+ Field& rShortName = *vFields[nShortNameField];
+ Row& rNameRow = *vRows[nNameRow];
+ // number of initials
+ unsigned const nInits = rNameRow.nLastField - rNameRow.nFirstField - 1;
+ // which field was updated? (in rNameRow)
+ unsigned nField = nInits;
+ for (unsigned i = 0; i != nInits; ++i)
+ {
+ if (vFields[rNameRow.nFirstField + i]->xEdit.get() == &rEdit)
+ nField = i;
+ }
+ // updating the initial
+ if (!(nField < nInits && rShortName.xEdit->get_sensitive()))
+ return;
+
+ OUString sShortName = rShortName.xEdit->get_text();
+ // clear short name if it contains more characters than the number of initials
+ if (o3tl::make_unsigned(sShortName.getLength()) > nInits)
+ {
+ rShortName.xEdit->set_text(OUString());
+ }
+ while (o3tl::make_unsigned(sShortName.getLength()) < nInits)
+ sShortName += " ";
+ OUString sName = rEdit.get_text();
+ OUString sLetter = sName.isEmpty()
+ ? OUString(u' ') : sName.copy(0, 1);
+ rShortName.xEdit->set_text(sShortName.replaceAt(nField, 1, sLetter).trim());
+}
+
+
+bool SvxGeneralTabPage::GetData_Impl()
+{
+ // updating
+ SvtUserOptions aUserOpt;
+ for (auto const & i: vFields)
+ aUserOpt.SetToken(
+ vFieldInfo[i->iField].nUserOptionsId,
+ i->xEdit->get_text()
+ );
+
+ // modified?
+ bool bModified = false;
+ for (auto const & i: vFields)
+ {
+ if (i->xEdit->get_value_changed_from_saved())
+ {
+ bModified = true;
+ break;
+ }
+ }
+
+#if HAVE_FEATURE_GPGME
+ OUString aSK = m_xSigningKeyLB->get_active() == 0 ? OUString() //i.e. no key
+ : m_xSigningKeyLB->get_active_text();
+ OUString aEK = m_xEncryptionKeyLB->get_active() == 0 ? OUString()
+ : m_xEncryptionKeyLB->get_active_text();
+
+ aUserOpt.SetToken( UserOptToken::SigningKey, aSK );
+ aUserOpt.SetToken( UserOptToken::EncryptionKey, aEK );
+ aUserOpt.SetBoolValue( UserOptToken::EncryptToSelf, m_xEncryptToSelfCB->get_active() );
+
+ bModified |= m_xSigningKeyLB->get_value_changed_from_saved() ||
+ m_xEncryptionKeyLB->get_value_changed_from_saved() ||
+ m_xEncryptToSelfCB->get_state_changed_from_saved();
+#endif
+
+ return bModified;
+}
+
+
+void SvxGeneralTabPage::SetData_Impl()
+{
+ // updating and disabling edit boxes
+ SvtUserOptions aUserOpt;
+ for (auto const & i: vRows)
+ {
+ Row& rRow = *i;
+ // the label is enabled if any of its edit fields are enabled
+ bool bEnableLabel = false;
+ for (unsigned iField = rRow.nFirstField; iField != rRow.nLastField; ++iField)
+ {
+ Field& rField = *vFields[iField];
+ // updating content
+ UserOptToken const nToken = vFieldInfo[rField.iField].nUserOptionsId;
+ rField.xEdit->set_text(aUserOpt.GetToken(nToken));
+ // is enabled?
+ bool const bEnableEdit = !aUserOpt.IsTokenReadonly(nToken);
+ rField.xEdit->set_sensitive(bEnableEdit);
+ bEnableLabel = bEnableLabel || bEnableEdit;
+ }
+ rRow.xLabel->set_sensitive(bEnableLabel);
+ }
+
+ // saving
+ for (auto const & i: vFields)
+ i->xEdit->save_value();
+
+#if HAVE_FEATURE_GPGME
+ OUString aSK = aUserOpt.GetToken(UserOptToken::SigningKey);
+ aSK.isEmpty() ? m_xSigningKeyLB->set_active( 0 ) //i.e. 'No Key'
+ : m_xSigningKeyLB->set_active_text( aSK );
+
+ OUString aEK = aUserOpt.GetToken(UserOptToken::EncryptionKey);
+ aEK.isEmpty() ? m_xEncryptionKeyLB->set_active( 0 ) //i.e. 'No Key'
+ : m_xEncryptionKeyLB->set_active_text( aEK );
+
+ m_xEncryptToSelfCB->set_active( aUserOpt.GetEncryptToSelf() );
+#endif
+}
+
+
+DeactivateRC SvxGeneralTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/opthtml.cxx b/cui/source/options/opthtml.cxx
new file mode 100644
index 000000000..18e3beceb
--- /dev/null
+++ b/cui/source/options/opthtml.cxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svtools/langtab.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <comphelper/configuration.hxx>
+#include <officecfg/Office/Common.hxx>
+#include "opthtml.hxx"
+
+
+OfaHtmlTabPage::OfaHtmlTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/opthtmlpage.ui", "OptHtmlPage", &rSet)
+ , m_xSize1NF(m_xBuilder->weld_spin_button("size1"))
+ , m_xSize2NF(m_xBuilder->weld_spin_button("size2"))
+ , m_xSize3NF(m_xBuilder->weld_spin_button("size3"))
+ , m_xSize4NF(m_xBuilder->weld_spin_button("size4"))
+ , m_xSize5NF(m_xBuilder->weld_spin_button("size5"))
+ , m_xSize6NF(m_xBuilder->weld_spin_button("size6"))
+ , m_xSize7NF(m_xBuilder->weld_spin_button("size7"))
+ , m_xNumbersEnglishUSCB(m_xBuilder->weld_check_button("numbersenglishus"))
+ , m_xUnknownTagCB(m_xBuilder->weld_check_button("unknowntag"))
+ , m_xIgnoreFontNamesCB(m_xBuilder->weld_check_button("ignorefontnames"))
+ , m_xStarBasicCB(m_xBuilder->weld_check_button("starbasic"))
+ , m_xStarBasicWarningCB(m_xBuilder->weld_check_button("starbasicwarning"))
+ , m_xPrintExtensionCB(m_xBuilder->weld_check_button("printextension"))
+ , m_xSaveGrfLocalCB(m_xBuilder->weld_check_button("savegrflocal"))
+{
+ // replace placeholder with UI string from language list
+ OUString aText(m_xNumbersEnglishUSCB->get_label());
+ OUString aPlaceholder("%ENGLISHUSLOCALE");
+ sal_Int32 nPos;
+ if ((nPos = aText.indexOf( aPlaceholder)) != -1)
+ {
+ const OUString& rStr = SvtLanguageTable::GetLanguageString( LANGUAGE_ENGLISH_US);
+ if (!rStr.isEmpty())
+ {
+ aText = aText.replaceAt( nPos, aPlaceholder.getLength(), rStr);
+ m_xNumbersEnglishUSCB->set_label( aText);
+ }
+ }
+
+ m_xStarBasicCB->connect_toggled(LINK(this, OfaHtmlTabPage, CheckBoxHdl_Impl));
+}
+
+OfaHtmlTabPage::~OfaHtmlTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaHtmlTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaHtmlTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaHtmlTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
+ if(m_xSize1NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_1::set(
+ static_cast<sal_uInt16>(m_xSize1NF->get_value()), xChanges);
+ if(m_xSize2NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_2::set(
+ static_cast<sal_uInt16>(m_xSize2NF->get_value()), xChanges);
+ if(m_xSize3NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_3::set(
+ static_cast<sal_uInt16>(m_xSize3NF->get_value()), xChanges);
+ if(m_xSize4NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_4::set(
+ static_cast<sal_uInt16>(m_xSize4NF->get_value()), xChanges);
+ if(m_xSize5NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_5::set(
+ static_cast<sal_uInt16>(m_xSize5NF->get_value()), xChanges);
+ if(m_xSize6NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_6::set(
+ static_cast<sal_uInt16>(m_xSize6NF->get_value()), xChanges);
+ if(m_xSize7NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_7::set(
+ static_cast<sal_uInt16>(m_xSize7NF->get_value()), xChanges);
+
+ if(m_xNumbersEnglishUSCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::NumbersEnglishUS::set(
+ m_xNumbersEnglishUSCB->get_active(), xChanges);
+
+ if(m_xUnknownTagCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::UnknownTag::set(
+ m_xUnknownTagCB->get_active(), xChanges);
+
+ if(m_xIgnoreFontNamesCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSetting::set(
+ m_xIgnoreFontNamesCB->get_active(), xChanges);
+
+ if(m_xStarBasicCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::Basic::set(
+ m_xStarBasicCB->get_active(), xChanges);
+
+ if(m_xStarBasicWarningCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::Warning::set(
+ m_xStarBasicWarningCB->get_active(), xChanges);
+
+ if(m_xSaveGrfLocalCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::LocalGraphic::set(
+ m_xSaveGrfLocalCB->get_active(), xChanges);
+
+ if(m_xPrintExtensionCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::PrintLayout::set(
+ m_xPrintExtensionCB->get_active(), xChanges);
+
+ xChanges->commit();
+ return false;
+}
+
+void OfaHtmlTabPage::Reset( const SfxItemSet* )
+{
+ m_xSize1NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_1::get());
+ m_xSize2NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_2::get());
+ m_xSize3NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_3::get());
+ m_xSize4NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_4::get());
+ m_xSize5NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_5::get());
+ m_xSize6NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_6::get());
+ m_xSize7NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_7::get());
+ m_xNumbersEnglishUSCB->set_active(officecfg::Office::Common::Filter::HTML::Import::NumbersEnglishUS::get());
+ m_xUnknownTagCB->set_active(officecfg::Office::Common::Filter::HTML::Import::UnknownTag::get());
+ m_xIgnoreFontNamesCB->set_active(officecfg::Office::Common::Filter::HTML::Import::FontSetting::get());
+
+ m_xStarBasicCB->set_active(officecfg::Office::Common::Filter::HTML::Export::Basic::get());
+ m_xStarBasicWarningCB->set_active(officecfg::Office::Common::Filter::HTML::Export::Warning::get());
+ m_xStarBasicWarningCB->set_sensitive(!m_xStarBasicCB->get_active());
+ m_xSaveGrfLocalCB->set_active(officecfg::Office::Common::Filter::HTML::Export::LocalGraphic::get());
+ m_xPrintExtensionCB->set_active(SvxHtmlOptions::IsPrintLayoutExtension());
+
+ m_xPrintExtensionCB->save_state();
+ m_xStarBasicCB->save_state();
+ m_xStarBasicWarningCB->save_state();
+ m_xSaveGrfLocalCB->save_state();
+ m_xSize1NF->save_value();
+ m_xSize2NF->save_value();
+ m_xSize3NF->save_value();
+ m_xSize4NF->save_value();
+ m_xSize5NF->save_value();
+ m_xSize6NF->save_value();
+ m_xSize7NF->save_value();
+ m_xNumbersEnglishUSCB->save_state();
+ m_xUnknownTagCB->save_state();
+ m_xIgnoreFontNamesCB->save_state();
+}
+
+IMPL_LINK(OfaHtmlTabPage, CheckBoxHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ m_xStarBasicWarningCB->set_sensitive(!rBox.get_active());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/opthtml.hxx b/cui/source/options/opthtml.hxx
new file mode 100644
index 000000000..33bff167b
--- /dev/null
+++ b/cui/source/options/opthtml.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/txencbox.hxx>
+
+class OfaHtmlTabPage : public SfxTabPage
+{
+
+ std::unique_ptr<weld::SpinButton> m_xSize1NF;
+ std::unique_ptr<weld::SpinButton> m_xSize2NF;
+ std::unique_ptr<weld::SpinButton> m_xSize3NF;
+ std::unique_ptr<weld::SpinButton> m_xSize4NF;
+ std::unique_ptr<weld::SpinButton> m_xSize5NF;
+ std::unique_ptr<weld::SpinButton> m_xSize6NF;
+ std::unique_ptr<weld::SpinButton> m_xSize7NF;
+
+ std::unique_ptr<weld::CheckButton> m_xNumbersEnglishUSCB;
+ std::unique_ptr<weld::CheckButton> m_xUnknownTagCB;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreFontNamesCB;
+
+ std::unique_ptr<weld::CheckButton> m_xStarBasicCB;
+ std::unique_ptr<weld::CheckButton> m_xStarBasicWarningCB;
+ std::unique_ptr<weld::CheckButton> m_xPrintExtensionCB;
+ std::unique_ptr<weld::CheckButton> m_xSaveGrfLocalCB;
+
+ DECL_LINK(CheckBoxHdl_Impl, weld::Toggleable&, void);
+
+public:
+ OfaHtmlTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaHtmlTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+};
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optinet2.cxx b/cui/source/options/optinet2.cxx
new file mode 100644
index 000000000..a3dd5826f
--- /dev/null
+++ b/cui/source/options/optinet2.cxx
@@ -0,0 +1,938 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <officecfg/Inet.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Security.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/securityoptions.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <dialmgr.hxx>
+#include "optinet2.hxx"
+#include <strings.hrc>
+
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include "securityoptions.hxx"
+#include "webconninfo.hxx"
+#include "certpath.hxx"
+#include "tsaurls.hxx"
+
+#include <svtools/restartdialog.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sfx2;
+
+namespace {
+
+bool isValidPort(OUString const & value) {
+ if (!comphelper::string::isdigitAsciiString(value)) {
+ return false;
+ }
+ auto const n = value.toUInt64();
+ if (n > 65535) {
+ return false;
+ }
+ if (n != 0) {
+ return true;
+ }
+ // Overflow in OUString::toUInt64 returns 0, so need to check value contains only zeroes:
+ return std::u16string_view(value).find_first_not_of(u'0') == std::u16string_view::npos;
+}
+
+}
+
+IMPL_LINK(SvxProxyTabPage, PortChangedHdl, weld::Entry&, rEdit, void)
+{
+ if (!isValidPort(rEdit.get_text()))
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_OPT_PROXYPORTS)));
+ xErrorBox->run();
+ }
+}
+
+constexpr OUStringLiteral g_aProxyModePN = u"ooInetProxyType";
+constexpr OUStringLiteral g_aHttpProxyPN = u"ooInetHTTPProxyName";
+constexpr OUStringLiteral g_aHttpPortPN = u"ooInetHTTPProxyPort";
+constexpr OUStringLiteral g_aHttpsProxyPN = u"ooInetHTTPSProxyName";
+constexpr OUStringLiteral g_aHttpsPortPN = u"ooInetHTTPSProxyPort";
+constexpr OUStringLiteral g_aFtpProxyPN = u"ooInetFTPProxyName";
+constexpr OUStringLiteral g_aFtpPortPN = u"ooInetFTPProxyPort";
+constexpr OUStringLiteral g_aNoProxyDescPN = u"ooInetNoProxy";
+
+IMPL_STATIC_LINK(SvxProxyTabPage, NumberOnlyTextFilterHdl, OUString&, rTest, bool)
+{
+ OUStringBuffer sAllowed;
+ for (sal_Int32 i = 0, nLen = rTest.getLength(); i < nLen; ++i)
+ {
+ if (rTest[i] >= '0' && rTest[i] <= '9')
+ sAllowed.append(rTest[i]);
+ }
+ rTest = sAllowed.makeStringAndClear();
+ return true;
+}
+
+IMPL_STATIC_LINK(SvxProxyTabPage, NoSpaceTextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = rTest.replaceAll(" ", "");
+ return true;
+}
+
+/********************************************************************/
+/* */
+/* SvxProxyTabPage */
+/* */
+/********************************************************************/
+SvxProxyTabPage::SvxProxyTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optproxypage.ui", "OptProxyPage", &rSet)
+ , m_xProxyModeLB(m_xBuilder->weld_combo_box("proxymode"))
+ , m_xHttpProxyFT(m_xBuilder->weld_label("httpft"))
+ , m_xHttpProxyED(m_xBuilder->weld_entry("http"))
+ , m_xHttpPortFT(m_xBuilder->weld_label("httpportft"))
+ , m_xHttpPortED(m_xBuilder->weld_entry("httpport"))
+ , m_xHttpsProxyFT(m_xBuilder->weld_label("httpsft"))
+ , m_xHttpsProxyED(m_xBuilder->weld_entry("https"))
+ , m_xHttpsPortFT(m_xBuilder->weld_label("httpsportft"))
+ , m_xHttpsPortED(m_xBuilder->weld_entry("httpsport"))
+ , m_xFtpProxyFT(m_xBuilder->weld_label("ftpft"))
+ , m_xFtpProxyED(m_xBuilder->weld_entry("ftp"))
+ , m_xFtpPortFT(m_xBuilder->weld_label("ftpportft"))
+ , m_xFtpPortED(m_xBuilder->weld_entry("ftpport"))
+ , m_xNoProxyForFT(m_xBuilder->weld_label("noproxyft"))
+ , m_xNoProxyForED(m_xBuilder->weld_entry("noproxy"))
+ , m_xNoProxyDescFT(m_xBuilder->weld_label("noproxydesc"))
+{
+ m_xHttpProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xHttpPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xHttpPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+ m_xHttpsProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xHttpsPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xHttpsPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+ m_xFtpProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xFtpPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xFtpPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+
+ Link<weld::Widget&,void> aLink = LINK( this, SvxProxyTabPage, LoseFocusHdl_Impl );
+ m_xHttpPortED->connect_focus_out( aLink );
+ m_xHttpsPortED->connect_focus_out( aLink );
+ m_xFtpPortED->connect_focus_out( aLink );
+
+ m_xProxyModeLB->connect_changed(LINK( this, SvxProxyTabPage, ProxyHdl_Impl ));
+
+ Reference< css::lang::XMultiServiceFactory >
+ xConfigurationProvider(
+ configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext() ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= OUString( "org.openoffice.Inet/Settings" );
+
+ Sequence< Any > aArgumentList{ Any(aProperty) };
+
+ m_xConfigurationUpdateAccess = xConfigurationProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ aArgumentList );
+}
+
+SvxProxyTabPage::~SvxProxyTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxProxyTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxProxyTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxProxyTabPage::ReadConfigData_Impl()
+{
+ sal_Int32 nIntValue = 0;
+
+ std::optional<sal_Int32> x(officecfg::Inet::Settings::ooInetProxyType::get());
+ if (x)
+ {
+ nIntValue = *x;
+ m_xProxyModeLB->set_active(nIntValue);
+ }
+
+ m_xHttpProxyED->set_text( officecfg::Inet::Settings::ooInetHTTPProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetHTTPProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xHttpPortED->set_text( OUString::number( nIntValue ));
+ }
+ else
+ m_xHttpPortED->set_text( "" );
+
+ m_xHttpsProxyED->set_text( officecfg::Inet::Settings::ooInetHTTPSProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetHTTPSProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xHttpsPortED->set_text( OUString::number( nIntValue ));
+ }
+ else
+ m_xHttpsPortED->set_text( "" );
+
+ m_xFtpProxyED->set_text( officecfg::Inet::Settings::ooInetFTPProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetFTPProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xFtpPortED->set_text( OUString::number( nIntValue ));
+ }
+ else
+ m_xFtpPortED->set_text( "" );
+
+ m_xNoProxyForED->set_text( officecfg::Inet::Settings::ooInetNoProxy::get() );
+}
+
+void SvxProxyTabPage::ReadConfigDefaults_Impl()
+{
+ try
+ {
+ Reference< beans::XPropertyState > xPropertyState(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+
+ sal_Int32 nIntValue = 0;
+ OUString aStringValue;
+
+ if( xPropertyState->getPropertyDefault(g_aHttpProxyPN) >>= aStringValue )
+ {
+ m_xHttpProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpPortPN) >>= nIntValue )
+ {
+ m_xHttpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpsProxyPN) >>= aStringValue )
+ {
+ m_xHttpsProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpsPortPN) >>= nIntValue )
+ {
+ m_xHttpsPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aFtpProxyPN) >>= aStringValue )
+ {
+ m_xFtpProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aFtpPortPN) >>= nIntValue )
+ {
+ m_xFtpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aNoProxyDescPN) >>= aStringValue )
+ {
+ m_xNoProxyForED->set_text( aStringValue );
+ }
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const css::lang::WrappedTargetException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const RuntimeException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+}
+
+void SvxProxyTabPage::RestoreConfigDefaults_Impl()
+{
+ try
+ {
+ Reference< beans::XPropertyState > xPropertyState(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+
+ xPropertyState->setPropertyToDefault(g_aProxyModePN);
+ xPropertyState->setPropertyToDefault(g_aHttpProxyPN);
+ xPropertyState->setPropertyToDefault(g_aHttpPortPN);
+ xPropertyState->setPropertyToDefault(g_aHttpsProxyPN);
+ xPropertyState->setPropertyToDefault(g_aHttpsPortPN);
+ xPropertyState->setPropertyToDefault(g_aFtpProxyPN);
+ xPropertyState->setPropertyToDefault(g_aFtpPortPN);
+ xPropertyState->setPropertyToDefault(g_aNoProxyDescPN);
+
+ Reference< util::XChangesBatch > xChangesBatch(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+ xChangesBatch->commitChanges();
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const css::lang::WrappedTargetException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const RuntimeException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+}
+
+void SvxProxyTabPage::Reset(const SfxItemSet*)
+{
+ ReadConfigData_Impl();
+
+ m_xProxyModeLB->save_value();
+ m_xHttpProxyED->save_value();
+ m_xHttpPortED->save_value();
+ m_xHttpsProxyED->save_value();
+ m_xHttpsPortED->save_value();
+ m_xFtpProxyED->save_value();
+ m_xFtpPortED->save_value();
+ m_xNoProxyForED->save_value();
+
+ EnableControls_Impl();
+}
+
+bool SvxProxyTabPage::FillItemSet(SfxItemSet* )
+{
+ bool bModified = false;
+
+ try {
+ Reference< beans::XPropertySet > xPropertySet(m_xConfigurationUpdateAccess, UNO_QUERY_THROW );
+
+ sal_Int32 nSelPos = m_xProxyModeLB->get_active();
+ if(m_xProxyModeLB->get_value_changed_from_saved())
+ {
+ if( nSelPos == 1 )
+ {
+ RestoreConfigDefaults_Impl();
+ return true;
+ }
+
+ xPropertySet->setPropertyValue(g_aProxyModePN, Any(nSelPos));
+ bModified = true;
+ }
+
+ if(m_xHttpProxyED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aHttpProxyPN, Any(m_xHttpProxyED->get_text()));
+ bModified = true;
+ }
+
+ if ( m_xHttpPortED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aHttpPortPN, Any(m_xHttpPortED->get_text().toInt32()));
+ bModified = true;
+ }
+
+ if( m_xHttpsProxyED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aHttpsProxyPN, Any(m_xHttpsProxyED->get_text()) );
+ bModified = true;
+ }
+
+ if ( m_xHttpsPortED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aHttpsPortPN, Any(m_xHttpsPortED->get_text().toInt32()) );
+ bModified = true;
+ }
+
+ if( m_xFtpProxyED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aFtpProxyPN, Any(m_xFtpProxyED->get_text()) );
+ bModified = true;
+ }
+
+ if ( m_xFtpPortED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aFtpPortPN, Any(m_xFtpPortED->get_text().toInt32()));
+ bModified = true;
+ }
+
+ if ( m_xNoProxyForED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aNoProxyDescPN, Any( m_xNoProxyForED->get_text()));
+ bModified = true;
+ }
+
+ Reference< util::XChangesBatch > xChangesBatch(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+ xChangesBatch->commitChanges();
+ }
+ catch (const css::lang::IllegalArgumentException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const beans::UnknownPropertyException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const beans::PropertyVetoException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const css::lang::WrappedTargetException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const RuntimeException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+
+ return bModified;
+}
+
+void SvxProxyTabPage::EnableControls_Impl()
+{
+ m_xProxyModeLB->set_sensitive(!officecfg::Inet::Settings::ooInetNoProxy::isReadOnly());
+
+ const bool bManualConfig = m_xProxyModeLB->get_active() == 2;
+
+ const bool bHTTPProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPProxyName::isReadOnly();
+ const bool bHTTPProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPProxyPort::isReadOnly();
+ m_xHttpProxyFT->set_sensitive(bHTTPProxyNameEnabled);
+ m_xHttpProxyED->set_sensitive(bHTTPProxyNameEnabled);
+ m_xHttpPortFT->set_sensitive(bHTTPProxyPortEnabled);
+ m_xHttpPortED->set_sensitive(bHTTPProxyPortEnabled);
+
+ const bool bHTTPSProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPSProxyName::isReadOnly();
+ const bool bHTTPSProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPSProxyPort::isReadOnly();
+ m_xHttpsProxyFT->set_sensitive(bHTTPSProxyNameEnabled);
+ m_xHttpsProxyED->set_sensitive(bHTTPSProxyNameEnabled);
+ m_xHttpsPortFT->set_sensitive(bHTTPSProxyPortEnabled);
+ m_xHttpsPortED->set_sensitive(bHTTPSProxyPortEnabled);
+
+ const bool bFTPProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetFTPProxyName::isReadOnly();
+ const bool bFTPProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetFTPProxyPort::isReadOnly();
+ m_xFtpProxyFT->set_sensitive(bFTPProxyNameEnabled);
+ m_xFtpProxyED->set_sensitive(bFTPProxyNameEnabled);
+ m_xFtpPortFT->set_sensitive(bFTPProxyPortEnabled);
+ m_xFtpPortED->set_sensitive(bFTPProxyPortEnabled);
+
+ const bool bInetNoProxyEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetNoProxy::isReadOnly();
+ m_xNoProxyForFT->set_sensitive(bInetNoProxyEnabled);
+ m_xNoProxyForED->set_sensitive(bInetNoProxyEnabled);
+ m_xNoProxyDescFT->set_sensitive(bInetNoProxyEnabled);
+}
+
+IMPL_LINK(SvxProxyTabPage, ProxyHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+
+ // Restore original system values
+ if( nPos == 1 )
+ {
+ ReadConfigDefaults_Impl();
+ }
+
+ EnableControls_Impl();
+}
+
+IMPL_STATIC_LINK(SvxProxyTabPage, LoseFocusHdl_Impl, weld::Widget&, rControl, void)
+{
+ weld::Entry* pEdit = dynamic_cast<weld::Entry*>(&rControl);
+ if (pEdit && !isValidPort(pEdit->get_text()))
+ pEdit->set_text(OUString('0'));
+}
+
+/********************************************************************/
+/* */
+/* SvxSecurityTabPage */
+/* */
+/********************************************************************/
+SvxSecurityTabPage::SvxSecurityTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optsecuritypage.ui", "OptSecurityPage", &rSet)
+ , m_xSecurityOptionsPB(m_xBuilder->weld_button("options"))
+ , m_xSavePasswordsCB(m_xBuilder->weld_check_button("savepassword"))
+ , m_xShowConnectionsPB(m_xBuilder->weld_button("connections"))
+ , m_xMasterPasswordCB(m_xBuilder->weld_check_button("usemasterpassword"))
+ , m_xMasterPasswordFT(m_xBuilder->weld_label("masterpasswordtext"))
+ , m_xMasterPasswordPB(m_xBuilder->weld_button("masterpassword"))
+ , m_xMacroSecFrame(m_xBuilder->weld_container("macrosecurity"))
+ , m_xMacroSecPB(m_xBuilder->weld_button("macro"))
+ , m_xCertFrame(m_xBuilder->weld_container("certificatepath"))
+ , m_xCertPathPB(m_xBuilder->weld_button("cert"))
+ , m_xTSAURLsFrame(m_xBuilder->weld_container("tsaurls"))
+ , m_xTSAURLsPB(m_xBuilder->weld_button("tsas"))
+ , m_xNoPasswordSaveFT(m_xBuilder->weld_label("nopasswordsave"))
+{
+ //fdo#65595, we need height-for-width support here, but for now we can
+ //bodge it
+ Size aPrefSize(m_xSavePasswordsCB->get_preferred_size());
+ int nMaxWidth = m_xSavePasswordsCB->get_approximate_digit_width() * 40;
+ if (aPrefSize.Width() > nMaxWidth)
+ {
+ m_xSavePasswordsCB->set_label_wrap(true);
+ m_xSavePasswordsCB->set_size_request(nMaxWidth, -1);
+ }
+
+ m_sPasswordStoringDeactivateStr = m_xNoPasswordSaveFT->get_label();
+
+ InitControls();
+
+ m_xSecurityOptionsPB->connect_clicked( LINK( this, SvxSecurityTabPage, SecurityOptionsHdl ) );
+ m_xSavePasswordsCB->connect_toggled( LINK( this, SvxSecurityTabPage, SavePasswordHdl ) );
+ m_xMasterPasswordPB->connect_clicked( LINK( this, SvxSecurityTabPage, MasterPasswordHdl ) );
+ m_xMasterPasswordCB->connect_toggled( LINK( this, SvxSecurityTabPage, MasterPasswordCBHdl ) );
+ m_xShowConnectionsPB->connect_clicked( LINK( this, SvxSecurityTabPage, ShowPasswordsHdl ) );
+ m_xMacroSecPB->connect_clicked( LINK( this, SvxSecurityTabPage, MacroSecPBHdl ) );
+ m_xCertPathPB->connect_clicked( LINK( this, SvxSecurityTabPage, CertPathPBHdl ) );
+ m_xTSAURLsPB->connect_clicked( LINK( this, SvxSecurityTabPage, TSAURLsPBHdl ) );
+
+ ActivatePage( rSet );
+}
+
+SvxSecurityTabPage::~SvxSecurityTabPage()
+{
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, SecurityOptionsHdl, weld::Button&, void)
+{
+ if (!m_xSecOptDlg)
+ m_xSecOptDlg.reset(new svx::SecurityOptionsDialog(GetFrameWeld()));
+ m_xSecOptDlg->run();
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, SavePasswordHdl, weld::Toggleable&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( m_xSavePasswordsCB->get_active() )
+ {
+ bool bOldValue = xMasterPasswd->allowPersistentStoring( true );
+ xMasterPasswd->removeMasterPassword();
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( xMasterPasswd->changeMasterPassword(xTmpHandler) )
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordCB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ else
+ {
+ xMasterPasswd->allowPersistentStoring( bOldValue );
+ m_xSavePasswordsCB->set_active( false );
+ }
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_sPasswordStoringDeactivateStr));
+ xQueryBox->set_default_response(RET_NO);
+
+ sal_uInt16 nRet = xQueryBox->run();
+
+ if( RET_YES == nRet )
+ {
+ xMasterPasswd->allowPersistentStoring( false );
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordCB->set_sensitive( false );
+ m_xMasterPasswordFT->set_sensitive( false );
+ m_xShowConnectionsPB->set_sensitive( false );
+ }
+ else
+ {
+ m_xSavePasswordsCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_active( !m_xSavePasswordsCB->get_active() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MasterPasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+ xMasterPasswd->changeMasterPassword(xTmpHandler);
+ }
+ }
+ catch (const Exception&)
+ {}
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MasterPasswordCBHdl, weld::Toggleable&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( m_xMasterPasswordCB->get_active() )
+ {
+ if (xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->changeMasterPassword(xTmpHandler))
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ else
+ {
+ m_xMasterPasswordCB->set_active( false );
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ }
+ else
+ {
+ if ( xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->useDefaultMasterPassword(xTmpHandler) )
+ {
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordFT->set_sensitive( false );
+ }
+ else
+ {
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_active( !m_xSavePasswordsCB->get_active() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, ShowPasswordsHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->authorizateWithMasterPassword(xTmpHandler) )
+ {
+ svx::WebConnectionInfoDialog aDlg(GetFrameWeld());
+ aDlg.run();
+ }
+ }
+ catch (const Exception&)
+ {}
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, CertPathPBHdl, weld::Button&, void)
+{
+ if (!mpCertPathDlg)
+ mpCertPathDlg.reset(new CertPathDialog(GetFrameWeld()));
+ mpCertPathDlg->Init();
+
+ if (mpCertPathDlg->run() == RET_OK && !mpCertPathDlg->isActiveServicePath())
+ {
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, svtools::RESTART_REASON_ADDING_PATH))
+ GetDialogController()->response(RET_OK);
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, TSAURLsPBHdl, weld::Button&, void)
+{
+ // Unlike the mpCertPathDlg, we *don't* keep the same dialog object around between
+ // invocations. Seems clearer to my little brain that way.
+ TSAURLsDialog aTSAURLsDlg(GetFrameWeld());
+ aTSAURLsDlg.run();
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MacroSecPBHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< security::XDocumentDigitalSignatures > xD(
+ security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext() ) );
+ xD->setParentWindow(GetDialogController()->getDialog()->GetXWindow());
+ xD->manageTrustedSources();
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "");
+ }
+}
+
+void SvxSecurityTabPage::InitControls()
+{
+#ifndef UNX
+ m_xCertFrame->hide();
+#endif
+
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordCB->set_sensitive( false );
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordFT->set_sensitive( false );
+ m_xShowConnectionsPB->set_sensitive( false );
+
+ // initialize the password saving checkbox
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ m_xMasterPasswordCB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ m_xSavePasswordsCB->set_active(true);
+
+ if ( xMasterPasswd->isDefaultMasterPasswordUsed() )
+ m_xMasterPasswordCB->set_active( false );
+ else
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_sensitive( false );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxSecurityTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxSecurityTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxSecurityTabPage::ActivatePage( const SfxItemSet& )
+{
+}
+
+DeactivateRC SvxSecurityTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+namespace
+{
+ bool CheckAndSave( SvtSecurityOptions::EOption _eOpt, const bool _bIsChecked, bool& _rModified )
+ {
+ bool bModified = false;
+ if ( !SvtSecurityOptions::IsReadOnly( _eOpt ) )
+ {
+ bModified = SvtSecurityOptions::IsOptionSet( _eOpt ) != _bIsChecked;
+ if ( bModified )
+ {
+ SvtSecurityOptions::SetOption( _eOpt, _bIsChecked );
+ _rModified = true;
+ }
+ }
+
+ return bModified;
+ }
+}
+
+bool SvxSecurityTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+
+ if (m_xSecOptDlg)
+ {
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnSaveOrSend, m_xSecOptDlg->IsSaveOrSendDocsChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnSigning, m_xSecOptDlg->IsSignDocsChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnPrint, m_xSecOptDlg->IsPrintDocsChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnCreatePdf, m_xSecOptDlg->IsCreatePdfChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo, m_xSecOptDlg->IsRemovePersInfoChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnRecommendPassword, m_xSecOptDlg->IsRecommPasswdChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::CtrlClickHyperlink, m_xSecOptDlg->IsCtrlHyperlinkChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, m_xSecOptDlg->IsBlockUntrustedRefererLinksChecked(), bModified );
+ }
+
+ return bModified;
+}
+
+/*--------------------------------------------------------------------*/
+
+void SvxSecurityTabPage::Reset( const SfxItemSet* )
+{
+}
+
+struct SvxEMailTabPage_Impl
+{
+ SvxEMailTabPage_Impl():
+ sProgram(officecfg::Office::Common::ExternalMailer::Program::get()),
+ bROProgram(
+ officecfg::Office::Common::ExternalMailer::Program::isReadOnly()),
+ bHideContent(
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::get()),
+ bROHideContent(
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::isReadOnly())
+ {}
+
+ OUString sProgram;
+ bool bROProgram;
+ bool bHideContent;
+ bool bROHideContent;
+};
+
+SvxEMailTabPage::SvxEMailTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optemailpage.ui", "OptEmailPage", &rSet)
+ , pImpl(new SvxEMailTabPage_Impl)
+ , m_xMailContainer(m_xBuilder->weld_container("program"))
+ , m_xMailerURLFI(m_xBuilder->weld_image("lockemail"))
+ , m_xMailerURLED(m_xBuilder->weld_entry("url"))
+ , m_xMailerURLPB(m_xBuilder->weld_button("browse"))
+ , m_xSuppressHiddenContainer(m_xBuilder->weld_container("suppressHiddenCont"))
+ , m_xSuppressHiddenFI(m_xBuilder->weld_image("lockSuppressHidden"))
+ , m_xSuppressHidden(m_xBuilder->weld_check_button("suppressHidden"))
+ , m_xDefaultFilterFT(m_xBuilder->weld_label("browsetitle"))
+{
+ m_sDefaultFilterName = m_xDefaultFilterFT->get_label();
+ m_xMailerURLPB->connect_clicked( LINK( this, SvxEMailTabPage, FileDialogHdl_Impl ) );
+}
+
+/* -------------------------------------------------------------------------*/
+
+SvxEMailTabPage::~SvxEMailTabPage()
+{
+}
+
+/* -------------------------------------------------------------------------*/
+
+std::unique_ptr<SfxTabPage> SvxEMailTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxEMailTabPage>(pPage, pController, *rAttrSet);
+}
+
+/* -------------------------------------------------------------------------*/
+
+bool SvxEMailTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ if (!pImpl->bROProgram && m_xMailerURLED->get_value_changed_from_saved())
+ {
+ pImpl->sProgram = m_xMailerURLED->get_text();
+ officecfg::Office::Common::ExternalMailer::Program::set(
+ pImpl->sProgram, batch);
+ }
+ if (!pImpl->bROHideContent
+ && pImpl->bHideContent != m_xSuppressHidden->get_active())
+ {
+ pImpl->bHideContent = m_xSuppressHidden->get_active();
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::set(
+ pImpl->bHideContent, batch);
+ }
+ batch->commit();
+ return false;
+}
+
+/* -------------------------------------------------------------------------*/
+
+void SvxEMailTabPage::Reset( const SfxItemSet* )
+{
+ m_xMailerURLED->set_sensitive(true);
+ m_xMailerURLPB->set_sensitive(true);
+
+ if (pImpl->bROProgram)
+ m_xMailerURLFI->show();
+
+ m_xMailerURLED->set_text(pImpl->sProgram);
+ m_xMailerURLED->save_value();
+
+ m_xMailContainer->set_sensitive(!pImpl->bROProgram);
+
+ if (pImpl->bROHideContent)
+ m_xSuppressHiddenFI->show();
+
+ m_xSuppressHidden->set_active(pImpl->bHideContent);
+
+ m_xSuppressHiddenContainer->set_sensitive(!pImpl->bROHideContent);
+}
+
+/* -------------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxEMailTabPage, FileDialogHdl_Impl, weld::Button&, void)
+{
+ if (pImpl->bROProgram)
+ return;
+
+ FileDialogHelper aHelper(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString sPath = m_xMailerURLED->get_text();
+ if ( sPath.isEmpty() )
+ sPath = "/usr/bin";
+
+ OUString sUrl;
+ osl::FileBase::getFileURLFromSystemPath(sPath, sUrl);
+ aHelper.SetDisplayDirectory(sUrl);
+ aHelper.AddFilter( m_sDefaultFilterName, "*");
+
+ if ( ERRCODE_NONE == aHelper.Execute() )
+ {
+ sUrl = aHelper.GetPath();
+ if (osl::FileBase::getSystemPathFromFileURL(sUrl, sPath)
+ != osl::FileBase::E_None)
+ {
+ sPath.clear();
+ }
+ m_xMailerURLED->set_text(sPath);
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optinet2.hxx b/cui/source/options/optinet2.hxx
new file mode 100644
index 000000000..4d03d2d04
--- /dev/null
+++ b/cui/source/options/optinet2.hxx
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+namespace svx {
+ class SecurityOptionsDialog;
+}
+
+// class SvxProxyTabPage -------------------------------------------------
+class SvxProxyTabPage : public SfxTabPage
+{
+private:
+
+ std::unique_ptr<weld::ComboBox> m_xProxyModeLB;
+
+ std::unique_ptr<weld::Label> m_xHttpProxyFT;
+ std::unique_ptr<weld::Entry> m_xHttpProxyED;
+ std::unique_ptr<weld::Label> m_xHttpPortFT;
+ std::unique_ptr<weld::Entry> m_xHttpPortED;
+
+ std::unique_ptr<weld::Label> m_xHttpsProxyFT;
+ std::unique_ptr<weld::Entry> m_xHttpsProxyED;
+ std::unique_ptr<weld::Label> m_xHttpsPortFT;
+ std::unique_ptr<weld::Entry> m_xHttpsPortED;
+
+ std::unique_ptr<weld::Label> m_xFtpProxyFT;
+ std::unique_ptr<weld::Entry> m_xFtpProxyED;
+ std::unique_ptr<weld::Label> m_xFtpPortFT;
+ std::unique_ptr<weld::Entry> m_xFtpPortED;
+
+ std::unique_ptr<weld::Label> m_xNoProxyForFT;
+ std::unique_ptr<weld::Entry> m_xNoProxyForED;
+ std::unique_ptr<weld::Label> m_xNoProxyDescFT;
+
+ css::uno::Reference< css::uno::XInterface > m_xConfigurationUpdateAccess;
+
+ void EnableControls_Impl();
+ void ReadConfigData_Impl();
+ void ReadConfigDefaults_Impl();
+ void RestoreConfigDefaults_Impl();
+
+ DECL_LINK(PortChangedHdl, weld::Entry&, void);
+ DECL_STATIC_LINK(SvxProxyTabPage, NumberOnlyTextFilterHdl, OUString&, bool);
+ DECL_STATIC_LINK(SvxProxyTabPage, NoSpaceTextFilterHdl, OUString&, bool);
+ DECL_LINK(ProxyHdl_Impl, weld::ComboBox&, void);
+ DECL_STATIC_LINK(SvxProxyTabPage, LoseFocusHdl_Impl, weld::Widget&, void);
+
+public:
+ SvxProxyTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxProxyTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+// class SvxSecurityTabPage ---------------------------------------------
+
+class CertPathDialog;
+class SvxSecurityTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<svx::SecurityOptionsDialog> m_xSecOptDlg;
+
+ std::unique_ptr<CertPathDialog> mpCertPathDlg;
+
+ OUString m_sPasswordStoringDeactivateStr;
+
+ std::unique_ptr<weld::Button> m_xSecurityOptionsPB;
+
+ std::unique_ptr<weld::CheckButton> m_xSavePasswordsCB;
+ std::unique_ptr<weld::Button> m_xShowConnectionsPB;
+
+ std::unique_ptr<weld::CheckButton> m_xMasterPasswordCB;
+ std::unique_ptr<weld::Label> m_xMasterPasswordFT;
+ std::unique_ptr<weld::Button> m_xMasterPasswordPB;
+
+ std::unique_ptr<weld::Container> m_xMacroSecFrame;
+ std::unique_ptr<weld::Button> m_xMacroSecPB;
+
+ std::unique_ptr<weld::Container> m_xCertFrame;
+ std::unique_ptr<weld::Button> m_xCertPathPB;
+
+ std::unique_ptr<weld::Container> m_xTSAURLsFrame;
+ std::unique_ptr<weld::Button> m_xTSAURLsPB;
+
+ std::unique_ptr<weld::Label> m_xNoPasswordSaveFT;
+
+ DECL_LINK(SecurityOptionsHdl, weld::Button&, void);
+ DECL_LINK(SavePasswordHdl, weld::Toggleable&, void);
+ DECL_LINK(MasterPasswordHdl, weld::Button&, void);
+ DECL_LINK(MasterPasswordCBHdl, weld::Toggleable&, void);
+ DECL_LINK(ShowPasswordsHdl, weld::Button&, void);
+ DECL_LINK(MacroSecPBHdl, weld::Button&, void );
+ DECL_LINK(CertPathPBHdl, weld::Button&, void );
+ DECL_LINK(TSAURLsPBHdl, weld::Button&, void );
+
+ void InitControls();
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxSecurityTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual ~SvxSecurityTabPage() override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+struct SvxEMailTabPage_Impl;
+class SvxEMailTabPage : public SfxTabPage
+{
+ OUString m_sDefaultFilterName;
+
+ std::unique_ptr<SvxEMailTabPage_Impl> pImpl;
+
+ std::unique_ptr<weld::Container> m_xMailContainer;
+ std::unique_ptr<weld::Image> m_xMailerURLFI;
+ std::unique_ptr<weld::Entry> m_xMailerURLED;
+ std::unique_ptr<weld::Button> m_xMailerURLPB;
+ std::unique_ptr<weld::Container> m_xSuppressHiddenContainer;
+ std::unique_ptr<weld::Image> m_xSuppressHiddenFI;
+ std::unique_ptr<weld::CheckButton> m_xSuppressHidden;
+ std::unique_ptr<weld::Label> m_xDefaultFilterFT;
+
+ DECL_LINK(FileDialogHdl_Impl, weld::Button&, void);
+
+public:
+ SvxEMailTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~SvxEMailTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx
new file mode 100644
index 000000000..693029822
--- /dev/null
+++ b/cui/source/options/optjava.cxx
@@ -0,0 +1,960 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <cassert>
+#include <memory>
+
+#include <config_java.h>
+
+#include "optaboutconfig.hxx"
+#include "optjava.hxx"
+#include <treeopt.hxx>
+#include <dialmgr.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+
+#include <strings.hrc>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/imagemgr.hxx>
+#include <svtools/restartdialog.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/inputdlg.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#if HAVE_FEATURE_JAVA
+#include <jvmfwk/framework.hxx>
+#endif
+
+// define ----------------------------------------------------------------
+
+#define CLASSPATH_DELIMITER SAL_PATHSEPARATOR
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+// class SvxJavaOptionsPage ----------------------------------------------
+SvxJavaOptionsPage::SvxJavaOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optadvancedpage.ui", "OptAdvancedPage", &rSet)
+ , m_aResetIdle("cui options SvxJavaOptionsPage Reset")
+ , xDialogListener(new ::svt::DialogClosedListener())
+ , m_xJavaEnableCB(m_xBuilder->weld_check_button("javaenabled"))
+ , m_xJavaList(m_xBuilder->weld_tree_view("javas"))
+ , m_xJavaPathText(m_xBuilder->weld_label("javapath"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xParameterBtn(m_xBuilder->weld_button("parameters"))
+ , m_xClassPathBtn(m_xBuilder->weld_button("classpath"))
+ , m_xExpertConfigBtn(m_xBuilder->weld_button("expertconfig"))
+ , m_xExperimentalCB(m_xBuilder->weld_check_button("experimental"))
+ , m_xMacroCB(m_xBuilder->weld_check_button("macrorecording"))
+ , m_xAddDialogText(m_xBuilder->weld_label("selectruntime"))
+ , m_xJavaFrame(m_xBuilder->weld_widget("javaframe"))
+{
+ m_sInstallText = m_xJavaPathText->get_label();
+ m_sAddDialogText = m_xAddDialogText->get_label();
+
+ m_xJavaList->set_size_request(m_xJavaList->get_approximate_digit_width() * 30,
+ m_xJavaList->get_height_rows(8));
+
+ m_xJavaList->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ m_xJavaList->connect_toggled( LINK( this, SvxJavaOptionsPage, CheckHdl_Impl ) );
+ m_xJavaList->connect_changed( LINK( this, SvxJavaOptionsPage, SelectHdl_Impl ) );
+
+ std::vector<int> aWidths
+ {
+ m_xJavaList->get_checkbox_column_width(),
+ o3tl::narrowing<int>(m_xJavaList->get_pixel_size("Sun Microsystems Inc.").Width())
+ };
+ m_xJavaList->set_column_fixed_widths(aWidths);
+
+ m_xJavaEnableCB->connect_toggled( LINK( this, SvxJavaOptionsPage, EnableHdl_Impl ) );
+ m_xAddBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, AddHdl_Impl ) );
+ m_xParameterBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ParameterHdl_Impl ) );
+ m_xClassPathBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ClassPathHdl_Impl ) );
+ m_aResetIdle.SetInvokeHandler( LINK( this, SvxJavaOptionsPage, ResetHdl_Impl ) );
+
+ m_xExpertConfigBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ExpertConfigHdl_Impl) );
+ if (!officecfg::Office::Common::Security::EnableExpertConfiguration::get())
+ m_xExpertConfigBtn->set_sensitive(false);
+
+ if (officecfg::Office::Common::Misc::MacroRecorderMode::isReadOnly())
+ m_xMacroCB->set_sensitive(false);
+
+ if (officecfg::Office::Common::Misc::ExperimentalMode::isReadOnly())
+ m_xExperimentalCB->set_sensitive(false);
+
+ xDialogListener->SetDialogClosedLink( LINK( this, SvxJavaOptionsPage, DialogClosedHdl ) );
+
+ EnableHdl_Impl(*m_xJavaEnableCB);
+#if HAVE_FEATURE_JAVA
+ jfw_lock();
+#else
+ m_xJavaFrame->set_sensitive(false);
+#endif
+}
+
+SvxJavaOptionsPage::~SvxJavaOptionsPage()
+{
+ ClearJavaInfo();
+#if HAVE_FEATURE_JAVA
+ m_aAddedInfos.clear();
+
+ jfw_unlock();
+#endif
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, EnableHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xJavaFrame->get_sensitive() && m_xJavaEnableCB->get_active();
+ m_xJavaList->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxJavaOptionsPage, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ HandleCheckEntry(m_xJavaList->get_iter_index_in_parent(rRowCol.first));
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, SelectHdl_Impl, weld::TreeView&, void)
+{
+ UpdateJavaPathText();
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, AddHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ OUString sWorkFolder = SvtPathOptions().GetWorkPath();
+ xFolderPicker->setDisplayDirectory( sWorkFolder );
+ xFolderPicker->setDescription( m_sAddDialogText );
+
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else if ( xFolderPicker.is() && xFolderPicker->execute() == ExecutableDialogResults::OK )
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxJavaOptionsPage::AddHdl_Impl()");
+ }
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ParameterHdl_Impl, weld::Button&, void)
+{
+#if HAVE_FEATURE_JAVA
+ std::vector< OUString > aParameterList;
+ if (!m_xParamDlg)
+ {
+ m_xParamDlg.reset(new SvxJavaParameterDlg(GetFrameWeld()));
+ javaFrameworkError eErr = jfw_getVMParameters( &m_parParameters );
+ if ( JFW_E_NONE == eErr && !m_parParameters.empty() )
+ {
+ aParameterList = m_parParameters;
+ m_xParamDlg->SetParameters( aParameterList );
+ }
+ }
+ else
+ {
+ aParameterList = m_xParamDlg->GetParameters();
+ m_xParamDlg->DisableButtons(); //disable add, edit and remove button when dialog is reopened
+ }
+
+ if (m_xParamDlg->run() == RET_OK)
+ {
+ if ( aParameterList != m_xParamDlg->GetParameters() )
+ {
+ aParameterList = m_xParamDlg->GetParameters();
+ if ( jfw_isVMRunning() )
+ {
+ RequestRestart( svtools::RESTART_REASON_ASSIGNING_JAVAPARAMETERS );
+ }
+ }
+ }
+ else
+ m_xParamDlg->SetParameters( aParameterList );
+#else
+ (void) this; // Silence loplugin:staticmethods
+#endif
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ClassPathHdl_Impl, weld::Button&, void)
+{
+#if HAVE_FEATURE_JAVA
+ OUString sClassPath;
+
+ if ( !m_xPathDlg )
+ {
+ m_xPathDlg.reset(new SvxJavaClassPathDlg(GetFrameWeld()));
+ javaFrameworkError eErr = jfw_getUserClassPath( &m_pClassPath );
+ if ( JFW_E_NONE == eErr )
+ {
+ sClassPath = m_pClassPath;
+ m_xPathDlg->SetClassPath( sClassPath );
+ }
+ }
+ else
+ sClassPath = m_xPathDlg->GetClassPath();
+
+ m_xPathDlg->SetFocus();
+ if (m_xPathDlg->run() == RET_OK)
+ {
+
+ if (m_xPathDlg->GetClassPath() != sClassPath)
+ {
+ sClassPath = m_xPathDlg->GetClassPath();
+ if ( jfw_isVMRunning() )
+ {
+ RequestRestart( svtools::RESTART_REASON_ASSIGNING_FOLDERS );
+ }
+ }
+ }
+ else
+ m_xPathDlg->SetClassPath( sClassPath );
+#else
+ (void) this;
+#endif
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ResetHdl_Impl, Timer *, void)
+{
+ LoadJREs();
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, StartFolderPickerHdl, void*, void)
+{
+ try
+ {
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else if ( xFolderPicker.is() && xFolderPicker->execute() == ExecutableDialogResults::OK )
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxJavaOptionsPage::StartFolderPickerHdl()" );
+ }
+}
+
+IMPL_LINK( SvxJavaOptionsPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
+{
+ if ( RET_OK == pEvt->DialogResult )
+ {
+ DBG_ASSERT( xFolderPicker.is(), "SvxJavaOptionsPage::DialogClosedHdl(): no folder picker" );
+
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ExpertConfigHdl_Impl, weld::Button&, void)
+{
+ CuiAboutConfigTabPage aExpertConfigDlg(GetFrameWeld());
+ {
+ weld::WaitObject aWait(GetFrameWeld());
+ aExpertConfigDlg.Reset();//initialize and reset function
+ }
+
+ if (RET_OK == aExpertConfigDlg.run())
+ {
+ aExpertConfigDlg.FillItemSet();//save changes if there are any
+ }
+}
+
+void SvxJavaOptionsPage::ClearJavaInfo()
+{
+#if HAVE_FEATURE_JAVA
+ m_parJavaInfo.clear();
+#else
+ (void) this;
+#endif
+}
+
+void SvxJavaOptionsPage::LoadJREs()
+{
+#if HAVE_FEATURE_JAVA
+ weld::WaitObject aWaitObj(GetFrameWeld());
+ javaFrameworkError eErr = jfw_findAllJREs( &m_parJavaInfo );
+ if ( JFW_E_NONE == eErr )
+ {
+ for (auto const & pInfo: m_parJavaInfo)
+ {
+ AddJRE( pInfo.get() );
+ }
+ }
+
+ for (auto const & pInfo: m_aAddedInfos)
+ {
+ AddJRE( pInfo.get() );
+ }
+
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ if ( !(JFW_E_NONE == eErr && pSelectedJava) )
+ return;
+
+ sal_Int32 i = 0;
+ for (auto const & pCmpInfo: m_parJavaInfo)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pSelectedJava.get() ) )
+ {
+ HandleCheckEntry(i);
+ UpdateJavaPathText();
+ break;
+ }
+ ++i;
+ }
+#else
+ (void) this;
+#endif
+}
+
+
+void SvxJavaOptionsPage::AddJRE( JavaInfo const * _pInfo )
+{
+#if HAVE_FEATURE_JAVA
+ int nPos = m_xJavaList->n_children();
+ m_xJavaList->append();
+ m_xJavaList->set_toggle(nPos, TRISTATE_FALSE);
+ m_xJavaList->set_text(nPos, _pInfo->sVendor, 1);
+ m_xJavaList->set_text(nPos, _pInfo->sVersion, 2);
+
+ INetURLObject aLocObj(_pInfo->sLocation);
+ OUString sLocation = aLocObj.getFSysPath(FSysStyle::Detect);
+ m_xJavaList->set_id(nPos, sLocation);
+#else
+ (void) this;
+ (void)_pInfo;
+#endif
+}
+
+void SvxJavaOptionsPage::HandleCheckEntry(int nCheckedRow)
+{
+ m_xJavaList->select(nCheckedRow);
+ for (int i = 0, nCount = m_xJavaList->n_children(); i < nCount; ++i)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ m_xJavaList->set_toggle(i, i == nCheckedRow ? TRISTATE_TRUE : TRISTATE_FALSE);
+ }
+}
+
+void SvxJavaOptionsPage::UpdateJavaPathText()
+{
+ assert(m_xJavaList->get_selected_index() != -1);
+ // set installation directory info
+ OUString sLocation = m_xJavaList->get_selected_id();
+ // tdf#80646 insert LTR mark after label
+ OUString sInfo = m_sInstallText + u"\u200E" + sLocation;
+ m_xJavaPathText->set_label(sInfo);
+}
+
+void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder )
+{
+#if HAVE_FEATURE_JAVA
+ bool bStartAgain = true;
+ std::unique_ptr<JavaInfo> pInfo;
+ javaFrameworkError eErr = jfw_getJavaInfoByPath( _rFolder, &pInfo );
+ if ( JFW_E_NONE == eErr && pInfo )
+ {
+ sal_Int32 nPos = 0;
+ bool bFound = false;
+ for (auto const & pCmpInfo: m_parJavaInfo)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
+ {
+ bFound = true;
+ break;
+ }
+ ++nPos;
+ }
+
+ if ( !bFound )
+ {
+ for (auto const & pCmpInfo: m_aAddedInfos)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
+ {
+ bFound = true;
+ break;
+ }
+ ++nPos;
+ }
+ }
+
+ if ( !bFound )
+ {
+ jfw_addJRELocation( pInfo->sLocation );
+ AddJRE( pInfo.get() );
+ m_aAddedInfos.push_back( std::move(pInfo) );
+ nPos = m_xJavaList->n_children() - 1;
+ }
+
+ HandleCheckEntry(nPos);
+ UpdateJavaPathText();
+ bStartAgain = false;
+ }
+ else if ( JFW_E_NOT_RECOGNIZED == eErr )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_JRE_NOT_RECOGNIZED)));
+ xBox->run();
+ }
+ else if ( JFW_E_FAILED_VERSION == eErr )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_JRE_FAILED_VERSION)));
+ xBox->run();
+ }
+
+ if ( bStartAgain )
+ {
+ xFolderPicker->setDisplayDirectory( _rFolder );
+ Application::PostUserEvent( LINK( this, SvxJavaOptionsPage, StartFolderPickerHdl ) );
+ }
+#else
+ (void) this;
+ (void)_rFolder;
+#endif
+}
+
+void SvxJavaOptionsPage::RequestRestart(svtools::RestartReason eReason)
+{
+ OfaTreeOptionsDialog* pParentDlg(static_cast<OfaTreeOptionsDialog*>(GetDialogController()));
+ if (pParentDlg)
+ pParentDlg->SetNeedsRestart(eReason);
+}
+
+std::unique_ptr<SfxTabPage> SvxJavaOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxJavaOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxJavaOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
+{
+ bool bModified = false;
+
+ if ( m_xExperimentalCB->get_state_changed_from_saved() )
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set( m_xExperimentalCB->get_active(), xChanges );
+ xChanges->commit();
+ bModified = true;
+ RequestRestart( svtools::RESTART_REASON_EXP_FEATURES );
+ }
+
+ if ( m_xMacroCB->get_state_changed_from_saved() )
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::MacroRecorderMode::set( m_xMacroCB->get_active(), xChanges );
+ xChanges->commit();
+ bModified = true;
+ }
+
+#if HAVE_FEATURE_JAVA
+ javaFrameworkError eErr = JFW_E_NONE;
+ if (m_xParamDlg)
+ {
+ eErr = jfw_setVMParameters(m_xParamDlg->GetParameters());
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setVMParameters");
+ bModified = true;
+ }
+
+ if (m_xPathDlg)
+ {
+ OUString sPath(m_xPathDlg->GetClassPath());
+ if (m_xPathDlg->GetOldPath() != sPath)
+ {
+ eErr = jfw_setUserClassPath( sPath );
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setUserClassPath");
+ bModified = true;
+ }
+ }
+
+ sal_uInt32 nCount = m_xJavaList->n_children();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ if (m_xJavaList->get_toggle(i) == TRISTATE_TRUE)
+ {
+ JavaInfo const * pInfo;
+ if ( i < m_parJavaInfo.size() )
+ pInfo = m_parJavaInfo[i].get();
+ else
+ pInfo = m_aAddedInfos[ i - m_parJavaInfo.size() ].get();
+
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ if ( JFW_E_NONE == eErr || JFW_E_INVALID_SETTINGS == eErr )
+ {
+ if (!pSelectedJava || !jfw_areEqualJavaInfo( pInfo, pSelectedJava.get() ) )
+ {
+ if ( jfw_isVMRunning() ||
+ ( ( pInfo->nRequirements & JFW_REQUIRE_NEEDRESTART ) == JFW_REQUIRE_NEEDRESTART ) )
+ {
+ RequestRestart( svtools::RESTART_REASON_JAVA );
+ }
+
+ eErr = jfw_setSelectedJRE( pInfo );
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setSelectedJRE");
+ bModified = true;
+ }
+ }
+ break;
+ }
+ }
+
+ bool bEnabled = false;
+ eErr = jfw_getEnabled( &bEnabled );
+ DBG_ASSERT( JFW_E_NONE == eErr,
+ "SvxJavaOptionsPage::FillItemSet(): error in jfw_getEnabled" );
+ if ( bEnabled != m_xJavaEnableCB->get_active() )
+ {
+ eErr = jfw_setEnabled( m_xJavaEnableCB->get_active() );
+ DBG_ASSERT( JFW_E_NONE == eErr,
+ "SvxJavaOptionsPage::FillItemSet(): error in jfw_setEnabled" );
+ bModified = true;
+ }
+#endif
+
+ return bModified;
+}
+
+
+void SvxJavaOptionsPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ ClearJavaInfo();
+ m_xJavaList->clear();
+
+#if HAVE_FEATURE_JAVA
+ bool bEnabled = false;
+ javaFrameworkError eErr = jfw_getEnabled( &bEnabled );
+ if (eErr == JFW_E_DIRECT_MODE)
+ {
+ // direct mode disregards Java settings made here, so gray them out
+ m_xJavaFrame->set_sensitive(false);
+ // check whether a usable JRE was set
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ bEnabled = (eErr == JFW_E_NONE);
+ }
+ else if ( eErr != JFW_E_NONE )
+ bEnabled = false;
+ m_xJavaEnableCB->set_active(bEnabled);
+ EnableHdl_Impl(*m_xJavaEnableCB);
+#else
+ m_xJavaEnableCB->set_active(false);
+ m_xJavaEnableCB->set_sensitive(false);
+#endif
+
+ m_xExperimentalCB->set_active( officecfg::Office::Common::Misc::ExperimentalMode::get() );
+ m_xExperimentalCB->save_state();
+ m_xMacroCB->set_active( officecfg::Office::Common::Misc::MacroRecorderMode::get() );
+ m_xMacroCB->save_state();
+
+ m_aResetIdle.Start();
+}
+
+
+void SvxJavaOptionsPage::FillUserData()
+{
+ SetUserData( OUString() );
+}
+
+// class SvxJavaParameterDlg ---------------------------------------------
+
+SvxJavaParameterDlg::SvxJavaParameterDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/javastartparametersdialog.ui",
+ "JavaStartParameters")
+ , m_xParameterEdit(m_xBuilder->weld_entry("parameterfield"))
+ , m_xAssignBtn(m_xBuilder->weld_button("assignbtn"))
+ , m_xAssignedList(m_xBuilder->weld_tree_view("assignlist"))
+ , m_xRemoveBtn(m_xBuilder->weld_button("removebtn"))
+ , m_xEditBtn(m_xBuilder->weld_button("editbtn"))
+{
+ m_xAssignedList->set_size_request(m_xAssignedList->get_approximate_digit_width() * 54,
+ m_xAssignedList->get_height_rows(6));
+ m_xParameterEdit->connect_changed( LINK( this, SvxJavaParameterDlg, ModifyHdl_Impl ) );
+ m_xParameterEdit->connect_activate(LINK(this, SvxJavaParameterDlg, ActivateHdl_Impl));
+ m_xAssignBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, AssignHdl_Impl ) );
+ m_xRemoveBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, RemoveHdl_Impl ) );
+ m_xEditBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, EditHdl_Impl ) );
+ m_xAssignedList->connect_changed( LINK( this, SvxJavaParameterDlg, SelectHdl_Impl ) );
+ m_xAssignedList->connect_row_activated( LINK( this, SvxJavaParameterDlg, DblClickHdl_Impl ) );
+
+ ModifyHdl_Impl(*m_xParameterEdit);
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+SvxJavaParameterDlg::~SvxJavaParameterDlg()
+{
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, ModifyHdl_Impl, weld::Entry&, void)
+{
+ OUString sParam = comphelper::string::strip(m_xParameterEdit->get_text(), ' ');
+ m_xAssignBtn->set_sensitive(!sParam.isEmpty());
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, AssignHdl_Impl, weld::Button&, void)
+{
+ OUString sParam = comphelper::string::strip(m_xParameterEdit->get_text(), ' ');
+ if (sParam.isEmpty())
+ return;
+
+ int nPos = m_xAssignedList->find_text(sParam);
+ if (nPos == -1)
+ {
+ m_xAssignedList->append_text(sParam);
+ m_xAssignedList->select(m_xAssignedList->n_children() - 1);
+ }
+ else
+ m_xAssignedList->select(nPos);
+ m_xParameterEdit->set_text(OUString());
+ ModifyHdl_Impl(*m_xParameterEdit);
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, ActivateHdl_Impl, weld::Entry&, bool)
+{
+ if (m_xAssignBtn->get_sensitive())
+ {
+ AssignHdl_Impl(*m_xAssignBtn);
+ return true;
+ }
+ return false;
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, EditHdl_Impl, weld::Button&, void)
+{
+ EditParameter();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, SelectHdl_Impl, weld::TreeView&, void)
+{
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, DblClickHdl_Impl, weld::TreeView&, bool)
+{
+ EditParameter();
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xAssignedList->get_selected_index();
+ if (nPos != -1)
+ {
+ m_xAssignedList->remove(nPos);
+ int nCount = m_xAssignedList->n_children();
+ if (nCount)
+ {
+ if (nPos >= nCount)
+ nPos = nCount - 1;
+ m_xAssignedList->select(nPos);
+ }
+ else
+ {
+ DisableEditButton();
+ }
+ }
+ EnableRemoveButton();
+}
+
+void SvxJavaParameterDlg::EditParameter()
+{
+ int nPos = m_xAssignedList->get_selected_index();
+ m_xParameterEdit->set_text(OUString());
+
+ if (nPos == -1)
+ return;
+
+ InputDialog aParamEditDlg(m_xDialog.get(), CuiResId(RID_CUISTR_JAVA_START_PARAM));
+ OUString editableClassPath = m_xAssignedList->get_selected_text();
+ aParamEditDlg.SetEntryText(editableClassPath);
+ aParamEditDlg.HideHelpBtn();
+
+ if (!aParamEditDlg.run())
+ return;
+ OUString editedClassPath = comphelper::string::strip(aParamEditDlg.GetEntryText(), ' ');
+
+ if ( !editedClassPath.isEmpty() && editableClassPath != editedClassPath )
+ {
+ m_xAssignedList->remove(nPos);
+ m_xAssignedList->insert_text(nPos, editedClassPath);
+ m_xAssignedList->select(nPos);
+ }
+}
+
+short SvxJavaParameterDlg::run()
+{
+ m_xParameterEdit->grab_focus();
+ m_xAssignedList->select(-1);
+ return GenericDialogController::run();
+}
+
+std::vector< OUString > SvxJavaParameterDlg::GetParameters() const
+{
+ int nCount = m_xAssignedList->n_children();
+ std::vector< OUString > aParamList;
+ aParamList.reserve(nCount);
+ for (int i = 0; i < nCount; ++i)
+ aParamList.push_back(m_xAssignedList->get_text(i));
+ return aParamList;
+}
+
+void SvxJavaParameterDlg::DisableButtons()
+{
+ DisableAssignButton();
+ DisableEditButton();
+ DisableRemoveButton();
+}
+
+void SvxJavaParameterDlg::SetParameters( std::vector< OUString > const & rParams )
+{
+ m_xAssignedList->clear();
+ for (auto const & sParam: rParams)
+ {
+ m_xAssignedList->append_text(sParam);
+ }
+ DisableEditButton();
+ DisableRemoveButton();
+}
+
+
+// class SvxJavaClassPathDlg ---------------------------------------------
+
+SvxJavaClassPathDlg::SvxJavaClassPathDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/javaclasspathdialog.ui", "JavaClassPath")
+ , m_xPathList(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddArchiveBtn(m_xBuilder->weld_button("archive"))
+ , m_xAddPathBtn(m_xBuilder->weld_button("folder"))
+ , m_xRemoveBtn(m_xBuilder->weld_button("remove"))
+{
+ m_xPathList->set_size_request(m_xPathList->get_approximate_digit_width() * 54,
+ m_xPathList->get_height_rows(8));
+ m_xAddArchiveBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, AddArchiveHdl_Impl ) );
+ m_xAddPathBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, AddPathHdl_Impl ) );
+ m_xRemoveBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, RemoveHdl_Impl ) );
+ m_xPathList->connect_changed( LINK( this, SvxJavaClassPathDlg, SelectHdl_Impl ) );
+
+ // set initial focus to path list
+ m_xPathList->grab_focus();
+}
+
+SvxJavaClassPathDlg::~SvxJavaClassPathDlg()
+{
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, AddArchiveHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aDlg(TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_xDialog.get());
+ aDlg.SetTitle( CuiResId( RID_CUISTR_ARCHIVE_TITLE ) );
+ aDlg.AddFilter( CuiResId( RID_CUISTR_ARCHIVE_HEADLINE ), "*.jar;*.zip" );
+ aDlg.SetContext(sfx2::FileDialogHelper::JavaClassPath);
+ OUString sFolder;
+ if (m_xPathList->count_selected_rows() > 0)
+ {
+ osl::FileBase::getFileURLFromSystemPath(m_xPathList->get_selected_text(), sFolder);
+ // best effort
+ }
+ if (!sFolder.isEmpty())
+ aDlg.SetDisplayDirectory( sFolder );
+ if ( aDlg.Execute() == ERRCODE_NONE )
+ {
+ OUString sURL = aDlg.GetPath();
+ OUString sFile;
+ if (osl::FileBase::getSystemPathFromFileURL(sURL, sFile) == osl::FileBase::E_None)
+ {
+ INetURLObject aURL( sURL );
+ if ( !IsPathDuplicate( sFile ) )
+ {
+ m_xPathList->append("", sFile, SvFileInformationManager::GetImageId(aURL));
+ m_xPathList->select(m_xPathList->n_children() - 1);
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_MULTIFILE_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sFile );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_CANNOTCONVERTURL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sURL );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, AddPathHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_xDialog.get());
+
+ OUString sOldFolder;
+ if (m_xPathList->count_selected_rows() > 0)
+ {
+ osl::FileBase::getFileURLFromSystemPath(m_xPathList->get_selected_text(), sOldFolder);
+ // best effort
+ }
+ if (sOldFolder.isEmpty())
+ sOldFolder = SvtPathOptions().GetWorkPath();
+ xFolderPicker->setDisplayDirectory( sOldFolder );
+ if ( xFolderPicker->execute() == ExecutableDialogResults::OK )
+ {
+ OUString sFolderURL( xFolderPicker->getDirectory() );
+ INetURLObject aURL( sFolderURL );
+ OUString sNewFolder;
+ if (osl::FileBase::getSystemPathFromFileURL(sFolderURL, sNewFolder)
+ == osl::FileBase::E_None)
+ {
+ if ( !IsPathDuplicate( sNewFolder ) )
+ {
+ m_xPathList->append("", sNewFolder, SvFileInformationManager::GetImageId(aURL));
+ m_xPathList->select(m_xPathList->n_children() - 1);
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_MULTIFILE_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sNewFolder );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_CANNOTCONVERTURL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sFolderURL );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xPathList->get_selected_index();
+ if (nPos != -1)
+ {
+ m_xPathList->remove(nPos);
+ int nCount = m_xPathList->n_children();
+ if (nCount)
+ {
+ if (nPos >= nCount)
+ nPos = nCount - 1;
+ m_xPathList->select( nPos );
+ }
+ }
+
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, SelectHdl_Impl, weld::TreeView&, void)
+{
+ EnableRemoveButton();
+}
+
+bool SvxJavaClassPathDlg::IsPathDuplicate( std::u16string_view _rPath )
+{
+ bool bRet = false;
+ int nCount = m_xPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if ( m_xPathList->get_text(i) == _rPath )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+OUString SvxJavaClassPathDlg::GetClassPath() const
+{
+ OUStringBuffer sPath;
+ int nCount = m_xPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (!sPath.isEmpty())
+ sPath.append(CLASSPATH_DELIMITER);
+ sPath.append(m_xPathList->get_text(i));
+ }
+ return sPath.makeStringAndClear();
+}
+
+void SvxJavaClassPathDlg::SetClassPath( const OUString& _rPath )
+{
+ if ( m_sOldPath.isEmpty() )
+ m_sOldPath = _rPath;
+ m_xPathList->clear();
+ if (!_rPath.isEmpty())
+ {
+ sal_Int32 nIdx = 0;
+ do
+ {
+ OUString sToken = _rPath.getToken( 0, CLASSPATH_DELIMITER, nIdx );
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath(sToken, sURL); // best effort
+ INetURLObject aURL( sURL );
+ m_xPathList->append("", sToken, SvFileInformationManager::GetImageId(aURL));
+ }
+ while (nIdx>=0);
+ // select first entry
+ m_xPathList->select(0);
+ }
+ SelectHdl_Impl(*m_xPathList);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjava.hxx b/cui/source/options/optjava.hxx
new file mode 100644
index 000000000..097b7ffb5
--- /dev/null
+++ b/cui/source/options/optjava.hxx
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <config_java.h>
+
+#include <memory>
+#include <vector>
+#include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+#include <svtools/restartdialog.hxx>
+
+// forward ---------------------------------------------------------------
+
+#if HAVE_FEATURE_JAVA
+struct JavaInfo;
+#else
+typedef void* JavaInfo;
+#endif
+
+class SvxJavaParameterDlg;
+class SvxJavaClassPathDlg;
+class SvxJavaListBox;
+class OfaTreeOptionsDialog;
+
+// class SvxJavaOptionsPage ----------------------------------------------
+
+class SvxJavaOptionsPage : public SfxTabPage
+{
+private:
+#if HAVE_FEATURE_JAVA
+ std::vector<std::unique_ptr<JavaInfo>> m_parJavaInfo;
+ std::vector<OUString> m_parParameters;
+ OUString m_pClassPath;
+#endif
+ OUString m_sInstallText;
+ OUString m_sAddDialogText;
+ Idle m_aResetIdle;
+
+ std::vector<std::unique_ptr<JavaInfo>> m_aAddedInfos;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ std::unique_ptr<weld::CheckButton> m_xJavaEnableCB;
+ std::unique_ptr<weld::TreeView> m_xJavaList;
+ std::unique_ptr<weld::Label> m_xJavaPathText;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xParameterBtn;
+ std::unique_ptr<weld::Button> m_xClassPathBtn;
+ std::unique_ptr<weld::Button> m_xExpertConfigBtn;
+
+ std::unique_ptr<SvxJavaParameterDlg> m_xParamDlg;
+ std::unique_ptr<SvxJavaClassPathDlg> m_xPathDlg;
+
+ std::unique_ptr<weld::CheckButton> m_xExperimentalCB;
+ std::unique_ptr<weld::CheckButton> m_xMacroCB;
+
+ std::unique_ptr<weld::Label> m_xAddDialogText;
+
+ std::unique_ptr<weld::Widget> m_xJavaFrame;
+
+ DECL_LINK(EnableHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(CheckHdl_Impl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ParameterHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClassPathHdl_Impl, weld::Button&, void);
+ DECL_LINK(ResetHdl_Impl, Timer *, void);
+
+ DECL_LINK(StartFolderPickerHdl, void *, void);
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+ DECL_LINK(ExpertConfigHdl_Impl, weld::Button&, void);
+
+ void ClearJavaInfo();
+ void LoadJREs();
+ void AddJRE( JavaInfo const * _pInfo );
+ void HandleCheckEntry(int nCheckedRow);
+ void UpdateJavaPathText();
+ void AddFolder( const OUString& _rFolder );
+ void RequestRestart( svtools::RestartReason eReason );
+
+public:
+ SvxJavaOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxJavaOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+// class SvxJavaParameterDlg ---------------------------------------------
+
+class SvxJavaParameterDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xParameterEdit;
+ std::unique_ptr<weld::Button> m_xAssignBtn;
+ std::unique_ptr<weld::TreeView> m_xAssignedList;
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(ActivateHdl_Impl, weld::Entry&, bool);
+ DECL_LINK(AssignHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(DblClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(EditHdl_Impl, weld::Button&, void);
+
+ void EnableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(m_xAssignedList->get_selected_index() != -1);
+ }
+
+ void EnableEditButton()
+ {
+ m_xEditBtn->set_sensitive(m_xAssignedList->get_selected_index() != -1);
+ }
+
+ void DisableAssignButton()
+ {
+ m_xAssignBtn->set_sensitive(false);
+ }
+
+ void DisableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(false);
+ }
+
+ void DisableEditButton()
+ {
+ m_xEditBtn->set_sensitive(false);
+ }
+
+public:
+ explicit SvxJavaParameterDlg(weld::Window* pParent);
+ virtual ~SvxJavaParameterDlg() override;
+
+ virtual short run() override;
+
+ std::vector< OUString > GetParameters() const;
+ void SetParameters( std::vector< OUString > const & rParams );
+ void DisableButtons();
+ void EditParameter();
+};
+
+// class SvxJavaClassPathDlg ---------------------------------------------
+
+class SvxJavaClassPathDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xPathList;
+ std::unique_ptr<weld::Button> m_xAddArchiveBtn;
+ std::unique_ptr<weld::Button> m_xAddPathBtn;
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+
+ OUString m_sOldPath;
+
+ DECL_LINK(AddArchiveHdl_Impl, weld::Button&, void);
+ DECL_LINK(AddPathHdl_Impl, weld::Button&, void);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+
+ bool IsPathDuplicate(std::u16string_view _rPath);
+ void EnableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(m_xPathList->get_selected_index() != -1);
+ }
+
+public:
+ explicit SvxJavaClassPathDlg(weld::Window* pParent);
+ virtual ~SvxJavaClassPathDlg() override;
+
+ const OUString& GetOldPath() const { return m_sOldPath; }
+ void SetFocus() { m_xPathList->grab_focus(); }
+
+ OUString GetClassPath() const;
+ void SetClassPath( const OUString& _rPath );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjsearch.cxx b/cui/source/options/optjsearch.cxx
new file mode 100644
index 000000000..4a2c31c49
--- /dev/null
+++ b/cui/source/options/optjsearch.cxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <unotools/searchopt.hxx>
+#include <i18nutil/transliteration.hxx>
+#include "optjsearch.hxx"
+
+using namespace com::sun::star::i18n;
+
+
+SvxJSearchOptionsPage::SvxJSearchOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optjsearchpage.ui", "OptJSearchPage", &rSet)
+ , m_xMatchCase(m_xBuilder->weld_check_button("matchcase"))
+ , m_xMatchFullHalfWidth(m_xBuilder->weld_check_button("matchfullhalfwidth"))
+ , m_xMatchHiraganaKatakana(m_xBuilder->weld_check_button("matchhiraganakatakana"))
+ , m_xMatchContractions(m_xBuilder->weld_check_button("matchcontractions"))
+ , m_xMatchMinusDashChoon(m_xBuilder->weld_check_button("matchminusdashchoon"))
+ , m_xMatchRepeatCharMarks(m_xBuilder->weld_check_button("matchrepeatcharmarks"))
+ , m_xMatchVariantFormKanji(m_xBuilder->weld_check_button("matchvariantformkanji"))
+ , m_xMatchOldKanaForms(m_xBuilder->weld_check_button("matcholdkanaforms"))
+ , m_xMatchDiziDuzu(m_xBuilder->weld_check_button("matchdiziduzu"))
+ , m_xMatchBavaHafa(m_xBuilder->weld_check_button("matchbavahafa"))
+ , m_xMatchTsithichiDhizi(m_xBuilder->weld_check_button("matchtsithichidhizi"))
+ , m_xMatchHyuiyuByuvyu(m_xBuilder->weld_check_button("matchhyuiyubyuvyu"))
+ , m_xMatchSesheZeje(m_xBuilder->weld_check_button("matchseshezeje"))
+ , m_xMatchIaiya(m_xBuilder->weld_check_button("matchiaiya"))
+ , m_xMatchKiku(m_xBuilder->weld_check_button("matchkiku"))
+ , m_xMatchProlongedSoundMark(m_xBuilder->weld_check_button("matchprolongedsoundmark"))
+ , m_xIgnorePunctuation(m_xBuilder->weld_check_button("ignorepunctuation"))
+ , m_xIgnoreWhitespace(m_xBuilder->weld_check_button("ignorewhitespace"))
+ , m_xIgnoreMiddleDot(m_xBuilder->weld_check_button("ignoremiddledot"))
+ , nTransliterationFlags(TransliterationFlags::NONE)
+ , bSaveOptions(true)
+{
+}
+
+SvxJSearchOptionsPage::~SvxJSearchOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxJSearchOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxJSearchOptionsPage>(pPage, pController, *rSet);
+}
+
+void SvxJSearchOptionsPage::SetTransliterationFlags( TransliterationFlags nSettings )
+{
+ bool bVal(nSettings & TransliterationFlags::IGNORE_CASE);
+ m_xMatchCase ->set_active( bVal ); //! treat as equal uppercase/lowercase
+ bVal = bool(nSettings & TransliterationFlags::IGNORE_WIDTH);
+ m_xMatchFullHalfWidth ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::IGNORE_KANA);
+ m_xMatchHiraganaKatakana ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSize_ja_JP);
+ m_xMatchContractions ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreMinusSign_ja_JP);
+ m_xMatchMinusDashChoon ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreIterationMark_ja_JP);
+ m_xMatchRepeatCharMarks ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTraditionalKanji_ja_JP);
+ m_xMatchVariantFormKanji ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTraditionalKana_ja_JP);
+ m_xMatchOldKanaForms ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreZiZu_ja_JP);
+ m_xMatchDiziDuzu ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreBaFa_ja_JP);
+ m_xMatchBavaHafa ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTiJi_ja_JP);
+ m_xMatchTsithichiDhizi ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreHyuByu_ja_JP);
+ m_xMatchHyuiyuByuvyu ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSeZe_ja_JP);
+ m_xMatchSesheZeje ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreIandEfollowedByYa_ja_JP);
+ m_xMatchIaiya ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP);
+ m_xMatchKiku ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSeparator_ja_JP);
+ m_xIgnorePunctuation ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSpace_ja_JP);
+ m_xIgnoreWhitespace ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreProlongedSoundMark_ja_JP);
+ m_xMatchProlongedSoundMark->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreMiddleDot_ja_JP);
+ m_xIgnoreMiddleDot ->set_active( bVal );
+
+ nTransliterationFlags = nSettings;
+}
+
+TransliterationFlags SvxJSearchOptionsPage::GetTransliterationFlags_Impl()
+{
+ TransliterationFlags nTmp = TransliterationFlags::NONE;
+ if (m_xMatchCase->get_active()) //! treat as equal uppercase/lowercase
+ nTmp |= TransliterationFlags::IGNORE_CASE;
+ if (m_xMatchFullHalfWidth->get_active())
+ nTmp |= TransliterationFlags::IGNORE_WIDTH;
+ if (m_xMatchHiraganaKatakana->get_active())
+ nTmp |= TransliterationFlags::IGNORE_KANA;
+ if (m_xMatchContractions->get_active())
+ nTmp |= TransliterationFlags::ignoreSize_ja_JP;
+ if (m_xMatchMinusDashChoon->get_active())
+ nTmp |= TransliterationFlags::ignoreMinusSign_ja_JP;
+ if (m_xMatchRepeatCharMarks->get_active())
+ nTmp |= TransliterationFlags::ignoreIterationMark_ja_JP;
+ if (m_xMatchVariantFormKanji->get_active())
+ nTmp |= TransliterationFlags::ignoreTraditionalKanji_ja_JP;
+ if (m_xMatchOldKanaForms->get_active())
+ nTmp |= TransliterationFlags::ignoreTraditionalKana_ja_JP;
+ if (m_xMatchDiziDuzu->get_active())
+ nTmp |= TransliterationFlags::ignoreZiZu_ja_JP;
+ if (m_xMatchBavaHafa->get_active())
+ nTmp |= TransliterationFlags::ignoreBaFa_ja_JP;
+ if (m_xMatchTsithichiDhizi->get_active())
+ nTmp |= TransliterationFlags::ignoreTiJi_ja_JP;
+ if (m_xMatchHyuiyuByuvyu->get_active())
+ nTmp |= TransliterationFlags::ignoreHyuByu_ja_JP;
+ if (m_xMatchSesheZeje->get_active())
+ nTmp |= TransliterationFlags::ignoreSeZe_ja_JP;
+ if (m_xMatchIaiya->get_active())
+ nTmp |= TransliterationFlags::ignoreIandEfollowedByYa_ja_JP;
+ if (m_xMatchKiku->get_active())
+ nTmp |= TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP;
+ if (m_xIgnorePunctuation->get_active())
+ nTmp |= TransliterationFlags::ignoreSeparator_ja_JP;
+ if (m_xIgnoreWhitespace->get_active())
+ nTmp |= TransliterationFlags::ignoreSpace_ja_JP;
+ if (m_xMatchProlongedSoundMark->get_active())
+ nTmp |= TransliterationFlags::ignoreProlongedSoundMark_ja_JP;
+ if (m_xIgnoreMiddleDot->get_active())
+ nTmp |= TransliterationFlags::ignoreMiddleDot_ja_JP;
+
+ nTransliterationFlags = nTmp;
+ return nTransliterationFlags;
+}
+
+
+void SvxJSearchOptionsPage::Reset( const SfxItemSet* )
+{
+ SvtSearchOptions aOpt;
+
+ // read settings from configuration
+ m_xMatchCase ->set_active(!aOpt.IsMatchCase() ); //! treat as equal uppercase/lowercase
+ m_xMatchFullHalfWidth ->set_active( aOpt.IsMatchFullHalfWidthForms() );
+ m_xMatchHiraganaKatakana ->set_active( aOpt.IsMatchHiraganaKatakana() );
+ m_xMatchContractions ->set_active( aOpt.IsMatchContractions() );
+ m_xMatchMinusDashChoon ->set_active( aOpt.IsMatchMinusDashChoon() );
+ m_xMatchRepeatCharMarks ->set_active( aOpt.IsMatchRepeatCharMarks() );
+ m_xMatchVariantFormKanji ->set_active( aOpt.IsMatchVariantFormKanji() );
+ m_xMatchOldKanaForms ->set_active( aOpt.IsMatchOldKanaForms() );
+ m_xMatchDiziDuzu ->set_active( aOpt.IsMatchDiziDuzu() );
+ m_xMatchBavaHafa ->set_active( aOpt.IsMatchBavaHafa() );
+ m_xMatchTsithichiDhizi ->set_active( aOpt.IsMatchTsithichiDhizi() );
+ m_xMatchHyuiyuByuvyu ->set_active( aOpt.IsMatchHyuiyuByuvyu() );
+ m_xMatchSesheZeje ->set_active( aOpt.IsMatchSesheZeje() );
+ m_xMatchIaiya ->set_active( aOpt.IsMatchIaiya() );
+ m_xMatchKiku ->set_active( aOpt.IsMatchKiku() );
+ m_xIgnorePunctuation ->set_active( aOpt.IsIgnorePunctuation() );
+ m_xIgnoreWhitespace ->set_active( aOpt.IsIgnoreWhitespace() );
+ m_xMatchProlongedSoundMark ->set_active( aOpt.IsIgnoreProlongedSoundMark() );
+ m_xIgnoreMiddleDot ->set_active( aOpt.IsIgnoreMiddleDot() );
+
+ nTransliterationFlags = GetTransliterationFlags_Impl();
+ DBG_ASSERT( nTransliterationFlags == aOpt.GetTransliterationFlags(),
+ "Transliteration settings different" );
+
+ m_xMatchCase ->save_state();
+ m_xMatchFullHalfWidth ->save_state();
+ m_xMatchHiraganaKatakana ->save_state();
+ m_xMatchContractions ->save_state();
+ m_xMatchMinusDashChoon ->save_state();
+ m_xMatchRepeatCharMarks ->save_state();
+ m_xMatchVariantFormKanji ->save_state();
+ m_xMatchOldKanaForms ->save_state();
+ m_xMatchDiziDuzu ->save_state();
+ m_xMatchBavaHafa ->save_state();
+ m_xMatchTsithichiDhizi ->save_state();
+ m_xMatchHyuiyuByuvyu ->save_state();
+ m_xMatchSesheZeje ->save_state();
+ m_xMatchIaiya ->save_state();
+ m_xMatchKiku ->save_state();
+ m_xIgnorePunctuation ->save_state();
+ m_xIgnoreWhitespace ->save_state();
+ m_xMatchProlongedSoundMark ->save_state();
+ m_xIgnoreMiddleDot ->save_state();
+}
+
+
+bool SvxJSearchOptionsPage::FillItemSet( SfxItemSet* )
+{
+ TransliterationFlags nOldVal = nTransliterationFlags;
+ nTransliterationFlags = GetTransliterationFlags_Impl();
+ bool bModified = nOldVal != nTransliterationFlags;
+
+ if (!bSaveOptions)
+ return bModified;
+
+ bModified = false;
+ SvtSearchOptions aOpt;
+ bool bNewVal, bChanged;
+
+ bNewVal = m_xMatchCase->get_active(); //! treat as equal uppercase/lowercase
+ bChanged = m_xMatchCase->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchCase(!bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchFullHalfWidth->get_active();
+ bChanged = m_xMatchFullHalfWidth->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchFullHalfWidthForms( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchHiraganaKatakana->get_active();
+ bChanged = m_xMatchHiraganaKatakana->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchHiraganaKatakana( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchContractions->get_active();
+ bChanged = m_xMatchContractions->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchContractions( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchMinusDashChoon->get_active();
+ bChanged = m_xMatchMinusDashChoon->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchMinusDashChoon( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchRepeatCharMarks->get_active();
+ bChanged = m_xMatchRepeatCharMarks->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchRepeatCharMarks( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchVariantFormKanji->get_active();
+ bChanged = m_xMatchVariantFormKanji->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchVariantFormKanji( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchOldKanaForms->get_active();
+ bChanged = m_xMatchOldKanaForms->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchOldKanaForms( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchDiziDuzu->get_active();
+ bChanged = m_xMatchDiziDuzu->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchDiziDuzu( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchBavaHafa->get_active();
+ bChanged = m_xMatchBavaHafa->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchBavaHafa( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchTsithichiDhizi->get_active();
+ bChanged = m_xMatchTsithichiDhizi->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchTsithichiDhizi( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchHyuiyuByuvyu->get_active();
+ bChanged = m_xMatchHyuiyuByuvyu->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchHyuiyuByuvyu( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchSesheZeje->get_active();
+ bChanged = m_xMatchSesheZeje->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchSesheZeje( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchIaiya->get_active();
+ bChanged = m_xMatchIaiya->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchIaiya( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchKiku->get_active();
+ bChanged = m_xMatchKiku->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchKiku( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnorePunctuation->get_active();
+ bChanged = m_xIgnorePunctuation->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnorePunctuation( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnoreWhitespace->get_active();
+ bChanged = m_xIgnoreWhitespace->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreWhitespace( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchProlongedSoundMark->get_active();
+ bChanged = m_xMatchProlongedSoundMark->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreProlongedSoundMark( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnoreMiddleDot->get_active();
+ bChanged = m_xIgnoreMiddleDot->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreMiddleDot( bNewVal );
+ bModified = true;
+ }
+
+ if (bModified)
+ aOpt.Commit();
+
+ return bModified;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjsearch.hxx b/cui/source/options/optjsearch.hxx
new file mode 100644
index 000000000..f0da350ae
--- /dev/null
+++ b/cui/source/options/optjsearch.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <i18nutil/transliteration.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SfxItemSet;
+
+class SvxJSearchOptionsPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xMatchCase;
+ std::unique_ptr<weld::CheckButton> m_xMatchFullHalfWidth;
+ std::unique_ptr<weld::CheckButton> m_xMatchHiraganaKatakana;
+ std::unique_ptr<weld::CheckButton> m_xMatchContractions;
+ std::unique_ptr<weld::CheckButton> m_xMatchMinusDashChoon;
+ std::unique_ptr<weld::CheckButton> m_xMatchRepeatCharMarks;
+ std::unique_ptr<weld::CheckButton> m_xMatchVariantFormKanji;
+ std::unique_ptr<weld::CheckButton> m_xMatchOldKanaForms;
+ std::unique_ptr<weld::CheckButton> m_xMatchDiziDuzu;
+ std::unique_ptr<weld::CheckButton> m_xMatchBavaHafa;
+ std::unique_ptr<weld::CheckButton> m_xMatchTsithichiDhizi;
+ std::unique_ptr<weld::CheckButton> m_xMatchHyuiyuByuvyu;
+ std::unique_ptr<weld::CheckButton> m_xMatchSesheZeje;
+ std::unique_ptr<weld::CheckButton> m_xMatchIaiya;
+ std::unique_ptr<weld::CheckButton> m_xMatchKiku;
+ std::unique_ptr<weld::CheckButton> m_xMatchProlongedSoundMark;
+
+ std::unique_ptr<weld::CheckButton> m_xIgnorePunctuation;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreWhitespace;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreMiddleDot;
+
+ TransliterationFlags nTransliterationFlags;
+ bool bSaveOptions;
+
+ TransliterationFlags GetTransliterationFlags_Impl();
+
+public:
+ SvxJSearchOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxJSearchOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+ void EnableSaveOptions( bool bVal ) { bSaveOptions = bVal; }
+
+ TransliterationFlags GetTransliterationFlags() const { return nTransliterationFlags; }
+ void SetTransliterationFlags( TransliterationFlags nSettings );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optlanguagetool.cxx b/cui/source/options/optlanguagetool.cxx
new file mode 100644
index 000000000..38807bc33
--- /dev/null
+++ b/cui/source/options/optlanguagetool.cxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optlanguagetool.hxx"
+#include <svtools/languagetoolcfg.hxx>
+#include <sal/log.hxx>
+
+OptLanguageToolTabPage::OptLanguageToolTabPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/langtoolconfigpage.ui", "OptLangToolPage", &rSet)
+ , m_xBaseURLED(m_xBuilder->weld_entry("baseurl"))
+ , m_xUsernameED(m_xBuilder->weld_entry("username"))
+ , m_xApiKeyED(m_xBuilder->weld_entry("apikey"))
+ , m_xActivateBox(m_xBuilder->weld_check_button("activate"))
+ , m_xApiSettingsFrame(m_xBuilder->weld_frame("apisettings"))
+{
+ m_xActivateBox->connect_toggled(LINK(this, OptLanguageToolTabPage, CheckHdl));
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ EnableControls(rLanguageOpts.getEnabled());
+}
+
+OptLanguageToolTabPage::~OptLanguageToolTabPage() {}
+
+void OptLanguageToolTabPage::EnableControls(bool bEnable)
+{
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ rLanguageOpts.setEnabled(bEnable);
+ m_xApiSettingsFrame->set_visible(bEnable);
+ m_xActivateBox->set_active(bEnable);
+}
+
+IMPL_LINK_NOARG(OptLanguageToolTabPage, CheckHdl, weld::Toggleable&, void)
+{
+ EnableControls(m_xActivateBox->get_active());
+}
+
+void OptLanguageToolTabPage::Reset(const SfxItemSet*)
+{
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ m_xBaseURLED->set_text(rLanguageOpts.getBaseURL());
+ m_xUsernameED->set_text(rLanguageOpts.getUsername());
+ m_xApiKeyED->set_text(rLanguageOpts.getApiKey());
+}
+
+bool OptLanguageToolTabPage::FillItemSet(SfxItemSet*)
+{
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ rLanguageOpts.setBaseURL(m_xBaseURLED->get_text());
+ rLanguageOpts.setUsername(m_xUsernameED->get_text());
+ rLanguageOpts.setApiKey(m_xApiKeyED->get_text());
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> OptLanguageToolTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OptLanguageToolTabPage>(pPage, pController, *rAttrSet);
+}
diff --git a/cui/source/options/optlanguagetool.hxx b/cui/source/options/optlanguagetool.hxx
new file mode 100644
index 000000000..46a60ecbe
--- /dev/null
+++ b/cui/source/options/optlanguagetool.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+#include <sfx2/tabdlg.hxx>
+
+class OptLanguageToolTabPage : public SfxTabPage
+{
+public:
+ OptLanguageToolTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~OptLanguageToolTabPage() override;
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+private:
+ std::unique_ptr<weld::Entry> m_xBaseURLED;
+ std::unique_ptr<weld::Entry> m_xUsernameED;
+ std::unique_ptr<weld::Entry> m_xApiKeyED;
+ std::unique_ptr<weld::CheckButton> m_xActivateBox;
+ std::unique_ptr<weld::Frame> m_xApiSettingsFrame;
+
+ void EnableControls(bool bEnable);
+
+ DECL_LINK(CheckHdl, weld::Toggleable&, void);
+}; \ No newline at end of file
diff --git a/cui/source/options/optlingu.cxx b/cui/source/options/optlingu.cxx
new file mode 100644
index 000000000..be2b891eb
--- /dev/null
+++ b/cui/source/options/optlingu.cxx
@@ -0,0 +1,1974 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <utility>
+#include <vcl/settings.hxx>
+#include <vcl/weld.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <officecfg/Office/Security.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/misc.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker.hpp>
+#include <com/sun/star/linguistic2/XProofreader.hpp>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+#include <com/sun/star/lang/XServiceDisplayName.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <unotools/extendedsecurityoptions.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <svx/svxdlg.hxx>
+#include <editeng/optitems.hxx>
+#include <optlingu.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#include <ucbhelper/content.hxx>
+
+#include <vector>
+#include <map>
+
+using namespace ::ucbhelper;
+using namespace ::com::sun::star;
+using namespace css::lang;
+using namespace css::uno;
+using namespace css::linguistic2;
+using namespace css::beans;
+
+constexpr OUStringLiteral cSpell(SN_SPELLCHECKER);
+constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER);
+constexpr OUStringLiteral cHyph(SN_HYPHENATOR);
+constexpr OUStringLiteral cThes(SN_THESAURUS);
+
+// static ----------------------------------------------------------------
+
+static sal_Int32 lcl_SeqGetEntryPos(
+ const Sequence< OUString > &rSeq, std::u16string_view rEntry )
+{
+ sal_Int32 i;
+ sal_Int32 nLen = rSeq.getLength();
+ const OUString *pItem = rSeq.getConstArray();
+ for (i = 0; i < nLen; ++i)
+ {
+ if (rEntry == pItem[i])
+ break;
+ }
+ return i < nLen ? i : -1;
+}
+
+static bool KillFile_Impl( const OUString& rURL )
+{
+ bool bRet = true;
+ try
+ {
+ Content aCnt( rURL, uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ aCnt.executeCommand( "delete", Any( true ) );
+ }
+ catch( ... )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "KillFile" );
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+// 0x 0p 0t 0c nn
+// p: 1 -> parent
+// t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
+// c: 1 -> checked 0 -> unchecked
+// n: index
+
+#define TYPE_SPELL sal_uInt8(1)
+#define TYPE_GRAMMAR sal_uInt8(2)
+#define TYPE_HYPH sal_uInt8(3)
+#define TYPE_THES sal_uInt8(4)
+
+namespace {
+
+class ModuleUserData_Impl
+{
+ bool bParent;
+ bool bIsChecked;
+ sal_uInt8 nType;
+ sal_uInt8 nIndex;
+ OUString sImplName;
+
+public:
+ ModuleUserData_Impl( OUString sImpName, bool bIsParent, bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
+ bParent(bIsParent),
+ bIsChecked(bChecked),
+ nType(nSetType),
+ nIndex(nSetIndex),
+ sImplName(std::move(sImpName))
+ {
+ }
+ bool IsParent() const {return bParent;}
+ sal_uInt8 GetType() const {return nType;}
+ bool IsChecked() const {return bIsChecked;}
+ sal_uInt8 GetIndex() const {return nIndex;}
+ const OUString& GetImplName() const {return sImplName;}
+
+};
+
+
+// User for user-dictionaries (XDictionary interface)
+
+class DicUserData
+{
+ sal_uInt32 nVal;
+
+public:
+ explicit DicUserData(sal_uInt32 nUserData) : nVal( nUserData ) {}
+ DicUserData( sal_uInt16 nEID,
+ bool bChecked, bool bEditable, bool bDeletable );
+
+ sal_uInt32 GetUserData() const { return nVal; }
+ sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
+ bool IsChecked() const { return static_cast<bool>((nVal >> 8) & 0x01); }
+ bool IsDeletable() const { return static_cast<bool>((nVal >> 10) & 0x01); }
+};
+
+}
+
+DicUserData::DicUserData(
+ sal_uInt16 nEID,
+ bool bChecked, bool bEditable, bool bDeletable )
+{
+ DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
+ nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
+ (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
+ (static_cast<sal_uInt32>(bEditable ? 1 : 0) << 9) |
+ (static_cast<sal_uInt32>(bDeletable ? 1 : 0) << 10);
+}
+
+/*--------------------------------------------------
+ Entry IDs for options listbox of dialog
+--------------------------------------------------*/
+
+namespace {
+
+enum EID_OPTIONS
+{
+ EID_SPELL_AUTO,
+ EID_GRAMMAR_AUTO,
+ EID_CAPITAL_WORDS,
+ EID_WORDS_WITH_DIGITS,
+ EID_SPELL_SPECIAL,
+ EID_NUM_MIN_WORDLEN,
+ EID_NUM_PRE_BREAK,
+ EID_NUM_POST_BREAK,
+ EID_HYPH_AUTO,
+ EID_HYPH_SPECIAL
+};
+
+}
+
+static OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
+{
+ switch (eEntryId)
+ {
+ case EID_SPELL_AUTO: return UPN_IS_SPELL_AUTO;
+ case EID_GRAMMAR_AUTO: return UPN_IS_GRAMMAR_AUTO;
+ case EID_CAPITAL_WORDS: return UPN_IS_SPELL_UPPER_CASE;
+ case EID_WORDS_WITH_DIGITS: return UPN_IS_SPELL_WITH_DIGITS;
+ case EID_SPELL_SPECIAL: return UPN_IS_SPELL_SPECIAL;
+ case EID_NUM_MIN_WORDLEN: return UPN_HYPH_MIN_WORD_LENGTH;
+ case EID_NUM_PRE_BREAK: return UPN_HYPH_MIN_LEADING;
+ case EID_NUM_POST_BREAK: return UPN_HYPH_MIN_TRAILING;
+ case EID_HYPH_AUTO: return UPN_IS_HYPH_AUTO;
+ case EID_HYPH_SPECIAL: return UPN_IS_HYPH_SPECIAL;
+ default: assert (false); abort();
+ }
+}
+
+namespace {
+
+class OptionsBreakSet : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Widget> m_xBeforeFrame;
+ std::unique_ptr<weld::Widget> m_xAfterFrame;
+ std::unique_ptr<weld::Widget> m_xMinimalFrame;
+ std::unique_ptr<weld::SpinButton> m_xBreakNF;
+
+public:
+ OptionsBreakSet(weld::Window* pParent, sal_uInt16 nRID)
+ : GenericDialogController(pParent, "cui/ui/breaknumberoption.ui", "BreakNumberOption")
+ , m_xBeforeFrame(m_xBuilder->weld_widget("beforeframe"))
+ , m_xAfterFrame(m_xBuilder->weld_widget("afterframe"))
+ , m_xMinimalFrame(m_xBuilder->weld_widget("miniframe"))
+ {
+ assert(EID_NUM_PRE_BREAK == nRID || EID_NUM_POST_BREAK == nRID || EID_NUM_MIN_WORDLEN == nRID); //unexpected ID
+
+ if (nRID == EID_NUM_PRE_BREAK)
+ {
+ m_xBeforeFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("beforebreak");
+ }
+ else if(nRID == EID_NUM_POST_BREAK)
+ {
+ m_xAfterFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("afterbreak");
+ }
+ else if(nRID == EID_NUM_MIN_WORDLEN)
+ {
+ m_xMinimalFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("wordlength");
+ }
+ }
+
+ weld::SpinButton& GetNumericFld()
+ {
+ return *m_xBreakNF;
+ }
+};
+
+// class OptionsUserData -------------------------------------------------
+
+class OptionsUserData
+{
+ sal_uInt32 nVal;
+
+public:
+ explicit OptionsUserData( sal_uInt32 nUserData ) : nVal( nUserData ) {}
+ OptionsUserData( sal_uInt16 nEID,
+ bool bHasNV, sal_uInt16 nNumVal,
+ bool bCheckable, bool bChecked );
+
+ sal_uInt32 GetUserData() const { return nVal; }
+ sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
+ bool HasNumericValue() const { return static_cast<bool>((nVal >> 10) & 0x01); }
+ sal_uInt16 GetNumericValue() const { return static_cast<sal_uInt16>(nVal & 0xFF); }
+ bool IsCheckable() const { return static_cast<bool>((nVal >> 9) & 0x01); }
+ bool IsModified() const { return static_cast<bool>((nVal >> 11) & 0x01); }
+
+ void SetNumericValue( sal_uInt8 nNumVal );
+};
+
+}
+
+OptionsUserData::OptionsUserData( sal_uInt16 nEID,
+ bool bHasNV, sal_uInt16 nNumVal,
+ bool bCheckable, bool bChecked )
+{
+ DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
+ DBG_ASSERT( nNumVal < 256, "value out of range" );
+ nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
+ (static_cast<sal_uInt32>(bHasNV ? 1 : 0) << 10) |
+ (static_cast<sal_uInt32>(bCheckable ? 1 : 0) << 9) |
+ (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
+ static_cast<sal_uInt32>(0xFF & nNumVal);
+}
+
+void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
+{
+ if (HasNumericValue() && (GetNumericValue() != nNumVal))
+ {
+ nVal &= 0xffffff00;
+ nVal |= nNumVal;
+ nVal |= sal_uInt32(1) << 11; // mark as modified
+ }
+}
+
+// ServiceInfo_Impl ----------------------------------------------------
+
+namespace {
+
+struct ServiceInfo_Impl
+{
+ OUString sDisplayName;
+ OUString sSpellImplName;
+ OUString sHyphImplName;
+ OUString sThesImplName;
+ OUString sGrammarImplName;
+ uno::Reference< XSpellChecker > xSpell;
+ uno::Reference< XHyphenator > xHyph;
+ uno::Reference< XThesaurus > xThes;
+ uno::Reference< XProofreader > xGrammar;
+ bool bConfigured;
+
+ ServiceInfo_Impl() : bConfigured(false) {}
+};
+
+}
+
+typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
+typedef std::map< LanguageType, Sequence< OUString > > LangImplNameTable;
+
+
+// SvxLinguData_Impl ----------------------------------------------------
+
+class SvxLinguData_Impl
+{
+ //contains services and implementation names sorted by implementation names
+ ServiceInfoArr aDisplayServiceArr;
+ sal_uInt32 nDisplayServices;
+
+ Sequence< Locale > aAllServiceLocales;
+ LangImplNameTable aCfgSpellTable;
+ LangImplNameTable aCfgHyphTable;
+ LangImplNameTable aCfgThesTable;
+ LangImplNameTable aCfgGrammarTable;
+ uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
+
+
+ static bool AddRemove( Sequence< OUString > &rConfigured,
+ const OUString &rImplName, bool bAdd );
+
+public:
+ SvxLinguData_Impl();
+
+ uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
+
+ void SetChecked( const Sequence< OUString > &rConfiguredServices );
+ void Reconfigure( std::u16string_view rDisplayName, bool bEnable );
+
+ const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
+
+ LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
+ LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
+ LangImplNameTable & GetThesTable() { return aCfgThesTable; }
+ LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
+
+ ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
+
+ const sal_uInt32 & GetDisplayServiceCount() const { return nDisplayServices; }
+ void SetDisplayServiceCount( sal_uInt32 nVal ) { nDisplayServices = nVal; }
+
+ // returns the list of service implementation names for the specified
+ // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
+ // the proper order for the SvxEditModulesDlg (the ones from the
+ // configuration (keeping that order!) first and then the other ones.
+ // I.e. the ones available but not configured in arbitrary order).
+ // They available ones may contain names that do not(!) support that
+ // language.
+ Sequence< OUString > GetSortedImplNames( LanguageType nLang, sal_uInt8 nType );
+
+ ServiceInfo_Impl * GetInfoByImplName( std::u16string_view rSvcImplName );
+};
+
+
+static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, std::u16string_view rTxt )
+{
+ sal_Int32 nRes = -1;
+ sal_Int32 nLen = rSeq.getLength();
+ const OUString *pString = rSeq.getConstArray();
+ for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
+ {
+ if (pString[i] == rTxt)
+ nRes = i;
+ }
+ return nRes;
+}
+
+
+Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( LanguageType nLang, sal_uInt8 nType )
+{
+ LangImplNameTable *pTable = nullptr;
+ switch (nType)
+ {
+ case TYPE_SPELL : pTable = &aCfgSpellTable; break;
+ case TYPE_HYPH : pTable = &aCfgHyphTable; break;
+ case TYPE_THES : pTable = &aCfgThesTable; break;
+ case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
+ }
+ Sequence< OUString > aRes;
+ if (!pTable)
+ {
+ SAL_WARN( "cui.options", "unknown linguistic type" );
+ return aRes;
+ }
+ if (pTable->count( nLang ))
+ aRes = (*pTable)[ nLang ]; // add configured services
+ sal_Int32 nIdx = aRes.getLength();
+ DBG_ASSERT( static_cast<sal_Int32>(nDisplayServices) >= nIdx, "size mismatch" );
+ aRes.realloc( nDisplayServices );
+ OUString *pRes = aRes.getArray();
+
+ // add not configured services
+ for (sal_Int32 i = 0; i < static_cast<sal_Int32>(nDisplayServices); ++i)
+ {
+ const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
+ OUString aImplName;
+ switch (nType)
+ {
+ case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
+ case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
+ case TYPE_THES : aImplName = rInfo.sThesImplName; break;
+ case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
+ }
+
+ if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
+ {
+ DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
+ if (nIdx < aRes.getLength())
+ pRes[ nIdx++ ] = aImplName;
+ }
+ }
+ // don't forget to put aRes back to its actual size just in case you allocated too much
+ // since all of the names may have already been added
+ // otherwise you get duplicate entries in the edit dialog
+ aRes.realloc( nIdx );
+ return aRes;
+}
+
+
+ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( std::u16string_view rSvcImplName )
+{
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
+ if (rTmp.sSpellImplName == rSvcImplName ||
+ rTmp.sHyphImplName == rSvcImplName ||
+ rTmp.sThesImplName == rSvcImplName ||
+ rTmp.sGrammarImplName == rSvcImplName)
+ {
+ return &rTmp;
+ }
+ }
+ return nullptr;
+}
+
+
+static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
+{
+ Sequence<Locale> aLocToAdd(rAdd.getLength());
+ Locale* pLocToAdd = aLocToAdd.getArray();
+ sal_Int32 nFound = 0;
+ for(const Locale& i : rAdd)
+ {
+ bool bFound = false;
+ for(const Locale& j : std::as_const(aAllLocales))
+ {
+ if (i.Language == j.Language &&
+ i.Country == j.Country &&
+ i.Variant == j.Variant)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ {
+ pLocToAdd[nFound++] = i;
+ }
+ }
+ sal_Int32 nLength = aAllLocales.getLength();
+ aAllLocales.realloc( nLength + nFound);
+ Locale* pAllLocales2 = aAllLocales.getArray();
+ for(sal_Int32 i = 0; i < nFound; i++)
+ pAllLocales2[nLength++] = pLocToAdd[i];
+}
+
+static void lcl_MergeDisplayArray(
+ SvxLinguData_Impl &rData,
+ const ServiceInfo_Impl &rToAdd )
+{
+ sal_uInt32 nCnt = 0;
+
+ ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
+ sal_uInt32 nEntries = rData.GetDisplayServiceCount();
+
+ for (sal_uInt32 i = 0; i < nEntries; ++i)
+ {
+ ServiceInfo_Impl& rEntry = rSvcInfoArr[i];
+ if (rEntry.sDisplayName == rToAdd.sDisplayName)
+ {
+ if(rToAdd.xSpell.is())
+ {
+ DBG_ASSERT( !rEntry.xSpell.is() &&
+ rEntry.sSpellImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sSpellImplName = rToAdd.sSpellImplName;
+ rEntry.xSpell = rToAdd.xSpell;
+ }
+ if(rToAdd.xGrammar.is())
+ {
+ DBG_ASSERT( !rEntry.xGrammar.is() &&
+ rEntry.sGrammarImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sGrammarImplName = rToAdd.sGrammarImplName;
+ rEntry.xGrammar = rToAdd.xGrammar;
+ }
+ if(rToAdd.xHyph.is())
+ {
+ DBG_ASSERT( !rEntry.xHyph.is() &&
+ rEntry.sHyphImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sHyphImplName = rToAdd.sHyphImplName;
+ rEntry.xHyph = rToAdd.xHyph;
+ }
+ if(rToAdd.xThes.is())
+ {
+ DBG_ASSERT( !rEntry.xThes.is() &&
+ rEntry.sThesImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sThesImplName = rToAdd.sThesImplName;
+ rEntry.xThes = rToAdd.xThes;
+ }
+ return ;
+ }
+ ++nCnt;
+ }
+ rData.GetDisplayServiceArray().push_back( rToAdd );
+ rData.SetDisplayServiceCount( nCnt + 1 );
+}
+
+SvxLinguData_Impl::SvxLinguData_Impl() :
+ nDisplayServices (0)
+{
+ uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ xLinguSrvcMgr = LinguServiceManager::create(xContext);
+
+ const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ Sequence<Any> aArgs(2);//second arguments has to be empty!
+ aArgs.getArray()[0] <<= LinguMgr::GetLinguPropertySet();
+
+ //read spell checker
+ const Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
+ cSpell, Locale() );
+
+ for(const OUString& spellName : aSpellNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sSpellImplName = spellName;
+ aInfo.xSpell.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read grammar checker
+ const Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
+ cGrammar, Locale() );
+ for(const OUString& grammarName : aGrammarNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sGrammarImplName = grammarName;
+ aInfo.xGrammar.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read hyphenator
+ const Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
+ cHyph, Locale() );
+ for(const OUString& hyphName : aHyphNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sHyphImplName = hyphName;
+ aInfo.xHyph.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read thesauri
+ const Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
+ cThes, Locale() );
+ for(const OUString& thesName : aThesNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sThesImplName = thesName;
+ aInfo.xThes.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ Sequence< OUString > aCfgSvcs;
+ for(auto const & locale : std::as_const(aAllServiceLocales))
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( locale );
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgSpellTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgGrammarTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgHyphTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgThesTable[ nLang ] = aCfgSvcs;
+ }
+}
+
+void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
+{
+ for(OUString const & configService : rConfiguredServices)
+ {
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl& rEntry = aDisplayServiceArr[i];
+ if (!rEntry.bConfigured)
+ {
+ const OUString &rSrvcImplName = configService;
+ if (!rSrvcImplName.isEmpty() &&
+ (rEntry.sSpellImplName == rSrvcImplName ||
+ rEntry.sGrammarImplName == rSrvcImplName ||
+ rEntry.sHyphImplName == rSrvcImplName ||
+ rEntry.sThesImplName == rSrvcImplName))
+ {
+ rEntry.bConfigured = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
+bool SvxLinguData_Impl::AddRemove(
+ Sequence< OUString > &rConfigured,
+ const OUString &rImplName, bool bAdd )
+{
+ bool bRet = false; // modified?
+
+ sal_Int32 nEntries = rConfigured.getLength();
+ sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
+ if (bAdd && nPos < 0) // add new entry
+ {
+ rConfigured.realloc( ++nEntries );
+ OUString *pConfigured = rConfigured.getArray();
+ pConfigured[nEntries - 1] = rImplName;
+ bRet = true;
+ }
+ else if (!bAdd && nPos >= 0) // remove existing entry
+ {
+ OUString *pConfigured = rConfigured.getArray();
+ for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
+ pConfigured[i] = pConfigured[i + 1];
+ rConfigured.realloc(--nEntries);
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+
+void SvxLinguData_Impl::Reconfigure( std::u16string_view rDisplayName, bool bEnable )
+{
+ DBG_ASSERT( !rDisplayName.empty(), "empty DisplayName" );
+
+ ServiceInfo_Impl *pInfo = nullptr;
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl& rTmp = aDisplayServiceArr[i];
+ if (rTmp.sDisplayName == rDisplayName)
+ {
+ pInfo = &rTmp;
+ break;
+ }
+ }
+ DBG_ASSERT( pInfo, "DisplayName entry not found" );
+ if (!pInfo)
+ return;
+
+ pInfo->bConfigured = bEnable;
+
+ Sequence< Locale > aLocales;
+ const Locale *pLocale = nullptr;
+ sal_Int32 nLocales = 0;
+ sal_Int32 i;
+
+ // update configured spellchecker entries
+ if (pInfo->xSpell.is())
+ {
+ aLocales = pInfo->xSpell->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgSpellTable.count( nLang ) && bEnable)
+ aCfgSpellTable[ nLang ] = Sequence< OUString >();
+ if (aCfgSpellTable.count( nLang ))
+ AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
+ }
+ }
+
+ // update configured grammar checker entries
+ if (pInfo->xGrammar.is())
+ {
+ aLocales = pInfo->xGrammar->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgGrammarTable.count( nLang ) && bEnable)
+ aCfgGrammarTable[ nLang ] = Sequence< OUString >();
+ if (aCfgGrammarTable.count( nLang ))
+ AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
+ }
+ }
+
+ // update configured hyphenator entries
+ if (pInfo->xHyph.is())
+ {
+ aLocales = pInfo->xHyph->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgHyphTable.count( nLang ) && bEnable)
+ aCfgHyphTable[ nLang ] = Sequence< OUString >();
+ if (aCfgHyphTable.count( nLang ))
+ AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
+ }
+ }
+
+ // update configured spellchecker entries
+ if (!pInfo->xThes.is())
+ return;
+
+ aLocales = pInfo->xThes->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgThesTable.count( nLang ) && bEnable)
+ aCfgThesTable[ nLang ] = Sequence< OUString >();
+ if (aCfgThesTable.count( nLang ))
+ AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
+ }
+}
+
+
+// class SvxLinguTabPage -------------------------------------------------
+
+SvxLinguTabPage::SvxLinguTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optlingupage.ui", "OptLinguPage", &rSet)
+ , sCapitalWords (CuiResId(RID_CUISTR_CAPITAL_WORDS))
+ , sWordsWithDigits(CuiResId(RID_CUISTR_WORDS_WITH_DIGITS))
+ , sSpellSpecial (CuiResId(RID_CUISTR_SPELL_SPECIAL))
+ , sSpellAuto (CuiResId(RID_CUISTR_SPELL_AUTO))
+ , sGrammarAuto (CuiResId(RID_CUISTR_GRAMMAR_AUTO))
+ , sNumMinWordlen (CuiResId(RID_CUISTR_NUM_MIN_WORDLEN))
+ , sNumPreBreak (CuiResId(RID_CUISTR_NUM_PRE_BREAK))
+ , sNumPostBreak (CuiResId(RID_CUISTR_NUM_POST_BREAK))
+ , sHyphAuto (CuiResId(RID_CUISTR_HYPH_AUTO))
+ , sHyphSpecial (CuiResId(RID_CUISTR_HYPH_SPECIAL))
+ , nUPN_HYPH_MIN_WORD_LENGTH(-1)
+ , nUPN_HYPH_MIN_LEADING(-1)
+ , nUPN_HYPH_MIN_TRAILING(-1)
+ , m_nDlbClickEventId(nullptr)
+ , m_xLinguModulesFT(m_xBuilder->weld_label("lingumodulesft"))
+ , m_xLinguModulesCLB(m_xBuilder->weld_tree_view("lingumodules"))
+ , m_xLinguModulesEditPB(m_xBuilder->weld_button("lingumodulesedit"))
+ , m_xLinguDicsFT(m_xBuilder->weld_label("lingudictsft"))
+ , m_xLinguDicsCLB(m_xBuilder->weld_tree_view("lingudicts"))
+ , m_xLinguDicsNewPB(m_xBuilder->weld_button("lingudictsnew"))
+ , m_xLinguDicsEditPB(m_xBuilder->weld_button("lingudictsedit"))
+ , m_xLinguDicsDelPB(m_xBuilder->weld_button("lingudictsdelete"))
+ , m_xLinguOptionsCLB(m_xBuilder->weld_tree_view("linguoptions"))
+ , m_xLinguOptionsEditPB(m_xBuilder->weld_button("linguoptionsedit"))
+ , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
+{
+ m_xLinguModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xLinguDicsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xLinguOptionsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ m_xLinguModulesCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguModulesCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
+ m_xLinguModulesCLB->connect_toggled(LINK(this, SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl));
+
+ m_xLinguModulesEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguOptionsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+
+ m_xLinguDicsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguDicsCLB->connect_toggled(LINK(this, SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl));
+
+ m_xLinguDicsNewPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguDicsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguDicsDelPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+
+ m_xLinguOptionsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguOptionsCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
+
+ m_xMoreDictsLink->connect_activate_link(LINK(this, SvxLinguTabPage, OnLinkClick));
+ if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
+ m_xMoreDictsLink->hide();
+
+ xProp = LinguMgr::GetLinguPropertySet();
+ xDicList.set( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ // keep references to all **currently** available dictionaries,
+ // since the diclist may get changed meanwhile (e.g. through the API).
+ // We want the dialog to operate on the same set of dictionaries it
+ // was started with.
+ // Also we have to take care to not lose the last reference when
+ // someone else removes a dictionary from the list.
+ // removed dics will be replaced by NULL new entries be added to the end
+ // Thus we may use indices as consistent references.
+ aDics = xDicList->getDictionaries();
+
+ UpdateDicBox_Impl();
+ }
+ else
+ {
+ m_xLinguDicsFT->set_sensitive(false);
+ m_xLinguDicsCLB->set_sensitive(false);
+ m_xLinguDicsNewPB->set_sensitive(false);
+ m_xLinguDicsEditPB->set_sensitive(false);
+ m_xLinguDicsDelPB->set_sensitive(false);
+ }
+}
+
+SvxLinguTabPage::~SvxLinguTabPage()
+{
+ if (m_nDlbClickEventId)
+ {
+ Application::RemoveUserEvent(m_nDlbClickEventId);
+ m_nDlbClickEventId = nullptr;
+ }
+ pLinguData.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxLinguTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxLinguTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxLinguTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ bool bModified = true; // !!!!
+
+ // if not HideGroups was called with GROUP_MODULES...
+ if (m_xLinguModulesCLB->get_visible())
+ {
+ DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+
+ // update spellchecker configuration entries
+ const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
+ }
+
+ // update grammar checker configuration entries
+ pTable = &pLinguData->GetGrammarTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
+ }
+
+ // update hyphenator configuration entries
+ pTable = &pLinguData->GetHyphTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
+ }
+
+ // update thesaurus configuration entries
+ pTable = &pLinguData->GetThesTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
+ }
+ }
+
+
+ // activate dictionaries according to checkbox state
+
+ Sequence< OUString > aActiveDics;
+ sal_Int32 nActiveDics = 0;
+ int nEntries = m_xLinguDicsCLB->n_children();
+ for (int i = 0; i < nEntries; ++i)
+ {
+ sal_Int32 nDics = aDics.getLength();
+
+ aActiveDics.realloc( nDics );
+ OUString *pActiveDic = aActiveDics.getArray();
+
+ DicUserData aData(m_xLinguDicsCLB->get_id(i).toUInt32());
+ if (aData.GetEntryId() < nDics)
+ {
+ bool bChecked = m_xLinguDicsCLB->get_toggle(i) == TRISTATE_TRUE;
+ uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
+ if (xDic.is())
+ {
+ if (LinguMgr::GetIgnoreAllList() == xDic)
+ bChecked = true;
+ xDic->setActive( bChecked );
+
+ if (bChecked)
+ {
+ OUString aDicName( xDic->getName() );
+ pActiveDic[ nActiveDics++ ] = aDicName;
+ }
+ }
+ }
+ }
+
+ aActiveDics.realloc( nActiveDics );
+ Any aTmp;
+ aTmp <<= aActiveDics;
+ SvtLinguConfig aLngCfg;
+ aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
+
+
+ nEntries = m_xLinguOptionsCLB->n_children();
+ for (int j = 0; j < nEntries; ++j)
+ {
+ OptionsUserData aData(m_xLinguOptionsCLB->get_id(j).toUInt32());
+ OUString aPropName( lcl_GetPropertyName( static_cast<EID_OPTIONS>(aData.GetEntryId()) ) );
+
+ Any aAny;
+ if (aData.IsCheckable())
+ {
+ bool bChecked = m_xLinguOptionsCLB->get_toggle(j) == TRISTATE_TRUE;
+ aAny <<= bChecked;
+ }
+ else if (aData.HasNumericValue())
+ {
+ sal_Int16 nVal = aData.GetNumericValue();
+ aAny <<= nVal;
+ }
+
+ if (xProp.is())
+ xProp->setPropertyValue( aPropName, aAny );
+ aLngCfg.SetProperty( aPropName, aAny );
+ }
+
+ OptionsUserData aPreBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_PRE_BREAK).toUInt32());
+ OptionsUserData aPostBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_POST_BREAK).toUInt32());
+ if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
+ {
+ SfxHyphenRegionItem aHyp( SID_ATTR_HYPHENREGION );
+ aHyp.GetMinLead() = static_cast<sal_uInt8>(aPreBreakData.GetNumericValue());
+ aHyp.GetMinTrail() = static_cast<sal_uInt8>(aPostBreakData.GetNumericValue());
+ rCoreSet->Put( aHyp );
+ }
+
+ // automatic spell checking
+ bool bNewAutoCheck = m_xLinguOptionsCLB->get_toggle(EID_SPELL_AUTO) == TRISTATE_TRUE;
+ const SfxPoolItem* pOld = GetOldItem( *rCoreSet, SID_AUTOSPELL_CHECK );
+ if ( !pOld || static_cast<const SfxBoolItem*>(pOld)->GetValue() != bNewAutoCheck )
+ {
+ rCoreSet->Put( SfxBoolItem( SID_AUTOSPELL_CHECK, bNewAutoCheck ) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+sal_uInt32 SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
+{
+ sal_uInt32 nRes = 0;
+ DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
+ if (rxDic.is())
+ {
+ uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
+
+ bool bChecked = rxDic->isActive();
+ bool bEditable = !xStor.is() || !xStor->isReadonly();
+ bool bDeletable = bEditable;
+
+ nRes = DicUserData( nIdx,
+ bChecked, bEditable, bDeletable ).GetUserData();
+ }
+ return nRes;
+}
+
+
+void SvxLinguTabPage::AddDicBoxEntry(
+ const uno::Reference< XDictionary > &rxDic,
+ sal_uInt16 nIdx )
+{
+ m_xLinguDicsCLB->freeze();
+
+ OUString aTxt( ::GetDicInfoStr( rxDic->getName(),
+ LanguageTag( rxDic->getLocale() ).getLanguageType(),
+ DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
+ m_xLinguDicsCLB->append(); // append at end
+ int nEntry = m_xLinguDicsCLB->n_children() - 1;
+ DicUserData aData( GetDicUserData( rxDic, nIdx ) );
+ m_xLinguDicsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ m_xLinguDicsCLB->set_toggle(nEntry, aData.IsChecked() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguDicsCLB->set_text(nEntry, aTxt, 0); // append at end
+
+ m_xLinguDicsCLB->thaw();
+}
+
+void SvxLinguTabPage::UpdateDicBox_Impl()
+{
+ m_xLinguDicsCLB->freeze();
+ m_xLinguDicsCLB->clear();
+
+ sal_Int32 nDics = aDics.getLength();
+ const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
+ for (sal_Int32 i = 0; i < nDics; ++i)
+ {
+ const uno::Reference< XDictionary > &rDic = pDic[i];
+ if (rDic.is())
+ AddDicBoxEntry( rDic, static_cast<sal_uInt16>(i) );
+ }
+
+ m_xLinguDicsCLB->thaw();
+ if (m_xLinguDicsCLB->n_children())
+ {
+ m_xLinguDicsCLB->select(0);
+ SelectHdl_Impl(*m_xLinguDicsCLB);
+ }
+}
+
+void SvxLinguTabPage::UpdateModulesBox_Impl()
+{
+ if (!pLinguData)
+ return;
+
+ const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
+ const sal_uInt32 nDispSrvcCount = pLinguData->GetDisplayServiceCount();
+
+ m_xLinguModulesCLB->clear();
+
+ for (sal_uInt32 i = 0; i < nDispSrvcCount; ++i)
+ {
+ const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
+ m_xLinguModulesCLB->append();
+ m_xLinguModulesCLB->set_id(i, weld::toId(&rInfo));
+ m_xLinguModulesCLB->set_toggle(i, rInfo.bConfigured ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguModulesCLB->set_text(i, rInfo.sDisplayName, 0);
+ }
+ if (nDispSrvcCount)
+ {
+ m_xLinguModulesCLB->select(0);
+ SelectHdl_Impl(*m_xLinguModulesCLB);
+ }
+ m_xLinguModulesEditPB->set_sensitive( nDispSrvcCount > 0 );
+}
+
+void SvxLinguTabPage::Reset( const SfxItemSet* rSet )
+{
+ // if not HideGroups was called with GROUP_MODULES...
+ if (m_xLinguModulesCLB->get_visible())
+ {
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+ UpdateModulesBox_Impl();
+ }
+
+
+ // get data from configuration
+ SvtLinguConfig aLngCfg;
+
+ m_xLinguOptionsCLB->freeze();
+ m_xLinguOptionsCLB->clear();
+
+ sal_Int16 nVal = 0;
+ bool bVal = false;
+ sal_uInt32 nUserData = 0;
+
+ m_xLinguOptionsCLB->append();
+ int nEntry = 0;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_AUTOSPELL_CHECK );
+ if (pItem)
+ bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
+ nUserData = OptionsUserData( EID_SPELL_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sSpellAuto, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
+ nUserData = OptionsUserData( EID_GRAMMAR_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sGrammarAuto, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
+ nUserData = OptionsUserData( EID_CAPITAL_WORDS, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sCapitalWords, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
+ nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sWordsWithDigits, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
+ nUserData = OptionsUserData( EID_SPELL_SPECIAL, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sSpellSpecial, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
+ nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_WORD_LENGTH = nEntry;
+
+ const SfxHyphenRegionItem *pHyp = nullptr;
+ if ( rSet->GetItemState( SID_ATTR_HYPHENREGION, false ) == SfxItemState::SET )
+ pHyp = & rSet->Get( SID_ATTR_HYPHENREGION );
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
+ if (pHyp)
+ nVal = static_cast<sal_Int16>(pHyp->GetMinLead());
+ nUserData = OptionsUserData( EID_NUM_PRE_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_LEADING = nEntry;
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
+ if (pHyp)
+ nVal = static_cast<sal_Int16>(pHyp->GetMinTrail());
+ nUserData = OptionsUserData( EID_NUM_POST_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_TRAILING = nEntry;
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
+ nUserData = OptionsUserData( EID_HYPH_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sHyphAuto, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
+ nUserData = OptionsUserData( EID_HYPH_SPECIAL, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sHyphSpecial, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->thaw();
+
+ m_xLinguOptionsCLB->select(0);
+ SelectHdl_Impl(*m_xLinguOptionsCLB);
+
+ m_xLinguModulesCLB->set_size_request(m_xLinguModulesCLB->get_preferred_size().Width(),
+ m_xLinguModulesCLB->get_height_rows(3));
+ m_xLinguDicsCLB->set_size_request(m_xLinguDicsCLB->get_preferred_size().Width(),
+ m_xLinguDicsCLB->get_height_rows(5));
+ m_xLinguOptionsCLB->set_size_request(m_xLinguOptionsCLB->get_preferred_size().Width(),
+ m_xLinguOptionsCLB->get_height_rows(5));
+}
+
+IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView&, rBox, bool)
+{
+ if (&rBox == m_xLinguModulesCLB.get() && !m_nDlbClickEventId)
+ {
+ //! in order to avoid a bug causing a GPF when double clicking
+ //! on a module entry and exiting the "Edit Modules" dialog
+ //! after that.
+ m_nDlbClickEventId = Application::PostUserEvent(LINK(this, SvxLinguTabPage, PostDblClickHdl_Impl));
+ }
+ else if (&rBox == m_xLinguOptionsCLB.get())
+ {
+ ClickHdl_Impl(*m_xLinguOptionsEditPB);
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void*, void)
+{
+ m_nDlbClickEventId = nullptr;
+ ClickHdl_Impl(*m_xLinguModulesEditPB);
+}
+
+IMPL_LINK(SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ if (!pLinguData)
+ return;
+ pLinguData->Reconfigure(m_xLinguModulesCLB->get_text(rRowCol.first),
+ m_xLinguModulesCLB->get_toggle(rRowCol.first) == TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ const uno::Reference<XDictionary> &rDic = aDics.getConstArray()[m_xLinguDicsCLB->get_iter_index_in_parent(rRowCol.first)];
+ if (LinguMgr::GetIgnoreAllList() == rDic)
+ m_xLinguDicsCLB->set_toggle(rRowCol.first, TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxLinguTabPage, ClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ if (m_xLinguModulesEditPB.get() == &rBtn)
+ {
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+
+ SvxLinguData_Impl aOldLinguData( *pLinguData );
+ SvxEditModulesDlg aDlg(GetFrameWeld(), *pLinguData);
+ if (aDlg.run() != RET_OK)
+ *pLinguData = aOldLinguData;
+
+ // evaluate new status of 'bConfigured' flag
+ sal_uInt32 nLen = pLinguData->GetDisplayServiceCount();
+ for (sal_uInt32 i = 0; i < nLen; ++i)
+ pLinguData->GetDisplayServiceArray()[i].bConfigured = false;
+ const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
+ sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
+ for (sal_Int32 k = 0; k < nLocales; ++k)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pAllLocales[k] );
+ if (pLinguData->GetSpellTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
+ if (pLinguData->GetGrammarTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
+ if (pLinguData->GetHyphTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
+ if (pLinguData->GetThesTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
+ }
+
+ // show new status of modules
+ UpdateModulesBox_Impl();
+ }
+ else if (m_xLinguDicsNewPB.get() == &rBtn)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNewDictionaryDialog> aDlg(pFact->CreateSvxNewDictionaryDialog(GetFrameWeld()));
+ uno::Reference< XDictionary > xNewDic;
+ if ( aDlg->Execute() == RET_OK )
+ xNewDic = aDlg->GetNewDictionary();
+ if ( xNewDic.is() )
+ {
+ // add new dics to the end
+ sal_Int32 nLen = aDics.getLength();
+ aDics.realloc( nLen + 1 );
+
+ aDics.getArray()[ nLen ] = xNewDic;
+
+ AddDicBoxEntry( xNewDic, static_cast<sal_uInt16>(nLen) );
+ }
+ }
+ else if (m_xLinguDicsEditPB.get() == &rBtn)
+ {
+ int nEntry = m_xLinguDicsCLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
+ sal_uInt16 nDicPos = aData.GetEntryId();
+ sal_Int32 nDics = aDics.getLength();
+ if (nDicPos < nDics)
+ {
+ uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
+ if (xDic.is())
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> aDlg(pFact->CreateSvxEditDictionaryDialog(GetFrameWeld(), xDic->getName()));
+ aDlg->Execute();
+ }
+ }
+ }
+ }
+ else if (m_xLinguDicsDelPB.get() == &rBtn)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletedictionarydialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteDictionaryDialog"));
+ if (RET_NO == xQuery->run())
+ return;
+
+ int nEntry = m_xLinguDicsCLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
+ sal_uInt16 nDicPos = aData.GetEntryId();
+ sal_Int32 nDics = aDics.getLength();
+ if (nDicPos < nDics)
+ {
+ uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
+ if (xDic.is())
+ {
+ if (LinguMgr::GetIgnoreAllList() == xDic)
+ xDic->clear();
+ else
+ {
+ if (xDicList.is())
+ xDicList->removeDictionary( xDic );
+
+ uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
+ if ( xStor->hasLocation() && !xStor->isReadonly() )
+ {
+ OUString sURL = xStor->getLocation();
+ INetURLObject aObj(sURL);
+ DBG_ASSERT( aObj.GetProtocol() == INetProtocol::File,
+ "non-file URLs cannot be deleted" );
+ if ( aObj.GetProtocol() == INetProtocol::File )
+ {
+ KillFile_Impl( aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ }
+ }
+
+ aDics.getArray()[ nDicPos ] = nullptr;
+
+ // remove entry from checklistbox
+ int nCnt = m_xLinguDicsCLB->n_children();
+ for (int i = 0; i < nCnt; ++i)
+ {
+ DicUserData aDicData(m_xLinguDicsCLB->get_id(i).toUInt32());
+ if (aDicData.GetEntryId() == nDicPos )
+ {
+ m_xLinguDicsCLB->remove(i);
+ break;
+ }
+ }
+ DBG_ASSERT( nCnt > m_xLinguDicsCLB->n_children(),
+ "remove failed ?");
+ }
+ }
+ }
+ }
+ }
+ else if (m_xLinguOptionsEditPB.get() == &rBtn)
+ {
+ int nEntry = m_xLinguOptionsCLB->get_selected_index();
+ DBG_ASSERT(nEntry != -1, "no entry selected");
+ if (nEntry != -1)
+ {
+ OptionsUserData aData(m_xLinguOptionsCLB->get_id(nEntry).toUInt32());
+ if (aData.HasNumericValue())
+ {
+ sal_uInt16 nRID = aData.GetEntryId();
+ OptionsBreakSet aDlg(GetFrameWeld(), nRID);
+ aDlg.GetNumericFld().set_value(aData.GetNumericValue());
+ if (RET_OK == aDlg.run())
+ {
+ int nVal = aDlg.GetNumericFld().get_value();
+ if (-1 != nVal && aData.GetNumericValue() != nVal)
+ {
+ aData.SetNumericValue( static_cast<sal_uInt8>(nVal) ); //! sets IsModified !
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ if (nEntry == nUPN_HYPH_MIN_WORD_LENGTH)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
+ else if (nEntry == nUPN_HYPH_MIN_LEADING)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
+ else if (nEntry == nUPN_HYPH_MIN_TRAILING)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL( "rBtn unexpected value" );
+ }
+}
+
+IMPL_LINK(SvxLinguTabPage, SelectHdl_Impl, weld::TreeView&, rBox, void)
+{
+ if (m_xLinguModulesCLB.get() == &rBox)
+ {
+ }
+ else if (m_xLinguDicsCLB.get() == &rBox)
+ {
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(rBox.get_id(nEntry).toUInt32());
+
+ // always allow to edit (i.e. at least view the content of the dictionary)
+ m_xLinguDicsEditPB->set_sensitive( true );
+ m_xLinguDicsDelPB->set_sensitive( aData.IsDeletable() );
+ }
+ }
+ else if (m_xLinguOptionsCLB.get() == &rBox)
+ {
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ OptionsUserData aData(rBox.get_id(nEntry).toUInt32());
+ m_xLinguOptionsEditPB->set_sensitive( aData.HasNumericValue() );
+ }
+ }
+ else
+ {
+ OSL_FAIL( "rBox unexpected value" );
+ }
+}
+
+void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
+{
+ if ( 0 != ( GROUP_MODULES & nGrp ) )
+ {
+ m_xLinguModulesFT->hide();
+ m_xLinguModulesCLB->hide();
+ m_xLinguModulesEditPB->hide();
+
+ if (officecfg::Office::Security::Hyperlinks::Open::get() != SvtExtendedSecurityOptions::OPEN_NEVER)
+ {
+ m_xMoreDictsLink->show();
+ }
+ }
+}
+
+IMPL_STATIC_LINK_NOARG(SvxLinguTabPage, OnLinkClick, weld::LinkButton&, bool)
+{
+ comphelper::dispatchCommand(".uno:MoreDictionaries", {});
+ return true;
+}
+
+SvxEditModulesDlg::SvxEditModulesDlg(weld::Window* pParent, SvxLinguData_Impl& rData)
+ : GenericDialogController(pParent, "cui/ui/editmodulesdialog.ui", "EditModulesDialog")
+ , sSpell(CuiResId(RID_CUISTR_SPELL))
+ , sHyph(CuiResId(RID_CUISTR_HYPH))
+ , sThes(CuiResId(RID_CUISTR_THES))
+ , sGrammar(CuiResId(RID_CUISTR_GRAMMAR))
+ , rLinguData(rData)
+ , m_xModulesCLB(m_xBuilder->weld_tree_view("lingudicts"))
+ , m_xPrioUpPB(m_xBuilder->weld_button("up"))
+ , m_xPrioDownPB(m_xBuilder->weld_button("down"))
+ , m_xBackPB(m_xBuilder->weld_button("back"))
+ , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
+ , m_xClosePB(m_xBuilder->weld_button("close"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+{
+ m_xModulesCLB->set_size_request(m_xModulesCLB->get_approximate_digit_width() * 40,
+ m_xModulesCLB->get_height_rows(12));
+
+ m_xModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ pDefaultLinguData.reset( new SvxLinguData_Impl( rLinguData ) );
+
+ m_xModulesCLB->connect_changed( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
+ m_xModulesCLB->connect_toggled(LINK(this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl));
+
+ m_xClosePB->connect_clicked( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
+ m_xPrioUpPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
+ m_xPrioDownPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
+ m_xBackPB->connect_clicked( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
+ // in case of not installed language modules
+ m_xPrioUpPB->set_sensitive( false );
+ m_xPrioDownPB->set_sensitive( false );
+
+ m_xMoreDictsLink->connect_activate_link(LINK(this, SvxEditModulesDlg, OnLinkClick));
+ if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
+ m_xMoreDictsLink->hide();
+
+ // set that we want the checkbox shown if spellchecking is available
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::EMPTY, false, false, true);
+
+ //fill language box
+ const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
+ for (Locale const & locale : rLoc)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( locale );
+ m_xLanguageLB->InsertLanguage(nLang);
+ }
+ LanguageType eSysLang = MsLangId::getConfiguredSystemLanguage();
+ m_xLanguageLB->set_active_id( eSysLang );
+ if (m_xLanguageLB->get_active_id() != eSysLang)
+ m_xLanguageLB->set_active(0);
+
+ m_xLanguageLB->connect_changed( LINK( this, SvxEditModulesDlg, LangSelectListBoxHdl_Impl ));
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+}
+
+SvxEditModulesDlg::~SvxEditModulesDlg()
+{
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ delete weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+}
+
+IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, weld::TreeView&, rBox, void )
+{
+ int nCurPos = rBox.get_selected_index();
+ if (nCurPos == -1)
+ return;
+
+ bool bDisableUp = true;
+ bool bDisableDown = true;
+ ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos));
+ if (!pData->IsParent() && pData->GetType() != TYPE_HYPH)
+ {
+ if (nCurPos < rBox.n_children() - 1)
+ {
+ bDisableDown = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos + 1))->IsParent();
+ }
+ if (nCurPos > 1)
+ {
+ bDisableUp = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos - 1))->IsParent();
+ }
+ }
+ m_xPrioUpPB->set_sensitive(!bDisableUp);
+ m_xPrioDownPB->set_sensitive(!bDisableDown);
+}
+
+IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void )
+{
+ ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(rRowCol.first));
+ if (pData->IsParent() || pData->GetType() != TYPE_HYPH)
+ return;
+
+ // make hyphenator checkboxes function as radio-buttons
+ // (at most one box may be checked)
+ auto nPos = m_xModulesCLB->get_iter_index_in_parent(rRowCol.first);
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ {
+ pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+ if (!pData->IsParent() && pData->GetType() == TYPE_HYPH && i != nPos)
+ {
+ m_xModulesCLB->set_toggle(i, TRISTATE_FALSE);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, LangSelectListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+}
+
+void SvxEditModulesDlg::LangSelectHdl_Impl(const SvxLanguageBox* pBox)
+{
+ LanguageType eCurLanguage = m_xLanguageLB->get_active_id();
+ static Locale aLastLocale;
+ Locale aCurLocale( LanguageTag::convertToLocale( eCurLanguage));
+
+ if (pBox)
+ {
+ // save old probably changed settings
+ // before switching to new language entries
+
+ LanguageType nLang = LanguageTag::convertToLanguageType( aLastLocale );
+
+ sal_Int32 nStart = 0, nLocalIndex = 0;
+ Sequence< OUString > aChange;
+ bool bChanged = false;
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ {
+ ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+ if (pData->IsParent())
+ {
+ if (bChanged)
+ {
+ LangImplNameTable *pTable = nullptr;
+ sal_uInt8 nType = pData->GetType();
+ switch (nType - 1)
+ {
+ case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
+ case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
+ case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
+ case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
+ }
+ if (pTable)
+ {
+ aChange.realloc(nStart);
+ (*pTable)[ nLang ] = aChange;
+ }
+ }
+ nLocalIndex = nStart = 0;
+ aChange.realloc(nEntryCount);
+ bChanged = false;
+ }
+ else
+ {
+ OUString* pChange = aChange.getArray();
+ pChange[nStart] = pData->GetImplName();
+ bChanged |= pData->GetIndex() != nLocalIndex ||
+ static_cast<TriState>(pData->IsChecked()) != m_xModulesCLB->get_toggle(i);
+ if (m_xModulesCLB->get_toggle(i))
+ nStart++;
+ ++nLocalIndex;
+ }
+ }
+ if(bChanged)
+ {
+ aChange.realloc(nStart);
+ rLinguData.GetThesTable()[ nLang ] = aChange;
+ }
+ }
+
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ delete weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+ m_xModulesCLB->clear();
+
+ // display entries for new selected language
+
+ if (LANGUAGE_DONTKNOW != eCurLanguage)
+ {
+ sal_Int32 n;
+ ServiceInfo_Impl* pInfo;
+
+ int nRow = 0;
+ // spellchecker entries
+
+ ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
+ OUString(), true, false, TYPE_SPELL, 0 );
+ OUString sId(weld::toId(pUserData));
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sSpell, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
+ const OUString *pName = aNames.getConstArray();
+ sal_Int32 nNames = aNames.getLength();
+ sal_Int32 nLocalIndex = 0; // index relative to parent
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xSpell.is() &&
+ pInfo->xSpell->hasLocale( aCurLocale );
+ aImplName = pInfo->sSpellImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetSpellTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_SPELL, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ // grammar checker entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR, 0 );
+ sId = weld::toId(pUserData);
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sGrammar, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xGrammar.is() &&
+ pInfo->xGrammar->hasLocale( aCurLocale );
+ aImplName = pInfo->sGrammarImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetGrammarTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_GRAMMAR, static_cast<sal_uInt8>(nLocalIndex++) );
+
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ // hyphenator entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH, 0 );
+ sId = weld::toId(pUserData);
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sHyph, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xHyph.is() &&
+ pInfo->xHyph->hasLocale( aCurLocale );
+ aImplName = pInfo->sHyphImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetHyphTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_HYPH, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ // thesaurus entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_THES, 0 );
+ sId = weld::toId(pUserData);
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sThes, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xThes.is() &&
+ pInfo->xThes->hasLocale( aCurLocale );
+ aImplName = pInfo->sThesImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetThesTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_THES, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+ }
+ aLastLocale = aCurLocale;
+}
+
+IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, weld::Button&, rBtn, void )
+{
+ bool bUp = m_xPrioUpPB.get() == &rBtn;
+ int nCurPos = m_xModulesCLB->get_selected_index();
+ if (nCurPos == -1)
+ return;
+
+ m_xModulesCLB->freeze();
+
+ OUString sId(m_xModulesCLB->get_id(nCurPos));
+ OUString sStr(m_xModulesCLB->get_text(nCurPos));
+ bool bIsChecked = m_xModulesCLB->get_toggle(nCurPos);
+
+ m_xModulesCLB->remove(nCurPos);
+
+ int nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
+
+ m_xModulesCLB->insert_text(nDestPos, sStr);
+ m_xModulesCLB->set_id(nDestPos, sId);
+ m_xModulesCLB->set_toggle(nDestPos, bIsChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ m_xModulesCLB->thaw();
+
+ m_xModulesCLB->select(nDestPos);
+ SelectHdl_Impl(*m_xModulesCLB);
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, ClickHdl_Impl, weld::Button&, void)
+{
+ // store language config
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl, weld::Button&, void)
+{
+ rLinguData = *pDefaultLinguData;
+ LangSelectHdl_Impl(nullptr);
+}
+
+IMPL_STATIC_LINK_NOARG(SvxEditModulesDlg, OnLinkClick, weld::LinkButton&, bool)
+{
+ comphelper::dispatchCommand(".uno:MoreDictionaries", {});
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optopencl.cxx b/cui/source/options/optopencl.cxx
new file mode 100644
index 000000000..e85ef1d7e
--- /dev/null
+++ b/cui/source/options/optopencl.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <opencl/openclconfig.hxx>
+#include <opencl/openclwrapper.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <svtools/restartdialog.hxx>
+
+#include "optopencl.hxx"
+
+SvxOpenCLTabPage::SvxOpenCLTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optopenclpage.ui", "OptOpenCLPage", &rSet)
+ , maConfig(OpenCLConfig::get())
+ , mxUseOpenCL(m_xBuilder->weld_check_button("useopencl"))
+ , mxOclUsed(m_xBuilder->weld_label("openclused"))
+ , mxOclNotUsed(m_xBuilder->weld_label("openclnotused"))
+{
+ mxUseOpenCL->set_active(maConfig.mbUseOpenCL);
+ mxUseOpenCL->set_sensitive(!officecfg::Office::Common::Misc::UseOpenCL::isReadOnly());
+
+ bool bCLUsed = openclwrapper::GPUEnv::isOpenCLEnabled();
+ mxOclUsed->set_visible(bCLUsed);
+ mxOclNotUsed->set_visible(!bCLUsed);
+}
+
+SvxOpenCLTabPage::~SvxOpenCLTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxOpenCLTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxOpenCLTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxOpenCLTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ if (mxUseOpenCL->get_state_changed_from_saved())
+ maConfig.mbUseOpenCL = mxUseOpenCL->get_active();
+
+ if (maConfig != OpenCLConfig::get())
+ {
+ maConfig.set();
+ bModified = true;
+ }
+
+ if (bModified)
+ {
+ batch->commit();
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_OPENCL))
+ GetDialogController()->response(RET_OK);
+ }
+
+ return bModified;
+}
+
+void SvxOpenCLTabPage::Reset( const SfxItemSet* )
+{
+ maConfig = OpenCLConfig::get();
+
+ mxUseOpenCL->set_active(maConfig.mbUseOpenCL);
+ mxUseOpenCL->save_state();
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optopencl.hxx b/cui/source/options/optopencl.hxx
new file mode 100644
index 000000000..f7097d3fd
--- /dev/null
+++ b/cui/source/options/optopencl.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <opencl/openclconfig.hxx>
+#include <sfx2/tabdlg.hxx>
+
+class SvxOpenCLTabPage : public SfxTabPage
+{
+private:
+ OpenCLConfig maConfig;
+
+ std::unique_ptr<weld::CheckButton> mxUseOpenCL;
+ std::unique_ptr<weld::Label> mxOclUsed;
+ std::unique_ptr<weld::Label> mxOclNotUsed;
+
+public:
+ SvxOpenCLTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxOpenCLTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optpath.cxx b/cui/source/options/optpath.cxx
new file mode 100644
index 000000000..18c3e32a1
--- /dev/null
+++ b/cui/source/options/optpath.cxx
@@ -0,0 +1,697 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxdlg.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/app.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/defaultoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/viewoptions.hxx>
+
+#include <bitmaps.hlst>
+#include <dialmgr.hxx>
+#include <optpath.hxx>
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <tools/diagnose_ex.h>
+#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::ui::dialogs;
+using namespace css::uno;
+using namespace svx;
+
+// define ----------------------------------------------------------------
+
+constexpr OUStringLiteral POSTFIX_INTERNAL = u"_internal";
+constexpr OUStringLiteral POSTFIX_USER = u"_user";
+constexpr OUStringLiteral POSTFIX_WRITABLE = u"_writable";
+constexpr OUStringLiteral VAR_ONE = u"%1";
+constexpr OUStringLiteral IODLG_CONFIGNAME = u"FilePicker_Save";
+
+// struct OptPath_Impl ---------------------------------------------------
+
+struct OptPath_Impl
+{
+ OUString m_sMultiPathDlg;
+ Reference< css::util::XPathSettings > m_xPathSettings;
+
+ OptPath_Impl()
+ : m_sMultiPathDlg(CuiResId(RID_CUISTR_EDIT_PATHS))
+ {
+ }
+};
+
+namespace {
+
+struct PathUserData_Impl
+{
+ SvtPathOptions::Paths nRealId;
+ bool bItemStateSet;
+ OUString sUserPath;
+ OUString sWritablePath;
+ bool bReadOnly;
+
+ explicit PathUserData_Impl(SvtPathOptions::Paths nId)
+ : nRealId(nId)
+ , bItemStateSet(false)
+ , bReadOnly(false)
+ {
+ }
+};
+
+struct Handle2CfgNameMapping_Impl
+{
+ SvtPathOptions::Paths m_nHandle;
+ const char* m_pCfgName;
+};
+
+}
+
+Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[] =
+{
+ { SvtPathOptions::Paths::AutoCorrect, "AutoCorrect" },
+ { SvtPathOptions::Paths::AutoText, "AutoText" },
+ { SvtPathOptions::Paths::Backup, "Backup" },
+ { SvtPathOptions::Paths::Gallery, "Gallery" },
+ { SvtPathOptions::Paths::Graphic, "Graphic" },
+ { SvtPathOptions::Paths::Temp, "Temp" },
+ { SvtPathOptions::Paths::Template, "Template" },
+ { SvtPathOptions::Paths::Work, "Work" },
+ { SvtPathOptions::Paths::Dictionary, "Dictionary" },
+ { SvtPathOptions::Paths::Classification, "Classification" },
+#if OSL_DEBUG_LEVEL > 1
+ { SvtPathOptions::Paths::Linguistic, "Linguistic" },
+#endif
+ { SvtPathOptions::Paths::LAST, nullptr }
+};
+
+static OUString getCfgName_Impl( SvtPathOptions::Paths _nHandle )
+{
+ OUString sCfgName;
+ sal_uInt16 nIndex = 0;
+ while ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle != SvtPathOptions::Paths::LAST )
+ {
+ if ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle == _nHandle )
+ {
+ // config name found
+ sCfgName = OUString::createFromAscii( Hdl2CfgMap_Impl[ nIndex ].m_pCfgName );
+ break;
+ }
+ ++nIndex;
+ }
+
+ return sCfgName;
+}
+
+#define MULTIPATH_DELIMITER ';'
+
+static OUString Convert_Impl( std::u16string_view rValue )
+{
+ if (rValue.empty())
+ return OUString();
+
+ sal_Int32 nPos = 0;
+ OUStringBuffer aReturn;
+ for (;;)
+ {
+ OUString aValue( o3tl::getToken(rValue, 0, MULTIPATH_DELIMITER, nPos ) );
+ INetURLObject aObj( aValue );
+ if ( aObj.GetProtocol() == INetProtocol::File )
+ aReturn.append(aObj.PathToFileName());
+ if ( nPos < 0 )
+ break;
+ aReturn.append(MULTIPATH_DELIMITER);
+ }
+
+ return aReturn.makeStringAndClear();
+}
+
+// functions -------------------------------------------------------------
+
+static bool IsMultiPath_Impl( const SvtPathOptions::Paths nIndex )
+{
+#if OSL_DEBUG_LEVEL > 1
+ return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
+ SvtPathOptions::Paths::AutoText == nIndex ||
+ SvtPathOptions::Paths::Basic == nIndex ||
+ SvtPathOptions::Paths::Gallery == nIndex ||
+ SvtPathOptions::Paths::Template == nIndex );
+#else
+ return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
+ SvtPathOptions::Paths::AutoText == nIndex ||
+ SvtPathOptions::Paths::Basic == nIndex ||
+ SvtPathOptions::Paths::Gallery == nIndex ||
+ SvtPathOptions::Paths::Template == nIndex ||
+ SvtPathOptions::Paths::Linguistic == nIndex ||
+ SvtPathOptions::Paths::Dictionary == nIndex );
+#endif
+}
+
+// class SvxPathTabPage --------------------------------------------------
+
+SvxPathTabPage::SvxPathTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optpathspage.ui", "OptPathsPage", &rSet)
+ , pImpl(new OptPath_Impl)
+ , xDialogListener ( new ::svt::DialogClosedListener() )
+ , m_xStandardBtn(m_xBuilder->weld_button("default"))
+ , m_xPathBtn(m_xBuilder->weld_button("edit"))
+ , m_xPathBox(m_xBuilder->weld_tree_view("paths"))
+{
+ m_xStandardBtn->connect_clicked(LINK(this, SvxPathTabPage, StandardHdl_Impl));
+ m_xPathBtn->connect_clicked( LINK( this, SvxPathTabPage, PathHdl_Impl ) );
+
+ m_xPathBox->set_size_request(m_xPathBox->get_approximate_digit_width() * 60,
+ m_xPathBox->get_height_rows(20));
+
+ m_xPathBox->connect_row_activated( LINK( this, SvxPathTabPage, DoubleClickPathHdl_Impl ) );
+ m_xPathBox->connect_column_clicked(LINK(this, SvxPathTabPage, HeaderBarClick));
+ m_xPathBox->connect_changed( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
+ m_xPathBox->set_selection_mode(SelectionMode::Multiple);
+
+ xDialogListener->SetDialogClosedLink( LINK( this, SvxPathTabPage, DialogClosedHdl ) );
+}
+
+IMPL_LINK(SvxPathTabPage, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = !m_xPathBox->get_sort_order();
+ m_xPathBox->set_sort_order(bSortAtoZ);
+ m_xPathBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+}
+
+SvxPathTabPage::~SvxPathTabPage()
+{
+ for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
+ delete weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(i));
+}
+
+std::unique_ptr<SfxTabPage> SvxPathTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxPathTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxPathTabPage::FillItemSet( SfxItemSet* )
+{
+ for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
+ {
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(i));
+ SvtPathOptions::Paths nRealId = pPathImpl->nRealId;
+ if (pPathImpl->bItemStateSet )
+ SetPathList( nRealId, pPathImpl->sUserPath, pPathImpl->sWritablePath );
+ }
+ return true;
+}
+
+void SvxPathTabPage::Reset( const SfxItemSet* )
+{
+ m_xPathBox->clear();
+ m_xPathBox->make_unsorted();
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xPathBox->make_iterator();
+ for( sal_uInt16 i = 0; i <= sal_uInt16(SvtPathOptions::Paths::Classification); ++i )
+ {
+ // only writer uses autotext
+ if ( static_cast<SvtPathOptions::Paths>(i) == SvtPathOptions::Paths::AutoText
+ && !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ continue;
+
+ TranslateId pId;
+
+ switch (static_cast<SvtPathOptions::Paths>(i))
+ {
+ case SvtPathOptions::Paths::AutoCorrect:
+ pId = RID_CUISTR_KEY_AUTOCORRECT_DIR;
+ break;
+ case SvtPathOptions::Paths::AutoText:
+ pId = RID_CUISTR_KEY_GLOSSARY_PATH;
+ break;
+ case SvtPathOptions::Paths::Backup:
+ pId = RID_CUISTR_KEY_BACKUP_PATH;
+ break;
+ case SvtPathOptions::Paths::Gallery:
+ pId = RID_CUISTR_KEY_GALLERY_DIR;
+ break;
+ case SvtPathOptions::Paths::Graphic:
+ pId = RID_CUISTR_KEY_GRAPHICS_PATH;
+ break;
+ case SvtPathOptions::Paths::Temp:
+ pId = RID_CUISTR_KEY_TEMP_PATH;
+ break;
+ case SvtPathOptions::Paths::Template:
+ pId = RID_CUISTR_KEY_TEMPLATE_PATH;
+ break;
+ case SvtPathOptions::Paths::Dictionary:
+ pId = RID_CUISTR_KEY_DICTIONARY_PATH;
+ break;
+ case SvtPathOptions::Paths::Classification:
+ pId = RID_CUISTR_KEY_CLASSIFICATION_PATH;
+ break;
+#if OSL_DEBUG_LEVEL > 1
+ case SvtPathOptions::Paths::Linguistic:
+ pId = RID_CUISTR_KEY_LINGUISTIC_DIR;
+ break;
+#endif
+ case SvtPathOptions::Paths::Work:
+ pId = RID_CUISTR_KEY_WORK_PATH;
+ break;
+ default: break;
+ }
+
+ if (pId)
+ {
+ m_xPathBox->append(xIter.get());
+
+ OUString aStr(CuiResId(pId));
+ m_xPathBox->set_text(*xIter, aStr, 0);
+
+ OUString sInternal, sUser, sWritable;
+ bool bReadOnly = false;
+ GetPathList( static_cast<SvtPathOptions::Paths>(i), sInternal, sUser, sWritable, bReadOnly );
+
+ if (bReadOnly)
+ m_xPathBox->set_image(*xIter, RID_SVXBMP_LOCK);
+
+ OUString sTmpPath = sUser;
+ if ( !sTmpPath.isEmpty() && !sWritable.isEmpty() )
+ sTmpPath += OUStringChar(MULTIPATH_DELIMITER);
+ sTmpPath += sWritable;
+ const OUString aValue = Convert_Impl( sTmpPath );
+
+ m_xPathBox->set_text(*xIter, aValue, 1);
+
+ const OUString aValueInternal = Convert_Impl( sInternal );
+
+ m_xPathBox->set_text(*xIter, aValueInternal, 2);
+
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 0);
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 1);
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 2);
+
+ PathUserData_Impl* pPathImpl = new PathUserData_Impl(static_cast<SvtPathOptions::Paths>(i));
+ pPathImpl->sUserPath = sUser;
+ pPathImpl->sWritablePath = sWritable;
+ pPathImpl->bReadOnly = bReadOnly;
+
+ OUString sId = weld::toId(pPathImpl);
+ m_xPathBox->set_id(*xIter, sId);
+ }
+ }
+
+ m_xPathBox->columns_autosize();
+ m_xPathBox->make_sorted();
+ PathSelect_Impl(*m_xPathBox);
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, PathSelect_Impl, weld::TreeView&, void)
+{
+ bool bEnable = false;
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry != -1)
+ {
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry));
+ bEnable = !pPathImpl->bReadOnly;
+ }
+ sal_uInt16 nSelCount = m_xPathBox->count_selected_rows();
+ m_xPathBtn->set_sensitive(1 == nSelCount && bEnable);
+ m_xStandardBtn->set_sensitive(nSelCount > 0 && bEnable);
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ m_xPathBox->selected_foreach([this](weld::TreeIter& rEntry){
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(rEntry));
+ OUString aOldPath = SvtDefaultOptions::GetDefaultPath( pPathImpl->nRealId );
+
+ if ( !aOldPath.isEmpty() )
+ {
+ OUString sInternal, sUser, sWritable, sTemp;
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+
+ sal_Int32 nOldPos = 0;
+ do
+ {
+ bool bFound = false;
+ const std::u16string_view sOnePath = o3tl::getToken(aOldPath, 0, MULTIPATH_DELIMITER, nOldPos );
+ if ( !sInternal.isEmpty() )
+ {
+ sal_Int32 nInternalPos = 0;
+ do
+ {
+ if ( o3tl::getToken(sInternal, 0, MULTIPATH_DELIMITER, nInternalPos ) == sOnePath )
+ bFound = true;
+ }
+ while ( !bFound && nInternalPos >= 0 );
+ }
+ if ( !bFound )
+ {
+ if ( !sTemp.isEmpty() )
+ sTemp += OUStringChar(MULTIPATH_DELIMITER);
+ sTemp += sOnePath;
+ }
+ }
+ while ( nOldPos >= 0 );
+
+ OUString sWritablePath;
+ OUStringBuffer sUserPath;
+ if ( !sTemp.isEmpty() )
+ {
+ sal_Int32 nNextPos = 0;
+ for (;;)
+ {
+ const OUString sToken = sTemp.getToken( 0, MULTIPATH_DELIMITER, nNextPos );
+ if ( nNextPos<0 )
+ {
+ // Last token need a different handling
+ sWritablePath = sToken;
+ break;
+ }
+ if ( !sUserPath.isEmpty() )
+ sUserPath.append(MULTIPATH_DELIMITER);
+ sUserPath.append(sToken);
+ }
+ }
+ m_xPathBox->set_text(rEntry, Convert_Impl(sTemp), 1);
+ pPathImpl->bItemStateSet = true;
+ pPathImpl->sUserPath = sUserPath.makeStringAndClear();
+ pPathImpl->sWritablePath = sWritablePath;
+ }
+ return false;
+ });
+}
+
+void SvxPathTabPage::ChangeCurrentEntry( const OUString& _rFolder )
+{
+ int nEntry = m_xPathBox->get_cursor_index();
+ if (nEntry == -1)
+ {
+ SAL_WARN( "cui.options", "SvxPathTabPage::ChangeCurrentEntry(): no entry" );
+ return;
+ }
+
+ OUString sInternal, sUser, sWritable;
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry));
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+ sUser = pPathImpl->sUserPath;
+ sWritable = pPathImpl->sWritablePath;
+
+ // old path is a URL?
+ INetURLObject aObj( sWritable );
+ bool bURL = ( aObj.GetProtocol() != INetProtocol::NotValid );
+ INetURLObject aNewObj( _rFolder );
+ aNewObj.removeFinalSlash();
+
+ // then the new path also a URL else system path
+ OUString sNewPathStr = bURL ? _rFolder : aNewObj.getFSysPath( FSysStyle::Detect );
+
+ bool bChanged =
+#ifdef UNX
+// Unix is case sensitive
+ ( sNewPathStr != sWritable );
+#else
+ !sNewPathStr.equalsIgnoreAsciiCase( sWritable );
+#endif
+
+ if ( !bChanged )
+ return;
+
+ m_xPathBox->set_text(nEntry, Convert_Impl(sNewPathStr), 1);
+ pPathImpl->bItemStateSet = true;
+ pPathImpl->sWritablePath = sNewPathStr;
+ if ( SvtPathOptions::Paths::Work == pPathImpl->nRealId )
+ {
+ // Remove view options entry so the new work path
+ // will be used for the next open dialog.
+ SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
+ aDlgOpt.Delete();
+ // Reset also last used dir in the sfx application instance
+ SfxApplication *pSfxApp = SfxGetpApp();
+ pSfxApp->ResetLastDir();
+ }
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, DoubleClickPathHdl_Impl, weld::TreeView&, bool)
+{
+ PathHdl_Impl(*m_xPathBtn);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, PathHdl_Impl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_cursor_index();
+ PathUserData_Impl* pPathImpl = nEntry != -1 ? weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry)) : nullptr;
+ if (!pPathImpl || pPathImpl->bReadOnly)
+ return;
+
+ SvtPathOptions::Paths nPos = pPathImpl->nRealId;
+ OUString sInternal, sUser, sWritable;
+ bool bPickFile = false;
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+ sUser = pPathImpl->sUserPath;
+ sWritable = pPathImpl->sWritablePath;
+ bPickFile = pPathImpl->nRealId == SvtPathOptions::Paths::Classification;
+
+ if (IsMultiPath_Impl(nPos))
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxMultiPathDialog> pMultiDlg(
+ pFact->CreateSvxMultiPathDialog(GetFrameWeld()));
+
+ OUString sPath( sUser );
+ if ( !sPath.isEmpty() )
+ sPath += OUStringChar(MULTIPATH_DELIMITER);
+ sPath += sWritable;
+ pMultiDlg->SetPath( sPath );
+
+ const OUString sPathName = m_xPathBox->get_text(nEntry, 0);
+ const OUString sNewTitle = pImpl->m_sMultiPathDlg.replaceFirst( VAR_ONE, sPathName );
+ pMultiDlg->SetTitle( sNewTitle );
+
+ if (pMultiDlg->Execute() == RET_OK)
+ {
+ sUser.clear();
+ sWritable.clear();
+ OUString sFullPath;
+ OUString sNewPath = pMultiDlg->GetPath();
+ if ( !sNewPath.isEmpty() )
+ {
+ sal_Int32 nNextPos = 0;
+ for (;;)
+ {
+ const OUString sToken(sNewPath.getToken( 0, MULTIPATH_DELIMITER, nNextPos ));
+ if ( nNextPos<0 )
+ {
+ // Last token need a different handling
+ sWritable = sToken;
+ break;
+ }
+ if ( !sUser.isEmpty() )
+ sUser += OUStringChar(MULTIPATH_DELIMITER);
+ sUser += sToken;
+ }
+ sFullPath = sUser;
+ if ( !sFullPath.isEmpty() )
+ sFullPath += OUStringChar(MULTIPATH_DELIMITER);
+ sFullPath += sWritable;
+ }
+
+ m_xPathBox->set_text(nEntry, Convert_Impl(sFullPath), 1);
+ // save modified flag
+ pPathImpl->bItemStateSet = true;
+ pPathImpl->sUserPath = sUser;
+ pPathImpl->sWritablePath = sWritable;
+ }
+ }
+ else if (!bPickFile)
+ {
+ try
+ {
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ INetURLObject aURL( sWritable, INetProtocol::File );
+ xFolderPicker->setDisplayDirectory( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else
+ {
+ short nRet = xFolderPicker->execute();
+ if (ExecutableDialogResults::OK != nRet)
+ return;
+
+ OUString sFolder(xFolderPicker->getDirectory());
+ ChangeCurrentEntry(sFolder);
+ }
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::PathHdl_Impl: exception from folder picker" );
+ }
+ }
+ else
+ {
+ try
+ {
+ sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = aHelper.GetFilePicker();
+ xFilePicker->appendFilter(OUString(), "*.xml");
+ if (xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ uno::Sequence<OUString> aPathSeq(xFilePicker->getSelectedFiles());
+ ChangeCurrentEntry(aPathSeq[0]);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.options", "exception from file picker");
+ }
+ }
+}
+
+IMPL_LINK( SvxPathTabPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
+{
+ if (RET_OK == pEvt->DialogResult)
+ {
+ assert(xFolderPicker.is() && "SvxPathTabPage::DialogClosedHdl(): no folder picker");
+ OUString sURL = xFolderPicker->getDirectory();
+ ChangeCurrentEntry( sURL );
+ }
+}
+
+void SvxPathTabPage::GetPathList(
+ SvtPathOptions::Paths _nPathHandle, OUString& _rInternalPath,
+ OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly )
+{
+ OUString sCfgName = getCfgName_Impl( _nPathHandle );
+
+ try
+ {
+ // load PathSettings service if necessary
+ if ( !pImpl->m_xPathSettings.is() )
+ {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
+ }
+
+ // load internal paths
+ Any aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_INTERNAL);
+ Sequence< OUString > aPathSeq;
+ if ( aAny >>= aPathSeq )
+ {
+ tools::Long i, nCount = aPathSeq.getLength();
+ const OUString* pPaths = aPathSeq.getConstArray();
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !_rInternalPath.isEmpty() )
+ _rInternalPath += ";";
+ _rInternalPath += pPaths[i];
+ }
+ }
+ // load user paths
+ aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_USER);
+ if ( aAny >>= aPathSeq )
+ {
+ tools::Long i, nCount = aPathSeq.getLength();
+ const OUString* pPaths = aPathSeq.getConstArray();
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !_rUserPath.isEmpty() )
+ _rUserPath += ";";
+ _rUserPath += pPaths[i];
+ }
+ }
+ // then the writable path
+ aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_WRITABLE);
+ OUString sWritablePath;
+ if ( aAny >>= sWritablePath )
+ _rWritablePath = sWritablePath;
+
+ // and the readonly flag
+ Reference< XPropertySetInfo > xInfo = pImpl->m_xPathSettings->getPropertySetInfo();
+ Property aProp = xInfo->getPropertyByName(sCfgName);
+ _rReadOnly = ( ( aProp.Attributes & PropertyAttribute::READONLY ) == PropertyAttribute::READONLY );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::GetPathList()" );
+ }
+}
+
+
+void SvxPathTabPage::SetPathList(
+ SvtPathOptions::Paths _nPathHandle, std::u16string_view _rUserPath, const OUString& _rWritablePath )
+{
+ OUString sCfgName = getCfgName_Impl( _nPathHandle );
+
+ try
+ {
+ // load PathSettings service if necessary
+ if ( !pImpl->m_xPathSettings.is() )
+ {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
+ }
+
+ // save user paths
+ const sal_Int32 nCount = comphelper::string::getTokenCount(_rUserPath, MULTIPATH_DELIMITER);
+ Sequence< OUString > aPathSeq( nCount );
+ OUString* pArray = aPathSeq.getArray();
+ sal_Int32 nPos = 0;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ pArray[i] = o3tl::getToken(_rUserPath, 0, MULTIPATH_DELIMITER, nPos );
+ Any aValue( aPathSeq );
+ pImpl->m_xPathSettings->setPropertyValue(
+ sCfgName + POSTFIX_USER, aValue);
+
+ // then the writable path
+ aValue <<= _rWritablePath;
+ pImpl->m_xPathSettings->setPropertyValue(
+ sCfgName + POSTFIX_WRITABLE, aValue);
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optsave.cxx b/cui/source/options/optsave.cxx
new file mode 100644
index 000000000..43468715c
--- /dev/null
+++ b/cui/source/options/optsave.cxx
@@ -0,0 +1,635 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <o3tl/string_view.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include "optsave.hxx"
+#include <treeopt.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/saveopt.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/docfilt.hxx>
+#include <svtools/restartdialog.hxx>
+#include <unotools/optionsdlg.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <officecfg/Office/Recovery.hxx>
+
+#include <sfx2/fcontnr.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace comphelper;
+
+#define CFG_PAGE_AND_GROUP u"General", u"LoadSave"
+
+
+struct SvxSaveTabPage_Impl
+{
+ Reference< XNameContainer > xFact;
+ std::vector< OUString > aFilterArr[APP_COUNT];
+ std::vector< bool > aODFArr[APP_COUNT];
+ std::vector< OUString > aUIFilterArr[APP_COUNT];
+ OUString aDefaultArr[APP_COUNT];
+ bool aDefaultReadonlyArr[APP_COUNT];
+ bool bInitialized;
+
+ SvxSaveTabPage_Impl();
+};
+
+SvxSaveTabPage_Impl::SvxSaveTabPage_Impl() : bInitialized( false )
+{
+}
+
+// class SvxSaveTabPage --------------------------------------------------
+
+SvxSaveTabPage::SvxSaveTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optsavepage.ui", "OptSavePage", &rCoreSet )
+ , pImpl(new SvxSaveTabPage_Impl)
+ , m_xLoadUserSettingsCB(m_xBuilder->weld_check_button("load_settings"))
+ , m_xLoadDocPrinterCB(m_xBuilder->weld_check_button("load_docprinter"))
+ , m_xDocInfoCB(m_xBuilder->weld_check_button("docinfo"))
+ , m_xBackupCB(m_xBuilder->weld_check_button("backup"))
+ , m_xAutoSaveCB(m_xBuilder->weld_check_button("autosave"))
+ , m_xAutoSaveEdit(m_xBuilder->weld_spin_button("autosave_spin"))
+ , m_xMinuteFT(m_xBuilder->weld_label("autosave_mins"))
+ , m_xUserAutoSaveCB(m_xBuilder->weld_check_button("userautosave"))
+ , m_xRelativeFsysCB(m_xBuilder->weld_check_button("relative_fsys"))
+ , m_xRelativeInetCB(m_xBuilder->weld_check_button("relative_inet"))
+ , m_xODFVersionLB(m_xBuilder->weld_combo_box("odfversion"))
+ , m_xWarnAlienFormatCB(m_xBuilder->weld_check_button("warnalienformat"))
+ , m_xDocTypeLB(m_xBuilder->weld_combo_box("doctype"))
+ , m_xSaveAsFT(m_xBuilder->weld_label("saveas_label"))
+ , m_xSaveAsLB(m_xBuilder->weld_combo_box("saveas"))
+ , m_xODFWarningFI(m_xBuilder->weld_widget("odfwarning_image"))
+ , m_xODFWarningFT(m_xBuilder->weld_label("odfwarning_label"))
+{
+ m_xAutoSaveEdit->set_max_length(2);
+
+ m_xODFVersionLB->set_id(0, OUString::number(SvtSaveOptions::ODFVER_011)); // 1.0/1.1
+ m_xODFVersionLB->set_id(1, OUString::number(SvtSaveOptions::ODFVER_012)); // 1.2
+ m_xODFVersionLB->set_id(2, OUString::number(SvtSaveOptions::ODFVER_012_EXT_COMPAT)); // 1.2 Extended (compatibility mode)
+ m_xODFVersionLB->set_id(3, OUString::number(SvtSaveOptions::ODFVER_012_EXTENDED)); // 1.2 Extended
+ m_xODFVersionLB->set_id(4, OUString::number(SvtSaveOptions::ODFVER_013)); // 1.3
+ m_xODFVersionLB->set_id(5, OUString::number(SvtSaveOptions::ODFVER_LATEST)); // 1.3 Extended (recommended)
+
+ m_xDocTypeLB->set_id(0, OUString::number(APP_WRITER) );
+ m_xDocTypeLB->set_id(1, OUString::number(APP_WRITER_WEB) );
+ m_xDocTypeLB->set_id(2, OUString::number(APP_WRITER_GLOBAL));
+ m_xDocTypeLB->set_id(3, OUString::number(APP_CALC) );
+ m_xDocTypeLB->set_id(4, OUString::number(APP_IMPRESS) );
+ m_xDocTypeLB->set_id(5, OUString::number(APP_DRAW) );
+ m_xDocTypeLB->set_id(6, OUString::number(APP_MATH) );
+
+ m_xAutoSaveCB->connect_toggled( LINK( this, SvxSaveTabPage, AutoClickHdl_Impl ) );
+
+ SvtModuleOptions aModuleOpt;
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_MATH));
+ m_xDocTypeLB->remove_id(OUString::number(APP_MATH));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_MATH] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH);
+ pImpl->aDefaultReadonlyArr[APP_MATH] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::MATH);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_DRAW));
+ m_xDocTypeLB->remove_id(OUString::number(APP_DRAW));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_DRAW] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW);
+ pImpl->aDefaultReadonlyArr[APP_DRAW] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::DRAW);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_IMPRESS));
+ m_xDocTypeLB->remove_id(OUString::number(APP_IMPRESS));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_IMPRESS] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS);
+ pImpl->aDefaultReadonlyArr[APP_IMPRESS] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::IMPRESS);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_CALC));
+ m_xDocTypeLB->remove_id(OUString::number(APP_CALC));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_CALC] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC);
+ pImpl->aDefaultReadonlyArr[APP_CALC] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::CALC);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER));
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER_WEB));
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER_GLOBAL));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER_WEB));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER_GLOBAL));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_WRITER] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER);
+ pImpl->aDefaultArr[APP_WRITER_WEB] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB);
+ pImpl->aDefaultArr[APP_WRITER_GLOBAL] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL);
+ pImpl->aDefaultReadonlyArr[APP_WRITER] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITER);
+ pImpl->aDefaultReadonlyArr[APP_WRITER_WEB] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITERWEB);
+ pImpl->aDefaultReadonlyArr[APP_WRITER_GLOBAL] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITERGLOBAL);
+ }
+
+ Link<weld::ComboBox&,void> aLink = LINK( this, SvxSaveTabPage, ODFVersionHdl_Impl );
+ m_xODFVersionLB->connect_changed( aLink );
+ aLink = LINK( this, SvxSaveTabPage, FilterHdl_Impl );
+ m_xDocTypeLB->connect_changed( aLink );
+ m_xSaveAsLB->connect_changed( aLink );
+
+ DetectHiddenControls();
+}
+
+SvxSaveTabPage::~SvxSaveTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxSaveTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSaveTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxSaveTabPage::DetectHiddenControls()
+{
+ SvtOptionsDialogOptions aOptionsDlgOpt;
+
+ if ( aOptionsDlgOpt.IsOptionHidden( u"Backup", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "Backup"
+ m_xBackupCB->hide();
+ }
+
+ if ( aOptionsDlgOpt.IsOptionHidden( u"AutoSave", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "AutoSave"
+ m_xAutoSaveCB->hide();
+ m_xAutoSaveEdit->hide();
+ m_xMinuteFT->hide();
+ }
+
+ if ( aOptionsDlgOpt.IsOptionHidden( u"UserAutoSave", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "UserAutoSave"
+ m_xUserAutoSaveCB->hide();
+ }
+
+}
+
+bool SvxSaveTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ bool bModified = false, bRequestRestart = false;
+ if(m_xLoadUserSettingsCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Load::UserDefinedSettings::set(m_xLoadUserSettingsCB->get_active(), xChanges);
+
+ if ( m_xLoadDocPrinterCB->get_state_changed_from_saved() )
+ officecfg::Office::Common::Save::Document::LoadPrinter::set(m_xLoadDocPrinterCB->get_active(), xChanges);
+
+ if ( m_xODFVersionLB->get_value_changed_from_saved() )
+ {
+ sal_Int32 nVersion = m_xODFVersionLB->get_active_id().toInt32();
+ SetODFDefaultVersion( SvtSaveOptions::ODFDefaultVersion( nVersion ), xChanges );
+ }
+
+ if ( m_xDocInfoCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_DOCINFO,
+ m_xDocInfoCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xBackupCB->get_sensitive() && m_xBackupCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_BACKUP, m_xBackupCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xAutoSaveCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_AUTOSAVE,
+ m_xAutoSaveCB->get_active() ) );
+ bModified = bRequestRestart = true;
+ }
+ if ( m_xWarnAlienFormatCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_WARNALIENFORMAT,
+ m_xWarnAlienFormatCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xAutoSaveEdit->get_value_changed_from_saved() )
+ {
+ rSet->Put( SfxUInt16Item( SID_ATTR_AUTOSAVEMINUTE,
+ static_cast<sal_uInt16>(m_xAutoSaveEdit->get_value()) ) );
+ bModified = bRequestRestart = true;
+ }
+
+ if ( m_xUserAutoSaveCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_USERAUTOSAVE,
+ m_xUserAutoSaveCB->get_active() ) );
+ bModified = true;
+ }
+ // save relatively
+ if ( m_xRelativeFsysCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_SAVEREL_FSYS,
+ m_xRelativeFsysCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xRelativeInetCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_SAVEREL_INET,
+ m_xRelativeInetCB->get_active() ) );
+ bModified = true;
+ }
+
+ SvtModuleOptions aModuleOpt;
+ if(!pImpl->aDefaultArr[APP_MATH].isEmpty() &&
+ pImpl->aDefaultArr[APP_MATH] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH, pImpl->aDefaultArr[APP_MATH]);
+
+ if( !pImpl->aDefaultArr[APP_DRAW].isEmpty() &&
+ pImpl->aDefaultArr[APP_DRAW] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW, pImpl->aDefaultArr[APP_DRAW]);
+
+ if(!pImpl->aDefaultArr[APP_IMPRESS].isEmpty() &&
+ pImpl->aDefaultArr[APP_IMPRESS] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS, pImpl->aDefaultArr[APP_IMPRESS]);
+
+ if(!pImpl->aDefaultArr[APP_CALC].isEmpty() &&
+ pImpl->aDefaultArr[APP_CALC] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC, pImpl->aDefaultArr[APP_CALC]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER, pImpl->aDefaultArr[APP_WRITER]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER_WEB].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER_WEB] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB, pImpl->aDefaultArr[APP_WRITER_WEB]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER_GLOBAL].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER_GLOBAL] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL, pImpl->aDefaultArr[APP_WRITER_GLOBAL]);
+
+ xChanges->commit();
+
+ if (bRequestRestart)
+ {
+ OfaTreeOptionsDialog* pParentDlg(static_cast<OfaTreeOptionsDialog*>(GetDialogController()));
+ if (pParentDlg)
+ pParentDlg->SetNeedsRestart(svtools::RESTART_REASON_SAVE);
+ }
+
+ return bModified;
+}
+
+static bool isODFFormat( std::u16string_view sFilter )
+{
+ static const char* aODFFormats[] =
+ {
+ "writer8",
+ "writer8_template",
+ "writerglobal8",
+ "writerglobal8_writer",
+ "calc8",
+ "calc8_template",
+ "draw8",
+ "draw8_template",
+ "impress8",
+ "impress8_template",
+ "impress8_draw",
+ "chart8",
+ "math8",
+ nullptr
+ };
+
+ bool bRet = false;
+ int i = 0;
+ while ( aODFFormats[i] != nullptr )
+ {
+ if ( o3tl::equalsAscii( sFilter, aODFFormats[i++] ) )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+void SvxSaveTabPage::Reset( const SfxItemSet* )
+{
+ m_xLoadUserSettingsCB->set_active(officecfg::Office::Common::Load::UserDefinedSettings::get());
+ m_xLoadUserSettingsCB->save_state();
+ m_xLoadUserSettingsCB->set_sensitive(!officecfg::Office::Common::Load::UserDefinedSettings::isReadOnly());
+ m_xLoadDocPrinterCB->set_active( officecfg::Office::Common::Save::Document::LoadPrinter::get() );
+ m_xLoadDocPrinterCB->save_state();
+ m_xLoadDocPrinterCB->set_sensitive(!officecfg::Office::Common::Save::Document::LoadPrinter::isReadOnly());
+
+ if ( !pImpl->bInitialized )
+ {
+ try
+ {
+ Reference< XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
+ pImpl->xFact.set(xMSF->createInstance("com.sun.star.document.FilterFactory"), UNO_QUERY);
+
+ DBG_ASSERT(pImpl->xFact.is(), "service com.sun.star.document.FilterFactory unavailable");
+ Reference< XContainerQuery > xQuery(pImpl->xFact, UNO_QUERY);
+ if(xQuery.is())
+ {
+ for (sal_Int32 n = 0, nEntryCount = m_xDocTypeLB->get_count(); n < nEntryCount; ++n)
+ {
+ unsigned int nData = m_xDocTypeLB->get_id(n).toUInt32();
+ OUString sCommand = "getSortedFilterList():module=%1:iflags=" +
+ OUString::number(static_cast<int>(SfxFilterFlags::IMPORT|SfxFilterFlags::EXPORT)) +
+ ":eflags=" +
+ OUString::number(static_cast<int>(SfxFilterFlags::NOTINFILEDLG));
+ OUString sReplace;
+ switch(nData)
+ {
+ case APP_WRITER : sReplace = "com.sun.star.text.TextDocument"; break;
+ case APP_WRITER_WEB : sReplace = "com.sun.star.text.WebDocument"; break;
+ case APP_WRITER_GLOBAL : sReplace = "com.sun.star.text.GlobalDocument"; break;
+ case APP_CALC : sReplace = "com.sun.star.sheet.SpreadsheetDocument";break;
+ case APP_IMPRESS : sReplace = "com.sun.star.presentation.PresentationDocument";break;
+ case APP_DRAW : sReplace = "com.sun.star.drawing.DrawingDocument";break;
+ case APP_MATH : sReplace = "com.sun.star.formula.FormulaProperties";break;
+ default: OSL_FAIL("illegal user data");
+ }
+ sCommand = sCommand.replaceFirst("%1", sReplace);
+ Reference< XEnumeration > xList = xQuery->createSubSetEnumerationByQuery(sCommand);
+ std::vector< OUString > lList;
+ std::vector<bool> lODFList;
+ while(xList->hasMoreElements())
+ {
+ SequenceAsHashMap aFilter(xList->nextElement());
+ OUString sFilter = aFilter.getUnpackedValueOrDefault("Name",OUString());
+ if (!sFilter.isEmpty())
+ {
+ lList.push_back(sFilter);
+ lODFList.push_back( isODFFormat( sFilter ) );
+ }
+ }
+ pImpl->aFilterArr[nData] = lList;
+ pImpl->aODFArr[nData] = lODFList;
+ }
+ }
+ m_xDocTypeLB->set_active(0);
+ FilterHdl_Impl(*m_xDocTypeLB);
+ }
+ catch(Exception const &)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "exception in FilterFactory access" );
+ }
+
+ pImpl->bInitialized = true;
+ }
+
+ m_xDocInfoCB->set_active(officecfg::Office::Common::Save::Document::EditProperty::get());
+ m_xDocInfoCB->set_sensitive(!officecfg::Office::Common::Save::Document::EditProperty::isReadOnly());
+
+ m_xBackupCB->set_active(officecfg::Office::Common::Save::Document::CreateBackup::get());
+ m_xBackupCB->set_sensitive(!officecfg::Office::Common::Save::Document::CreateBackup::isReadOnly());
+
+ m_xAutoSaveCB->set_active(officecfg::Office::Common::Save::Document::AutoSave::get());
+ m_xAutoSaveCB->set_sensitive(!officecfg::Office::Common::Save::Document::AutoSave::isReadOnly());
+
+ m_xUserAutoSaveCB->set_active(officecfg::Office::Recovery::AutoSave::UserAutoSaveEnabled::get());
+ m_xUserAutoSaveCB->set_sensitive(!officecfg::Office::Recovery::AutoSave::UserAutoSaveEnabled::isReadOnly());
+
+ m_xWarnAlienFormatCB->set_active(officecfg::Office::Common::Save::Document::WarnAlienFormat::get());
+ m_xWarnAlienFormatCB->set_sensitive(!officecfg::Office::Common::Save::Document::WarnAlienFormat::isReadOnly());
+
+ m_xAutoSaveEdit->set_value(officecfg::Office::Common::Save::Document::AutoSaveTimeIntervall::get());
+ m_xAutoSaveEdit->set_sensitive(!officecfg::Office::Common::Save::Document::AutoSaveTimeIntervall::isReadOnly());
+
+ // save relatively
+ m_xRelativeFsysCB->set_active(officecfg::Office::Common::Save::URL::FileSystem::get());
+ m_xRelativeFsysCB->set_sensitive(!officecfg::Office::Common::Save::URL::FileSystem::isReadOnly());
+
+ m_xRelativeInetCB->set_active(officecfg::Office::Common::Save::URL::Internet::get());
+ m_xRelativeInetCB->set_sensitive(!officecfg::Office::Common::Save::URL::Internet::isReadOnly());
+
+ sal_Int32 nDefaultVersion = GetODFDefaultVersion();
+ m_xODFVersionLB->set_active_id(OUString::number(nDefaultVersion));
+ m_xODFVersionLB->set_sensitive(!officecfg::Office::Common::Save::ODF::DefaultVersion::isReadOnly());
+
+ AutoClickHdl_Impl(*m_xAutoSaveCB);
+ ODFVersionHdl_Impl(*m_xODFVersionLB);
+
+ m_xDocInfoCB->save_state();
+ m_xBackupCB->save_state();
+ m_xWarnAlienFormatCB->save_state();
+ m_xAutoSaveCB->save_state();
+ m_xAutoSaveEdit->save_value();
+
+ m_xUserAutoSaveCB->save_state();
+
+ m_xRelativeFsysCB->save_state();
+ m_xRelativeInetCB->save_state();
+ m_xODFVersionLB->save_value();
+}
+
+IMPL_LINK(SvxSaveTabPage, AutoClickHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (&rBox != m_xAutoSaveCB.get())
+ return;
+
+ if (m_xAutoSaveCB->get_active())
+ {
+ m_xAutoSaveEdit->set_sensitive(true);
+ m_xMinuteFT->set_sensitive(true);
+ m_xUserAutoSaveCB->set_sensitive(true);
+ }
+ else
+ {
+ m_xAutoSaveEdit->set_sensitive(false);
+ m_xMinuteFT->set_sensitive(false);
+ m_xUserAutoSaveCB->set_sensitive(false);
+ }
+}
+
+static OUString lcl_ExtracUIName(const Sequence<PropertyValue> &rProperties, std::u16string_view rExtension)
+{
+ OUString sName;
+ const PropertyValue* pPropVal = rProperties.getConstArray();
+ const PropertyValue* const pEnd = pPropVal + rProperties.getLength();
+ for( ; pPropVal != pEnd; pPropVal++ )
+ {
+ const OUString &rName = pPropVal->Name;
+ if (rName == "UIName")
+ {
+ OUString sUIName;
+ if ( ( pPropVal->Value >>= sUIName ) && sUIName.getLength() )
+ {
+ if (!rExtension.empty())
+ {
+ return sUIName + " (" + rExtension + ")";
+ }
+ else
+ {
+ return sUIName;
+ }
+ }
+ }
+ else if (rName == "Name")
+ {
+ pPropVal->Value >>= sName;
+ }
+ }
+
+ OSL_ENSURE( false, "Filter without UIName!" );
+
+ return sName;
+}
+
+IMPL_LINK( SvxSaveTabPage, FilterHdl_Impl, weld::ComboBox&, rBox, void )
+{
+ const int nCurPos = m_xDocTypeLB->get_active();
+
+ int nData = -1;
+ if (nCurPos < APP_COUNT)
+ nData = m_xDocTypeLB->get_id(nCurPos).toInt32();
+
+ if ( nData >= 0 && nData < APP_COUNT )
+ {
+ if(m_xDocTypeLB.get() == &rBox)
+ {
+ m_xSaveAsLB->clear();
+ auto & rFilters = pImpl->aFilterArr[nData];
+ if(pImpl->aUIFilterArr[nData].empty())
+ {
+ pImpl->aUIFilterArr[nData].resize(pImpl->aFilterArr[nData].size());
+ auto & rUIFilters = pImpl->aUIFilterArr[nData];
+ for(size_t nFilter = 0; nFilter < pImpl->aFilterArr[nData].size(); nFilter++)
+ {
+ Any aProps = pImpl->xFact->getByName(rFilters[nFilter]);
+ // get the extension of the filter
+ OUString extension;
+ SfxFilterMatcher matcher;
+ std::shared_ptr<const SfxFilter> pFilter = matcher.GetFilter4FilterName(rFilters[nFilter]);
+ if (pFilter)
+ {
+ extension = pFilter->GetWildcard().getGlob().getToken(0, ';');
+ }
+ Sequence<PropertyValue> aProperties;
+ aProps >>= aProperties;
+ rUIFilters[nFilter] = lcl_ExtracUIName(aProperties, extension);
+ }
+ }
+ auto const & rUIFilters = pImpl->aUIFilterArr[nData];
+ OUString sSelect;
+ for(size_t i = 0; i < pImpl->aUIFilterArr[nData].size(); i++)
+ {
+ OUString sId;
+ if (pImpl->aODFArr[nData][i])
+ sId = weld::toId(pImpl.get());
+ m_xSaveAsLB->append(sId, rUIFilters[i]);
+ if (rFilters[i] == pImpl->aDefaultArr[nData])
+ sSelect = rUIFilters[i];
+ }
+ if (!sSelect.isEmpty())
+ {
+ m_xSaveAsLB->set_active_text(sSelect);
+ }
+
+ m_xSaveAsFT->set_sensitive(!pImpl->aDefaultReadonlyArr[nData]);
+ m_xSaveAsLB->set_sensitive(!pImpl->aDefaultReadonlyArr[nData]);
+ }
+ else
+ {
+ OUString sSelect = rBox.get_active_text();
+ auto const & rFilters = pImpl->aFilterArr[nData];
+ auto const & rUIFilters = pImpl->aUIFilterArr[nData];
+ for(size_t i = 0; i < pImpl->aUIFilterArr[nData].size(); i++)
+ if(rUIFilters[i] == sSelect)
+ {
+ sSelect = rFilters[i];
+ break;
+ }
+
+ pImpl->aDefaultArr[nData] = sSelect;
+ }
+ }
+
+ ODFVersionHdl_Impl( *m_xSaveAsLB );
+}
+
+IMPL_LINK_NOARG(SvxSaveTabPage, ODFVersionHdl_Impl, weld::ComboBox&, void)
+{
+ sal_Int32 nVersion = m_xODFVersionLB->get_active_id().toInt32();
+ bool bShown = SvtSaveOptions::ODFDefaultVersion(nVersion) != SvtSaveOptions::ODFVER_LATEST;
+ if ( bShown )
+ {
+ bool bHasODFFormat = false;
+ const int nCount = m_xSaveAsLB->get_count();
+ for (int i = 0; i < nCount; ++i )
+ {
+ if ( m_xSaveAsLB->get_id(i).toInt64() != 0 )
+ {
+ bHasODFFormat = true;
+ break;
+ }
+ }
+
+ bShown = !bHasODFFormat
+ || ( m_xSaveAsLB->get_active_id().toInt64() != 0);
+ }
+
+ m_xODFWarningFI->set_visible(bShown);
+ m_xODFWarningFT->set_visible(bShown);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optsave.hxx b/cui/source/options/optsave.hxx
new file mode 100644
index 000000000..4ec3b1dda
--- /dev/null
+++ b/cui/source/options/optsave.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+#define APP_WRITER 0
+#define APP_WRITER_WEB 1
+#define APP_WRITER_GLOBAL 2
+#define APP_CALC 3
+#define APP_IMPRESS 4
+#define APP_DRAW 5
+#define APP_MATH 6
+#define APP_COUNT 7
+
+namespace com::sun::star::beans { struct PropertyValue; }
+
+// class SvxSaveTabPage --------------------------------------------------
+
+struct SvxSaveTabPage_Impl;
+
+class SvxSaveTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvxSaveTabPage_Impl> pImpl;
+
+ std::unique_ptr<weld::CheckButton> m_xLoadUserSettingsCB;
+ std::unique_ptr<weld::CheckButton> m_xLoadDocPrinterCB;
+ std::unique_ptr<weld::CheckButton> m_xDocInfoCB;
+ std::unique_ptr<weld::CheckButton> m_xBackupCB;
+ std::unique_ptr<weld::CheckButton> m_xAutoSaveCB;
+ std::unique_ptr<weld::SpinButton> m_xAutoSaveEdit;
+ std::unique_ptr<weld::Label> m_xMinuteFT;
+ std::unique_ptr<weld::CheckButton> m_xUserAutoSaveCB;
+ std::unique_ptr<weld::CheckButton> m_xRelativeFsysCB;
+ std::unique_ptr<weld::CheckButton> m_xRelativeInetCB;
+ std::unique_ptr<weld::ComboBox> m_xODFVersionLB;
+ std::unique_ptr<weld::CheckButton> m_xWarnAlienFormatCB;
+ std::unique_ptr<weld::ComboBox> m_xDocTypeLB;
+ std::unique_ptr<weld::Label> m_xSaveAsFT;
+ std::unique_ptr<weld::ComboBox> m_xSaveAsLB;
+ std::unique_ptr<weld::Widget> m_xODFWarningFI;
+ std::unique_ptr<weld::Label> m_xODFWarningFT;
+
+ DECL_LINK( AutoClickHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK( FilterHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK(ODFVersionHdl_Impl, weld::ComboBox&, void );
+
+ void DetectHiddenControls();
+
+public:
+ SvxSaveTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxSaveTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optupdt.cxx b/cui/source/options/optupdt.cxx
new file mode 100644
index 000000000..754fb5fdc
--- /dev/null
+++ b/cui/source/options/optupdt.cxx
@@ -0,0 +1,405 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include "optupdt.hxx"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/deployment/UpdateInformationProvider.hpp>
+#include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/setup/UpdateCheckConfig.hpp>
+#include <com/sun/star/configuration/ReadWriteAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <sfx2/filedlghelper.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+
+using namespace ::css;
+
+SvxOnlineUpdateTabPage::SvxOnlineUpdateTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optonlineupdatepage.ui", "OptOnlineUpdatePage", &rSet)
+ , m_xNeverChecked(m_xBuilder->weld_label("neverchecked"))
+ , m_xAutoCheckCheckBox(m_xBuilder->weld_check_button("autocheck"))
+ , m_xEveryDayButton(m_xBuilder->weld_radio_button("everyday"))
+ , m_xEveryWeekButton(m_xBuilder->weld_radio_button("everyweek"))
+ , m_xEveryMonthButton(m_xBuilder->weld_radio_button("everymonth"))
+ , m_xCheckNowButton(m_xBuilder->weld_button("checknow"))
+ , m_xAutoDownloadCheckBox(m_xBuilder->weld_check_button("autodownload"))
+ , m_xDestPathLabel(m_xBuilder->weld_label("destpathlabel"))
+ , m_xDestPath(m_xBuilder->weld_label("destpath"))
+ , m_xChangePathButton(m_xBuilder->weld_button("changepath"))
+ , m_xLastChecked(m_xBuilder->weld_label("lastchecked"))
+ , m_xExtrasCheckBox(m_xBuilder->weld_check_button("extrabits"))
+ , m_xUserAgentLabel(m_xBuilder->weld_label("useragent"))
+ , m_xPrivacyPolicyButton(m_xBuilder->weld_link_button("btnPrivacyPolicy"))
+{
+ m_aNeverChecked = m_xNeverChecked->get_label();
+
+ m_xAutoCheckCheckBox->connect_toggled( LINK( this, SvxOnlineUpdateTabPage, AutoCheckHdl_Impl ) );
+ m_xExtrasCheckBox->connect_toggled( LINK( this, SvxOnlineUpdateTabPage, ExtrasCheckHdl_Impl ) );
+ m_xCheckNowButton->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, CheckNowHdl_Impl ) );
+ m_xChangePathButton->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, FileDialogHdl_Impl ) );
+ m_xPrivacyPolicyButton->set_uri(
+ officecfg::Office::Common::Menus::PrivacyPolicyURL::get()
+ + "?type=updatecheck&LOvers=" + utl::ConfigManager::getProductVersion()
+ + "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47());
+
+
+ uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ m_xUpdateAccess = setup::UpdateCheckConfig::create( xContext );
+ m_xReadWriteAccess = css::configuration::ReadWriteAccess::create(xContext, "*");
+
+ bool bDownloadSupported = false;
+ m_xUpdateAccess->getByName( "DownloadSupported" ) >>= bDownloadSupported;
+
+ m_xAutoDownloadCheckBox->set_visible(bDownloadSupported);
+ m_xDestPathLabel->set_visible(bDownloadSupported);
+ m_xDestPath->set_visible(bDownloadSupported);
+ m_xChangePathButton->set_visible(bDownloadSupported);
+
+ m_aLastCheckedTemplate = m_xLastChecked->get_label();
+
+ UpdateLastCheckedText();
+ UpdateUserAgent();
+}
+
+SvxOnlineUpdateTabPage::~SvxOnlineUpdateTabPage()
+{
+}
+
+void SvxOnlineUpdateTabPage::UpdateLastCheckedText()
+{
+ OUString aText;
+ sal_Int64 lastChecked = 0;
+
+ m_xUpdateAccess->getByName("LastCheck") >>= lastChecked;
+
+ if( lastChecked == 0 ) // never checked
+ {
+ aText = m_aNeverChecked;
+ }
+ else
+ {
+ TimeValue lastCheckedTV;
+ oslDateTime lastCheckedDT;
+
+ Date aDate( Date::EMPTY );
+ tools::Time aTime( tools::Time::EMPTY );
+
+ lastCheckedTV.Seconds = static_cast<sal_uInt32>(lastChecked);
+ osl_getLocalTimeFromSystemTime( &lastCheckedTV, &lastCheckedTV );
+
+ if ( osl_getDateTimeFromTimeValue( &lastCheckedTV, &lastCheckedDT ) )
+ {
+ aDate = Date( lastCheckedDT.Day, lastCheckedDT.Month, lastCheckedDT.Year );
+ aTime = ::tools::Time( lastCheckedDT.Hours, lastCheckedDT.Minutes );
+ }
+
+ LanguageType eUILang = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ std::optional<SvNumberFormatter> pNumberFormatter( std::in_place, ::comphelper::getProcessComponentContext(), eUILang );
+ const Color* pColor = nullptr;
+ const Date& rNullDate = pNumberFormatter->GetNullDate();
+ sal_uInt32 nFormat = pNumberFormatter->GetStandardFormat( SvNumFormatType::DATE, eUILang );
+
+ OUString aDateStr;
+ pNumberFormatter->GetOutputString( aDate - rNullDate, nFormat, aDateStr, &pColor );
+
+ nFormat = pNumberFormatter->GetStandardFormat( SvNumFormatType::TIME, eUILang );
+ OUString aTimeStr;
+ pNumberFormatter->GetOutputString( aTime.GetTimeInDays(), nFormat, aTimeStr, &pColor );
+
+ pNumberFormatter.reset();
+
+ aText = m_aLastCheckedTemplate;
+ sal_Int32 nIndex = aText.indexOf( "%DATE%" );
+ if ( nIndex != -1 )
+ aText = aText.replaceAt( nIndex, 6, aDateStr );
+
+ nIndex = aText.indexOf( "%TIME%" );
+ if ( nIndex != -1 )
+ aText = aText.replaceAt( nIndex, 6, aTimeStr );
+ }
+
+ m_xLastChecked->set_label(aText);
+}
+
+void SvxOnlineUpdateTabPage::UpdateUserAgent()
+{
+ try {
+ uno::Reference< ucb::XWebDAVCommandEnvironment > xDav(
+ css::deployment::UpdateInformationProvider::create(
+ ::comphelper::getProcessComponentContext() ),
+ css::uno::UNO_QUERY_THROW );
+
+ OUString aPseudoURL = "useragent:normal";
+ if( m_xExtrasCheckBox->get_active() )
+ aPseudoURL = "useragent:extended";
+ const uno::Sequence< beans::StringPair > aHeaders
+ = xDav->getUserRequestHeaders( aPseudoURL, ucb::WebDAVHTTPMethod(0) );
+
+ for (const css::beans::StringPair & aHeader : aHeaders)
+ {
+ if ( aHeader.First == "User-Agent" )
+ {
+ OUString aText = aHeader.Second;
+ aText = aText.replaceAll(";", ";\n");
+ aText = aText.replaceAll("(", "\n(");
+ m_xUserAgentLabel->set_label(aText);
+ break;
+ }
+ }
+ } catch (const uno::Exception &) {
+ TOOLS_WARN_EXCEPTION( "cui.options", "Unexpected exception fetching User Agent" );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxOnlineUpdateTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxOnlineUpdateTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxOnlineUpdateTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+
+ bool bValue;
+ sal_Int64 nValue;
+
+ if( m_xAutoCheckCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xAutoCheckCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "AutoCheckEnabled", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ nValue = 0;
+ if( m_xEveryDayButton->get_active() )
+ {
+ if( !m_xEveryDayButton->get_saved_state() )
+ nValue = 86400;
+ }
+ else if( m_xEveryWeekButton->get_active() )
+ {
+ if( !m_xEveryWeekButton->get_saved_state() )
+ nValue = 604800;
+ }
+ else if( m_xEveryMonthButton->get_active() )
+ {
+ if( !m_xEveryMonthButton->get_saved_state() )
+ nValue = 2592000;
+ }
+
+ if( nValue > 0 )
+ {
+ m_xUpdateAccess->replaceByName( "CheckInterval", uno::Any( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xAutoDownloadCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xAutoDownloadCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "AutoDownloadEnabled", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ OUString sValue, aURL;
+ m_xUpdateAccess->getByName( "DownloadDestination" ) >>= sValue;
+
+ if( ( osl::FileBase::E_None == osl::FileBase::getFileURLFromSystemPath(m_xDestPath->get_label(), aURL) ) &&
+ ( aURL != sValue ) )
+ {
+ m_xUpdateAccess->replaceByName( "DownloadDestination", uno::Any( aURL ) );
+ bModified = true;
+ }
+
+ if( m_xExtrasCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xExtrasCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "ExtendedUserAgent", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ uno::Reference< util::XChangesBatch > xChangesBatch(m_xUpdateAccess, uno::UNO_QUERY);
+ if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
+ xChangesBatch->commitChanges();
+
+ return bModified;
+}
+
+void SvxOnlineUpdateTabPage::Reset( const SfxItemSet* )
+{
+ bool bValue = false;
+ m_xUpdateAccess->getByName( "AutoCheckEnabled" ) >>= bValue;
+ beans::Property aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoCheckEnabled");
+ bool bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+
+ m_xAutoCheckCheckBox->set_active(bValue);
+ m_xAutoCheckCheckBox->set_sensitive(!bReadOnly);
+
+ sal_Int64 nValue = 0;
+ m_xUpdateAccess->getByName( "CheckInterval" ) >>= nValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
+ bool bReadOnly2 = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xEveryDayButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+ m_xEveryWeekButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+ m_xEveryMonthButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+
+ if( nValue == 86400 )
+ m_xEveryDayButton->set_active(true);
+ else if( nValue == 604800 )
+ m_xEveryWeekButton->set_active(true);
+ else
+ m_xEveryMonthButton->set_active(true);
+
+ m_xAutoCheckCheckBox->save_state();
+ m_xEveryDayButton->save_state();
+ m_xEveryWeekButton->save_state();
+ m_xEveryMonthButton->save_state();
+
+ m_xUpdateAccess->getByName( "AutoDownloadEnabled" ) >>= bValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoDownloadEnabled");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xAutoDownloadCheckBox->set_active(bValue);
+ m_xAutoDownloadCheckBox->set_sensitive(!bReadOnly);
+ m_xDestPathLabel->set_sensitive(true);
+ m_xDestPath->set_sensitive(true);
+
+ OUString sValue, aPath;
+ m_xUpdateAccess->getByName( "DownloadDestination" ) >>= sValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/DownloadDestination");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xChangePathButton->set_sensitive(!bReadOnly);
+
+ if( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sValue, aPath) )
+ m_xDestPath->set_label(aPath);
+
+ m_xUpdateAccess->getByName( "ExtendedUserAgent" ) >>= bValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/ExtendedUserAgent");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xExtrasCheckBox->set_active(bValue);
+ m_xExtrasCheckBox->set_sensitive(!bReadOnly);
+ m_xExtrasCheckBox->save_state();
+ UpdateUserAgent();
+
+ m_xAutoDownloadCheckBox->save_state();
+}
+
+void SvxOnlineUpdateTabPage::FillUserData()
+{
+}
+
+IMPL_LINK(SvxOnlineUpdateTabPage, AutoCheckHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bEnabled = rBox.get_active();
+ beans::Property aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
+ bool bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xEveryDayButton->set_sensitive(bEnabled && !bReadOnly);
+ m_xEveryWeekButton->set_sensitive(bEnabled && !bReadOnly);
+ m_xEveryMonthButton->set_sensitive(bEnabled && !bReadOnly);
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, ExtrasCheckHdl_Impl, weld::Toggleable&, void)
+{
+ UpdateUserAgent();
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, FileDialogHdl_Impl, weld::Button&, void)
+{
+ uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference < ui::dialogs::XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ OUString aURL;
+ if( osl::FileBase::E_None != osl::FileBase::getFileURLFromSystemPath(m_xDestPath->get_label(), aURL) )
+ osl::Security().getHomeDir(aURL);
+
+ xFolderPicker->setDisplayDirectory( aURL );
+ sal_Int16 nRet = xFolderPicker->execute();
+
+ if ( ui::dialogs::ExecutableDialogResults::OK == nRet )
+ {
+ OUString aFolder;
+ if( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(xFolderPicker->getDirectory(), aFolder))
+ m_xDestPath->set_label(aFolder);
+ }
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, CheckNowHdl_Impl, weld::Button&, void)
+{
+ uno::Reference < uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ css::configuration::theDefaultProvider::get( xContext ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= OUString("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob");
+
+ uno::Sequence< uno::Any > aArgumentList{ uno::Any(aProperty) };
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess", aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ util::URL aURL;
+ xNameAccess->getByName("URL") >>= aURL.Complete;
+
+ uno::Reference < util::XURLTransformer > xTransformer( util::URLTransformer::create( xContext ) );
+
+ xTransformer->parseStrict(aURL);
+
+ uno::Reference < frame::XDesktop2 > xDesktop = frame::Desktop::create( xContext );
+
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider(
+ xDesktop->getCurrentFrame(), uno::UNO_QUERY );
+
+ uno::Reference< frame::XDispatch > xDispatch;
+ if( xDispatchProvider.is() )
+ xDispatch = xDispatchProvider->queryDispatch(aURL, OUString(), 0);
+
+ if( xDispatch.is() )
+ xDispatch->dispatch(aURL, uno::Sequence< beans::PropertyValue > ());
+
+ UpdateLastCheckedText();
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "Caught exception, thread terminated");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optupdt.hxx b/cui/source/options/optupdt.hxx
new file mode 100644
index 000000000..7143bf333
--- /dev/null
+++ b/cui/source/options/optupdt.hxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/configuration/XReadWriteAccess.hpp>
+
+// class SvxPathTabPage --------------------------------------------------
+
+class SvxOnlineUpdateTabPage : public SfxTabPage
+{
+private:
+ OUString m_aNeverChecked;
+ OUString m_aLastCheckedTemplate;
+
+ css::uno::Reference< css::container::XNameReplace > m_xUpdateAccess;
+ css::uno::Reference<css::configuration::XReadWriteAccess> m_xReadWriteAccess;
+
+ std::unique_ptr<weld::Label> m_xNeverChecked;
+ std::unique_ptr<weld::CheckButton> m_xAutoCheckCheckBox;
+ std::unique_ptr<weld::RadioButton> m_xEveryDayButton;
+ std::unique_ptr<weld::RadioButton> m_xEveryWeekButton;
+ std::unique_ptr<weld::RadioButton> m_xEveryMonthButton;
+ std::unique_ptr<weld::Button> m_xCheckNowButton;
+ std::unique_ptr<weld::CheckButton> m_xAutoDownloadCheckBox;
+ std::unique_ptr<weld::Label> m_xDestPathLabel;
+ std::unique_ptr<weld::Label> m_xDestPath;
+ std::unique_ptr<weld::Button> m_xChangePathButton;
+ std::unique_ptr<weld::Label> m_xLastChecked;
+ std::unique_ptr<weld::CheckButton> m_xExtrasCheckBox;
+ std::unique_ptr<weld::Label> m_xUserAgentLabel;
+ std::unique_ptr<weld::LinkButton> m_xPrivacyPolicyButton;
+
+ DECL_LINK(FileDialogHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckNowHdl_Impl, weld::Button&, void);
+ DECL_LINK(AutoCheckHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ExtrasCheckHdl_Impl, weld::Toggleable&, void);
+
+ void UpdateLastCheckedText();
+ void UpdateUserAgent();
+
+public:
+ SvxOnlineUpdateTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxOnlineUpdateTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.cxx b/cui/source/options/personalization.cxx
new file mode 100644
index 000000000..ec62fb105
--- /dev/null
+++ b/cui/source/options/personalization.cxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config_folders.h>
+
+#include "personalization.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <rtl/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/virdev.hxx>
+
+using namespace com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+// persona
+SvxPersonalizationTabPage::SvxPersonalizationTabPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/personalization_tab.ui", "PersonalizationTabPage",
+ &rSet)
+ , m_xNoPersona(m_xBuilder->weld_radio_button("no_persona"))
+ , m_xDefaultPersona(m_xBuilder->weld_radio_button("default_persona"))
+{
+ for (sal_uInt32 i = 0; i < MAX_DEFAULT_PERSONAS; ++i)
+ {
+ OString sDefaultId("default" + OString::number(i));
+ m_vDefaultPersonaImages[i] = m_xBuilder->weld_toggle_button(sDefaultId);
+ m_vDefaultPersonaImages[i]->connect_clicked(
+ LINK(this, SvxPersonalizationTabPage, DefaultPersona));
+ }
+
+ LoadDefaultImages();
+}
+
+SvxPersonalizationTabPage::~SvxPersonalizationTabPage() {}
+
+std::unique_ptr<SfxTabPage> SvxPersonalizationTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxPersonalizationTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxPersonalizationTabPage::FillItemSet(SfxItemSet*)
+{
+ // persona
+ OUString aPersona("default");
+ if (m_xNoPersona->get_active())
+ aPersona = "no";
+
+ bool bModified = false;
+ if (aPersona != officecfg::Office::Common::Misc::Persona::get()
+ || m_aPersonaSettings != officecfg::Office::Common::Misc::PersonaSettings::get())
+ {
+ bModified = true;
+ }
+
+ // write
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ if (aPersona == "no")
+ m_aPersonaSettings.clear();
+ officecfg::Office::Common::Misc::Persona::set(aPersona, batch);
+ officecfg::Office::Common::Misc::PersonaSettings::set(m_aPersonaSettings, batch);
+ batch->commit();
+
+ if (bModified)
+ {
+ // broadcast the change
+ DataChangedEvent aDataChanged(DataChangedEventType::SETTINGS, nullptr,
+ AllSettingsFlags::STYLE);
+ Application::NotifyAllWindows(aDataChanged);
+ }
+
+ return bModified;
+}
+
+void SvxPersonalizationTabPage::Reset(const SfxItemSet*)
+{
+ // persona
+ OUString aPersona = officecfg::Office::Common::Misc::Persona::get();
+ m_aPersonaSettings = officecfg::Office::Common::Misc::PersonaSettings::get();
+
+ if (aPersona == "no")
+ m_xNoPersona->set_active(true);
+ else
+ m_xDefaultPersona->set_active(true);
+}
+
+void SvxPersonalizationTabPage::LoadDefaultImages()
+{
+ // Load the pre saved personas
+
+ OUString gallery = "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/gallery/personas/";
+ rtl::Bootstrap::expandMacros(gallery);
+ OUString aPersonasList = gallery + "personas_list.txt";
+ SvFileStream aStream(aPersonasList, StreamMode::READ);
+ GraphicFilter aFilter;
+ Graphic aGraphic;
+ sal_Int32 nIndex = 0;
+ bool foundOne = false;
+
+ OStringBuffer aLine;
+ while (aStream.IsOpen() && !aStream.eof() && nIndex < MAX_DEFAULT_PERSONAS)
+ {
+ OUString aPersonaSetting, aPreviewFile, aName;
+ sal_Int32 nParseIndex = 0;
+
+ aStream.ReadLine(aLine);
+ aPersonaSetting = OStringToOUString(aLine, RTL_TEXTENCODING_UTF8);
+ aName = aPersonaSetting.getToken(1, ';', nParseIndex);
+ aPreviewFile = aPersonaSetting.getToken(0, ';', nParseIndex);
+
+ if (aPreviewFile.isEmpty())
+ break;
+
+ m_vDefaultPersonaSettings.push_back(aPersonaSetting);
+
+ INetURLObject aURLObj(rtl::OUStringConcatenation(gallery + aPreviewFile));
+ aFilter.ImportGraphic(aGraphic, aURLObj);
+
+ Size aSize(aGraphic.GetSizePixel());
+ aSize.setWidth(aSize.Width() / 4);
+ aSize.setHeight(aSize.Height() / 1.5);
+ ScopedVclPtr<VirtualDevice> xVirDev
+ = m_vDefaultPersonaImages[nIndex]->create_virtual_device();
+ xVirDev->SetOutputSizePixel(aSize);
+ aGraphic.Draw(*xVirDev, Point(0, 0));
+ m_vDefaultPersonaImages[nIndex]->set_image(xVirDev.get());
+ xVirDev.disposeAndClear();
+
+ m_vDefaultPersonaImages[nIndex]->set_tooltip_text(aName);
+ m_vDefaultPersonaImages[nIndex++]->show();
+ foundOne = true;
+ }
+
+ m_xDefaultPersona->set_sensitive(foundOne);
+}
+
+IMPL_LINK(SvxPersonalizationTabPage, DefaultPersona, weld::Button&, rButton, void)
+{
+ m_xDefaultPersona->set_active(true);
+ for (sal_Int32 nIndex = 0; nIndex < MAX_DEFAULT_PERSONAS; ++nIndex)
+ {
+ if (&rButton == m_vDefaultPersonaImages[nIndex].get())
+ m_aPersonaSettings = m_vDefaultPersonaSettings[nIndex];
+ else
+ m_vDefaultPersonaImages[nIndex]->set_active(false);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.hxx b/cui/source/options/personalization.hxx
new file mode 100644
index 000000000..671f194c2
--- /dev/null
+++ b/cui/source/options/personalization.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <vector>
+
+#define MAX_DEFAULT_PERSONAS 6 // Maximum number of default personas
+
+class SvxPersonalizationTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::RadioButton> m_xNoPersona; ///< Just the default look, without any bitmap
+ std::unique_ptr<weld::RadioButton> m_xDefaultPersona; ///< Use the built-in bitmap
+ std::unique_ptr<weld::ToggleButton> m_vDefaultPersonaImages
+ [MAX_DEFAULT_PERSONAS]; ///< Buttons to show the default persona images
+ OUString m_aPersonaSettings; ///< Header and footer images + color to be set in the settings.
+
+ std::vector<OUString> m_vDefaultPersonaSettings;
+
+public:
+ SvxPersonalizationTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SvxPersonalizationTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ /// Apply the settings ([OK] button).
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+
+ /// Reset to default settings ([Revert] button).
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+ /*
+ * Loads the default personas from the shared personas directory
+ * which resides in the shared gallery.
+ * There needs to be a separate subdirectory for each default persona,
+ * which includes the preview, header, and footer images.
+ * And there needs to be a personas_list.txt file in the personas directory
+ * which keeps the index/info of the default personas, one persona per line.
+ * A line should look like this:
+ * persona_slug;Persona Name;subdir/preview.jpg;subdir/header.jpg;subdir/footer.jpg;#textcolor
+ * (It is recommended to keep the subdir name the same as the slug)
+ * Example line:
+ * abstract;Abstract;abstract/preview.jpg;abstract/Header2.jpg;abstract/Footer2.jpg;#ffffff
+ */
+ void LoadDefaultImages();
+
+private:
+ /// Handle the default Persona selection
+ DECL_LINK(DefaultPersona, weld::Button&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/sdbcdriverenum.cxx b/cui/source/options/sdbcdriverenum.cxx
new file mode 100644
index 000000000..629fb7056
--- /dev/null
+++ b/cui/source/options/sdbcdriverenum.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "sdbcdriverenum.hxx"
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdbc/DriverManager.hpp>
+
+
+namespace offapp
+{
+
+
+ using namespace css::uno;
+ using namespace css::lang;
+ using namespace css::container;
+ using namespace css::sdbc;
+
+ class ODriverEnumerationImpl
+ {
+ protected:
+ std::vector< OUString > m_aImplNames;
+
+ public:
+ ODriverEnumerationImpl();
+
+ const std::vector< OUString >& getDriverImplNames() const { return m_aImplNames; }
+ };
+
+
+ ODriverEnumerationImpl::ODriverEnumerationImpl()
+ {
+ try
+ {
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XDriverManager2 > xEnumAccess = DriverManager::create( xContext );
+
+ Reference< XEnumeration > xEnumDrivers = xEnumAccess->createEnumeration();
+ OSL_ENSURE(xEnumDrivers.is(), "ODriverEnumerationImpl::ODriverEnumerationImpl: invalid enumeration object!");
+
+ Reference< XServiceInfo > xDriverSI;
+ while (xEnumDrivers->hasMoreElements())
+ {
+ xEnumDrivers->nextElement() >>= xDriverSI;
+ OSL_ENSURE(xDriverSI.is(), "ODriverEnumerationImpl::ODriverEnumerationImpl: driver without service info!");
+ if (xDriverSI.is())
+ m_aImplNames.push_back(xDriverSI->getImplementationName());
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ODriverEnumerationImpl::ODriverEnumerationImpl: caught an exception while enumerating the drivers!");
+ }
+ }
+
+ ODriverEnumeration::ODriverEnumeration() noexcept
+ :m_pImpl(new ODriverEnumerationImpl)
+ {
+ }
+
+
+ ODriverEnumeration::~ODriverEnumeration() noexcept
+ {
+ }
+
+
+ ODriverEnumeration::const_iterator ODriverEnumeration::begin() const noexcept
+ {
+ return m_pImpl->getDriverImplNames().begin();
+ }
+
+
+ ODriverEnumeration::const_iterator ODriverEnumeration::end() const noexcept
+ {
+ return m_pImpl->getDriverImplNames().end();
+ }
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/sdbcdriverenum.hxx b/cui/source/options/sdbcdriverenum.hxx
new file mode 100644
index 000000000..852648893
--- /dev/null
+++ b/cui/source/options/sdbcdriverenum.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+#include <vector>
+#include <memory>
+
+
+namespace offapp
+{
+
+ class ODriverEnumerationImpl;
+ /** simple class for accessing SDBC drivers registered within the office
+ <p>Rather small, introduced to not contaminate other instances with the
+ exception handling (code-size-bloating) implementations here.
+ </p>
+ */
+ class ODriverEnumeration
+ {
+ private:
+ std::unique_ptr<ODriverEnumerationImpl> m_pImpl;
+
+ public:
+ ODriverEnumeration() noexcept;
+ ~ODriverEnumeration() noexcept;
+ typedef std::vector< OUString >::const_iterator const_iterator;
+
+ const_iterator begin() const noexcept;
+ const_iterator end() const noexcept;
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/securityoptions.cxx b/cui/source/options/securityoptions.cxx
new file mode 100644
index 000000000..4b00176ab
--- /dev/null
+++ b/cui/source/options/securityoptions.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/securityoptions.hxx>
+#include "securityoptions.hxx"
+
+namespace
+{
+ bool enableAndSet(SvtSecurityOptions::EOption eOption,
+ weld::CheckButton& rCheckBox, weld::Widget& rFixedImage)
+ {
+ bool bEnable = !SvtSecurityOptions::IsReadOnly(eOption);
+ rCheckBox.set_sensitive(bEnable);
+ rFixedImage.set_visible(!bEnable);
+ rCheckBox.set_active(SvtSecurityOptions::IsOptionSet(eOption));
+ return bEnable;
+ }
+}
+
+namespace svx
+{
+
+SecurityOptionsDialog::SecurityOptionsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/securityoptionsdialog.ui", "SecurityOptionsDialog")
+ , m_xSaveOrSendDocsCB(m_xBuilder->weld_check_button("savesenddocs"))
+ , m_xSaveOrSendDocsImg(m_xBuilder->weld_widget("locksavesenddocs"))
+ , m_xSignDocsCB(m_xBuilder->weld_check_button("whensigning"))
+ , m_xSignDocsImg(m_xBuilder->weld_widget("lockwhensigning"))
+ , m_xPrintDocsCB(m_xBuilder->weld_check_button("whenprinting"))
+ , m_xPrintDocsImg(m_xBuilder->weld_widget("lockwhenprinting"))
+ , m_xCreatePdfCB(m_xBuilder->weld_check_button("whenpdf"))
+ , m_xCreatePdfImg(m_xBuilder->weld_widget("lockwhenpdf"))
+ , m_xRemovePersInfoCB(m_xBuilder->weld_check_button("removepersonal"))
+ , m_xRemovePersInfoImg(m_xBuilder->weld_widget("lockremovepersonal"))
+ , m_xRecommPasswdCB(m_xBuilder->weld_check_button("password"))
+ , m_xRecommPasswdImg(m_xBuilder->weld_widget("lockpassword"))
+ , m_xCtrlHyperlinkCB(m_xBuilder->weld_check_button("ctrlclick"))
+ , m_xCtrlHyperlinkImg(m_xBuilder->weld_widget("lockctrlclick"))
+ , m_xBlockUntrustedRefererLinksCB(m_xBuilder->weld_check_button("blockuntrusted"))
+ , m_xBlockUntrustedRefererLinksImg(m_xBuilder->weld_widget("lockblockuntrusted"))
+{
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnSaveOrSend, *m_xSaveOrSendDocsCB,
+ *m_xSaveOrSendDocsImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnSigning, *m_xSignDocsCB,
+ *m_xSignDocsImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnPrint, *m_xPrintDocsCB,
+ *m_xPrintDocsImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnCreatePdf, *m_xCreatePdfCB,
+ *m_xCreatePdfImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo, *m_xRemovePersInfoCB,
+ *m_xRemovePersInfoImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnRecommendPassword, *m_xRecommPasswdCB,
+ *m_xRecommPasswdImg);
+ enableAndSet(SvtSecurityOptions::EOption::CtrlClickHyperlink, *m_xCtrlHyperlinkCB,
+ *m_xCtrlHyperlinkImg);
+ enableAndSet(SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, *m_xBlockUntrustedRefererLinksCB,
+ *m_xBlockUntrustedRefererLinksImg);
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/securityoptions.hxx b/cui/source/options/securityoptions.hxx
new file mode 100644
index 000000000..dc05f5bb8
--- /dev/null
+++ b/cui/source/options/securityoptions.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+namespace svx
+{
+
+ class SecurityOptionsDialog : public weld::GenericDialogController
+ {
+ private:
+ std::unique_ptr<weld::CheckButton> m_xSaveOrSendDocsCB;
+ std::unique_ptr<weld::Widget> m_xSaveOrSendDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xSignDocsCB;
+ std::unique_ptr<weld::Widget> m_xSignDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xPrintDocsCB;
+ std::unique_ptr<weld::Widget> m_xPrintDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xCreatePdfCB;
+ std::unique_ptr<weld::Widget> m_xCreatePdfImg;
+
+ std::unique_ptr<weld::CheckButton> m_xRemovePersInfoCB;
+ std::unique_ptr<weld::Widget> m_xRemovePersInfoImg;
+ std::unique_ptr<weld::CheckButton> m_xRecommPasswdCB;
+ std::unique_ptr<weld::Widget> m_xRecommPasswdImg;
+ std::unique_ptr<weld::CheckButton> m_xCtrlHyperlinkCB;
+ std::unique_ptr<weld::Widget> m_xCtrlHyperlinkImg;
+ std::unique_ptr<weld::CheckButton> m_xBlockUntrustedRefererLinksCB;
+ std::unique_ptr<weld::Widget> m_xBlockUntrustedRefererLinksImg;
+
+ public:
+ SecurityOptionsDialog(weld::Window* pParent);
+
+ bool IsSaveOrSendDocsChecked() const { return m_xSaveOrSendDocsCB->get_active(); }
+ bool IsSignDocsChecked() const { return m_xSignDocsCB->get_active(); }
+ bool IsPrintDocsChecked() const { return m_xPrintDocsCB->get_active(); }
+ bool IsCreatePdfChecked() const { return m_xCreatePdfCB->get_active(); }
+ bool IsRemovePersInfoChecked() const { return m_xRemovePersInfoCB->get_active(); }
+ bool IsRecommPasswdChecked() const { return m_xRecommPasswdCB->get_active(); }
+ bool IsCtrlHyperlinkChecked() const { return m_xCtrlHyperlinkCB->get_active(); }
+ bool IsBlockUntrustedRefererLinksChecked() const { return m_xBlockUntrustedRefererLinksCB->get_active(); }
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/treeopt.cxx b/cui/source/options/treeopt.cxx
new file mode 100644
index 000000000..5973f422a
--- /dev/null
+++ b/cui/source/options/treeopt.cxx
@@ -0,0 +1,2115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <string_view>
+
+#include <config_features.h>
+#include <config_feature_opencl.h>
+#include <config_feature_desktop.h>
+#include <config_gpgme.h>
+
+#include <officecfg/Office/Common.hxx>
+
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+
+#include <treeopt.hrc>
+#include <helpids.h>
+
+#include "cfgchart.hxx"
+#include "connpoolconfig.hxx"
+#include "connpooloptions.hxx"
+#include <cuioptgenrl.hxx>
+#include <dbregister.hxx>
+#include "dbregisterednamesconfig.hxx"
+#include <dialmgr.hxx>
+#include "fontsubs.hxx"
+#include "optaccessibility.hxx"
+#include <optasian.hxx>
+#include "optchart.hxx"
+#include "optcolor.hxx"
+#include "optctl.hxx"
+#include "optfltr.hxx"
+#include "optgdlg.hxx"
+#include "opthtml.hxx"
+#include "optinet2.hxx"
+#include "optjava.hxx"
+#include "optjsearch.hxx"
+#include <optlingu.hxx>
+#if HAVE_FEATURE_OPENCL
+#include "optopencl.hxx"
+#endif
+#include <optpath.hxx>
+#include "optsave.hxx"
+#include "optupdt.hxx"
+#include "personalization.hxx"
+#include <treeopt.hxx>
+#include "optbasic.hxx"
+#include "optlanguagetool.hxx"
+
+#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
+#include <com/sun/star/awt/ContainerWindowProvider.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/linguistic2/LinguProperties.hpp>
+#include <com/sun/star/setup/UpdateCheck.hpp>
+#include <comphelper/getexpandeduri.hxx>
+#include <comphelper/processfactory.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/optitems.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/misc.hxx>
+#include <officecfg/Office/OptionsDialog.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/printopt.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/flagitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/optionsdlg.hxx>
+#include <unotools/viewoptions.hxx>
+#include <utility>
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <vcl/window.hxx>
+#include <sal/log.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::lang;
+using namespace ::com::sun::star::linguistic2;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+LastPageSaver* OfaTreeOptionsDialog::pLastPageSaver = nullptr;
+
+// some stuff for easier changes for SvtViewOptions
+constexpr OUStringLiteral VIEWOPT_DATANAME = u"page data";
+
+static void SetViewOptUserItem( SvtViewOptions& rOpt, const OUString& rData )
+{
+ rOpt.SetUserItem( VIEWOPT_DATANAME, Any( rData ) );
+}
+
+static OUString GetViewOptUserItem( const SvtViewOptions& rOpt )
+{
+ Any aAny( rOpt.GetUserItem( VIEWOPT_DATANAME ) );
+ OUString aUserData;
+ aAny >>= aUserData;
+
+ return aUserData;
+}
+
+namespace {
+
+struct ModuleToGroupNameMap_Impl
+{
+ std::u16string_view m_pModule;
+ OUString m_sGroupName;
+ sal_uInt16 m_nNodeId;
+};
+}
+
+static ModuleToGroupNameMap_Impl ModuleMap[] =
+{
+ { u"ProductName", OUString(), SID_GENERAL_OPTIONS },
+ { u"LanguageSettings", OUString(), SID_LANGUAGE_OPTIONS },
+ { u"Internet", OUString(), SID_INET_DLG },
+ { u"LoadSave", OUString(), SID_FILTER_DLG },
+ { u"Writer", OUString(), SID_SW_EDITOPTIONS },
+ { u"WriterWeb", OUString(), SID_SW_ONLINEOPTIONS },
+ { u"Math", OUString(), SID_SM_EDITOPTIONS },
+ { u"Calc", OUString(), SID_SC_EDITOPTIONS },
+ { u"Impress", OUString(), SID_SD_EDITOPTIONS },
+ { u"Draw", OUString(), SID_SD_GRAPHIC_OPTIONS },
+ { u"Charts", OUString(), SID_SCH_EDITOPTIONS },
+ { u"Base", OUString(), SID_SB_STARBASEOPTIONS },
+};
+
+static void setGroupName( std::u16string_view rModule, const OUString& rGroupName )
+{
+ for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ rEntry.m_sGroupName = rGroupName;
+ break;
+ }
+ }
+}
+
+static OUString getGroupName( std::u16string_view rModule, bool bForced )
+{
+ OUString sGroupName;
+ for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ sGroupName = rEntry.m_sGroupName;
+ break;
+ }
+ }
+
+ if ( sGroupName.isEmpty() && bForced )
+ {
+ if ( rModule == u"Writer" )
+ sGroupName = CuiResId(SID_SW_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"WriterWeb" )
+ sGroupName = CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first);
+ else if ( rModule == u"Calc" )
+ sGroupName = CuiResId(SID_SC_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"Impress" )
+ sGroupName = CuiResId(SID_SD_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"Draw" )
+ sGroupName = CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first);
+ else if ( rModule == u"Math" )
+ sGroupName = CuiResId(SID_SM_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"Base" )
+ sGroupName = CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first);
+ }
+ return sGroupName;
+}
+
+static void deleteGroupNames()
+{
+ for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ rEntry.m_sGroupName.clear();
+}
+
+static sal_uInt16 getGroupNodeId( std::u16string_view rModule )
+{
+ sal_uInt16 nNodeId = 0xFFFF;
+ for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ nNodeId = rEntry.m_nNodeId;
+ break;
+ }
+ }
+
+ return nNodeId;
+}
+
+namespace {
+
+class MailMergeCfg_Impl : public utl::ConfigItem
+{
+private:
+ // variables
+ bool bIsEmailSupported;
+
+ virtual void ImplCommit() override;
+
+public:
+ MailMergeCfg_Impl();
+
+ virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override;
+
+ bool IsEmailSupported() const {return bIsEmailSupported;}
+
+};
+
+}
+
+MailMergeCfg_Impl::MailMergeCfg_Impl() :
+ utl::ConfigItem("Office.Writer/MailMergeWizard"),
+ bIsEmailSupported(false)
+{
+ Sequence<OUString> aNames { "EMailSupported" };
+ const Sequence< Any > aValues = GetProperties(aNames);
+ const Any* pValues = aValues.getConstArray();
+ if(aValues.hasElements() && pValues[0].hasValue())
+ pValues[0] >>= bIsEmailSupported;
+}
+
+void MailMergeCfg_Impl::ImplCommit()
+{
+}
+
+void MailMergeCfg_Impl::Notify( const css::uno::Sequence< OUString >& )
+{
+}
+
+//typedef SfxTabPage* (*FNCreateTabPage)(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet);
+static std::unique_ptr<SfxTabPage> CreateGeneralTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+{
+ CreateTabPage fnCreate = nullptr;
+ switch(nId)
+ {
+ case RID_SFXPAGE_SAVE: fnCreate = &SvxSaveTabPage::Create; break;
+ case RID_SFXPAGE_PATH: fnCreate = &SvxPathTabPage::Create; break;
+ case RID_SFXPAGE_GENERAL: fnCreate = &SvxGeneralTabPage::Create; break;
+ case RID_SFXPAGE_PRINTOPTIONS: fnCreate = &SfxCommonPrintOptionsTabPage::Create; break;
+ case OFA_TP_LANGUAGES: fnCreate = &OfaLanguagesTabPage::Create; break;
+ case RID_SFXPAGE_LINGU: fnCreate = &SvxLinguTabPage::Create; break;
+ case OFA_TP_VIEW: fnCreate = &OfaViewTabPage::Create; break;
+ case OFA_TP_MISC: fnCreate = &OfaMiscTabPage::Create; break;
+ case RID_SVXPAGE_ASIAN_LAYOUT: fnCreate = &SvxAsianLayoutPage::Create; break;
+ case RID_SVX_FONT_SUBSTITUTION: fnCreate = &SvxFontSubstTabPage::Create; break;
+ case RID_SVXPAGE_INET_PROXY: fnCreate = &SvxProxyTabPage::Create; break;
+ case RID_SVXPAGE_INET_SECURITY: fnCreate = &SvxSecurityTabPage::Create; break;
+ case RID_SVXPAGE_INET_MAIL: fnCreate = &SvxEMailTabPage::Create; break;
+#if HAVE_FEATURE_DESKTOP
+ case RID_SVXPAGE_PERSONALIZATION: fnCreate = &SvxPersonalizationTabPage::Create; break;
+#endif
+ case RID_SVXPAGE_COLORCONFIG: fnCreate = &SvxColorOptionsTabPage::Create; break;
+ case RID_OFAPAGE_HTMLOPT: fnCreate = &OfaHtmlTabPage::Create; break;
+ case SID_OPTFILTER_MSOFFICE: fnCreate = &OfaMSFilterTabPage::Create; break;
+ case RID_OFAPAGE_MSFILTEROPT2: fnCreate = &OfaMSFilterTabPage2::Create; break;
+ case RID_SVXPAGE_JSEARCH_OPTIONS: fnCreate = &SvxJSearchOptionsPage::Create ; break;
+ case SID_SB_CONNECTIONPOOLING: fnCreate = &::offapp::ConnectionPoolOptionsPage::Create; break;
+ case SID_SB_DBREGISTEROPTIONS: fnCreate = &svx::DbRegistrationOptionsPage::Create; break;
+ case RID_SVXPAGE_ACCESSIBILITYCONFIG: fnCreate = &SvxAccessibilityOptionsTabPage::Create; break;
+ case RID_SVXPAGE_OPTIONS_CTL: fnCreate = &SvxCTLOptionsPage::Create ; break;
+ case RID_SVXPAGE_LANGTOOL_OPTIONS: fnCreate = &OptLanguageToolTabPage::Create ; break;
+ case RID_SVXPAGE_OPTIONS_JAVA: fnCreate = &SvxJavaOptionsPage::Create ; break;
+#if HAVE_FEATURE_OPENCL
+ case RID_SVXPAGE_OPENCL: fnCreate = &SvxOpenCLTabPage::Create ; break;
+#endif
+ case RID_SVXPAGE_ONLINEUPDATE: fnCreate = &SvxOnlineUpdateTabPage::Create; break;
+ case RID_OPTPAGE_CHART_DEFCOLORS: fnCreate = &SvxDefaultColorOptPage::Create; break;
+#if HAVE_FEATURE_SCRIPTING
+ case RID_SVXPAGE_BASICIDE_OPTIONS: fnCreate = &SvxBasicIDEOptionsPage::Create; break;
+#endif
+ }
+
+ return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
+}
+
+namespace {
+
+struct OptionsMapping_Impl
+{
+ const char* m_pGroupName;
+ const char* m_pPageName;
+ sal_uInt16 m_nPageId;
+};
+
+}
+
+OptionsMapping_Impl const OptionsMap_Impl[] =
+{
+// GROUP PAGE PAGE-ID
+ { "ProductName", nullptr, SID_GENERAL_OPTIONS },
+ { "ProductName", "UserData", RID_SFXPAGE_GENERAL },
+ { "ProductName", "General", OFA_TP_MISC },
+ { "ProductName", "View", OFA_TP_VIEW },
+ { "ProductName", "Print", RID_SFXPAGE_PRINTOPTIONS },
+ { "ProductName", "Paths", RID_SFXPAGE_PATH },
+ { "ProductName", "Fonts", RID_SVX_FONT_SUBSTITUTION },
+ { "ProductName", "Security", RID_SVXPAGE_INET_SECURITY },
+ { "ProductName", "Personalization", RID_SVXPAGE_PERSONALIZATION },
+ { "ProductName", "Appearance", RID_SVXPAGE_COLORCONFIG },
+ { "ProductName", "Accessibility", RID_SVXPAGE_ACCESSIBILITYCONFIG },
+ { "ProductName", "Java", RID_SVXPAGE_OPTIONS_JAVA },
+ { "ProductName", "BasicIDEOptions", RID_SVXPAGE_BASICIDE_OPTIONS },
+ { "ProductName", "OnlineUpdate", RID_SVXPAGE_ONLINEUPDATE },
+ { "LanguageSettings", nullptr, SID_LANGUAGE_OPTIONS },
+ { "LanguageSettings", "Languages", OFA_TP_LANGUAGES },
+ { "LanguageSettings", "WritingAids", RID_SFXPAGE_LINGU },
+ { "LanguageSettings", "SearchingInJapanese", RID_SVXPAGE_JSEARCH_OPTIONS },
+ { "LanguageSettings", "AsianLayout", RID_SVXPAGE_ASIAN_LAYOUT },
+ { "LanguageSettings", "ComplexTextLayout", RID_SVXPAGE_OPTIONS_CTL },
+ { "Internet", nullptr, SID_INET_DLG },
+ { "Internet", "Proxy", RID_SVXPAGE_INET_PROXY },
+ { "Internet", "Email", RID_SVXPAGE_INET_MAIL },
+ { "LoadSave", nullptr, SID_FILTER_DLG },
+ { "LoadSave", "General", RID_SFXPAGE_SAVE },
+ { "LoadSave", "VBAProperties", SID_OPTFILTER_MSOFFICE },
+ { "LoadSave", "MicrosoftOffice", RID_OFAPAGE_MSFILTEROPT2 },
+ { "LoadSave", "HTMLCompatibility", RID_OFAPAGE_HTMLOPT },
+ { "Writer", nullptr, SID_SW_EDITOPTIONS },
+ { "Writer", "General", RID_SW_TP_OPTLOAD_PAGE },
+ { "Writer", "View", RID_SW_TP_CONTENT_OPT },
+ { "Writer", "FormattingAids", RID_SW_TP_OPTSHDWCRSR },
+ { "Writer", "Grid", RID_SVXPAGE_GRID },
+ { "Writer", "BasicFontsWestern", RID_SW_TP_STD_FONT },
+ { "Writer", "BasicFontsAsian", RID_SW_TP_STD_FONT_CJK },
+ { "Writer", "BasicFontsCTL", RID_SW_TP_STD_FONT_CTL },
+ { "Writer", "Print", RID_SW_TP_OPTPRINT_PAGE },
+ { "Writer", "Table", RID_SW_TP_OPTTABLE_PAGE },
+ { "Writer", "Changes", RID_SW_TP_REDLINE_OPT },
+ { "Writer", "Comparison", RID_SW_TP_COMPARISON_OPT },
+ { "Writer", "Compatibility", RID_SW_TP_OPTCOMPATIBILITY_PAGE },
+ { "Writer", "AutoCaption", RID_SW_TP_OPTCAPTION_PAGE },
+ { "Writer", "MailMerge", RID_SW_TP_MAILCONFIG },
+ { "WriterWeb", nullptr, SID_SW_ONLINEOPTIONS },
+ { "WriterWeb", "View", RID_SW_TP_HTML_CONTENT_OPT },
+ { "WriterWeb", "FormattingAids", RID_SW_TP_HTML_OPTSHDWCRSR },
+ { "WriterWeb", "Grid", RID_SW_TP_HTML_OPTGRID_PAGE },
+ { "WriterWeb", "Print", RID_SW_TP_HTML_OPTPRINT_PAGE },
+ { "WriterWeb", "Table", RID_SW_TP_HTML_OPTTABLE_PAGE },
+ { "WriterWeb", "Background", RID_SW_TP_BACKGROUND },
+ { "Math", nullptr, SID_SM_EDITOPTIONS },
+ { "Math", "Settings", SID_SM_TP_PRINTOPTIONS },
+ { "Calc", nullptr, SID_SC_EDITOPTIONS },
+ { "Calc", "General", SID_SC_TP_LAYOUT },
+ { "Calc", "View", SID_SC_TP_CONTENT },
+ { "Calc", "Calculate", SID_SC_TP_CALC },
+ { "Calc", "Formula", SID_SC_TP_FORMULA },
+ { "Calc", "SortLists", SID_SC_TP_USERLISTS },
+ { "Calc", "Changes", SID_SC_TP_CHANGES },
+ { "Calc", "Compatibility", SID_SC_TP_COMPATIBILITY },
+ { "Calc", "Grid", SID_SC_TP_GRID },
+ { "Calc", "Print", RID_SC_TP_PRINT },
+ { "Impress", nullptr, SID_SD_EDITOPTIONS },
+ { "Impress", "General", SID_SI_TP_MISC },
+ { "Impress", "View", SID_SI_TP_CONTENTS },
+ { "Impress", "Grid", SID_SI_TP_SNAP },
+ { "Impress", "Print", SID_SI_TP_PRINT },
+ { "Draw", nullptr, SID_SD_GRAPHIC_OPTIONS },
+ { "Draw", "General", SID_SD_TP_MISC },
+ { "Draw", "View", SID_SD_TP_CONTENTS },
+ { "Draw", "Grid", SID_SD_TP_SNAP },
+ { "Draw", "Print", SID_SD_TP_PRINT },
+ { "Charts", nullptr, SID_SCH_EDITOPTIONS },
+ { "Charts", "DefaultColors", RID_OPTPAGE_CHART_DEFCOLORS },
+ { "Base", nullptr, SID_SB_STARBASEOPTIONS },
+ { "Base", "Connections", SID_SB_CONNECTIONPOOLING },
+ { "Base", "Databases", SID_SB_DBREGISTEROPTIONS },
+ { nullptr, nullptr, 0 }
+};
+
+static bool lcl_getStringFromID( sal_uInt16 _nPageId, OUString& _rGroupName, OUString& _rPageName )
+{
+ bool bRet = false;
+
+ sal_uInt16 nIdx = 0;
+ while ( OptionsMap_Impl[nIdx].m_pGroupName != nullptr )
+ {
+ if ( _nPageId == OptionsMap_Impl[nIdx].m_nPageId )
+ {
+ bRet = true;
+ _rGroupName = OUString::createFromAscii( OptionsMap_Impl[nIdx].m_pGroupName );
+ if ( OptionsMap_Impl[nIdx].m_pPageName != nullptr )
+ _rPageName = OUString::createFromAscii( OptionsMap_Impl[nIdx].m_pPageName );
+ break;
+ }
+ ++nIdx;
+ }
+
+ return bRet;
+}
+
+static bool lcl_isOptionHidden( sal_uInt16 _nPageId, const SvtOptionsDialogOptions& _rOptOptions )
+{
+ bool bIsHidden = false;
+ OUString sGroupName, sPageName;
+ if ( lcl_getStringFromID( _nPageId, sGroupName, sPageName ) )
+ {
+ if ( sPageName.isEmpty() )
+ bIsHidden = _rOptOptions.IsGroupHidden( sGroupName );
+ else
+ bIsHidden = _rOptOptions.IsPageHidden( sPageName, sGroupName );
+ }
+ return bIsHidden;
+}
+
+struct OptionsPageInfo
+{
+ std::unique_ptr<SfxTabPage> m_xPage;
+ sal_uInt16 m_nPageId;
+ OUString m_sPageURL;
+ OUString m_sEventHdl;
+ std::unique_ptr<ExtensionsTabPage> m_xExtPage;
+
+ explicit OptionsPageInfo( sal_uInt16 nId ) : m_nPageId( nId ) {}
+};
+
+struct OptionsGroupInfo
+{
+ std::optional<SfxItemSet> m_pInItemSet;
+ std::unique_ptr<SfxItemSet> m_pOutItemSet;
+ SfxShell* m_pShell; // used to create the page
+ SfxModule* m_pModule; // used to create the ItemSet
+ sal_uInt16 m_nDialogId; // Id of the former dialog
+
+ OptionsGroupInfo( SfxShell* pSh, SfxModule* pMod, sal_uInt16 nId ) :
+ m_pShell( pSh ),
+ m_pModule( pMod ), m_nDialogId( nId ) {}
+};
+
+#define INI_LIST() \
+ , m_pParent ( pParent )\
+ , sTitle ( m_xDialog->get_title() )\
+ , bForgetSelection ( false )\
+ , bIsFromExtensionManager( false ) \
+ , bIsForSetDocumentLanguage( false ) \
+ , bNeedsRestart ( false ) \
+ , eRestartReason( svtools::RESTART_REASON_NONE )
+
+void OfaTreeOptionsDialog::InitWidgets()
+{
+ xOkPB = m_xBuilder->weld_button("ok");
+ xApplyPB = m_xBuilder->weld_button("apply");
+ xBackPB = m_xBuilder->weld_button("revert");
+ xTreeLB = m_xBuilder->weld_tree_view("pages");
+ xTabBox = m_xBuilder->weld_container("box");
+ Size aSize(xTreeLB->get_approximate_digit_width() * 82, xTreeLB->get_height_rows(30));
+#if HAVE_FEATURE_GPGME
+ // tdf#115015: make enough space for crypto settings (approx. 14 text edits + padding)
+ aSize.setHeight((weld::GetMinimumEditHeight() + 6) * 14);
+#endif
+ xTabBox->set_size_request(aSize.Width(), aSize.Height());
+ xTreeLB->set_size_request(xTreeLB->get_approximate_digit_width() * 35, aSize.Height());
+}
+
+// Ctor() with Frame -----------------------------------------------------
+OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, const Reference< XFrame >& _xFrame, bool bActivateLastSelection)
+ : SfxOkDialogController(pParent, "cui/ui/optionsdialog.ui", "OptionsDialog")
+ INI_LIST()
+{
+ InitWidgets();
+
+ InitTreeAndHandler();
+ Initialize( _xFrame );
+ LoadExtensionOptions( u"" );
+ if (bActivateLastSelection)
+ ActivateLastSelection();
+
+ xTreeLB->set_accessible_name(m_xDialog->get_title());
+}
+
+// Ctor() with ExtensionId -----------------------------------------------
+OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, std::u16string_view rExtensionId)
+ : SfxOkDialogController(pParent, "cui/ui/optionsdialog.ui", "OptionsDialog")
+ INI_LIST()
+{
+ InitWidgets();
+
+ bIsFromExtensionManager = ( !rExtensionId.empty() );
+ InitTreeAndHandler();
+ LoadExtensionOptions( rExtensionId );
+ ActivateLastSelection();
+}
+
+OfaTreeOptionsDialog::~OfaTreeOptionsDialog()
+{
+ xCurrentPageEntry.reset();
+
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ // first children
+ while (bEntry)
+ {
+ // if Child (has parent), then OptionsPageInfo
+ if (xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsPageInfo *pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
+ if(pPageInfo->m_xPage)
+ {
+ pPageInfo->m_xPage->FillUserData();
+ OUString aPageData(pPageInfo->m_xPage->GetUserData());
+ if ( !aPageData.isEmpty() )
+ {
+ SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
+ SetViewOptUserItem( aTabPageOpt, aPageData );
+ }
+ pPageInfo->m_xPage.reset();
+ }
+
+ if (pPageInfo->m_nPageId == RID_SFXPAGE_LINGU)
+ {
+ // write personal dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ linguistic::SaveDictionaries( xDicList );
+ }
+ }
+
+ pPageInfo->m_xExtPage.reset();
+
+ delete pPageInfo;
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+
+ // and parents
+ bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
+ delete pGroupInfo;
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+ deleteGroupNames();
+}
+
+OptionsPageInfo* OfaTreeOptionsDialog::AddTabPage(
+ sal_uInt16 nId, const OUString& rPageName, sal_uInt16 nGroup )
+{
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator();
+ if (!xTreeLB->get_iter_first(*xParent))
+ return nullptr;
+ xTreeLB->iter_nth_sibling(*xParent, nGroup);
+
+ OptionsPageInfo* pPageInfo = new OptionsPageInfo( nId );
+ OUString sId(weld::toId(pPageInfo));
+ xTreeLB->insert(xParent.get(), -1, &rPageName, &sId, nullptr, nullptr, false, nullptr);
+ return pPageInfo;
+}
+
+// the ItemSet* is passed on to the dialog's ownership
+sal_uInt16 OfaTreeOptionsDialog::AddGroup(const OUString& rGroupName,
+ SfxShell* pCreateShell,
+ SfxModule* pCreateModule,
+ sal_uInt16 nDialogId )
+{
+ OptionsGroupInfo* pInfo =
+ new OptionsGroupInfo( pCreateShell, pCreateModule, nDialogId );
+ OUString sId(weld::toId(pInfo));
+ xTreeLB->append(sId, rGroupName);
+
+ sal_uInt16 nRet = 0;
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ nRet++;
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+ return nRet - 1;
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, ShowPageHdl_Impl, weld::TreeView&, void)
+{
+ SelectHdl_Impl();
+}
+
+void OfaTreeOptionsDialog::ResetCurrentPageFromConfig()
+{
+ if (!(xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry)))
+ return;
+
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
+ if (pPageInfo->m_xPage)
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
+ xTreeLB->iter_parent(*xParent);
+ OptionsGroupInfo* pGroupInfo =
+ weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ pPageInfo->m_xPage->Reset( &*pGroupInfo->m_pInItemSet );
+ }
+ else if ( pPageInfo->m_xExtPage )
+ pPageInfo->m_xExtPage->ResetPage();
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, BackHdl_Impl, weld::Button&, void)
+{
+ ResetCurrentPageFromConfig();
+}
+
+void OfaTreeOptionsDialog::ApplyOptions()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
+ if ( pPageInfo->m_xPage && !pPageInfo->m_xPage->HasExchangeSupport() )
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xEntry.get());
+ xTreeLB->iter_parent(*xParent);
+ OptionsGroupInfo* pGroupInfo =
+ weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ pPageInfo->m_xPage->FillItemSet(pGroupInfo->m_pOutItemSet.get());
+ }
+
+ if ( pPageInfo->m_xExtPage )
+ {
+ pPageInfo->m_xExtPage->DeactivatePage();
+ pPageInfo->m_xExtPage->SavePage();
+ }
+ if ( pPageInfo->m_xPage && RID_OPTPAGE_CHART_DEFCOLORS == pPageInfo->m_nPageId )
+ {
+ SvxDefaultColorOptPage* pPage = static_cast<SvxDefaultColorOptPage *>(pPageInfo->m_xPage.get());
+ pPage->SaveChartOptions();
+ }
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, HelpHdl_Impl, weld::Widget&, bool)
+{
+ Help* pHelp = Application::GetHelp();
+ if (pHelp && xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
+ if (pPageInfo->m_xPage)
+ {
+ OString sHelpId(pPageInfo->m_xPage->GetHelpId());
+ pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), m_xDialog.get());
+ return false;
+ }
+ }
+ return true;
+}
+
+IMPL_LINK(OfaTreeOptionsDialog, ApplyHdl_Impl, weld::Button&, rButton, void)
+{
+ bool bOkPressed = &rButton == xOkPB.get();
+
+ OptionsGroupInfo* pGroupInfo = nullptr;
+
+ if (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
+ if ( pPageInfo->m_xPage )
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
+ xTreeLB->iter_parent(*xParent);
+
+ pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId
+ && pPageInfo->m_xPage->HasExchangeSupport() )
+ {
+ DeactivateRC nLeave = pPageInfo->m_xPage->DeactivatePage(pGroupInfo->m_pOutItemSet.get());
+ if ( nLeave == DeactivateRC::KeepPage )
+ {
+ // the page mustn't be left, so return early
+ assert(xTreeLB->is_selected(*xCurrentPageEntry)); // presumably this must be true here
+ if (bOkPressed)
+ return;
+ }
+ }
+ }
+ }
+
+ ApplyOptions();
+ ApplyItemSets();
+ utl::ConfigManager::storeConfigItems();
+
+ if (bOkPressed)
+ m_xDialog->response(RET_OK);
+ else
+ {
+ // tdf#137930 rebuild the in and out itemsets to reflect the current
+ // post-apply state
+ if (pGroupInfo && pGroupInfo->m_pInItemSet)
+ {
+ // tdf#138596 seeing as the SfxTabPages keep pointers to the m_pInItemSet
+ // we update the contents of the existing SfxItemSets to match
+ // the current settings, rather than create new ones
+ auto xInItemSet = pGroupInfo->m_pShell
+ ? pGroupInfo->m_pShell->CreateItemSet( pGroupInfo->m_nDialogId )
+ : CreateItemSet( pGroupInfo->m_nDialogId );
+ pGroupInfo->m_pInItemSet->Set(*xInItemSet, false);
+ pGroupInfo->m_pOutItemSet->ClearItem();
+ }
+
+ // for the Apply case, now that the settings are saved to config,
+ // reload the current page so it knows what the config now states
+ ResetCurrentPageFromConfig();
+ // reselect it to undo possible DeactivatePage above
+ xCurrentPageEntry.reset();
+ SelectHdl_Impl();
+ }
+
+ if (!bNeedsRestart)
+ return;
+
+ SolarMutexGuard aGuard;
+ weld::Window* pParent;
+ if (!bOkPressed)
+ pParent = m_xDialog.get();
+ else
+ {
+ m_xDialog->hide();
+ pParent = m_pParent;
+ }
+ bool bRestart = ::svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
+ pParent, eRestartReason);
+ if (bRestart && !bOkPressed)
+ m_xDialog->response(RET_OK);
+}
+
+void OfaTreeOptionsDialog::ApplyItemSets()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
+ if(pGroupInfo->m_pOutItemSet)
+ {
+ if(pGroupInfo->m_pShell)
+ pGroupInfo->m_pShell->ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
+ else
+ ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
+ }
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+}
+
+void OfaTreeOptionsDialog::InitTreeAndHandler()
+{
+ xTreeLB->set_help_id(HID_OFADLG_TREELISTBOX);
+ xTreeLB->connect_changed( LINK( this, OfaTreeOptionsDialog, ShowPageHdl_Impl ) );
+ xBackPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, BackHdl_Impl ) );
+ xApplyPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, ApplyHdl_Impl ) );
+ xOkPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, ApplyHdl_Impl ) );
+ m_xDialog->connect_help( LINK( this, OfaTreeOptionsDialog, HelpHdl_Impl ) );
+}
+
+void OfaTreeOptionsDialog::ActivatePage( sal_uInt16 nResId )
+{
+ bIsForSetDocumentLanguage = false;
+ if ( nResId == OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE )
+ {
+ bIsForSetDocumentLanguage = true;
+ nResId = OFA_TP_LANGUAGES;
+ }
+
+ DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ bForgetSelection = true;
+ sal_uInt16 nTemp = pLastPageSaver->m_nLastPageId;
+ pLastPageSaver->m_nLastPageId = nResId;
+ ActivateLastSelection();
+ pLastPageSaver->m_nLastPageId = nTemp;
+}
+
+void OfaTreeOptionsDialog::ActivatePage( const OUString& rPageURL )
+{
+ DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ bForgetSelection = true;
+ pLastPageSaver->m_nLastPageId = 0;
+ pLastPageSaver->m_sLastPageURL_Tools = rPageURL;
+ ActivateLastSelection();
+}
+
+void OfaTreeOptionsDialog::ActivateLastSelection()
+{
+ std::unique_ptr<weld::TreeIter> xEntry;
+
+ if (pLastPageSaver)
+ {
+ OUString sLastURL = bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
+ : pLastPageSaver->m_sLastPageURL_Tools;
+ if ( sLastURL.isEmpty() )
+ {
+ sLastURL = !bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
+ : pLastPageSaver->m_sLastPageURL_Tools;
+ }
+
+ bool bMustExpand = ( INetURLObject( sLastURL ).GetProtocol() == INetProtocol::File );
+
+ std::unique_ptr<weld::TreeIter> xTemp = xTreeLB->make_iterator();
+ bool bTemp = xTreeLB->get_iter_first(*xTemp);
+ while (bTemp)
+ {
+ // restore only selection of a leaf
+ if (xTreeLB->get_iter_depth(*xTemp) && xTreeLB->get_id(*xTemp).toInt64())
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xTemp));
+ OUString sPageURL = pPageInfo->m_sPageURL;
+ if ( bMustExpand )
+ {
+ sPageURL = comphelper::getExpandedUri(
+ comphelper::getProcessComponentContext(), sPageURL);
+ }
+
+ if ( ( !bIsFromExtensionManager
+ && pPageInfo->m_nPageId && pPageInfo->m_nPageId == pLastPageSaver->m_nLastPageId )
+ || ( !pPageInfo->m_nPageId && sLastURL == sPageURL ) )
+ {
+ xEntry = xTreeLB->make_iterator(xTemp.get());
+ break;
+ }
+ }
+ bTemp = xTreeLB->iter_next(*xTemp);
+ }
+ }
+
+ if (!xEntry)
+ {
+ xEntry = xTreeLB->make_iterator();
+ if (!xTreeLB->get_iter_first(*xEntry) || !xTreeLB->iter_next(*xEntry))
+ xEntry.reset();
+ }
+
+ if (!xEntry)
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
+ xTreeLB->iter_parent(*xParent);
+ xTreeLB->expand_row(*xParent);
+ xTreeLB->scroll_to_row(*xParent);
+ xTreeLB->scroll_to_row(*xEntry);
+ xTreeLB->set_cursor(*xEntry);
+ xTreeLB->select(*xEntry);
+ xTreeLB->grab_focus();
+ SelectHdl_Impl();
+}
+
+void OfaTreeOptionsDialog::InitItemSets(OptionsGroupInfo& rGroupInfo)
+{
+ if (!rGroupInfo.m_pInItemSet)
+ rGroupInfo.m_pInItemSet.emplace( rGroupInfo.m_pShell
+ ? *rGroupInfo.m_pShell->CreateItemSet( rGroupInfo.m_nDialogId )
+ : *CreateItemSet( rGroupInfo.m_nDialogId ) );
+ if (!rGroupInfo.m_pOutItemSet)
+ rGroupInfo.m_pOutItemSet = std::make_unique<SfxItemSet>(
+ *rGroupInfo.m_pInItemSet->GetPool(),
+ rGroupInfo.m_pInItemSet->GetRanges());
+}
+
+void OfaTreeOptionsDialog::SelectHdl_Impl()
+{
+ std::unique_ptr<weld::TreeIter> xEntry(xTreeLB->make_iterator());
+
+ if (!xTreeLB->get_cursor(xEntry.get()))
+ return;
+
+ if (xCurrentPageEntry && xCurrentPageEntry->equal(*xEntry))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
+ bool bParent = xTreeLB->iter_parent(*xParent);
+
+ // If the user has selected a category, automatically switch to a suitable
+ // default sub-page instead.
+ if (!bParent)
+ return;
+
+ BuilderPage* pNewPage = nullptr;
+ OptionsPageInfo* pOptPageInfo = (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ ? weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry)) : nullptr;
+
+ if (pOptPageInfo && pOptPageInfo->m_xPage && pOptPageInfo->m_xPage->IsVisible())
+ {
+ std::unique_ptr<weld::TreeIter> xCurParent(xTreeLB->make_iterator(xCurrentPageEntry.get()));
+ xTreeLB->iter_parent(*xCurParent);
+
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xCurParent));
+ DeactivateRC nLeave = DeactivateRC::LeavePage;
+ if ( RID_SVXPAGE_COLOR != pOptPageInfo->m_nPageId && pOptPageInfo->m_xPage->HasExchangeSupport() )
+ nLeave = pOptPageInfo->m_xPage->DeactivatePage( pGroupInfo->m_pOutItemSet.get() );
+
+ if ( nLeave == DeactivateRC::KeepPage )
+ {
+ // we cannot leave this page, this is may be from a user clicking a different entry
+ // in the tree so reselect the current page
+ xTreeLB->select(*xCurrentPageEntry);
+ return;
+ }
+ else
+ pOptPageInfo->m_xPage->set_visible(false);
+ }
+ else if ( pOptPageInfo && pOptPageInfo->m_xExtPage )
+ {
+ pOptPageInfo->m_xExtPage->Hide();
+ pOptPageInfo->m_xExtPage->DeactivatePage();
+ }
+
+ OptionsPageInfo *pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ if(!pPageInfo->m_xPage && pPageInfo->m_nPageId > 0)
+ {
+ InitItemSets(*pGroupInfo);
+
+ pPageInfo->m_xPage = ::CreateGeneralTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
+
+ if(!pPageInfo->m_xPage && pGroupInfo->m_pModule)
+ pPageInfo->m_xPage = pGroupInfo->m_pModule->CreateTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
+
+ DBG_ASSERT( pPageInfo->m_xPage, "tabpage could not created");
+ if ( pPageInfo->m_xPage )
+ {
+ SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
+ pPageInfo->m_xPage->SetUserData( GetViewOptUserItem( aTabPageOpt ) );
+ pPageInfo->m_xPage->Reset( &*pGroupInfo->m_pInItemSet );
+ }
+ }
+ else if ( 0 == pPageInfo->m_nPageId && !pPageInfo->m_xExtPage )
+ {
+ if ( !m_xContainerWinProvider.is() )
+ {
+ m_xContainerWinProvider = awt::ContainerWindowProvider::create( ::comphelper::getProcessComponentContext() );
+ }
+
+ pPageInfo->m_xExtPage = std::make_unique<ExtensionsTabPage>(
+ xTabBox.get(), pPageInfo->m_sPageURL, pPageInfo->m_sEventHdl, m_xContainerWinProvider);
+ }
+
+ if ( pPageInfo->m_xPage )
+ {
+ if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId &&
+ pPageInfo->m_xPage->HasExchangeSupport())
+ {
+ pPageInfo->m_xPage->ActivatePage(*pGroupInfo->m_pOutItemSet);
+ }
+ pPageInfo->m_xPage->set_visible(true);
+ }
+ else if ( pPageInfo->m_xExtPage )
+ {
+ pPageInfo->m_xExtPage->Show();
+ pPageInfo->m_xExtPage->ActivatePage();
+ }
+
+ {
+ OUString sTitleText = sTitle
+ + " - " + xTreeLB->get_text(*xParent)
+ + " - " + xTreeLB->get_text(*xEntry);
+ m_xDialog->set_title(sTitleText);
+ }
+
+ xCurrentPageEntry = std::move(xEntry);
+
+ if ( !bForgetSelection )
+ {
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ if ( !bIsFromExtensionManager )
+ pLastPageSaver->m_nLastPageId = pPageInfo->m_nPageId;
+ if ( pPageInfo->m_xExtPage )
+ {
+ if ( bIsFromExtensionManager )
+ pLastPageSaver->m_sLastPageURL_ExtMgr = pPageInfo->m_sPageURL;
+ else
+ pLastPageSaver->m_sLastPageURL_Tools = pPageInfo->m_sPageURL;
+ }
+ }
+ pNewPage = pPageInfo->m_xPage.get();
+
+ // fdo#58170 use current page's layout child HelpId, unless there isn't a current page
+ OString sHelpId(pNewPage ? pNewPage->GetHelpId() : OString());
+ if (sHelpId.isEmpty())
+ sHelpId = HID_OFADLG_TREELISTBOX;
+ xTreeLB->set_help_id(sHelpId);
+}
+
+std::optional<SfxItemSet> OfaTreeOptionsDialog::CreateItemSet( sal_uInt16 nId )
+{
+ Reference< XLinguProperties > xProp( LinguMgr::GetLinguPropertySet() );
+ std::optional<SfxItemSet> pRet;
+ switch(nId)
+ {
+ case SID_GENERAL_OPTIONS:
+ {
+ pRet.emplace(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_METRIC, SID_ATTR_METRIC,
+ SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
+ SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER,
+ SID_ATTR_YEAR2000, SID_ATTR_YEAR2000> );
+
+ SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aOptSet( SfxGetpApp()->GetPool() );
+ SfxApplication::GetOptions(aOptSet);
+ pRet->Put(aOptSet);
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ const SfxUInt16Item* pItem = nullptr;
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+
+ // miscellaneous - Year2000
+ if( SfxItemState::DEFAULT <= pDispatch->QueryState( SID_ATTR_YEAR2000, pItem ) )
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, pItem->GetValue() ) );
+ else
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, officecfg::Office::Common::DateFormat::TwoDigitYear::get() ) );
+ }
+ else
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, officecfg::Office::Common::DateFormat::TwoDigitYear::get() ) );
+
+
+ // miscellaneous - Tabulator
+ pRet->Put(SfxBoolItem(SID_PRINTER_NOTFOUND_WARN, officecfg::Office::Common::Print::Warning::NotFound::get()));
+
+ SfxPrinterChangeFlags nFlag = officecfg::Office::Common::Print::Warning::PaperSize::get() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE;
+ nFlag |= officecfg::Office::Common::Print::Warning::PaperOrientation::get() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE;
+ pRet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, static_cast<int>(nFlag) ));
+
+ }
+ break;
+ case SID_LANGUAGE_OPTIONS :
+ {
+ pRet.emplace(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_ATTR_CHAR_CJK_LANGUAGE, SID_ATTR_CHAR_CJK_LANGUAGE,
+ SID_ATTR_CHAR_CTL_LANGUAGE, SID_ATTR_CHAR_CTL_LANGUAGE,
+ SID_SET_DOCUMENT_LANGUAGE, SID_SET_DOCUMENT_LANGUAGE,
+ SID_ATTR_LANGUAGE, SID_ATTR_LANGUAGE,
+ SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
+ SID_OPT_LOCALE_CHANGED, SID_OPT_LOCALE_CHANGED>);
+
+ // for linguistic
+ SfxHyphenRegionItem aHyphen( SID_ATTR_HYPHENREGION );
+
+ sal_Int16 nMinLead = 2,
+ nMinTrail = 2;
+ if (xProp.is())
+ {
+ nMinLead = xProp->getHyphMinLeading();
+ nMinTrail = xProp->getHyphMinTrailing();
+ }
+ aHyphen.GetMinLead() = static_cast<sal_uInt8>(nMinLead);
+ aHyphen.GetMinTrail() = static_cast<sal_uInt8>(nMinTrail);
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ const SvxLanguageItem* pLangItem = nullptr;
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_LANGUAGE, pLangItem))
+ pRet->Put(*pLangItem, SID_ATTR_LANGUAGE);
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_CHAR_CJK_LANGUAGE, pLangItem))
+ pRet->Put(*pLangItem, SID_ATTR_CHAR_CJK_LANGUAGE);
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_CHAR_CTL_LANGUAGE, pLangItem))
+ pRet->Put(*pLangItem, SID_ATTR_CHAR_CTL_LANGUAGE);
+
+ pRet->Put(aHyphen);
+ const SfxPoolItem* pItem = nullptr;
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_AUTOSPELL_CHECK, pItem))
+ {
+ pRet->Put(std::unique_ptr<SfxPoolItem>(pItem->Clone()));
+ }
+ else
+ {
+ bool bVal = false;
+ if (xProp.is())
+ {
+ bVal = xProp->getIsSpellAuto();
+ }
+
+ pRet->Put(SfxBoolItem(SID_AUTOSPELL_CHECK, bVal));
+ }
+ }
+ pRet->Put( SfxBoolItem( SID_SET_DOCUMENT_LANGUAGE, bIsForSetDocumentLanguage ) );
+ }
+ break;
+ case SID_INET_DLG :
+ pRet.emplace( SfxGetpApp()->GetPool(),
+ svl::Items<
+ //SID_OPTIONS_START - ..END
+ SID_SAVEREL_INET, SID_SAVEREL_FSYS,
+ SID_INET_NOPROXY, SID_INET_FTP_PROXY_PORT,
+ SID_SECURE_URL, SID_SECURE_URL> );
+ SfxApplication::GetOptions(*pRet);
+ break;
+ case SID_FILTER_DLG:
+ pRet.emplace(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_ATTR_WARNALIENFORMAT, SID_ATTR_WARNALIENFORMAT,
+ SID_ATTR_DOCINFO, SID_ATTR_AUTOSAVEMINUTE,
+ SID_SAVEREL_INET, SID_SAVEREL_FSYS,
+ SID_ATTR_PRETTYPRINTING, SID_ATTR_PRETTYPRINTING> );
+ SfxApplication::GetOptions(*pRet);
+ break;
+
+ case SID_SB_STARBASEOPTIONS:
+ pRet.emplace( SfxGetpApp()->GetPool(),
+ svl::Items<SID_SB_POOLING_ENABLED, SID_SB_DB_REGISTER> );
+ ::offapp::ConnectionPoolConfig::GetOptions(*pRet);
+ svx::DbRegisteredNamesConfig::GetOptions(*pRet);
+ break;
+
+ case SID_SCH_EDITOPTIONS:
+ {
+ SvxChartOptions aChartOpt;
+ pRet.emplace( SfxGetpApp()->GetPool(), svl::Items<SID_SCH_EDITOPTIONS, SID_SCH_EDITOPTIONS> );
+ pRet->Put( SvxChartColorTableItem( SID_SCH_EDITOPTIONS, aChartOpt.GetDefaultColors() ) );
+ break;
+ }
+ }
+ return pRet;
+}
+
+void OfaTreeOptionsDialog::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
+{
+ switch(nId)
+ {
+ case SID_GENERAL_OPTIONS:
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aOptSet(SfxGetpApp()->GetPool());
+ aOptSet.Put(rSet);
+ if(aOptSet.Count())
+ SfxGetpApp()->SetOptions( aOptSet );
+ // get dispatcher anew, because SetOptions() might have destroyed the dispatcher
+ SfxViewFrame *pViewFrame = SfxViewFrame::Current();
+
+// evaluate Year2000
+ sal_uInt16 nY2K = USHRT_MAX;
+ const SfxUInt16Item* pYearItem = rSet.GetItemIfSet( SID_ATTR_YEAR2000, false );
+ if( pYearItem )
+ nY2K = pYearItem->GetValue();
+ if( USHRT_MAX != nY2K )
+ {
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ pDispatch->ExecuteList(SID_ATTR_YEAR2000,
+ SfxCallMode::ASYNCHRON, { pYearItem });
+ }
+ officecfg::Office::Common::DateFormat::TwoDigitYear::set(nY2K, batch);
+ }
+
+// evaluate print
+ if(const SfxBoolItem* pWarnItem = rSet.GetItemIfSet(SID_PRINTER_NOTFOUND_WARN, false))
+ officecfg::Office::Common::Print::Warning::NotFound::set(pWarnItem->GetValue(), batch);
+
+ if(const SfxFlagItem* pFlag = rSet.GetItemIfSet(SID_PRINTER_CHANGESTODOC, false))
+ {
+ bool bPaperSizeWarning = bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
+ officecfg::Office::Common::Print::Warning::PaperSize::set(bPaperSizeWarning, batch);
+ bool bPaperOrientationWarning = bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
+ officecfg::Office::Common::Print::Warning::PaperOrientation::set(bPaperOrientationWarning, batch);
+ }
+
+// evaluate help options
+ bool bHelpTips = officecfg::Office::Common::Help::Tip::get();
+ if ( bHelpTips != Help::IsQuickHelpEnabled() )
+ bHelpTips ? Help::EnableQuickHelp() : Help::DisableQuickHelp();
+ bool bExtendedHelp = officecfg::Office::Common::Help::ExtendedTip::get();
+ if ( bExtendedHelp != Help::IsBalloonHelpEnabled() )
+ bExtendedHelp ? Help::EnableBalloonHelp() : Help::DisableBalloonHelp();
+
+ batch->commit();
+ }
+ break;
+ case SID_LANGUAGE_OPTIONS :
+ {
+ OfaTreeOptionsDialog::ApplyLanguageOptions(rSet);
+ }
+ break;
+ case SID_INET_DLG :
+ case SID_FILTER_DLG:
+ SfxGetpApp()->SetOptions( rSet );
+ break;
+
+ case SID_SB_STARBASEOPTIONS:
+ ::offapp::ConnectionPoolConfig::SetOptions( rSet );
+ svx::DbRegisteredNamesConfig::SetOptions(rSet);
+ break;
+
+ case SID_SCH_EDITOPTIONS:
+ // nothing to do. Chart options only apply to newly created charts
+ break;
+
+ default:
+ {
+ OSL_FAIL( "Unhandled option in ApplyItemSet" );
+ }
+ break;
+ }
+
+}
+void OfaTreeOptionsDialog::ApplyLanguageOptions(const SfxItemSet& rSet)
+{
+ bool bSaveSpellCheck = false;
+ const SfxPoolItem* pItem = nullptr;
+
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XLinguProperties > xProp = LinguProperties::create( xContext );
+ if ( const SfxHyphenRegionItem* pHyphenItem = rSet.GetItemIfSet(SID_ATTR_HYPHENREGION, false ) )
+ {
+ xProp->setHyphMinLeading( static_cast<sal_Int16>(pHyphenItem->GetMinLead()) );
+ xProp->setHyphMinTrailing( static_cast<sal_Int16>(pHyphenItem->GetMinTrail()) );
+ bSaveSpellCheck = true;
+ }
+
+ SfxViewFrame *pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ pItem = nullptr;
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CTL_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CJK_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+
+ if( SfxItemState::SET == rSet.GetItemState(SID_AUTOSPELL_CHECK, false, &pItem ))
+ {
+ bool bOnlineSpelling = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ pDispatch->ExecuteList(SID_AUTOSPELL_CHECK,
+ SfxCallMode::ASYNCHRON|SfxCallMode::RECORD, { pItem });
+
+ xProp->setIsSpellAuto( bOnlineSpelling );
+ }
+
+ if( bSaveSpellCheck )
+ {
+ //! the config item has changed since we modified the
+ //! property set it uses
+ pDispatch->Execute(SID_SPELLCHECKER_CHANGED, SfxCallMode::ASYNCHRON);
+ }
+ }
+
+ if( SfxItemState::SET == rSet.GetItemState(SID_OPT_LOCALE_CHANGED, false, &pItem ))
+ {
+ SfxViewFrame* _pViewFrame = SfxViewFrame::GetFirst();
+ while ( _pViewFrame )
+ {
+ _pViewFrame->GetDispatcher()->ExecuteList(pItem->Which(),
+ SfxCallMode::ASYNCHRON, { pItem });
+ _pViewFrame = SfxViewFrame::GetNext( *_pViewFrame );
+ }
+ }
+}
+
+static OUString getCurrentFactory_Impl( const Reference< XFrame >& _xFrame )
+{
+ OUString sIdentifier;
+ Reference < XFrame > xCurrentFrame( _xFrame );
+ Reference < XModuleManager2 > xModuleManager = ModuleManager::create(::comphelper::getProcessComponentContext());
+ if ( !xCurrentFrame.is() )
+ {
+ Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ xCurrentFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( xCurrentFrame.is() )
+ {
+ try
+ {
+ sIdentifier = xModuleManager->identify( xCurrentFrame );
+ }
+ catch ( css::frame::UnknownModuleException& )
+ {
+ SAL_INFO( "cui.options", "unknown module" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "getActiveModule_Impl(): exception of XModuleManager::identify()" );
+ }
+ }
+
+ return sIdentifier;
+}
+
+void OfaTreeOptionsDialog::Initialize( const Reference< XFrame >& _xFrame )
+{
+ sal_uInt16 nGroup = 0;
+
+ SvtOptionsDialogOptions aOptionsDlgOpt;
+ sal_uInt16 nPageId;
+
+ // %PRODUCTNAME options
+ if ( !lcl_isOptionHidden( SID_GENERAL_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName(u"ProductName", CuiResId(SID_GENERAL_OPTIONS_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_GENERAL_OPTIONS_RES[0].first), nullptr, nullptr, SID_GENERAL_OPTIONS );
+ const sal_uInt16 nEnd = static_cast<sal_uInt16>(std::size(SID_GENERAL_OPTIONS_RES));
+
+ for (sal_uInt16 i = 1; i < nEnd; ++i)
+ {
+ OUString sNewTitle = CuiResId(SID_GENERAL_OPTIONS_RES[i].first);
+ nPageId = SID_GENERAL_OPTIONS_RES[i].second;
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ // Disable Online Update page if service not installed
+ if( RID_SVXPAGE_ONLINEUPDATE == nPageId )
+ {
+ try
+ {
+ Reference < XInterface > xService( setup::UpdateCheck::create( ::comphelper::getProcessComponentContext() ) );
+ if( ! xService.is() )
+ continue;
+ }
+ catch ( css::uno::DeploymentException& )
+ {
+ continue;
+ }
+ }
+
+ // Disable Basic IDE options, if experimental features are not enabled
+ if( RID_SVXPAGE_BASICIDE_OPTIONS == nPageId )
+ {
+ if( ! officecfg::Office::Common::Misc::ExperimentalMode::get() )
+ continue;
+ }
+
+ AddTabPage( nPageId, sNewTitle, nGroup );
+ }
+ }
+
+ // Load and Save options
+ if ( !lcl_isOptionHidden( SID_FILTER_DLG, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"LoadSave", CuiResId(SID_FILTER_DLG_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_FILTER_DLG_RES[0].first), nullptr, nullptr, SID_FILTER_DLG );
+ for ( size_t i = 1; i < std::size(SID_FILTER_DLG_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_FILTER_DLG_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_FILTER_DLG_RES[i].first), nGroup );
+ }
+ }
+
+ // Language options
+ SvtCTLOptions aCTLLanguageOptions;
+ if ( !lcl_isOptionHidden( SID_LANGUAGE_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName(u"LanguageSettings", CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first), nullptr, nullptr, SID_LANGUAGE_OPTIONS );
+ for (size_t i = 1; i < std::size(SID_LANGUAGE_OPTIONS_RES); ++i)
+ {
+ nPageId = static_cast<sal_uInt16>(SID_LANGUAGE_OPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+ if ( ( RID_SVXPAGE_JSEARCH_OPTIONS != nPageId || SvtCJKOptions::IsJapaneseFindEnabled() ) &&
+ ( RID_SVXPAGE_ASIAN_LAYOUT != nPageId || SvtCJKOptions::IsAsianTypographyEnabled() ) &&
+ ( RID_SVXPAGE_OPTIONS_CTL != nPageId || aCTLLanguageOptions.IsCTLFontEnabled() ) )
+ AddTabPage(nPageId, CuiResId(SID_LANGUAGE_OPTIONS_RES[i].first), nGroup);
+ }
+ }
+
+ OUString aFactory = getCurrentFactory_Impl( _xFrame );
+ DBG_ASSERT( GetModuleIdentifier( _xFrame ) == aFactory, "S H I T!!!" );
+
+ // Writer and Writer/Web options
+ SvtModuleOptions aModuleOpt;
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ {
+ // text document
+ if ( aFactory == "com.sun.star.text.TextDocument"
+ || aFactory == "com.sun.star.text.WebDocument"
+ || aFactory == "com.sun.star.text.GlobalDocument" )
+ {
+ SfxModule* pSwMod = SfxApplication::GetModule(SfxToolsModule::Writer);
+ if ( !lcl_isOptionHidden( SID_SW_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ if ( aFactory == "com.sun.star.text.WebDocument" )
+ setGroupName( u"WriterWeb", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
+ else
+ setGroupName( u"Writer", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup(CuiResId(SID_SW_EDITOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_EDITOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SW_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SW_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+ if ( ( RID_SW_TP_STD_FONT_CJK != nPageId || SvtCJKOptions::IsCJKFontEnabled() ) &&
+ ( RID_SW_TP_STD_FONT_CTL != nPageId || aCTLLanguageOptions.IsCTLFontEnabled() ) &&
+ ( RID_SW_TP_MAILCONFIG != nPageId || MailMergeCfg_Impl().IsEmailSupported() ) )
+ AddTabPage( nPageId, CuiResId(SID_SW_EDITOPTIONS_RES[i].first), nGroup );
+ }
+#ifdef DBG_UTIL
+ AddTabPage( RID_SW_TP_OPTTEST_PAGE, "Internal Test", nGroup );
+#endif
+ }
+
+ // HTML documents
+ if ( !lcl_isOptionHidden( SID_SW_ONLINEOPTIONS, aOptionsDlgOpt ) )
+ {
+ nGroup = AddGroup(CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_ONLINEOPTIONS );
+ for( size_t i = 1; i < std::size(SID_SW_ONLINEOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SW_ONLINEOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage(nPageId, CuiResId(SID_SW_ONLINEOPTIONS_RES[i].first), nGroup);
+ }
+#ifdef DBG_UTIL
+ AddTabPage( RID_SW_TP_OPTTEST_PAGE, "Internal Test", nGroup );
+#endif
+ }
+ }
+ }
+
+ // Calc options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ {
+ if ( aFactory == "com.sun.star.sheet.SpreadsheetDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SC_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ SfxModule* pScMod = SfxApplication::GetModule( SfxToolsModule::Calc );
+ setGroupName( u"Calc", CuiResId(SID_SC_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SC_EDITOPTIONS_RES[0].first), pScMod, pScMod, SID_SC_EDITOPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(std::size(SID_SC_EDITOPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SC_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SC_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Impress options
+ SfxModule* pSdMod = SfxApplication::GetModule( SfxToolsModule::Draw );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ {
+ if ( aFactory == "com.sun.star.presentation.PresentationDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SD_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"Impress", CuiResId(SID_SD_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SD_EDITOPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_EDITOPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(std::size(SID_SD_EDITOPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SD_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SD_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Draw options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ {
+ if ( aFactory == "com.sun.star.drawing.DrawingDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SD_GRAPHIC_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"Draw", CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_GRAPHIC_OPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(std::size(SID_SD_GRAPHIC_OPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SD_GRAPHIC_OPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Math options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ {
+ if ( aFactory == "com.sun.star.formula.FormulaProperties" )
+ {
+ if ( !lcl_isOptionHidden( SID_SM_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ SfxModule* pSmMod = SfxApplication::GetModule(SfxToolsModule::Math);
+ setGroupName( u"Math", CuiResId(SID_SM_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup(CuiResId(SID_SM_EDITOPTIONS_RES[0].first), pSmMod, pSmMod, SID_SM_EDITOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SM_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SM_EDITOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SM_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Database - needed only if there is an application which integrates with databases
+ if ( !lcl_isOptionHidden( SID_SB_STARBASEOPTIONS, aOptionsDlgOpt ) &&
+ ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE )
+ || aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER )
+ || aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC )
+ ) )
+ {
+ setGroupName( u"Base", CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first), nullptr, nullptr, SID_SB_STARBASEOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SB_STARBASEOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SB_STARBASEOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SB_STARBASEOPTIONS_RES[i].first), nGroup );
+ }
+ }
+
+ // Chart options (always installed and active)
+ if ( !lcl_isOptionHidden( SID_SCH_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"Charts", CuiResId(SID_SCH_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SCH_EDITOPTIONS_RES[0].first), nullptr, nullptr, SID_SCH_EDITOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SCH_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SCH_EDITOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SCH_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+
+ // Internet options
+ if ( lcl_isOptionHidden( SID_INET_DLG, aOptionsDlgOpt ) )
+ return;
+
+ setGroupName(u"Internet", CuiResId(SID_INET_DLG_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_INET_DLG_RES[0].first), nullptr, nullptr, SID_INET_DLG );
+
+ for ( size_t i = 1; i < std::size(SID_INET_DLG_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_INET_DLG_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+#if defined(_WIN32)
+ // Disable E-mail tab-page on Windows
+ if ( nPageId == RID_SVXPAGE_INET_MAIL )
+ continue;
+#endif
+ AddTabPage( nPageId, CuiResId(SID_INET_DLG_RES[i].first), nGroup );
+ }
+}
+
+static bool isNodeActive( OptionsNode const * pNode, Module* pModule )
+{
+ if ( !pNode )
+ return false;
+
+ // Node for all modules active?
+ if ( pNode->m_bAllModules )
+ return true;
+
+ // OOo-Nodes (Writer, Calc, Impress...) are active if node is already inserted
+ if ( !getGroupName( pNode->m_sId, false ).isEmpty() )
+ return true;
+
+ // no module -> not active
+ if ( !pModule )
+ return false;
+
+ // search node in active module
+ if ( pModule->m_bActive )
+ {
+ for (auto const& j : pModule->m_aNodeList)
+ if ( j->m_sId == pNode->m_sId )
+ return true;
+ }
+ return false;
+}
+
+void OfaTreeOptionsDialog::LoadExtensionOptions( std::u16string_view rExtensionId )
+{
+ std::unique_ptr<Module> pModule;
+
+ // when called by Tools - Options then load nodes of active module
+ if ( rExtensionId.empty() )
+ {
+ pModule = LoadModule( GetModuleIdentifier( Reference< XFrame >() ) );
+ }
+
+ VectorOfNodes aNodeList = LoadNodes( pModule.get(), rExtensionId );
+ InsertNodes( aNodeList );
+}
+
+OUString OfaTreeOptionsDialog::GetModuleIdentifier( const Reference< XFrame >& rFrame )
+{
+ OUString sModule;
+ Reference < XFrame > xCurrentFrame( rFrame );
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ Reference < XModuleManager2 > xModuleManager = ModuleManager::create(xContext);
+
+ if ( !xCurrentFrame.is() )
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create( xContext );
+ xCurrentFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( xCurrentFrame.is() )
+ {
+ try
+ {
+ sModule = xModuleManager->identify( xCurrentFrame );
+ }
+ catch ( css::frame::UnknownModuleException& )
+ {
+ SAL_INFO( "cui.options", "unknown module" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "OfaTreeOptionsDialog::GetModuleIdentifier(): exception of XModuleManager::identify()");
+ }
+ }
+ return sModule;
+}
+
+std::unique_ptr<Module> OfaTreeOptionsDialog::LoadModule(
+ std::u16string_view rModuleIdentifier )
+{
+ std::unique_ptr<Module> pModule;
+ Reference< XNameAccess > xSet(
+ officecfg::Office::OptionsDialog::Modules::get());
+
+ const Sequence< OUString > seqNames = xSet->getElementNames();
+ for ( const OUString& rModule : seqNames )
+ {
+ if ( rModuleIdentifier == rModule )
+ {
+ // current active module found
+ pModule.reset(new Module);
+ pModule->m_bActive = true;
+
+ Reference< XNameAccess > xModAccess;
+ xSet->getByName( rModule ) >>= xModAccess;
+ if ( xModAccess.is() )
+ {
+ // load the nodes of this module
+ Reference< XNameAccess > xNodeAccess;
+ xModAccess->getByName( "Nodes" ) >>= xNodeAccess;
+ if ( xNodeAccess.is() )
+ {
+ const Sequence< OUString > xTemp = xNodeAccess->getElementNames();
+ Reference< XNameAccess > xAccess;
+ sal_Int32 nIndex = -1;
+ for ( const OUString& rNode : xTemp)
+ {
+ xNodeAccess->getByName( rNode ) >>= xAccess;
+ if ( xAccess.is() )
+ {
+ xAccess->getByName( "Index" ) >>= nIndex;
+ if ( nIndex < 0 )
+ // append nodes with index < 0
+ pModule->m_aNodeList.push_back(
+ std::unique_ptr<OrderedEntry>(new OrderedEntry(nIndex, rNode)));
+ else
+ {
+ // search position of the node
+ std::vector<OrderedEntry *>::size_type y = 0;
+ for ( ; y < pModule->m_aNodeList.size(); ++y )
+ {
+ sal_Int32 nNodeIdx = pModule->m_aNodeList[y]->m_nIndex;
+ if ( nNodeIdx < 0 || nNodeIdx > nIndex )
+ break;
+ }
+ // and insert the node on this position
+ pModule->m_aNodeList.insert(
+ pModule->m_aNodeList.begin() + y,
+ std::unique_ptr<OrderedEntry>(new OrderedEntry( nIndex, rNode )) );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ return pModule;
+}
+
+VectorOfNodes OfaTreeOptionsDialog::LoadNodes(
+ Module* pModule, std::u16string_view rExtensionId)
+{
+ VectorOfNodes aOutNodeList;
+
+ Reference< XNameAccess > xSet(
+ officecfg::Office::OptionsDialog::Nodes::get());
+ VectorOfNodes aNodeList;
+ const Sequence< OUString > seqNames = xSet->getElementNames();
+
+ for ( OUString const & sGroupName : seqNames )
+ {
+ Reference< XNameAccess > xNodeAccess;
+ xSet->getByName( sGroupName ) >>= xNodeAccess;
+
+ if ( xNodeAccess.is() )
+ {
+ OUString sNodeId, sLabel, sPageURL;
+ bool bAllModules = false;
+
+ sNodeId = sGroupName;
+ xNodeAccess->getByName( "Label" ) >>= sLabel;
+ xNodeAccess->getByName( "OptionsPage" ) >>= sPageURL;
+ xNodeAccess->getByName( "AllModules" ) >>= bAllModules;
+
+ if ( sLabel.isEmpty() )
+ sLabel = sGroupName;
+ OUString sTemp = getGroupName( sLabel, !rExtensionId.empty() );
+ if ( !sTemp.isEmpty() )
+ sLabel = sTemp;
+ std::unique_ptr<OptionsNode> pNode(new OptionsNode(sNodeId, sLabel, bAllModules));
+
+ if ( rExtensionId.empty() && !isNodeActive( pNode.get(), pModule ) )
+ {
+ continue;
+ }
+
+ Reference< XNameAccess > xLeavesSet;
+ xNodeAccess->getByName( "Leaves" ) >>= xLeavesSet;
+ if ( xLeavesSet.is() )
+ {
+ const Sequence< OUString > seqLeaves = xLeavesSet->getElementNames();
+ for ( OUString const & leafName : seqLeaves )
+ {
+ Reference< XNameAccess > xLeaveAccess;
+ xLeavesSet->getByName( leafName ) >>= xLeaveAccess;
+
+ if ( xLeaveAccess.is() )
+ {
+ OUString sId, sLeafLabel, sEventHdl, sLeafURL, sLeafGrpId;
+ sal_Int32 nLeafGrpIdx = 0;
+
+ xLeaveAccess->getByName( "Id" ) >>= sId;
+ xLeaveAccess->getByName( "Label" ) >>= sLeafLabel;
+ xLeaveAccess->getByName( "OptionsPage" ) >>= sLeafURL;
+ xLeaveAccess->getByName( "EventHandlerService" ) >>= sEventHdl;
+ xLeaveAccess->getByName( "GroupId" ) >>= sLeafGrpId;
+ xLeaveAccess->getByName( "GroupIndex" ) >>= nLeafGrpIdx;
+
+ if ( rExtensionId.empty() || sId == rExtensionId )
+ {
+ std::unique_ptr<OptionsLeaf> pLeaf(new OptionsLeaf(
+ sLeafLabel, sLeafURL, sEventHdl, sLeafGrpId, nLeafGrpIdx ));
+
+ if ( !sLeafGrpId.isEmpty() )
+ {
+ bool bAlreadyOpened = false;
+ if ( !pNode->m_aGroupedLeaves.empty() )
+ {
+ for (auto & rGroup : pNode->m_aGroupedLeaves)
+ {
+ if ( !rGroup.empty() &&
+ rGroup[0]->m_sGroupId == sLeafGrpId )
+ {
+ std::vector<std::unique_ptr<OptionsLeaf>>::size_type l = 0;
+ for ( ; l < rGroup.size(); ++l )
+ {
+ if ( rGroup[l]->m_nGroupIndex >= nLeafGrpIdx )
+ break;
+ }
+ rGroup.insert( rGroup.begin() + l, std::move(pLeaf) );
+ bAlreadyOpened = true;
+ break;
+ }
+ }
+ }
+ if ( !bAlreadyOpened )
+ {
+ std::vector< std::unique_ptr<OptionsLeaf> > aGroupedLeaves;
+ aGroupedLeaves.push_back( std::move(pLeaf) );
+ pNode->m_aGroupedLeaves.push_back( std::move(aGroupedLeaves) );
+ }
+ }
+ else
+ pNode->m_aLeaves.push_back( std::move(pLeaf) );
+ }
+ }
+ }
+ }
+
+ // do not insert nodes without leaves
+ if ( !pNode->m_aLeaves.empty() || !pNode->m_aGroupedLeaves.empty() )
+ {
+ pModule ? aNodeList.push_back( std::move(pNode) ) : aOutNodeList.push_back( std::move(pNode) );
+ }
+ }
+ }
+
+ if ( pModule && !aNodeList.empty() )
+ {
+ for ( auto const & i: pModule->m_aNodeList )
+ {
+ OUString sNodeId = i->m_sId;
+ for ( auto j = aNodeList.begin(); j != aNodeList.end(); ++j )
+ {
+ if ( (*j)->m_sId == sNodeId )
+ {
+ aOutNodeList.push_back( std::move(*j) );
+ aNodeList.erase( j );
+ break;
+ }
+ }
+ }
+
+ for ( auto & i: aNodeList )
+ aOutNodeList.push_back( std::move(i) );
+ }
+ return aOutNodeList;
+}
+
+static sal_uInt16 lcl_getGroupId( std::u16string_view rGroupName, const weld::TreeView& rTreeLB )
+{
+ sal_uInt16 nRet = 0;
+
+ std::unique_ptr<weld::TreeIter> xEntry = rTreeLB.make_iterator();
+ bool bEntry = rTreeLB.get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!rTreeLB.get_iter_depth(*xEntry))
+ {
+ OUString sTemp(rTreeLB.get_text(*xEntry));
+ if (sTemp == rGroupName)
+ return nRet;
+ nRet++;
+ }
+ bEntry = rTreeLB.iter_next(*xEntry);
+ }
+
+ return USHRT_MAX;
+}
+
+static void lcl_insertLeaf(
+ OfaTreeOptionsDialog* pDlg, OptionsNode const * pNode, OptionsLeaf const * pLeaf, const weld::TreeView& rTreeLB )
+{
+ sal_uInt16 nGrpId = lcl_getGroupId( pNode->m_sLabel, rTreeLB );
+ if ( USHRT_MAX == nGrpId )
+ {
+ sal_uInt16 nNodeGrpId = getGroupNodeId( pNode->m_sId );
+ nGrpId = pDlg->AddGroup( pNode->m_sLabel, nullptr, nullptr, nNodeGrpId );
+ }
+ OptionsPageInfo* pInfo = pDlg->AddTabPage( 0, pLeaf->m_sLabel, nGrpId );
+ pInfo->m_sPageURL = pLeaf->m_sPageURL;
+ pInfo->m_sEventHdl = pLeaf->m_sEventHdl;
+}
+
+void OfaTreeOptionsDialog::InsertNodes( const VectorOfNodes& rNodeList )
+{
+ for (auto const& node : rNodeList)
+ {
+ if ( !node->m_aLeaves.empty() || !node->m_aGroupedLeaves.empty() )
+ {
+ for ( auto const & j: node->m_aGroupedLeaves )
+ {
+ for ( size_t k = 0; k < j.size(); ++k )
+ {
+ lcl_insertLeaf( this, node.get(), j[k].get(), *xTreeLB );
+ }
+ }
+
+ for ( auto const & j: node->m_aLeaves )
+ {
+ lcl_insertLeaf( this, node.get(), j.get(), *xTreeLB );
+ }
+ }
+ }
+}
+
+void OfaTreeOptionsDialog::SetNeedsRestart( svtools::RestartReason eReason)
+{
+ bNeedsRestart = true;
+ eRestartReason = eReason;
+}
+
+short OfaTreeOptionsDialog::run()
+{
+ std::unique_ptr< SvxDicListChgClamp > pClamp;
+ if ( !bIsFromExtensionManager )
+ {
+ // collect all DictionaryList Events while the dialog is executed
+ Reference<css::linguistic2::XSearchableDictionaryList> xDictionaryList(LinguMgr::GetDictionaryList());
+ pClamp.reset( new SvxDicListChgClamp( xDictionaryList ) );
+ }
+
+ return SfxOkDialogController::run();
+}
+
+// class ExtensionsTabPage -----------------------------------------------
+ExtensionsTabPage::ExtensionsTabPage(
+ weld::Container* pParent, OUString aPageURL,
+ OUString aEvtHdl, const Reference< awt::XContainerWindowProvider >& rProvider )
+ : m_pContainer(pParent)
+ , m_sPageURL(std::move(aPageURL))
+ , m_sEventHdl(std::move(aEvtHdl))
+ , m_xWinProvider(rProvider)
+{
+}
+
+ExtensionsTabPage::~ExtensionsTabPage()
+{
+ Hide();
+ DeactivatePage();
+
+ if ( m_xPage.is() )
+ {
+ try
+ {
+ m_xPage->dispose();
+ }
+ catch (const Exception&)
+ {
+ }
+ m_xPage.clear();
+ }
+
+ if ( m_xPageParent.is() )
+ {
+ try
+ {
+ m_xPageParent->dispose();
+ }
+ catch (const Exception&)
+ {
+ }
+ m_xPageParent.clear();
+ }
+}
+
+void ExtensionsTabPage::CreateDialogWithHandler()
+{
+ try
+ {
+ bool bWithHandler = !m_sEventHdl.isEmpty();
+ if ( bWithHandler )
+ {
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ m_xEventHdl.set( xFactory->createInstance( m_sEventHdl ), UNO_QUERY );
+ }
+
+ if ( !bWithHandler || m_xEventHdl.is() )
+ {
+ m_xPageParent = m_pContainer->CreateChildFrame();
+ Reference<awt::XWindowPeer> xParent(m_xPageParent, UNO_QUERY);
+ m_xPage =
+ m_xWinProvider->createContainerWindow(
+ m_sPageURL, OUString(), xParent, m_xEventHdl );
+
+ Reference< awt::XControl > xPageControl( m_xPage, UNO_QUERY );
+ if ( xPageControl.is() )
+ {
+ Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
+ if ( xWinPeer.is() )
+ {
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWinPeer );
+ if ( pWindow )
+ pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::CreateDialogWithHandler(): exception of XDialogProvider2::createDialogWithHandler()");
+ }
+}
+
+bool ExtensionsTabPage::DispatchAction( const OUString& rAction )
+{
+ bool bRet = false;
+ if ( m_xEventHdl.is() )
+ {
+ try
+ {
+ bRet = m_xEventHdl->callHandlerMethod( m_xPage, Any( rAction ), "external_event" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::DispatchAction(): exception of XDialogEventHandler::callHandlerMethod()" );
+ }
+ }
+ return bRet;
+}
+
+void ExtensionsTabPage::Show()
+{
+ if (!m_xPageParent.is())
+ return;
+
+ VclPtr<vcl::Window> xPageParent = VCLUnoHelper::GetWindow(m_xPageParent);
+ if (xPageParent)
+ {
+ // NoActivate otherwise setVisible will call Window::Show which will grab
+ // focus to the page by default
+ xPageParent->Show(true, ShowFlags::NoActivate);
+ }
+
+ m_xPageParent->setVisible(true);
+}
+
+void ExtensionsTabPage::Hide()
+{
+ if (!m_xPageParent.is())
+ return;
+ m_xPageParent->setVisible(false);
+}
+
+void ExtensionsTabPage::ActivatePage()
+{
+ if ( !m_xPage.is() )
+ {
+ CreateDialogWithHandler();
+
+ if ( m_xPage.is() )
+ {
+ auto aWindowRect = m_xPageParent->getPosSize();
+ m_xPage->setPosSize(0, 0, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POSSIZE);
+ if ( !m_sEventHdl.isEmpty() )
+ DispatchAction( "initialize" );
+ }
+ }
+
+ if ( m_xPage.is() )
+ {
+ m_xPage->setVisible( true );
+ }
+}
+
+void ExtensionsTabPage::DeactivatePage()
+{
+ if ( m_xPage.is() )
+ m_xPage->setVisible( false );
+}
+
+void ExtensionsTabPage::ResetPage()
+{
+ DispatchAction( "back" );
+ ActivatePage();
+}
+
+void ExtensionsTabPage::SavePage()
+{
+ DispatchAction( "ok" );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/tsaurls.cxx b/cui/source/options/tsaurls.cxx
new file mode 100644
index 000000000..5c01e1c5b
--- /dev/null
+++ b/cui/source/options/tsaurls.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include <svx/svxdlg.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#include "tsaurls.hxx"
+
+using namespace ::com::sun::star;
+
+TSAURLsDialog::TSAURLsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/tsaurldialog.ui", "TSAURLDialog")
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xURLListBox(m_xBuilder->weld_tree_view("urls"))
+ , m_xEnterAUrl(m_xBuilder->weld_label("enteraurl"))
+{
+ m_xURLListBox->set_size_request(m_xURLListBox->get_approximate_digit_width() * 28,
+ m_xURLListBox->get_height_rows(8));
+ m_xOKBtn->set_sensitive(false);
+
+ m_xAddBtn->connect_clicked(LINK(this, TSAURLsDialog, AddHdl_Impl));
+ m_xDeleteBtn->connect_clicked(LINK(this, TSAURLsDialog, DeleteHdl_Impl));
+ m_xOKBtn->connect_clicked(LINK(this, TSAURLsDialog, OKHdl_Impl));
+ m_xURLListBox->connect_changed(LINK(this, TSAURLsDialog, SelectHdl));
+
+ try
+ {
+ std::optional<css::uno::Sequence<OUString>> aUserSetTSAURLs(
+ officecfg::Office::Common::Security::Scripting::TSAURLs::get());
+ if (aUserSetTSAURLs)
+ {
+ const css::uno::Sequence<OUString>& rUserSetTSAURLs = *aUserSetTSAURLs;
+ for (auto const& userSetTSAURL : rUserSetTSAURLs)
+ {
+ AddTSAURL(userSetTSAURL);
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "TSAURLsDialog::TSAURLsDialog()");
+ }
+
+ if (m_xURLListBox->get_selected_index() == -1)
+ {
+ m_xDeleteBtn->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, OKHdl_Impl, weld::Button&, void)
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+
+ officecfg::Office::Common::Security::Scripting::TSAURLs::set(
+ comphelper::containerToSequence(m_aURLs), batch);
+ batch->commit();
+
+ m_xDialog->response(RET_OK);
+}
+
+TSAURLsDialog::~TSAURLsDialog() {}
+
+void TSAURLsDialog::AddTSAURL(const OUString& rURL)
+{
+ m_aURLs.insert(rURL);
+
+ m_xURLListBox->freeze();
+ m_xURLListBox->clear();
+
+ for (auto const& url : m_aURLs)
+ {
+ m_xURLListBox->append_text(url);
+ }
+
+ m_xURLListBox->thaw();
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, AddHdl_Impl, weld::Button&, void)
+{
+ OUString aURL;
+ OUString aDesc(m_xEnterAUrl->get_label());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(
+ pFact->CreateSvxNameDialog(m_xDialog.get(), aURL, aDesc));
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName(aURL);
+ AddTSAURL(aURL);
+ m_xOKBtn->set_sensitive(true);
+ }
+ m_xURLListBox->unselect_all();
+ // After operations in a ListBox we have nothing selected
+ m_xDeleteBtn->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, SelectHdl, weld::TreeView&, void)
+{
+ m_xDeleteBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ int nSel = m_xURLListBox->get_selected_index();
+ if (nSel == -1)
+ return;
+
+ m_aURLs.erase(m_xURLListBox->get_text(nSel));
+ m_xURLListBox->remove(nSel);
+ m_xURLListBox->unselect_all();
+ // After operations in a ListBox we have nothing selected
+ m_xDeleteBtn->set_sensitive(false);
+ m_xOKBtn->set_sensitive(true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/tsaurls.hxx b/cui/source/options/tsaurls.hxx
new file mode 100644
index 000000000..8fb1d0490
--- /dev/null
+++ b/cui/source/options/tsaurls.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+
+#include <set>
+
+class TSAURLsDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDeleteBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::TreeView> m_xURLListBox;
+ std::unique_ptr<weld::Label> m_xEnterAUrl;
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ // After operations in a TreeView we have nothing selected
+ // Is Selected element handler for the TreeView
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+ std::set<OUString> m_aURLs;
+
+ void AddTSAURL(const OUString& rURL);
+
+public:
+ explicit TSAURLsDialog(weld::Window* pParent);
+ virtual ~TSAURLsDialog() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/webconninfo.cxx b/cui/source/options/webconninfo.cxx
new file mode 100644
index 000000000..d9acbd18f
--- /dev/null
+++ b/cui/source/options/webconninfo.cxx
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include "webconninfo.hxx"
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/UrlRecord.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/docpasswordrequest.hxx>
+
+using namespace ::com::sun::star;
+
+
+namespace svx
+{
+
+// class WebConnectionInfoDialog -----------------------------------------
+
+WebConnectionInfoDialog::WebConnectionInfoDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/storedwebconnectiondialog.ui", "StoredWebConnectionDialog")
+ , m_nPos( -1 )
+ , m_xRemoveBtn(m_xBuilder->weld_button("remove"))
+ , m_xRemoveAllBtn(m_xBuilder->weld_button("removeall"))
+ , m_xChangeBtn(m_xBuilder->weld_button("change"))
+ , m_xPasswordsLB(m_xBuilder->weld_tree_view("logins"))
+{
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xPasswordsLB->get_approximate_digit_width() * 50)
+ };
+ m_xPasswordsLB->set_column_fixed_widths(aWidths);
+ m_xPasswordsLB->set_size_request(m_xPasswordsLB->get_approximate_digit_width() * 70,
+ m_xPasswordsLB->get_height_rows(8));
+
+ m_xPasswordsLB->connect_column_clicked(LINK(this, WebConnectionInfoDialog, HeaderBarClickedHdl));
+
+ FillPasswordList();
+
+ m_xRemoveBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, RemovePasswordHdl ) );
+ m_xRemoveAllBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, RemoveAllPasswordsHdl ) );
+ m_xChangeBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, ChangePasswordHdl ) );
+ m_xPasswordsLB->connect_changed( LINK( this, WebConnectionInfoDialog, EntrySelectedHdl ) );
+
+ m_xRemoveBtn->set_sensitive( false );
+ m_xChangeBtn->set_sensitive( false );
+
+ m_xPasswordsLB->make_sorted();
+}
+
+WebConnectionInfoDialog::~WebConnectionInfoDialog()
+{
+}
+
+IMPL_LINK(WebConnectionInfoDialog, HeaderBarClickedHdl, int, nColumn, void)
+{
+ if (nColumn == 0) // only the first column is sorted
+ {
+ m_xPasswordsLB->set_sort_order(!m_xPasswordsLB->get_sort_order());
+ }
+}
+
+void WebConnectionInfoDialog::FillPasswordList()
+{
+ try
+ {
+ uno::Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ uno::Reference< task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr);
+
+ const uno::Sequence< task::UrlRecord > aURLEntries = xMasterPasswd->getAllPersistent( xInteractionHandler );
+ sal_Int32 nCount = 0;
+ for ( task::UrlRecord const & urlEntry : aURLEntries )
+ {
+ for ( auto const & user : urlEntry.UserList )
+ {
+ m_xPasswordsLB->append(OUString::number(nCount), urlEntry.Url);
+ m_xPasswordsLB->set_text(nCount, user.UserName, 1);
+ ++nCount;
+ }
+ }
+
+ // remember pos of first url container entry.
+ m_nPos = nCount;
+
+ const uno::Sequence< OUString > aUrls
+ = xMasterPasswd->getUrls( true /* OnlyPersistent */ );
+
+ for ( OUString const & url : aUrls )
+ {
+ m_xPasswordsLB->append(OUString::number(nCount), url);
+ m_xPasswordsLB->set_text(nCount, "*");
+ ++nCount;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, RemovePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ OUString aURL = m_xPasswordsLB->get_text(nEntry, 0);
+ OUString aUserName = m_xPasswordsLB->get_text(nEntry, 1);
+
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ int nPos = m_xPasswordsLB->get_id(nEntry).toInt32();
+ if ( nPos < m_nPos )
+ {
+ xPasswdContainer->removePersistent( aURL, aUserName );
+ }
+ else
+ {
+ xPasswdContainer->removeUrl( aURL );
+ }
+
+ m_xPasswordsLB->remove(nEntry);
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, RemoveAllPasswordsHdl, weld::Button&, void)
+{
+ try
+ {
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ // should the master password be requested before?
+ xPasswdContainer->removeAllPersistent();
+
+ const uno::Sequence< OUString > aUrls
+ = xPasswdContainer->getUrls( true /* OnlyPersistent */ );
+ for ( OUString const & url : aUrls )
+ xPasswdContainer->removeUrl( url );
+
+ m_xPasswordsLB->clear();
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, ChangePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ OUString aURL = m_xPasswordsLB->get_text(nEntry, 0);
+ OUString aUserName = m_xPasswordsLB->get_text(nEntry, 1);
+
+ rtl::Reference<::comphelper::SimplePasswordRequest> pPasswordRequest
+ = new ::comphelper::SimplePasswordRequest;
+
+ uno::Reference< task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), m_xDialog->GetXWindow());
+ xInteractionHandler->handle( pPasswordRequest );
+
+ if ( pPasswordRequest->isPassword() )
+ {
+ OUString aNewPass = pPasswordRequest->getPassword();
+ uno::Sequence<OUString> aPasswd { aNewPass };
+
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+ xPasswdContainer->addPersistent(
+ aURL, aUserName, aPasswd, xInteractionHandler );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, EntrySelectedHdl, weld::TreeView&, void)
+{
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry == -1)
+ {
+ m_xRemoveBtn->set_sensitive(false);
+ m_xChangeBtn->set_sensitive(false);
+ }
+ else
+ {
+ m_xRemoveBtn->set_sensitive(true);
+
+ // url container entries (-> use system credentials) have
+ // no password
+ int nPos = m_xPasswordsLB->get_id(nEntry).toInt32();
+ m_xChangeBtn->set_sensitive(nPos < m_nPos);
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/webconninfo.hxx b/cui/source/options/webconninfo.hxx
new file mode 100644
index 000000000..6c52d2163
--- /dev/null
+++ b/cui/source/options/webconninfo.hxx
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+namespace svx
+{
+ class WebConnectionInfoDialog : public weld::GenericDialogController
+ {
+ private:
+ sal_Int32 m_nPos;
+
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+ std::unique_ptr<weld::Button> m_xRemoveAllBtn;
+ std::unique_ptr<weld::Button> m_xChangeBtn;
+ std::unique_ptr<weld::TreeView> m_xPasswordsLB;
+
+ DECL_LINK( HeaderBarClickedHdl, int, void );
+ DECL_LINK( RemovePasswordHdl, weld::Button&, void );
+ DECL_LINK( RemoveAllPasswordsHdl, weld::Button&, void );
+ DECL_LINK( ChangePasswordHdl, weld::Button&, void );
+ DECL_LINK( EntrySelectedHdl, weld::TreeView&, void );
+
+ void FillPasswordList();
+
+ public:
+ explicit WebConnectionInfoDialog(weld::Window* pParent);
+ virtual ~WebConnectionInfoDialog() override;
+ };
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/TextColumnsPage.cxx b/cui/source/tabpages/TextColumnsPage.cxx
new file mode 100644
index 000000000..5bfd3b47a
--- /dev/null
+++ b/cui/source/tabpages/TextColumnsPage.cxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <svtools/unitconv.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/svddef.hxx>
+
+#include <TextColumnsPage.hxx>
+
+const WhichRangesContainer
+ SvxTextColumnsPage::pRanges(svl::Items<SDRATTR_TEXTCOLUMNS_FIRST, SDRATTR_TEXTCOLUMNS_LAST>);
+
+SvxTextColumnsPage::SvxTextColumnsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/textcolumnstabpage.ui", "TextColumnsPage", &rInAttrs)
+ , m_xColumnsNumber(m_xBuilder->weld_spin_button("FLD_COL_NUMBER"))
+ , m_xColumnsSpacing(
+ m_xBuilder->weld_metric_spin_button("MTR_FLD_COL_SPACING", GetModuleFieldUnit(rInAttrs)))
+{
+}
+
+SvxTextColumnsPage::~SvxTextColumnsPage() = default;
+
+// read the passed item set
+void SvxTextColumnsPage::Reset(const SfxItemSet* rAttrs)
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ assert(pPool);
+
+ {
+ auto pItem = GetItem(*rAttrs, SDRATTR_TEXTCOLUMNS_NUMBER);
+ if (!pItem)
+ pItem = &pPool->GetDefaultItem(SDRATTR_TEXTCOLUMNS_NUMBER);
+ m_xColumnsNumber->set_value(pItem->GetValue());
+ m_xColumnsNumber->save_value();
+ }
+
+ {
+ MapUnit eUnit = pPool->GetMetric(SDRATTR_TEXTCOLUMNS_SPACING);
+ auto pItem = GetItem(*rAttrs, SDRATTR_TEXTCOLUMNS_SPACING);
+ if (!pItem)
+ pItem = &pPool->GetDefaultItem(SDRATTR_TEXTCOLUMNS_SPACING);
+ SetMetricValue(*m_xColumnsSpacing, pItem->GetValue(), eUnit);
+ m_xColumnsSpacing->save_value();
+ }
+}
+
+// fill the passed item set with dialog box attributes
+bool SvxTextColumnsPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ if (m_xColumnsNumber->get_value_changed_from_saved())
+ rAttrs->Put(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, m_xColumnsNumber->get_value()));
+
+ if (m_xColumnsSpacing->get_value_changed_from_saved())
+ {
+ SfxItemPool* pPool = rAttrs->GetPool();
+ assert(pPool);
+ MapUnit eUnit = pPool->GetMetric(SDRATTR_TEXTCOLUMNS_SPACING);
+ sal_Int32 nValue = GetCoreValue(*m_xColumnsSpacing, eUnit);
+ rAttrs->Put(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, nValue));
+ }
+
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxTextColumnsPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextColumnsPage>(pPage, pController, *rAttrs);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/tabpages/align.cxx b/cui/source/tabpages/align.cxx
new file mode 100644
index 000000000..8d2425e7e
--- /dev/null
+++ b/cui/source/tabpages/align.cxx
@@ -0,0 +1,790 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <align.hxx>
+
+#include <editeng/svxenum.hxx>
+#include <svx/svxids.hrc>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <bitmaps.hlst>
+#include <svx/rotmodit.hxx>
+#include <svx/sdangitm.hxx>
+
+#include <editeng/frmdiritem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/image.hxx>
+
+#define IID_BOTTOMLOCK 1
+#define IID_TOPLOCK 2
+#define IID_CELLLOCK 3
+
+namespace svx {
+
+const WhichRangesContainer AlignmentTabPage::s_pRanges(
+ svl::Items<
+ SID_ATTR_ALIGN_STACKED, SID_ATTR_ALIGN_LINEBREAK, // 10229 - 10230
+ SID_ATTR_ALIGN_INDENT, SID_ATTR_ALIGN_INDENT, // 10460 - 10460
+ SID_ATTR_ALIGN_DEGREES, SID_ATTR_ALIGN_DEGREES, // 10577 - 10577
+ SID_ATTR_ALIGN_LOCKPOS, SID_ATTR_ALIGN_LOCKPOS, // 10578 - 10578
+ SID_ATTR_ALIGN_HYPHENATION, SID_ATTR_ALIGN_HYPHENATION, // 10931 - 10931
+ SID_ATTR_FRAMEDIRECTION, SID_ATTR_FRAMEDIRECTION, // 10944 - 10944
+ SID_ATTR_ALIGN_ASIANVERTICAL, SID_ATTR_ALIGN_ASIANVERTICAL, // 10949 - 10949
+ SID_ATTR_ALIGN_SHRINKTOFIT, SID_ATTR_ALIGN_SHRINKTOFIT, // 11015 - 11015
+ SID_ATTR_ALIGN_HOR_JUSTIFY, SID_ATTR_ALIGN_VER_JUSTIFY>); // 11571 - 11572
+
+
+namespace {
+
+template<typename JustContainerType, typename JustEnumType>
+void lcl_MaybeResetAlignToDistro(
+ weld::ComboBox& rLB, sal_uInt16 nListId, const SfxItemSet& rCoreAttrs, TypedWhichId<SfxEnumItemInterface> nWhichAlign, TypedWhichId<SfxEnumItemInterface> nWhichJM, JustEnumType eBlock)
+{
+ const SfxEnumItemInterface* p = rCoreAttrs.GetItemIfSet(nWhichAlign);
+ if (!p)
+ // alignment not set.
+ return;
+
+ JustContainerType eVal = static_cast<JustContainerType>(p->GetEnumValue());
+ if (eVal != eBlock)
+ // alignment is not 'justify'. No need to go further.
+ return;
+
+ p = rCoreAttrs.GetItemIfSet(nWhichJM);
+ if (!p)
+ // justification method is not set.
+ return;
+
+ SvxCellJustifyMethod eMethod = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ if (eMethod == SvxCellJustifyMethod::Distribute)
+ {
+ // Select the 'distribute' entry in the specified list box.
+ rLB.set_active_id(OUString::number(nListId));
+ }
+}
+
+void lcl_SetJustifyMethodToItemSet(SfxItemSet& rSet, const SfxItemSet& rOldSet, sal_uInt16 nWhichJM, const weld::ComboBox& rLB, sal_uInt16 nListId)
+{
+ // tdf#138698 unsupported, e.g. dbaccess
+ if (rLB.find_id(OUString::number(nListId)) == -1)
+ return;
+
+ // feature supported , e.g. calc
+ SvxCellJustifyMethod eJM = SvxCellJustifyMethod::Auto;
+ if (rLB.get_active_id().toInt32() == nListId)
+ eJM = SvxCellJustifyMethod::Distribute;
+
+ // tdf#129300 If it would create no change, don't force it
+ const SvxJustifyMethodItem& rOldItem = static_cast<const SvxJustifyMethodItem&>(rOldSet.Get(nWhichJM));
+ if (rOldItem.GetValue() == eJM)
+ {
+ rSet.InvalidateItem(nWhichJM);
+ return;
+ }
+
+ SvxJustifyMethodItem aItem(eJM, nWhichJM);
+ rSet.Put(aItem);
+}
+
+}//namespace
+
+AlignmentTabPage::AlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/cellalignment.ui", "CellAlignPage", &rCoreAttrs)
+ , m_aVsRefEdge(nullptr)
+ // text alignment
+ , m_xLbHorAlign(m_xBuilder->weld_combo_box("comboboxHorzAlign"))
+ , m_xFtIndent(m_xBuilder->weld_label("labelIndent"))
+ , m_xEdIndent(m_xBuilder->weld_metric_spin_button("spinIndentFrom", FieldUnit::POINT))
+ , m_xFtVerAlign(m_xBuilder->weld_label("labelVertAlign"))
+ , m_xLbVerAlign(m_xBuilder->weld_combo_box("comboboxVertAlign"))
+ //text rotation
+ , m_xFtRotate(m_xBuilder->weld_label("labelDegrees"))
+ , m_xNfRotate(m_xBuilder->weld_metric_spin_button("spinDegrees", FieldUnit::DEGREE))
+ , m_xFtRefEdge(m_xBuilder->weld_label("labelRefEdge"))
+ //Asian mode
+ , m_xCbStacked(m_xBuilder->weld_check_button("checkVertStack"))
+ , m_xCbAsianMode(m_xBuilder->weld_check_button("checkAsianMode"))
+ // Properties
+ , m_xBoxDirection(m_xBuilder->weld_widget("boxDirection"))
+ , m_xBtnWrap(m_xBuilder->weld_check_button("checkWrapTextAuto"))
+ , m_xBtnHyphen(m_xBuilder->weld_check_button("checkHyphActive"))
+ , m_xBtnShrink(m_xBuilder->weld_check_button("checkShrinkFitCellSize"))
+ , m_xLbFrameDir(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboTextDirBox")))
+ //ValueSet hover strings
+ , m_xFtBotLock(m_xBuilder->weld_label("labelSTR_BOTTOMLOCK"))
+ , m_xFtTopLock(m_xBuilder->weld_label("labelSTR_TOPLOCK"))
+ , m_xFtCelLock(m_xBuilder->weld_label("labelSTR_CELLLOCK"))
+ , m_xFtABCD(m_xBuilder->weld_label("labelABCD"))
+ , m_xAlignmentFrame(m_xBuilder->weld_widget("alignment"))
+ , m_xOrientFrame(m_xBuilder->weld_widget("orientation"))
+ , m_xPropertiesFrame(m_xBuilder->weld_widget("properties"))
+ , m_xVsRefEdge(new weld::CustomWeld(*m_xBuilder, "references", m_aVsRefEdge))
+ , m_xCtrlDial(new DialControl)
+ , m_xCtrlDialWin(new weld::CustomWeld(*m_xBuilder, "dialcontrol", *m_xCtrlDial))
+{
+ m_xCtrlDial->SetLinkedField(m_xNfRotate.get());
+ m_xCtrlDial->SetText(m_xFtABCD->get_label());
+
+ InitVsRefEgde();
+
+ m_xLbHorAlign->connect_changed(LINK(this, AlignmentTabPage, UpdateEnableHdl));
+
+ m_xCbStacked->connect_toggled(LINK(this, AlignmentTabPage, StackedClickHdl));
+ m_xCbAsianMode->connect_toggled(LINK(this, AlignmentTabPage, AsianModeClickHdl));
+ m_xBtnWrap->connect_toggled(LINK(this, AlignmentTabPage, WrapClickHdl));
+ m_xBtnHyphen->connect_toggled(LINK(this, AlignmentTabPage, HyphenClickHdl));
+ m_xBtnShrink->connect_toggled(LINK(this, AlignmentTabPage, ShrinkClickHdl));
+
+ // Asian vertical mode
+ m_xCbAsianMode->set_visible(SvtCJKOptions::IsVerticalTextEnabled());
+
+ m_xLbFrameDir->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xLbFrameDir->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+ m_xLbFrameDir->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+
+ // This page needs ExchangeSupport.
+ SetExchangeSupport();
+}
+
+AlignmentTabPage::~AlignmentTabPage()
+{
+ m_xCtrlDialWin.reset();
+ m_xCtrlDial.reset();
+ m_xVsRefEdge.reset();
+ m_xLbFrameDir.reset();
+}
+
+std::unique_ptr<SfxTabPage> AlignmentTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<AlignmentTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool AlignmentTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ bool bChanged = SfxTabPage::FillItemSet(rSet);
+
+ sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
+ if (m_xLbHorAlign->get_value_changed_from_saved())
+ {
+ SvxCellHorJustify eJustify(SvxCellHorJustify::Standard);
+ switch (m_xLbHorAlign->get_active_id().toInt32())
+ {
+ case ALIGNDLG_HORALIGN_STD:
+ eJustify = SvxCellHorJustify::Standard;
+ break;
+ case ALIGNDLG_HORALIGN_LEFT:
+ eJustify = SvxCellHorJustify::Left;
+ break;
+ case ALIGNDLG_HORALIGN_CENTER:
+ eJustify = SvxCellHorJustify::Center;
+ break;
+ case ALIGNDLG_HORALIGN_RIGHT:
+ eJustify = SvxCellHorJustify::Right;
+ break;
+ case ALIGNDLG_HORALIGN_BLOCK:
+ case ALIGNDLG_HORALIGN_DISTRIBUTED:
+ eJustify = SvxCellHorJustify::Block;
+ break;
+ case ALIGNDLG_HORALIGN_FILL:
+ eJustify = SvxCellHorJustify::Repeat;
+ break;
+ }
+ rSet->Put(SvxHorJustifyItem(eJustify, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
+ if (m_xEdIndent->get_value_changed_from_saved())
+ {
+ const SfxUInt16Item* pIndentItem = static_cast<const SfxUInt16Item*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_INDENT));
+ assert(pIndentItem);
+ std::unique_ptr<SfxUInt16Item> pNewIndentItem(pIndentItem->Clone());
+ pNewIndentItem->SetValue(m_xEdIndent->get_value(FieldUnit::TWIP));
+ rSet->Put(std::move(pNewIndentItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
+ if (m_xLbVerAlign->get_value_changed_from_saved())
+ {
+ SvxCellVerJustify eJustify(SvxCellVerJustify::Standard);
+ switch (m_xLbVerAlign->get_active_id().toInt32())
+ {
+ case ALIGNDLG_VERALIGN_STD:
+ eJustify = SvxCellVerJustify::Standard;
+ break;
+ case ALIGNDLG_VERALIGN_TOP:
+ eJustify = SvxCellVerJustify::Top;
+ break;
+ case ALIGNDLG_VERALIGN_MID:
+ eJustify = SvxCellVerJustify::Center;
+ break;
+ case ALIGNDLG_VERALIGN_BOTTOM:
+ eJustify = SvxCellVerJustify::Bottom;
+ break;
+ case ALIGNDLG_VERALIGN_BLOCK:
+ case ALIGNDLG_VERALIGN_DISTRIBUTED:
+ eJustify = SvxCellVerJustify::Block;
+ break;
+ }
+ rSet->Put(SvxVerJustifyItem(eJustify, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
+ if (m_xNfRotate->get_value_changed_from_saved())
+ {
+ const SdrAngleItem* pAngleItem = static_cast<const SdrAngleItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_DEGREES));
+ assert(pAngleItem);
+ std::unique_ptr<SdrAngleItem> pNewAngleItem(pAngleItem->Clone());
+ pNewAngleItem->SetValue(m_xCtrlDial->GetRotation());
+ rSet->Put(std::move(pNewAngleItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ TypedWhichId<SvxRotateModeItem> nWhichLockPos(GetWhich(SID_ATTR_ALIGN_LOCKPOS));
+ if (m_aVsRefEdge.IsValueChangedFromSaved())
+ {
+ switch (m_aVsRefEdge.GetSelectedItemId())
+ {
+ case IID_CELLLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_STANDARD, nWhichLockPos));
+ break;
+ case IID_TOPLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_TOP, nWhichLockPos));
+ break;
+ case IID_BOTTOMLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_BOTTOM, nWhichLockPos));
+ break;
+ default:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ }
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhichLockPos, false))
+ rSet->InvalidateItem(nWhichLockPos);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_STACKED);
+ if (m_xCbStacked->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pStackItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_STACKED));
+ assert(pStackItem);
+ std::unique_ptr<SfxBoolItem> pNewStackItem(pStackItem->Clone());
+ pNewStackItem->SetValue(m_xCbStacked->get_active());
+ rSet->Put(std::move(pNewStackItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL);
+ if (m_xCbAsianMode->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(nWhich, m_xCbAsianMode->get_active()));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LINEBREAK);
+ if (m_xBtnWrap->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pWrapItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_LINEBREAK));
+ assert(pWrapItem);
+ std::unique_ptr<SfxBoolItem> pNewWrapItem(pWrapItem->Clone());
+ pNewWrapItem->SetValue(m_xBtnWrap->get_active());
+ rSet->Put(std::move(pNewWrapItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_HYPHENATION);
+ if (m_xBtnHyphen->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pHyphItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_HYPHENATION));
+ assert(pHyphItem);
+ std::unique_ptr<SfxBoolItem> pNewHyphItem(pHyphItem->Clone());
+ pNewHyphItem->SetValue(m_xBtnHyphen->get_active());
+ rSet->Put(std::move(pNewHyphItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT);
+ if (m_xBtnShrink->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pShrinkItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_SHRINKTOFIT));
+ assert(pShrinkItem);
+ std::unique_ptr<SfxBoolItem> pNewShrinkItem(pShrinkItem->Clone());
+ pNewShrinkItem->SetValue(m_xBtnShrink->get_active());
+ rSet->Put(std::move(pNewShrinkItem));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ if (m_xLbFrameDir->get_visible())
+ {
+ nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
+ if (m_xLbFrameDir->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDir = m_xLbFrameDir->get_active_id();
+ rSet->Put(SvxFrameDirectionItem(eDir, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+ }
+
+ // Special treatment for distributed alignment; we need to set the justify
+ // method to 'distribute' to distinguish from the normal justification.
+ TypedWhichId<SfxEnumItemInterface> nWhichHorJM(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD));
+ lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichHorJM, *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED);
+ if (!bChanged)
+ bChanged = HasAlignmentChanged(*rSet, nWhichHorJM);
+
+ TypedWhichId<SfxEnumItemInterface> nWhichVerJM(GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD));
+ lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichVerJM, *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED);
+ if (!bChanged)
+ bChanged = HasAlignmentChanged(*rSet, nWhichVerJM);
+
+ return bChanged;
+}
+
+namespace
+{
+ void ResetBool(sal_uInt16 nWhich, const SfxItemSet* pSet, weld::CheckButton& rBtn, weld::TriStateEnabled& rTriState)
+ {
+ SfxItemState eState = pSet->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ rBtn.hide();
+ rTriState.bTriStateEnabled = false;
+ break;
+ case SfxItemState::DISABLED:
+ rBtn.set_sensitive(false);
+ rTriState.bTriStateEnabled = false;
+ break;
+ case SfxItemState::DONTCARE:
+ rBtn.set_state(TRISTATE_INDET);
+ rTriState.bTriStateEnabled = true;
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SfxBoolItem& rItem = static_cast<const SfxBoolItem&>(pSet->Get(nWhich));
+ rBtn.set_state(static_cast<TriState>(rItem.GetValue()));
+ rTriState.bTriStateEnabled = false;
+ break;
+ }
+ }
+ rBtn.save_state();
+ }
+}
+
+void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
+{
+ SfxTabPage::Reset(pCoreAttrs);
+
+ ResetBool(GetWhich(SID_ATTR_ALIGN_STACKED), pCoreAttrs, *m_xCbStacked, m_aStackedState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL), pCoreAttrs, *m_xCbAsianMode, m_aAsianModeState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_LINEBREAK), pCoreAttrs, *m_xBtnWrap, m_aWrapState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_HYPHENATION), pCoreAttrs, *m_xBtnHyphen, m_aHyphenState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT), pCoreAttrs, *m_xBtnShrink, m_aShrinkState);
+
+ sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
+ SfxItemState eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbHorAlign->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xLbHorAlign->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbHorAlign->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxHorJustifyItem& rJustifyItem = static_cast<const SvxHorJustifyItem&>(pCoreAttrs->Get(nWhich));
+ switch (rJustifyItem.GetValue())
+ {
+ case SvxCellHorJustify::Standard:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_STD));
+ break;
+ case SvxCellHorJustify::Left:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_LEFT));
+ break;
+ case SvxCellHorJustify::Center:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_CENTER));
+ break;
+ case SvxCellHorJustify::Right:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_RIGHT));
+ break;
+ case SvxCellHorJustify::Block:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_BLOCK));
+ break;
+ case SvxCellHorJustify::Repeat:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_FILL));
+ break;
+ }
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xEdIndent->hide();
+ m_xFtIndent->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xEdIndent->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xEdIndent->set_text("");
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SfxUInt16Item& rIndentItem = static_cast<const SfxUInt16Item&>(pCoreAttrs->Get(nWhich));
+ m_xEdIndent->set_value(rIndentItem.GetValue(), FieldUnit::TWIP);
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbVerAlign->hide();
+ m_xFtVerAlign->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xLbVerAlign->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbVerAlign->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxVerJustifyItem& rJustifyItem = static_cast<const SvxVerJustifyItem&>(pCoreAttrs->Get(nWhich));
+ switch (rJustifyItem.GetValue())
+ {
+ case SvxCellVerJustify::Standard:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_STD));
+ break;
+ case SvxCellVerJustify::Top:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_TOP));
+ break;
+ case SvxCellVerJustify::Center:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_MID));
+ break;
+ case SvxCellVerJustify::Bottom:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BOTTOM));
+ break;
+ case SvxCellVerJustify::Block:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BLOCK));
+ break;
+ }
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xNfRotate->hide();
+ m_xCtrlDialWin->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xNfRotate->set_sensitive(false);
+ m_xCtrlDialWin->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xCtrlDial->SetNoRotation();
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SdrAngleItem& rAlignItem = static_cast<const SdrAngleItem&>(pCoreAttrs->Get(nWhich));
+ m_xCtrlDial->SetRotation(rAlignItem.GetValue());
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LOCKPOS);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xVsRefEdge->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xVsRefEdge->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxRotateModeItem& rRotateModeItem = static_cast<const SvxRotateModeItem&>(pCoreAttrs->Get(nWhich));
+ switch (rRotateModeItem.GetValue())
+ {
+ case SvxRotateMode::SVX_ROTATE_MODE_STANDARD:
+ m_aVsRefEdge.SelectItem(IID_CELLLOCK);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_TOP:
+ m_aVsRefEdge.SelectItem(IID_TOPLOCK);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
+ m_aVsRefEdge.SelectItem(IID_BOTTOMLOCK);
+ break;
+ default:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ }
+ break;
+ }
+ }
+ m_aVsRefEdge.SaveValue();
+
+ //text direction
+ nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbFrameDir->hide();
+ break;
+ case SfxItemState::DISABLED:
+ m_xLbFrameDir->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbFrameDir->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>(pCoreAttrs->Get(nWhich));
+ m_xLbFrameDir->set_active_id(rFrameDirItem.GetValue());
+ break;
+ }
+ }
+
+ // Special treatment for distributed alignment; we need to set the justify
+ // method to 'distribute' to distinguish from the normal justification.
+ TypedWhichId<SfxEnumItemInterface> nHorJustifyMethodWhich(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD));
+ SfxItemState eHorJustifyMethodState = pCoreAttrs->GetItemState(nHorJustifyMethodWhich);
+ if (eHorJustifyMethodState == SfxItemState::UNKNOWN)
+ {
+ // feature unknown, e.g. dbaccess, remove the option
+ int nDistribId = m_xLbHorAlign->find_id(OUString::number(ALIGNDLG_HORALIGN_DISTRIBUTED));
+ if (nDistribId != -1)
+ m_xLbHorAlign->remove(nDistribId);
+ }
+ else
+ {
+ // feature known, e.g. calc
+ lcl_MaybeResetAlignToDistro<SvxCellHorJustify, SvxCellHorJustify>(
+ *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED, *pCoreAttrs,
+ TypedWhichId<SfxEnumItemInterface>(GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY)), nHorJustifyMethodWhich,
+ SvxCellHorJustify::Block);
+ }
+
+ TypedWhichId<SfxEnumItemInterface> nVerJustifyMethodWhich( GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD) );
+ SfxItemState eVerJustifyMethodState = pCoreAttrs->GetItemState(nVerJustifyMethodWhich);
+ if (eVerJustifyMethodState == SfxItemState::UNKNOWN)
+ {
+ // feature unknown, e.g. dbaccess, remove the option
+ int nDistribId = m_xLbVerAlign->find_id(OUString::number(ALIGNDLG_VERALIGN_DISTRIBUTED));
+ if (nDistribId != -1)
+ m_xLbVerAlign->remove(nDistribId);
+ }
+ else
+ {
+ // feature known, e.g. calc
+ lcl_MaybeResetAlignToDistro<SvxCellVerJustify, SvxCellVerJustify>(
+ *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED, *pCoreAttrs,
+ TypedWhichId<SfxEnumItemInterface>(GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY)), nVerJustifyMethodWhich,
+ SvxCellVerJustify::Block);
+ }
+
+ m_xLbHorAlign->save_value();
+ m_xLbFrameDir->save_value();
+ m_xLbVerAlign->save_value();
+ m_xNfRotate->save_value();
+ m_xEdIndent->save_value();
+
+ UpdateEnableControls();
+}
+
+DeactivateRC AlignmentTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void AlignmentTabPage::InitVsRefEgde()
+{
+ // remember selection - is deleted in call to ValueSet::Clear()
+ sal_uInt16 nSel = m_aVsRefEdge.GetSelectedItemId();
+
+ Image aBottomLock(StockImage::Yes, RID_SVXBMP_BOTTOMLOCK);
+ Image aTopLock(StockImage::Yes, RID_SVXBMP_TOPLOCK);
+ Image aCellLock(StockImage::Yes, RID_SVXBMP_CELLLOCK);
+
+ m_aVsRefEdge.Clear();
+ m_aVsRefEdge.SetStyle(m_aVsRefEdge.GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER);
+
+ m_aVsRefEdge.SetColCount(3);
+ m_aVsRefEdge.InsertItem(IID_BOTTOMLOCK, aBottomLock, m_xFtBotLock->get_label());
+ m_aVsRefEdge.InsertItem(IID_TOPLOCK, aTopLock, m_xFtTopLock->get_label());
+ m_aVsRefEdge.InsertItem(IID_CELLLOCK, aCellLock, m_xFtCelLock->get_label());
+ m_aVsRefEdge.SetOptimalSize();
+
+ m_aVsRefEdge.SelectItem( nSel );
+}
+
+void AlignmentTabPage::UpdateEnableControls()
+{
+ const sal_Int32 nHorAlign = m_xLbHorAlign->get_active_id().toInt32();
+ bool bHorLeft = (nHorAlign == ALIGNDLG_HORALIGN_LEFT);
+ bool bHorBlock = (nHorAlign == ALIGNDLG_HORALIGN_BLOCK);
+ bool bHorFill = (nHorAlign == ALIGNDLG_HORALIGN_FILL);
+ bool bHorDist = (nHorAlign == ALIGNDLG_HORALIGN_DISTRIBUTED);
+
+ // indent edit field only for left alignment
+ m_xFtIndent->set_sensitive( bHorLeft );
+ m_xEdIndent->set_sensitive( bHorLeft );
+
+ // stacked disabled for fill alignment
+ m_xCbStacked->set_sensitive(!bHorFill);
+
+ // hyphenation only for automatic line breaks or for block alignment
+ m_xBtnHyphen->set_sensitive( m_xBtnWrap->get_active() || bHorBlock );
+
+ // shrink only without automatic line break, and not for block, fill or distribute.
+ m_xBtnShrink->set_sensitive( (m_xBtnWrap->get_state() == TRISTATE_FALSE) && !bHorBlock && !bHorFill && !bHorDist );
+
+ // visibility of frames
+ m_xAlignmentFrame->set_visible(m_xLbHorAlign->get_visible() || m_xEdIndent->get_visible() ||
+ m_xLbVerAlign->get_visible());
+ m_xOrientFrame->set_visible(m_xCtrlDialWin->get_visible() || m_xVsRefEdge->get_visible() ||
+ m_xCbStacked->get_visible() || m_xCbAsianMode->get_visible());
+ m_xPropertiesFrame->set_visible(m_xBtnWrap->get_visible() || m_xBtnHyphen->get_visible() ||
+ m_xBtnShrink->get_visible() || m_xLbFrameDir->get_visible());
+
+ bool bStackedText = m_xCbStacked->get_active();
+ // windows to be disabled, if stacked text is turned ON
+ m_xFtRotate->set_sensitive(!bStackedText);
+ m_xFtRefEdge->set_sensitive(!bStackedText);
+ m_xVsRefEdge->set_sensitive(!bStackedText);
+ // windows to be disabled, if stacked text is turned OFF
+ m_xCbAsianMode->set_sensitive(bStackedText);
+ // rotation/stacked disabled for fill alignment/stacked
+ m_xCtrlDialWin->set_sensitive(!bHorFill && !bStackedText);
+ m_xNfRotate->set_sensitive(!bHorFill && !bStackedText);
+}
+
+bool AlignmentTabPage::HasAlignmentChanged( const SfxItemSet& rNew, TypedWhichId<SfxEnumItemInterface> nWhich ) const
+{
+ const SfxItemSet& rOld = GetItemSet();
+ SvxCellJustifyMethod eMethodOld = SvxCellJustifyMethod::Auto;
+ SvxCellJustifyMethod eMethodNew = SvxCellJustifyMethod::Auto;
+ if (const SfxEnumItemInterface* p = rOld.GetItemIfSet(nWhich))
+ {
+ eMethodOld = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ }
+
+ if (const SfxEnumItemInterface* p = rNew.GetItemIfSet(nWhich))
+ {
+ eMethodNew = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ }
+
+ return eMethodOld != eMethodNew;
+}
+
+IMPL_LINK(AlignmentTabPage, StackedClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aStackedState.ButtonToggled(rToggle);
+ UpdateEnableControls();
+}
+
+IMPL_LINK(AlignmentTabPage, AsianModeClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aAsianModeState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(AlignmentTabPage, WrapClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aWrapState.ButtonToggled(rToggle);
+ UpdateEnableControls();
+}
+
+IMPL_LINK(AlignmentTabPage, HyphenClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aHyphenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(AlignmentTabPage, ShrinkClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aShrinkState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK_NOARG(AlignmentTabPage, UpdateEnableHdl, weld::ComboBox&, void)
+{
+ UpdateEnableControls();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
new file mode 100644
index 000000000..2c978a835
--- /dev/null
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -0,0 +1,2364 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <i18nutil/unicode.hxx>
+#include <o3tl/safeint.hxx>
+#include <utility>
+#include <vcl/event.hxx>
+#include <vcl/keycodes.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/module.hxx>
+#include <svl/eitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svx/SmartTagMgr.hxx>
+#include <com/sun/star/smarttags/XSmartTagRecognizer.hpp>
+#include <rtl/strbuf.hxx>
+#include <o3tl/temporary.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+
+#include <autocdlg.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <editeng/svxacorr.hxx>
+#include <cui/cuicharmap.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+#include <svx/svxids.hrc>
+
+static LanguageType eLastDialogLanguage = LANGUAGE_SYSTEM;
+
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star;
+
+OfaAutoCorrDlg::OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet* _pSet )
+ : SfxTabDialogController(pParent, "cui/ui/autocorrectdialog.ui", "AutoCorrectDialog", _pSet)
+ , m_xLanguageBox(m_xBuilder->weld_widget("langbox"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+{
+ bool bShowSWOptions = false;
+ bool bOpenSmartTagOptions = false;
+
+ if ( _pSet )
+ {
+ const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_AUTO_CORRECT_DLG, false);
+ if ( pItem && pItem->GetValue() )
+ bShowSWOptions = true;
+
+ const SfxBoolItem* pItem2 = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_OPEN_SMARTTAGOPTIONS, false);
+ if ( pItem2 && pItem2->GetValue() )
+ bOpenSmartTagOptions = true;
+ }
+
+ AddTabPage("options", OfaAutocorrOptionsPage::Create, nullptr);
+ AddTabPage("applypage", OfaSwAutoFmtOptionsPage::Create, nullptr);
+ AddTabPage("wordcompletion", OfaAutoCompleteTabPage::Create, nullptr);
+ AddTabPage("smarttags", OfaSmartTagOptionsTabPage::Create, nullptr);
+
+ if (!bShowSWOptions)
+ {
+ RemoveTabPage("applypage");
+ RemoveTabPage("wordcompletion");
+ RemoveTabPage("smarttags");
+ }
+ else
+ {
+ // remove smart tag tab page if no extensions are installed
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags& rOpt = pAutoCorrect->GetSwFlags();
+ if (!rOpt.pSmartTagMgr || 0 == rOpt.pSmartTagMgr->NumberOfRecognizers())
+ RemoveTabPage("smarttags");
+
+ RemoveTabPage("options");
+ }
+
+ AddTabPage("replace", OfaAutocorrReplacePage::Create, nullptr);
+ AddTabPage("exceptions", OfaAutocorrExceptPage::Create, nullptr);
+ AddTabPage("localized", OfaQuoteTabPage::Create, nullptr);
+
+ // initialize languages
+ //! LANGUAGE_NONE is displayed as '[All]' and the LanguageType
+ //! will be set to LANGUAGE_UNDETERMINED
+ SvxLanguageListFlags nLangList = SvxLanguageListFlags::WESTERN;
+
+ if( SvtCTLOptions().IsCTLFontEnabled() )
+ nLangList |= SvxLanguageListFlags::CTL;
+ if( SvtCJKOptions::IsCJKFontEnabled() )
+ nLangList |= SvxLanguageListFlags::CJK;
+ m_xLanguageLB->SetLanguageList( nLangList, true, true );
+ m_xLanguageLB->set_active_id( LANGUAGE_NONE );
+ int nPos = m_xLanguageLB->get_active();
+ DBG_ASSERT(nPos != -1, "listbox entry missing" );
+ m_xLanguageLB->set_id(nPos, LANGUAGE_UNDETERMINED);
+
+ // Initializing doesn't work for static on linux - therefore here
+ if (LANGUAGE_SYSTEM == eLastDialogLanguage)
+ eLastDialogLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
+
+ LanguageType nSelectLang = LANGUAGE_UNDETERMINED;
+ nPos = m_xLanguageLB->find_id(eLastDialogLanguage);
+ if (nPos != -1)
+ nSelectLang = eLastDialogLanguage;
+ m_xLanguageLB->set_active_id(nSelectLang);
+
+ m_xLanguageLB->connect_changed(LINK(this, OfaAutoCorrDlg, SelectLanguageHdl));
+
+ if ( bOpenSmartTagOptions )
+ SetCurPageId("smarttags");
+}
+
+OfaAutoCorrDlg::~OfaAutoCorrDlg()
+{
+}
+
+void OfaAutoCorrDlg::EnableLanguage(bool bEnable)
+{
+ m_xLanguageBox->set_sensitive(bEnable);
+}
+
+static bool lcl_FindEntry(weld::TreeView& rLB, const OUString& rEntry,
+ CollatorWrapper const & rCmpClass)
+{
+ int nCount = rLB.n_children();
+ int nSelPos = rLB.get_selected_index();
+ for (int i = 0; i < nCount; i++)
+ {
+ if (0 == rCmpClass.compareString(rEntry, rLB.get_text(i)))
+ {
+ rLB.select(i);
+ return true;
+ }
+ }
+ if (nSelPos != -1)
+ rLB.unselect(nSelPos);
+ return false;
+}
+
+IMPL_LINK_NOARG(OfaAutoCorrDlg, SelectLanguageHdl, weld::ComboBox&, void)
+{
+ LanguageType eNewLang = m_xLanguageLB->get_active_id();
+ // save old settings and fill anew
+ if(eNewLang == eLastDialogLanguage)
+ return;
+
+ OString sPageId = GetCurPageId();
+ if (sPageId == "replace")
+ {
+ OfaAutocorrReplacePage* pPage = static_cast<OfaAutocorrReplacePage*>(GetTabPage(sPageId));
+ assert(pPage);
+ pPage->SetLanguage(eNewLang);
+ }
+ else if (sPageId == "exceptions")
+ {
+ OfaAutocorrExceptPage* pPage = static_cast<OfaAutocorrExceptPage*>(GetTabPage(sPageId));
+ assert(pPage);
+ pPage->SetLanguage(eNewLang);
+ }
+}
+
+OfaAutocorrOptionsPage::OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acoroptionspage.ui", "AutocorrectOptionsPage", &rSet)
+ , m_sInput(CuiResId(RID_CUISTR_USE_REPLACE))
+ , m_sDoubleCaps(CuiResId(RID_CUISTR_CPTL_STT_WORD))
+ , m_sStartCap(CuiResId(RID_CUISTR_CPTL_STT_SENT))
+ , m_sBoldUnderline(CuiResId(RID_CUISTR_BOLD_UNDER))
+ , m_sURL(CuiResId(RID_CUISTR_DETECT_URL))
+ , m_sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
+ , m_sDash(CuiResId(RID_CUISTR_DASH))
+ , m_sAccidentalCaps(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
+{
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xCheckLB->set_size_request(-1, m_xCheckLB->get_height_rows(10));
+}
+
+OfaAutocorrOptionsPage::~OfaAutocorrOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrOptionsPage>(pPage, pController, *rSet);
+}
+
+#define CBCOL_FIRST 0
+#define CBCOL_SECOND 1
+#define CBCOL_BOTH 2
+
+bool OfaAutocorrOptionsPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ int nPos = 0;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+
+ bool bReturn = nFlags != pAutoCorrect->GetFlags();
+ if(bReturn )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return bReturn;
+}
+
+void OfaAutocorrOptionsPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaAutocorrOptionsPage::InsertEntry(const OUString& rTxt)
+{
+ m_xCheckLB->append();
+ const int nRow = m_xCheckLB->n_children() - 1;
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE);
+ m_xCheckLB->set_text(nRow, rTxt, 0);
+}
+
+void OfaAutocorrOptionsPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ InsertEntry(m_sInput);
+ InsertEntry(m_sDoubleCaps);
+ InsertEntry(m_sStartCap);
+ InsertEntry(m_sBoldUnderline);
+ InsertEntry(m_sURL);
+ InsertEntry(m_sDash);
+ InsertEntry(m_sNoDblSpaces);
+ InsertEntry(m_sAccidentalCaps);
+
+ int nPos = 0;
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE );
+
+ m_xCheckLB->thaw();
+}
+
+/*********************************************************************/
+/* */
+/* helping struct for dUserData of the Checklistbox */
+/* */
+/*********************************************************************/
+
+namespace {
+
+struct ImpUserData
+{
+ OUString *pString;
+ vcl::Font *pFont;
+
+ ImpUserData(OUString* pText, vcl::Font* pFnt)
+ { pString = pText; pFont = pFnt;}
+};
+
+
+/*********************************************************************/
+/* */
+/* dialog for per cent settings */
+/* */
+/*********************************************************************/
+
+class OfaAutoFmtPrcntSet : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::MetricSpinButton> m_xPrcntMF;
+public:
+ explicit OfaAutoFmtPrcntSet(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/percentdialog.ui", "PercentDialog")
+ , m_xPrcntMF(m_xBuilder->weld_metric_spin_button("margin", FieldUnit::PERCENT))
+ {
+ }
+
+ weld::MetricSpinButton& GetPrcntFld()
+ {
+ return *m_xPrcntMF;
+ }
+};
+
+/*********************************************************************/
+/* */
+/* use TabPage autoformat */
+/* */
+/*********************************************************************/
+
+enum OfaAutoFmtOptions
+{
+ USE_REPLACE_TABLE,
+ CORR_UPPER,
+ BEGIN_UPPER,
+ BOLD_UNDERLINE,
+ DETECT_URL,
+ REPLACE_DASHES,
+ DEL_SPACES_AT_STT_END,
+ DEL_SPACES_BETWEEN_LINES,
+ IGNORE_DBLSPACE,
+ CORRECT_CAPS_LOCK,
+ APPLY_NUMBERING,
+ INSERT_BORDER,
+ CREATE_TABLE,
+ REPLACE_STYLES,
+ DEL_EMPTY_NODE,
+ REPLACE_USER_COLL,
+ REPLACE_BULLETS,
+ MERGE_SINGLE_LINE_PARA
+};
+
+}
+
+OfaSwAutoFmtOptionsPage::OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pPage, pController, "cui/ui/applyautofmtpage.ui", "ApplyAutoFmtPage", &rSet)
+ , sDeleteEmptyPara(CuiResId(RID_CUISTR_DEL_EMPTY_PARA))
+ , sUseReplaceTbl(CuiResId(RID_CUISTR_USE_REPLACE))
+ , sCapitalStartWord(CuiResId(RID_CUISTR_CPTL_STT_WORD))
+ , sCapitalStartSentence(CuiResId(RID_CUISTR_CPTL_STT_SENT))
+ , sUserStyle(CuiResId(RID_CUISTR_USER_STYLE))
+ , sBullet(CuiResId(RID_CUISTR_BULLET))
+ , sBoldUnder(CuiResId(RID_CUISTR_BOLD_UNDER))
+ , sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
+ , sCorrectCapsLock(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
+ , sDetectURL(CuiResId(RID_CUISTR_DETECT_URL))
+ , sDash(CuiResId(RID_CUISTR_DASH))
+ , sRightMargin(CuiResId(RID_CUISTR_RIGHT_MARGIN))
+ , sNum(CuiResId(RID_CUISTR_NUM))
+ , sBorder(CuiResId(RID_CUISTR_BORDER))
+ , sTable(CuiResId(RID_CUISTR_CREATE_TABLE))
+ , sReplaceTemplates(CuiResId(RID_CUISTR_REPLACE_TEMPLATES))
+ , sDelSpaceAtSttEnd(CuiResId(RID_CUISTR_DEL_SPACES_AT_STT_END))
+ , sDelSpaceBetweenLines(CuiResId(RID_CUISTR_DEL_SPACES_BETWEEN_LINES))
+ , nPercent(50)
+ , m_xCheckLB(m_xBuilder->weld_tree_view("list"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+{
+ m_xCheckLB->connect_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl));
+ m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl));
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2),
+ o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(1)).Width() * 2)
+ };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+
+ m_xEditPB->connect_clicked(LINK(this, OfaSwAutoFmtOptionsPage, EditHdl));
+}
+
+void OfaSwAutoFmtOptionsPage::CreateEntry(const OUString& rTxt, sal_uInt16 nCol)
+{
+ m_xCheckLB->append();
+ const int nRow = m_xCheckLB->n_children() - 1;
+ if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_text(nRow, rTxt, 2);
+}
+
+OfaSwAutoFmtOptionsPage::~OfaSwAutoFmtOptionsPage()
+{
+ delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(REPLACE_BULLETS));
+ delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(APPLY_NUMBERING));
+ delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA));
+}
+
+std::unique_ptr<SfxTabPage> OfaSwAutoFmtOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OfaSwAutoFmtOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaSwAutoFmtOptionsPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ bool bCheck = m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAutoCorrect != bCheck;
+ pOpt->bAutoCorrect = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,
+ m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bCapitalStartWord != bCheck;
+ pOpt->bCapitalStartWord = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,
+ m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bCapitalStartSentence != bCheck;
+ pOpt->bCapitalStartSentence = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence,
+ m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgWeightUnderl != bCheck;
+ pOpt->bChgWeightUnderl = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,
+ m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,
+ m_xCheckLB->get_toggle(IGNORE_DBLSPACE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,
+ m_xCheckLB->get_toggle(CORRECT_CAPS_LOCK, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DETECT_URL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetINetAttr != bCheck;
+ pOpt->bSetINetAttr = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,
+ m_xCheckLB->get_toggle(DETECT_URL, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DEL_EMPTY_NODE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bDelEmptyNode != bCheck;
+ pOpt->bDelEmptyNode = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_USER_COLL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgUserColl != bCheck;
+ pOpt->bChgUserColl = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_BULLETS, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgEnumNum != bCheck;
+ pOpt->bChgEnumNum = bCheck;
+ bModified |= aBulletFont != pOpt->aBulletFont;
+ pOpt->aBulletFont = aBulletFont;
+ bModified |= sBulletChar != OUString(&pOpt->cBullet, 1);
+ pOpt->cBullet = sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+
+ bModified |= aByInputBulletFont != pOpt->aByInputBulletFont;
+ bModified |= sByInputBulletChar != OUString(&pOpt->cByInputBullet, 1);
+ pOpt->aByInputBulletFont = aByInputBulletFont;
+ pOpt->cByInputBullet = sByInputBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
+
+ bCheck = m_xCheckLB->get_toggle(MERGE_SINGLE_LINE_PARA, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bRightMargin != bCheck;
+ pOpt->bRightMargin = bCheck;
+ bModified |= nPercent != pOpt->nRightMargin;
+ pOpt->nRightMargin = static_cast<sal_uInt8>(nPercent);
+
+ bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetNumRule != bCheck;
+ pOpt->bSetNumRule = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(INSERT_BORDER, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetBorder != bCheck;
+ pOpt->bSetBorder = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(CREATE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bCreateTable != bCheck;
+ pOpt->bCreateTable = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_STYLES, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bReplaceStyles != bCheck;
+ pOpt->bReplaceStyles = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgToEnEmDash != bCheck;
+ pOpt->bChgToEnEmDash = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,
+ m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatDelSpacesAtSttEnd != bCheck;
+ pOpt->bAFormatDelSpacesAtSttEnd = bCheck;
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatByInpDelSpacesAtSttEnd != bCheck;
+ pOpt->bAFormatByInpDelSpacesAtSttEnd = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatDelSpacesBetweenLines != bCheck;
+ pOpt->bAFormatDelSpacesBetweenLines = bCheck;
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatByInpDelSpacesBetweenLines != bCheck;
+ pOpt->bAFormatByInpDelSpacesBetweenLines = bCheck;
+
+ if(bModified || nFlags != pAutoCorrect->GetFlags())
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+
+ return true;
+}
+
+void OfaSwAutoFmtOptionsPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaSwAutoFmtOptionsPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ aBulletFont = pOpt->aBulletFont;
+ sBulletChar = OUString(&pOpt->cBullet, 1);
+
+ aByInputBulletFont = pOpt->aByInputBulletFont;
+ sByInputBulletChar = OUString(&pOpt->cByInputBullet, 1);
+
+ nPercent = pOpt->nRightMargin;
+ sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ // The following entries have to be inserted in the same order
+ // as in the OfaAutoFmtOptions-enum!
+ CreateEntry(sUseReplaceTbl, CBCOL_BOTH );
+ CreateEntry(sCapitalStartWord, CBCOL_BOTH );
+ CreateEntry(sCapitalStartSentence, CBCOL_BOTH );
+ CreateEntry(sBoldUnder, CBCOL_BOTH );
+ CreateEntry(sDetectURL, CBCOL_BOTH );
+ CreateEntry(sDash, CBCOL_BOTH );
+ CreateEntry(sDelSpaceAtSttEnd, CBCOL_BOTH );
+ CreateEntry(sDelSpaceBetweenLines, CBCOL_BOTH );
+
+ CreateEntry(sNoDblSpaces, CBCOL_SECOND);
+ CreateEntry(sCorrectCapsLock, CBCOL_SECOND);
+ CreateEntry(sNum.replaceFirst("%1", sBulletChar), CBCOL_SECOND);
+ CreateEntry(sBorder, CBCOL_SECOND);
+ CreateEntry(sTable, CBCOL_SECOND);
+ CreateEntry(sReplaceTemplates, CBCOL_SECOND);
+ CreateEntry(sDeleteEmptyPara, CBCOL_FIRST );
+ CreateEntry(sUserStyle, CBCOL_FIRST );
+ CreateEntry(sBullet.replaceFirst("%1", sByInputBulletChar), CBCOL_FIRST);
+ CreateEntry(sRightMargin.replaceFirst("%1", sMargin), CBCOL_FIRST);
+
+ m_xCheckLB->set_toggle(USE_REPLACE_TABLE, pOpt->bAutoCorrect ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(USE_REPLACE_TABLE, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CORR_UPPER, pOpt->bCapitalStartWord ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(CORR_UPPER, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(BEGIN_UPPER, pOpt->bCapitalStartSentence ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(BEGIN_UPPER, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(BOLD_UNDERLINE, pOpt->bChgWeightUnderl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(BOLD_UNDERLINE, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DETECT_URL, pOpt->bSetINetAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DETECT_URL, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(REPLACE_DASHES, pOpt->bChgToEnEmDash ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_DASHES, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatByInpDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatByInpDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(IGNORE_DBLSPACE, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CORRECT_CAPS_LOCK, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(APPLY_NUMBERING, pOpt->bSetNumRule ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(INSERT_BORDER, pOpt->bSetBorder ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CREATE_TABLE, pOpt->bCreateTable ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(REPLACE_STYLES, pOpt->bReplaceStyles ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_EMPTY_NODE, pOpt->bDelEmptyNode ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_USER_COLL, pOpt->bChgUserColl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_BULLETS, pOpt->bChgEnumNum ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(MERGE_SINGLE_LINE_PARA, pOpt->bRightMargin ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+
+ ImpUserData* pUserData = new ImpUserData(&sBulletChar, &aBulletFont);
+ OUString sId(weld::toId(pUserData));
+ m_xCheckLB->set_id(REPLACE_BULLETS, sId);
+
+ pUserData = new ImpUserData(&sMargin, nullptr);
+ sId = weld::toId(pUserData);
+ m_xCheckLB->set_id(MERGE_SINGLE_LINE_PARA, sId);
+
+ ImpUserData* pUserData2 = new ImpUserData(&sByInputBulletChar, &aByInputBulletFont);
+ sId = weld::toId(pUserData2);
+ m_xCheckLB->set_id(APPLY_NUMBERING, sId);
+
+ m_xCheckLB->thaw();
+}
+
+IMPL_LINK(OfaSwAutoFmtOptionsPage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ m_xEditPB->set_sensitive(rBox.get_selected_id().toInt64() != 0);
+}
+
+IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, DoubleClickEditHdl, weld::TreeView&, bool)
+{
+ EditHdl(*m_xEditPB);
+ return true;
+}
+
+IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, EditHdl, weld::Button&, void)
+{
+ int nSelEntryPos = m_xCheckLB->get_selected_index();
+ if (nSelEntryPos == REPLACE_BULLETS || nSelEntryPos == APPLY_NUMBERING)
+ {
+ SvxCharacterMap aMapDlg(GetFrameWeld(), nullptr, nullptr);
+ ImpUserData* pUserData = weld::fromId<ImpUserData*>(m_xCheckLB->get_id(nSelEntryPos));
+ aMapDlg.SetCharFont(*pUserData->pFont);
+ aMapDlg.SetChar( (*pUserData->pString)[0] );
+ if (RET_OK == aMapDlg.run())
+ {
+ const vcl::Font& aFont(aMapDlg.GetCharFont());
+ *pUserData->pFont = aFont;
+ sal_UCS4 aChar = aMapDlg.GetChar();
+ // using the UCS4 constructor
+ OUString aOUStr( &aChar, 1 );
+ *pUserData->pString = aOUStr;
+ if (nSelEntryPos == REPLACE_BULLETS)
+ m_xCheckLB->set_text(nSelEntryPos, sNum.replaceFirst("%1", aOUStr), 2);
+ else
+ m_xCheckLB->set_text(nSelEntryPos, sBullet.replaceFirst("%1", aOUStr), 2);
+ }
+ }
+ else if( MERGE_SINGLE_LINE_PARA == nSelEntryPos )
+ {
+ // dialog for per cent settings
+ OfaAutoFmtPrcntSet aDlg(GetFrameWeld());
+ aDlg.GetPrcntFld().set_value(nPercent, FieldUnit::PERCENT);
+ if (aDlg.run() == RET_OK)
+ {
+ nPercent = static_cast<sal_uInt16>(aDlg.GetPrcntFld().get_value(FieldUnit::PERCENT));
+ sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
+ m_xCheckLB->set_text(nSelEntryPos, sRightMargin.replaceFirst("%1", sMargin), 2);
+ }
+ }
+}
+
+
+OfaAutocorrReplacePage::OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acorreplacepage.ui", "AcorReplacePage", &rSet)
+ , eLang(eLastDialogLanguage)
+ , bHasSelectionText(false)
+ , bFirstSelect(true)
+ , bReplaceEditChanged(false)
+ , bSWriter(true)
+ , m_xTextOnlyCB(m_xBuilder->weld_check_button("textonly"))
+ , m_xShortED(m_xBuilder->weld_entry("origtext"))
+ , m_xReplaceED(m_xBuilder->weld_entry("newtext"))
+ , m_xReplaceTLB(m_xBuilder->weld_tree_view("tabview"))
+ , m_xNewReplacePB(m_xBuilder->weld_button("new"))
+ , m_xReplacePB(m_xBuilder->weld_button("replace"))
+ , m_xDeleteReplacePB(m_xBuilder->weld_button("delete"))
+ , m_xButtonBox(m_xBuilder->weld_container("buttonbox"))
+{
+ sNew = m_xNewReplacePB->get_label();
+ sModify = m_xReplacePB->get_label();
+
+ // lock down the width of the button box to its max
+ // desired width
+ auto nMaxWidth = m_xButtonBox->get_preferred_size().Width();
+ m_xButtonBox->set_size_request(nMaxWidth, -1);
+ m_xReplacePB->hide();
+
+ // tdf#125348 set some small but fixed initial width size, final width will
+ // depend on the size of the entry boxes
+ m_xReplaceTLB->set_size_request(42, m_xReplaceTLB->get_height_rows(10));
+
+ SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
+ bSWriter = pMod == SfxModule::GetActiveModule();
+
+ LanguageTag aLanguageTag( eLastDialogLanguage );
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
+ pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
+
+ auto nColWidth = m_xReplaceTLB->get_approximate_digit_width() * 32;
+ m_aReplaceFixedWidths.push_back(nColWidth);
+ m_aReplaceFixedWidths.push_back(nColWidth);
+
+ m_xReplaceTLB->connect_changed( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
+ m_xNewReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
+ m_xDeleteReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
+ m_xShortED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
+ m_xReplaceED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
+ m_xShortED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
+ m_xReplaceED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
+ m_xShortED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
+ m_xReplaceED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
+}
+
+OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
+{
+ aDoubleStringTable.clear();
+ aChangesTable.clear();
+
+ pCompareClass.reset();
+ pCharClass.reset();
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrReplacePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrReplacePage>(pPage, pController, *rSet);
+}
+
+void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
+{
+ if(eLang != eLastDialogLanguage)
+ SetLanguage(eLastDialogLanguage);
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
+}
+
+DeactivateRC OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+ for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); ++it)
+ {
+ LanguageType eCurrentLang = it->first;
+ StringChangeList& rStringChangeList = it->second;
+ std::vector<SvxAutocorrWord> aDeleteWords;
+ std::vector<SvxAutocorrWord> aNewWords;
+
+ aDeleteWords.reserve( rStringChangeList.aDeletedEntries.size() );
+ for (const DoubleString & deleteEntry : rStringChangeList.aDeletedEntries)
+ {
+ SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
+ aDeleteWords.push_back( aDeleteWord );
+ }
+
+ aNewWords.reserve( rStringChangeList.aNewEntries.size() );
+ for (const DoubleString & newEntry : rStringChangeList.aNewEntries)
+ {
+ //fdo#67697 if the user data is set then we want to retain the
+ //source formatting of the entry, so don't use the optimized
+ //text-only MakeCombinedChanges for this entry
+ bool bKeepSourceFormatting = newEntry.pUserData == &bHasSelectionText;
+ if (bKeepSourceFormatting)
+ {
+ if (SfxObjectShell* pSh = SfxObjectShell::Current())
+ pAutoCorrect->PutText(newEntry.sShort, *pSh, eCurrentLang);
+ continue;
+ }
+
+ SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
+ aNewWords.push_back( aNewWord );
+ }
+ pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
+ }
+ aChangesTable.clear();
+ return false;
+}
+
+void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage)
+{
+ eLang = eNewLanguage;
+ if(bFromReset)
+ {
+ aDoubleStringTable.clear();
+ aChangesTable.clear();
+ }
+ else
+ {
+ DoubleStringArray* pArray;
+ if(aDoubleStringTable.find(eOldLanguage) != aDoubleStringTable.end())
+ {
+ pArray = &aDoubleStringTable[eOldLanguage];
+ pArray->clear();
+ }
+ else
+ {
+ pArray = &aDoubleStringTable[eOldLanguage]; // create new array
+ }
+
+ m_xReplaceTLB->all_foreach([this, &pArray](weld::TreeIter& rIter) {
+ pArray->push_back(DoubleString(m_xReplaceTLB->get_text(rIter, 0),
+ m_xReplaceTLB->get_text(rIter, 1)));
+ DoubleString& rDouble = pArray->back();
+ rDouble.pUserData = weld::fromId<void*>(m_xReplaceTLB->get_id(rIter));
+ return false;
+ });
+ }
+
+ if( !bSWriter )
+ aFormatText.clear();
+
+ if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
+ {
+ DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
+
+ m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
+ DoubleString &rDouble = rArray[nIndex];
+ bool bTextOnly = nullptr == rDouble.pUserData;
+ // formatted text is only in Writer
+ if (bSWriter || bTextOnly)
+ {
+ if (!bTextOnly)
+ {
+ // that means: with format info or even with selection text
+ OUString sId = weld::toId(rDouble.pUserData);
+ m_xReplaceTLB->set_id(rIter, sId);
+ }
+ m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
+ m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
+ }
+ else
+ {
+ aFormatText.insert(rDouble.sShort);
+ }
+ }, nullptr, &m_aReplaceFixedWidths);
+ }
+ else
+ {
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
+ const SvxAutocorrWordList::AutocorrWordSetType & rContent = pWordList->getSortedContent();
+ m_xReplaceTLB->bulk_insert_for_each(rContent.size(), [this, rContent](weld::TreeIter& rIter, int nIndex) {
+ auto const& elem = rContent[nIndex];
+ bool bTextOnly = elem.IsTextOnly();
+ // formatted text is only in Writer
+ if (bSWriter || bTextOnly)
+ {
+ if (!bTextOnly)
+ {
+ // that means: with format info or even with selection text
+ OUString sId = weld::toId(m_xTextOnlyCB.get());
+ m_xReplaceTLB->set_id(rIter, sId);
+ }
+ m_xReplaceTLB->set_text(rIter, elem.GetShort(), 0);
+ m_xReplaceTLB->set_text(rIter, elem.GetLong(), 1);
+ }
+ else
+ {
+ aFormatText.insert(elem.GetShort());
+ }
+ }, nullptr, &m_aReplaceFixedWidths);
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeleteReplacePB->set_sensitive(false);
+ }
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if (pViewShell && pViewShell->HasSelection())
+ {
+ bHasSelectionText = true;
+ const OUString sSelection( pViewShell->GetSelectionText() );
+ m_xReplaceED->set_text(sSelection);
+ m_xTextOnlyCB->set_active(!bSWriter);
+ m_xTextOnlyCB->set_sensitive(bSWriter && !sSelection.isEmpty());
+ }
+ else
+ {
+ m_xTextOnlyCB->set_active(true);
+ m_xTextOnlyCB->set_sensitive(false);
+ }
+}
+
+void OfaAutocorrReplacePage::Reset( const SfxItemSet* )
+{
+ RefillReplaceBox(true, eLang, eLang);
+ m_xShortED->grab_focus();
+}
+
+void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
+{
+ //save old settings and refill
+ if(eSet != eLang)
+ {
+ RefillReplaceBox(false, eLang, eSet);
+ eLastDialogLanguage = eSet;
+
+ LanguageTag aLanguageTag( eLastDialogLanguage );
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
+ pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
+ ModifyHdl(*m_xShortED);
+ }
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if(!bFirstSelect || !bHasSelectionText)
+ {
+ int nEntry = rBox.get_selected_index();
+ OUString sTmpShort(rBox.get_text(nEntry, 0));
+ // if the text is set via ModifyHdl, the cursor is always at the beginning
+ // of a word, although you're editing here
+ bool bSameContent = 0 == pCompareClass->compareString(sTmpShort, m_xShortED->get_text());
+ int nStartPos, nEndPos;
+ m_xShortED->get_selection_bounds(nStartPos, nEndPos);
+ if (m_xShortED->get_text() != sTmpShort)
+ {
+ m_xShortED->set_text(sTmpShort);
+ // if it was only a different notation, the selection has to be set again
+ if (bSameContent)
+ {
+ m_xShortED->select_region(nStartPos, nEndPos);
+ }
+ }
+ m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
+ // with UserData there is a Formatinfo
+ m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
+ }
+ else
+ {
+ bFirstSelect = false;
+ }
+
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeleteReplacePB->set_sensitive(true);
+};
+
+void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
+{
+ DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+ for (size_t i = 0; i < rNewArray.size(); i++)
+ {
+ if (rNewArray[i].sShort == sShort)
+ {
+ rNewArray.erase(rNewArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+ for (size_t i = 0; i < rDeletedArray.size(); i++)
+ {
+ if (rDeletedArray[i].sShort == sShort)
+ {
+ rDeletedArray.erase(rDeletedArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleString aNewString(sShort, sLong);
+ rNewArray.push_back(aNewString);
+ if (bKeepSourceFormatting)
+ rNewArray.back().pUserData = &bHasSelectionText;
+}
+
+void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString& sLong)
+{
+ DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+ for (size_t i = 0; i < rNewArray.size(); i++)
+ {
+ if (rNewArray[i].sShort == sShort)
+ {
+ rNewArray.erase(rNewArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+ for (size_t i = 0; i < rDeletedArray.size(); i++)
+ {
+ if (rDeletedArray[i].sShort == sShort)
+ {
+ rDeletedArray.erase(rDeletedArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleString aDeletedString(sShort, sLong);
+ rDeletedArray.push_back(aDeletedString);
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
+{
+ return NewDelHdl(&rEdit);
+}
+
+IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
+{
+ m_aReplaceFixedWidths.clear();
+ int x, y, width, height;
+ if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
+ {
+ m_aReplaceFixedWidths.push_back(x);
+ m_aReplaceFixedWidths.push_back(width - 1);
+ m_xReplaceTLB->set_column_fixed_widths(m_aReplaceFixedWidths);
+ }
+}
+
+bool OfaAutocorrReplacePage::NewDelHdl(const weld::Widget* pBtn)
+{
+ int nEntry = m_xReplaceTLB->get_selected_index();
+ if (pBtn == m_xDeleteReplacePB.get())
+ {
+ DBG_ASSERT( nEntry != -1, "no entry selected" );
+ if (nEntry != -1)
+ {
+ DeleteEntry(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
+ m_xReplaceTLB->remove(nEntry);
+ ModifyHdl(*m_xShortED);
+ return true;
+ }
+ }
+
+ if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
+ {
+ OUString sEntry(m_xShortED->get_text());
+ if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
+ ( bHasSelectionText && bSWriter ) ))
+ {
+ bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();
+
+ NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
+ m_xReplaceTLB->freeze();
+ int nPos = -1;
+ if (nEntry != -1)
+ {
+ nPos = nEntry;
+ m_xReplaceTLB->remove(nEntry);
+ }
+ else
+ {
+ int j;
+ int nCount = m_xReplaceTLB->n_children();
+ for (j = 0; j < nCount; ++j)
+ {
+ if (0 >= pCompareClass->compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
+ break;
+ }
+ nPos = j;
+ }
+
+ OUString sId;
+ if (bKeepSourceFormatting)
+ {
+ sId = weld::toId(&bHasSelectionText); // new formatted text
+ }
+
+ m_xReplaceTLB->insert(nPos, sEntry, &sId, nullptr, nullptr);
+ m_xReplaceTLB->set_text(nPos, m_xReplaceED->get_text(), 1);
+ m_xReplaceTLB->thaw();
+ m_xReplaceTLB->scroll_to_row(nPos);
+ // if the request came from the ReplaceEdit, give focus to the ShortEdit
+ if (m_xReplaceED->has_focus())
+ {
+ m_xShortED->grab_focus();
+ }
+ }
+ }
+ else
+ {
+ // this can only be an enter in one of the two edit fields
+ // which means EndDialog() - has to be evaluated in KeyInput
+ return false;
+ }
+ ModifyHdl(*m_xShortED);
+ return true;
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ std::unique_ptr<weld::TreeIter> xFirstSel(m_xReplaceTLB->make_iterator());
+ bool bFirstSelIterSet = m_xReplaceTLB->get_selected(xFirstSel.get());
+ bool bShort = &rEdt == m_xShortED.get();
+ const OUString rEntry = rEdt.get_text();
+ const OUString rRepString = m_xReplaceED->get_text();
+ OUString aWordStr(pCharClass->lowercase(rEntry));
+
+ if(bShort)
+ {
+ if(!rEntry.isEmpty())
+ {
+ bool bFound = false;
+ bool bTmpSelEntry=false;
+
+ m_xReplaceTLB->all_foreach([this, &rEntry, &rRepString, &bFound,
+ &bTmpSelEntry, &bFirstSelIterSet,
+ &xFirstSel, &aWordStr](weld::TreeIter& rIter){
+ OUString aTestStr = m_xReplaceTLB->get_text(rIter, 0);
+ if( pCompareClass->compareString(rEntry, aTestStr ) == 0 )
+ {
+ if (!rRepString.isEmpty())
+ bFirstSelect = true;
+ m_xReplaceTLB->set_cursor(rIter);
+ m_xReplaceTLB->copy_iterator(rIter, *xFirstSel);
+ bFirstSelIterSet = true;
+ m_xNewReplacePB->set_label(sModify);
+ bFound = true;
+ return true;
+ }
+ else
+ {
+ aTestStr = pCharClass->lowercase( aTestStr );
+ if( aTestStr.startsWith(aWordStr) && !bTmpSelEntry )
+ {
+ m_xReplaceTLB->scroll_to_row(rIter);
+ bTmpSelEntry = true;
+ }
+ }
+ return false;
+ });
+ if( !bFound )
+ {
+ m_xReplaceTLB->select(-1);
+ bFirstSelIterSet = false;
+ m_xNewReplacePB->set_label(sNew);
+ if( bReplaceEditChanged )
+ m_xTextOnlyCB->set_sensitive(false);
+ }
+ m_xDeleteReplacePB->set_sensitive(bFound);
+ }
+ else if (m_xReplaceTLB->n_children() > 0)
+ {
+ m_xReplaceTLB->scroll_to_row(0);
+ }
+
+ }
+ else if( !bShort )
+ {
+ bReplaceEditChanged = true;
+ if (bFirstSelIterSet)
+ {
+ m_xNewReplacePB->set_label(sModify);
+ }
+ }
+
+ const OUString& rShortTxt = m_xShortED->get_text();
+ bool bEnableNew = !rShortTxt.isEmpty() &&
+ ( !rRepString.isEmpty() ||
+ ( bHasSelectionText && bSWriter )) &&
+ ( !bFirstSelIterSet || rRepString !=
+ m_xReplaceTLB->get_text(*xFirstSel, 1) );
+ if( bEnableNew )
+ {
+ for (auto const& elem : aFormatText)
+ {
+ if(elem == rShortTxt)
+ {
+ bEnableNew = false;
+ break;
+ }
+ }
+ }
+ m_xNewReplacePB->set_sensitive(bEnableNew);
+}
+
+static bool lcl_FindInArray(std::vector<OUString>& rStrings, std::u16string_view rString)
+{
+ for (auto const& elem : rStrings)
+ {
+ if(elem == rString)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+OfaAutocorrExceptPage::OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acorexceptpage.ui", "AcorExceptPage", &rSet)
+ , eLang(eLastDialogLanguage)
+ , m_xAbbrevED(m_xBuilder->weld_entry("abbrev"))
+ , m_xAbbrevLB(m_xBuilder->weld_tree_view("abbrevlist"))
+ , m_xNewAbbrevPB(m_xBuilder->weld_button("newabbrev"))
+ , m_xDelAbbrevPB(m_xBuilder->weld_button("delabbrev"))
+ , m_xAutoAbbrevCB(m_xBuilder->weld_check_button("autoabbrev"))
+ , m_xDoubleCapsED(m_xBuilder->weld_entry("double"))
+ , m_xDoubleCapsLB(m_xBuilder->weld_tree_view("doublelist"))
+ , m_xNewDoublePB(m_xBuilder->weld_button("newdouble"))
+ , m_xDelDoublePB(m_xBuilder->weld_button("deldouble"))
+ , m_xAutoCapsCB(m_xBuilder->weld_check_button("autodouble"))
+{
+ m_xAbbrevLB->make_sorted();
+ m_xAbbrevLB->set_size_request(-1, m_xAbbrevLB->get_height_rows(6));
+
+ m_xDoubleCapsLB->make_sorted();
+ m_xDoubleCapsLB->set_size_request(-1, m_xDoubleCapsLB->get_height_rows(6));
+
+ css::lang::Locale aLcl( LanguageTag::convertToLocale(eLastDialogLanguage ));
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( aLcl, 0 );
+
+ m_xNewAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xDelAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xNewDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xDelDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+
+ m_xAbbrevLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
+ m_xDoubleCapsLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
+ m_xAbbrevED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
+ m_xDoubleCapsED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
+
+ m_xAbbrevED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
+ m_xDoubleCapsED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
+}
+
+OfaAutocorrExceptPage::~OfaAutocorrExceptPage()
+{
+ aStringsTable.clear();
+ pCompareClass.reset();
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrExceptPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrExceptPage>(pPage, pController, *rSet);
+}
+
+void OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& )
+{
+ if(eLang != eLastDialogLanguage)
+ SetLanguage(eLastDialogLanguage);
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
+}
+
+DeactivateRC OfaAutocorrExceptPage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool OfaAutocorrExceptPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ for(StringsTable::reverse_iterator it1 = aStringsTable.rbegin(); it1 != aStringsTable.rend(); ++it1)
+ {
+ LanguageType eCurLang = it1->first;
+ StringsArrays& rArrays = it1->second;
+ if(eCurLang != eLang) // current language is treated later
+ {
+ SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eCurLang);
+
+ if(pWrdList)
+ {
+ size_t nCount = pWrdList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pWrdList)[ --i ];
+
+ if( !lcl_FindInArray(rArrays.aDoubleCapsStrings, aString))
+ {
+ pWrdList->erase_at(i);
+ }
+ }
+
+ for (auto const& elem : rArrays.aDoubleCapsStrings)
+ {
+ pWrdList->insert(elem);
+ }
+ pAutoCorrect->SaveWordStartExceptList(eCurLang);
+ }
+
+ SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eCurLang);
+
+ if(pCplList)
+ {
+ size_t nCount = pCplList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pCplList)[ --i ];
+ if( !lcl_FindInArray(rArrays.aAbbrevStrings, aString))
+ {
+ pCplList->erase_at(i);
+ }
+ }
+
+ for (auto const& elem : rArrays.aAbbrevStrings)
+ {
+ pCplList->insert(elem);
+ }
+
+ pAutoCorrect->SaveCplSttExceptList(eCurLang);
+ }
+ }
+ }
+ aStringsTable.clear();
+
+ SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eLang);
+
+ if(pWrdList)
+ {
+ size_t nCount = pWrdList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pWrdList)[ --i ];
+ if (m_xDoubleCapsLB->find_text(aString) == -1)
+ {
+ pWrdList->erase_at(i);
+ }
+ }
+ nCount = m_xDoubleCapsLB->n_children();
+ for( i = 0; i < nCount; ++i )
+ {
+ pWrdList->insert(m_xDoubleCapsLB->get_text(i));
+ }
+ pAutoCorrect->SaveWordStartExceptList(eLang);
+ }
+
+ SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eLang);
+
+ if(pCplList)
+ {
+ size_t nCount = pCplList->size();
+ for( size_t i = nCount; i; )
+ {
+ OUString aString = (*pCplList)[ --i ];
+ if (m_xAbbrevLB->find_text(aString) == -1)
+ {
+ pCplList->erase_at(i);
+ }
+ }
+ sal_Int32 nAbbrevCount = m_xAbbrevLB->n_children();
+ for( sal_Int32 ia = 0; ia < nAbbrevCount; ++ia )
+ {
+ pCplList->insert(m_xAbbrevLB->get_text(ia));
+ }
+ pAutoCorrect->SaveCplSttExceptList(eLang);
+ }
+ if (m_xAutoAbbrevCB->get_state_changed_from_saved())
+ pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordCplSttLst, m_xAutoAbbrevCB->get_active());
+ if (m_xAutoCapsCB->get_state_changed_from_saved())
+ pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordWordStartLst, m_xAutoCapsCB->get_active());
+ return false;
+}
+
+void OfaAutocorrExceptPage::SetLanguage(LanguageType eSet)
+{
+ if(eLang != eSet)
+ {
+ // save old settings and fill anew
+ RefillReplaceBoxes(false, eLang, eSet);
+ eLastDialogLanguage = eSet;
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( LanguageTag::convertToLocale( eLastDialogLanguage ), 0 );
+ ModifyHdl(*m_xAbbrevED);
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+}
+
+void OfaAutocorrExceptPage::RefillReplaceBoxes(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage)
+{
+ eLang = eNewLanguage;
+ if(bFromReset)
+ {
+ aStringsTable.clear();
+ }
+ else
+ {
+ StringsArrays* pArrays;
+ if(aStringsTable.find(eOldLanguage) != aStringsTable.end())
+ {
+ pArrays = &aStringsTable[eOldLanguage];
+ pArrays->aAbbrevStrings.clear();
+ pArrays->aDoubleCapsStrings.clear();
+ }
+ else
+ {
+ pArrays = &aStringsTable[eOldLanguage]; // create new array
+ }
+
+ sal_Int32 i, nCount;
+ nCount = m_xAbbrevLB->n_children();
+ for(i = 0; i < nCount; i++)
+ pArrays->aAbbrevStrings.push_back(m_xAbbrevLB->get_text(i));
+
+ nCount = m_xDoubleCapsLB->n_children();
+ for(i = 0; i < nCount; i++)
+ pArrays->aDoubleCapsStrings.push_back(m_xDoubleCapsLB->get_text(i));
+ }
+ m_xDoubleCapsLB->clear();
+ m_xAbbrevLB->clear();
+ m_xAbbrevED->set_text("");
+ m_xDoubleCapsED->set_text("");
+
+ if(aStringsTable.find(eLang) != aStringsTable.end())
+ {
+ StringsArrays& rArrays = aStringsTable[eLang];
+ for (auto const& elem : rArrays.aAbbrevStrings)
+ m_xAbbrevLB->append_text(elem);
+
+ for (auto const& elem : rArrays.aDoubleCapsStrings)
+ m_xDoubleCapsLB->append_text(elem);
+ }
+ else
+ {
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const SvStringsISortDtor* pCplList = pAutoCorrect->GetCplSttExceptList(eLang);
+ const SvStringsISortDtor* pWrdList = pAutoCorrect->GetWordStartExceptList(eLang);
+ size_t i;
+ for( i = 0; i < pCplList->size(); i++ )
+ {
+ m_xAbbrevLB->append_text((*pCplList)[i]);
+ }
+ for( i = 0; i < pWrdList->size(); i++ )
+ {
+ m_xDoubleCapsLB->append_text((*pWrdList)[i]);
+ }
+ }
+}
+
+void OfaAutocorrExceptPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ RefillReplaceBoxes(true, eLang, eLang);
+ m_xAutoAbbrevCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordCplSttLst));
+ m_xAutoCapsCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordWordStartLst));
+ m_xAutoAbbrevCB->save_state();
+ m_xAutoCapsCB->save_state();
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, NewDelActionHdl, weld::Entry&, rEdit, bool)
+{
+ return NewDelHdl(&rEdit);
+}
+
+bool OfaAutocorrExceptPage::NewDelHdl(const weld::Widget* pBtn)
+{
+ if ((pBtn == m_xNewAbbrevPB.get() || pBtn == m_xAbbrevED.get())
+ && !m_xAbbrevED->get_text().isEmpty() && m_xNewAbbrevPB->get_sensitive())
+ {
+ m_xAbbrevLB->append_text(m_xAbbrevED->get_text());
+ ModifyHdl(*m_xAbbrevED);
+ }
+ else if(pBtn == m_xDelAbbrevPB.get())
+ {
+ m_xAbbrevLB->remove_text(m_xAbbrevED->get_text());
+ ModifyHdl(*m_xAbbrevED);
+ }
+ else if((pBtn == m_xNewDoublePB.get() || pBtn == m_xDoubleCapsED.get() )
+ && !m_xDoubleCapsED->get_text().isEmpty() && m_xNewDoublePB->get_sensitive())
+ {
+ m_xDoubleCapsLB->append_text(m_xDoubleCapsED->get_text());
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+ else if (pBtn == m_xDelDoublePB.get())
+ {
+ m_xDoubleCapsLB->remove_text(m_xDoubleCapsED->get_text());
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+ else
+ {
+ // we didn't do anything, if this was because of 'activate' in an
+ // entry then let it continue to close the dialog like the replace
+ // page does
+ return false;
+ }
+ return true;
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (&rBox == m_xAbbrevLB.get())
+ {
+ m_xAbbrevED->set_text(rBox.get_selected_text());
+ m_xNewAbbrevPB->set_sensitive(false);
+ m_xDelAbbrevPB->set_sensitive(true);
+ }
+ else
+ {
+ m_xDoubleCapsED->set_text(rBox.get_selected_text());
+ m_xNewDoublePB->set_sensitive(false);
+ m_xDelDoublePB->set_sensitive(true);
+ }
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ const OUString& sEntry = rEdt.get_text();
+ bool bEntryLen = !sEntry.isEmpty();
+ if (&rEdt == m_xAbbrevED.get())
+ {
+ bool bSame = lcl_FindEntry(*m_xAbbrevLB, sEntry, *pCompareClass);
+ if(bSame && sEntry != m_xAbbrevLB->get_selected_text())
+ rEdt.set_text(m_xAbbrevLB->get_selected_text());
+ m_xNewAbbrevPB->set_sensitive(!bSame && bEntryLen);
+ m_xDelAbbrevPB->set_sensitive(bSame && bEntryLen);
+ }
+ else
+ {
+ bool bSame = lcl_FindEntry(*m_xDoubleCapsLB, sEntry, *pCompareClass);
+ if(bSame && sEntry != m_xDoubleCapsLB->get_selected_text())
+ rEdt.set_text(m_xDoubleCapsLB->get_selected_text());
+ m_xNewDoublePB->set_sensitive(!bSame && bEntryLen);
+ m_xDelDoublePB->set_sensitive(bSame && bEntryLen);
+ }
+}
+
+namespace {
+
+enum OfaQuoteOptions
+{
+ ADD_NONBRK_SPACE,
+ REPLACE_1ST,
+ TRANSLITERATE_RTL,
+ REPLACE_ANGLE_QUOTES
+};
+
+}
+
+void OfaQuoteTabPage::CreateEntry(weld::TreeView& rCheckLB, const OUString& rTxt, sal_uInt16 nCol, sal_uInt16 nTextCol)
+{
+ rCheckLB.append();
+ const int nRow = rCheckLB.n_children() - 1;
+ if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
+ rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
+ rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
+ rCheckLB.set_text(nRow, rTxt, nTextCol);
+}
+
+OfaQuoteTabPage::OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/applylocalizedpage.ui", "ApplyLocalizedPage", &rSet)
+ , sNonBrkSpace(CuiResId(RID_CUISTR_NON_BREAK_SPACE))
+ , sOrdinal(CuiResId(RID_CUISTR_ORDINAL))
+ , sTransliterateRTL(CuiResId(RID_CUISTR_OLD_HUNGARIAN))
+ , sAngleQuotes(CuiResId(RID_CUISTR_ANGLE_QUOTES))
+ , cSglStartQuote(0)
+ , cSglEndQuote(0)
+ , cStartQuote(0)
+ , cEndQuote(0)
+ , m_xSingleTypoCB(m_xBuilder->weld_check_button("singlereplace"))
+ , m_xSglStartQuotePB(m_xBuilder->weld_button("startsingle"))
+ , m_xSglStartExFT(m_xBuilder->weld_label("singlestartex"))
+ , m_xSglEndQuotePB(m_xBuilder->weld_button("endsingle"))
+ , m_xSglEndExFT(m_xBuilder->weld_label("singleendex"))
+ , m_xSglStandardPB(m_xBuilder->weld_button("defaultsingle"))
+ , m_xDoubleTypoCB(m_xBuilder->weld_check_button("doublereplace"))
+ , m_xDblStartQuotePB(m_xBuilder->weld_button("startdouble"))
+ , m_xDblStartExFT(m_xBuilder->weld_label("doublestartex"))
+ , m_xDblEndQuotePB(m_xBuilder->weld_button("enddouble"))
+ , m_xDblEndExFT(m_xBuilder->weld_label("doubleendex"))
+ , m_xDblStandardPB(m_xBuilder->weld_button("defaultdouble"))
+ , m_sStandard(m_xSglStartExFT->get_label())
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
+ , m_xSwCheckLB(m_xBuilder->weld_tree_view("list"))
+{
+ m_xSwCheckLB->set_size_request(m_xSwCheckLB->get_approximate_digit_width() * 50,
+ m_xSwCheckLB->get_height_rows(6));
+
+ bool bShowSWOptions = false;
+
+ const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>(SID_AUTO_CORRECT_DLG, false);
+ if ( pItem && pItem->GetValue() )
+ bShowSWOptions = true;
+
+ if ( bShowSWOptions )
+ {
+ m_xSwCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2),
+ o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(1)).Width() * 2)
+ };
+ m_xSwCheckLB->set_column_fixed_widths(aWidths);
+ m_xCheckLB->hide();
+ }
+ else
+ {
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xSwCheckLB->hide();
+ }
+
+ m_xDblStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xDblEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xSglStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xSglEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xDblStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
+ m_xSglStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
+}
+
+OfaQuoteTabPage::~OfaQuoteTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaQuoteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OfaQuoteTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaQuoteTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ if (m_xCheckLB->get_visible())
+ {
+ int nPos = 0;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
+ }
+
+ bool bModified = false;
+ if (m_xSwCheckLB->get_visible())
+ {
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ bool bCheck = m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAddNonBrkSpace != bCheck;
+ pOpt->bAddNonBrkSpace = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace,
+ m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgOrdinalNumber != bCheck;
+ pOpt->bChgOrdinalNumber = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber,
+ m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bTransliterateRTL != bCheck;
+ pOpt->bTransliterateRTL = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL,
+ m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgAngleQuotes != bCheck;
+ pOpt->bChgAngleQuotes = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes,
+ m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_SECOND) == TRISTATE_TRUE);
+ }
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active());
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgSglQuotes, m_xSingleTypoCB->get_active());
+ bool bReturn = nFlags != pAutoCorrect->GetFlags();
+ if(cStartQuote != pAutoCorrect->GetStartDoubleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cStartQuote); //TODO
+ pAutoCorrect->SetStartDoubleQuote(cUCS2);
+ }
+ if(cEndQuote != pAutoCorrect->GetEndDoubleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cEndQuote); //TODO
+ pAutoCorrect->SetEndDoubleQuote(cUCS2);
+ }
+ if(cSglStartQuote != pAutoCorrect->GetStartSingleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglStartQuote); //TODO
+ pAutoCorrect->SetStartSingleQuote(cUCS2);
+ }
+ if(cSglEndQuote != pAutoCorrect->GetEndSingleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglEndQuote); //TODO
+ pAutoCorrect->SetEndSingleQuote(cUCS2);
+ }
+
+ if( bModified || bReturn )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return bReturn;
+}
+
+void OfaQuoteTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaQuoteTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ // Initialize the Sw options
+ if (m_xSwCheckLB->get_visible())
+ {
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ m_xSwCheckLB->freeze();
+ m_xSwCheckLB->clear();
+
+ CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sTransliterateRTL, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sAngleQuotes, CBCOL_BOTH, 2);
+
+ m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, pOpt->bTransliterateRTL ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, pOpt->bChgAngleQuotes ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+
+ m_xSwCheckLB->thaw();
+ }
+
+ // Initialize the non Sw options
+ if (m_xCheckLB->get_visible())
+ {
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ int nPos = 0;
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sNonBrkSpace, 0);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sOrdinal, 0);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sTransliterateRTL, 0);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos++, sAngleQuotes, 0);
+
+ m_xCheckLB->thaw();
+ }
+
+ // Initialize the quote stuffs
+ m_xDoubleTypoCB->set_active(bool(nFlags & ACFlags::ChgQuotes));
+ m_xSingleTypoCB->set_active(bool(nFlags & ACFlags::ChgSglQuotes));
+ m_xDoubleTypoCB->save_state();
+ m_xSingleTypoCB->save_state();
+
+ cStartQuote = pAutoCorrect->GetStartDoubleQuote();
+ cEndQuote = pAutoCorrect->GetEndDoubleQuote();
+ cSglStartQuote = pAutoCorrect->GetStartSingleQuote();
+ cSglEndQuote = pAutoCorrect->GetEndSingleQuote();
+
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(cSglStartQuote));
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(cSglEndQuote));
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(cStartQuote));
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(cEndQuote));
+}
+
+#define SGL_START 0
+#define DBL_START 1
+#define SGL_END 2
+#define DBL_END 3
+
+
+IMPL_LINK(OfaQuoteTabPage, QuoteHdl, weld::Button&, rBtn, void)
+{
+ sal_uInt16 nMode = SGL_START;
+ if (&rBtn == m_xSglEndQuotePB.get())
+ nMode = SGL_END;
+ else if (&rBtn == m_xDblStartQuotePB.get())
+ nMode = DBL_START;
+ else if (&rBtn == m_xDblEndQuotePB.get())
+ nMode = DBL_END;
+ // start character selection dialog
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+ aMap.SetCharFont( OutputDevice::GetDefaultFont(DefaultFontType::LATIN_TEXT,
+ LANGUAGE_ENGLISH_US, GetDefaultFontFlags::OnlyOne ));
+ aMap.set_title(nMode < SGL_END ? CuiResId(RID_CUISTR_STARTQUOTE) : CuiResId(RID_CUISTR_ENDQUOTE));
+ sal_UCS4 cDlg;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
+ switch( nMode )
+ {
+ case SGL_START:
+ cDlg = cSglStartQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\'', true, eLang);
+ break;
+ case SGL_END:
+ cDlg = cSglEndQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\'', false, eLang);
+ break;
+ case DBL_START:
+ cDlg = cStartQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\"', true, eLang);
+ break;
+ case DBL_END:
+ cDlg = cEndQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\"', false, eLang);
+ break;
+ default:
+ OSL_FAIL("svx::OfaQuoteTabPage::QuoteHdl(), how to initialize cDlg?" );
+ cDlg = 0;
+ break;
+
+ }
+ aMap.SetChar( cDlg );
+ aMap.DisableFontSelection();
+ if (aMap.run() != RET_OK)
+ return;
+
+ sal_UCS4 cNewChar = aMap.GetChar();
+ switch( nMode )
+ {
+ case SGL_START:
+ cSglStartQuote = cNewChar;
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case SGL_END:
+ cSglEndQuote = cNewChar;
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case DBL_START:
+ cStartQuote = cNewChar;
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case DBL_END:
+ cEndQuote = cNewChar;
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ }
+}
+
+IMPL_LINK(OfaQuoteTabPage, StdQuoteHdl, weld::Button&, rBtn, void)
+{
+ if (&rBtn == m_xDblStandardPB.get())
+ {
+ cStartQuote = 0;
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(0));
+ cEndQuote = 0;
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(0));
+
+ }
+ else
+ {
+ cSglStartQuote = 0;
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(0));
+ cSglEndQuote = 0;
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(0));
+ }
+}
+
+OUString OfaQuoteTabPage::ChangeStringExt_Impl( sal_UCS4 cChar )
+{
+ if (!cChar)
+ return m_sStandard;
+
+ // convert codepoint value to unicode-hex string
+ sal_UCS4 aStrCodes[32] = { 0, ' ', '(', 'U', '+', '0' };
+ aStrCodes[0] = cChar;
+ int nFullLen = 5;
+ int nHexLen = 4;
+ while( (cChar >> (4*nHexLen)) != 0 )
+ ++nHexLen;
+ for( int i = nHexLen; --i >= 0;)
+ {
+ sal_UCS4 cHexDigit = ((cChar >> (4*i)) & 0x0f) + '0';
+ if( cHexDigit > '9' )
+ cHexDigit += 'A' - ('9' + 1);
+ aStrCodes[ nFullLen++ ] = cHexDigit;
+ }
+ aStrCodes[ nFullLen++ ] = ')';
+ // using the new UCS4 constructor
+ OUString aOUStr( aStrCodes, nFullLen );
+ return aOUStr;
+}
+
+OfaAutoCompleteTabPage::OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/wordcompletionpage.ui",
+ "WordCompletionPage", &rSet)
+ , m_pAutoCompleteList(nullptr)
+ , m_nAutoCmpltListCnt(0)
+ , m_xCBActiv(m_xBuilder->weld_check_button("enablewordcomplete"))
+ , m_xCBAppendSpace(m_xBuilder->weld_check_button("appendspace"))
+ , m_xCBAsTip(m_xBuilder->weld_check_button("showastip"))
+ , m_xCBCollect(m_xBuilder->weld_check_button("collectwords"))
+ , m_xCBRemoveList(m_xBuilder->weld_check_button("whenclosing"))
+ , m_xDCBExpandKey(m_xBuilder->weld_combo_box("acceptwith"))
+ , m_xNFMinWordlen(m_xBuilder->weld_spin_button("minwordlen"))
+ , m_xNFMaxEntries(m_xBuilder->weld_spin_button("maxentries"))
+ , m_xLBEntries(m_xBuilder->weld_tree_view("entries"))
+ , m_xPBEntries(m_xBuilder->weld_button("delete"))
+{
+ //fdo#65595, we need height-for-width support here, but for now we can
+ //bodge it
+ Size aPrefSize(m_xCBRemoveList->get_preferred_size());
+ int nMaxWidth = m_xCBRemoveList->get_approximate_digit_width() * 40;
+ if (aPrefSize.Width() > nMaxWidth)
+ {
+ m_xCBRemoveList->set_label_wrap(true);
+ m_xCBRemoveList->set_size_request(nMaxWidth, -1);
+ }
+
+ m_xLBEntries->set_size_request(m_xLBEntries->get_approximate_digit_width() * 30,
+ m_xLBEntries->get_height_rows(10));
+ m_xLBEntries->set_selection_mode(SelectionMode::Multiple);
+
+ // the defined KEYs
+ static const sal_uInt16 aKeyCodes[] = {
+ KEY_END,
+ KEY_RETURN,
+ KEY_SPACE,
+ KEY_RIGHT,
+ KEY_TAB,
+ 0
+ };
+
+ for( const sal_uInt16* pKeys = aKeyCodes; *pKeys; ++pKeys )
+ {
+ vcl::KeyCode aKCode(*pKeys);
+ m_xDCBExpandKey->append(OUString::number(static_cast<sal_Int32>(*pKeys)), aKCode.GetName());
+ if (KEY_RETURN == *pKeys) // default to RETURN
+ m_xDCBExpandKey->set_active(std::distance(aKeyCodes, pKeys));
+ }
+
+ m_xPBEntries->connect_clicked(LINK(this, OfaAutoCompleteTabPage, DeleteHdl));
+ m_xCBActiv->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
+ m_xCBCollect->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
+ m_xLBEntries->connect_key_release(LINK(this, OfaAutoCompleteTabPage, KeyReleaseHdl));
+}
+
+OfaAutoCompleteTabPage::~OfaAutoCompleteTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaAutoCompleteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutoCompleteTabPage>(pPage, pController, *rSet);
+}
+
+bool OfaAutoCompleteTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false, bCheck;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ sal_uInt16 nVal;
+
+ bCheck = m_xCBActiv->get_active();
+ bModified |= pOpt->bAutoCompleteWords != bCheck;
+ pOpt->bAutoCompleteWords = bCheck;
+ bCheck = m_xCBCollect->get_active();
+ bModified |= pOpt->bAutoCmpltCollectWords != bCheck;
+ pOpt->bAutoCmpltCollectWords = bCheck;
+ bCheck = !m_xCBRemoveList->get_active(); // inverted value!
+ bModified |= pOpt->bAutoCmpltKeepList != bCheck;
+ pOpt->bAutoCmpltKeepList = bCheck;
+ bCheck = m_xCBAppendSpace->get_active();
+ bModified |= pOpt->bAutoCmpltAppendBlank != bCheck;
+ pOpt->bAutoCmpltAppendBlank = bCheck;
+ bCheck = m_xCBAsTip->get_active();
+ bModified |= pOpt->bAutoCmpltShowAsTip != bCheck;
+ pOpt->bAutoCmpltShowAsTip = bCheck;
+
+ nVal = static_cast<sal_uInt16>(m_xNFMinWordlen->get_value());
+ bModified |= nVal != pOpt->nAutoCmpltWordLen;
+ pOpt->nAutoCmpltWordLen = nVal;
+
+ nVal = static_cast<sal_uInt16>(m_xNFMaxEntries->get_value());
+ bModified |= nVal != pOpt->nAutoCmpltListLen;
+ pOpt->nAutoCmpltListLen = nVal;
+
+ const int nPos = m_xDCBExpandKey->get_active();
+ if (nPos != -1)
+ {
+ sal_Int32 nKey = m_xDCBExpandKey->get_id(nPos).toInt32();
+ bModified |= nKey != pOpt->nAutoCmpltExpandKey;
+ pOpt->nAutoCmpltExpandKey = static_cast<sal_uInt16>(nKey);
+ }
+
+ if (m_pAutoCompleteList && m_nAutoCmpltListCnt != m_xLBEntries->n_children())
+ {
+ bModified = true;
+ pOpt->m_pAutoCompleteList = m_pAutoCompleteList;
+ }
+ if( bModified )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return true;
+}
+
+void OfaAutoCompleteTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ m_xCBActiv->set_active( pOpt->bAutoCompleteWords );
+ m_xCBCollect->set_active( pOpt->bAutoCmpltCollectWords );
+ m_xCBRemoveList->set_active( !pOpt->bAutoCmpltKeepList ); //inverted value!
+ m_xCBAppendSpace->set_active( pOpt->bAutoCmpltAppendBlank );
+ m_xCBAsTip->set_active( pOpt->bAutoCmpltShowAsTip );
+
+ m_xNFMinWordlen->set_value( pOpt->nAutoCmpltWordLen );
+ m_xNFMaxEntries->set_value( pOpt->nAutoCmpltListLen );
+
+ // select the specific KeyCode:
+ {
+ sal_Int32 nKey = pOpt->nAutoCmpltExpandKey;
+ for (int n = 0, nCnt = m_xDCBExpandKey->get_count(); n < nCnt; ++n)
+ {
+ if (nKey == m_xDCBExpandKey->get_id(n).toInt32())
+ {
+ m_xDCBExpandKey->set_active(n);
+ break;
+ }
+ }
+ }
+
+ if (pOpt->m_pAutoCompleteList && !pOpt->m_pAutoCompleteList->empty())
+ {
+ m_pAutoCompleteList = const_cast<editeng::SortedAutoCompleteStrings*>(
+ pOpt->m_pAutoCompleteList);
+ pOpt->m_pAutoCompleteList = nullptr;
+ m_nAutoCmpltListCnt = m_pAutoCompleteList->size();
+ for (size_t n = 0; n < m_nAutoCmpltListCnt; ++n)
+ {
+ const OUString* pStr =
+ &(*m_pAutoCompleteList)[n]->GetAutoCompleteString();
+ OUString sId(weld::toId(pStr));
+ m_xLBEntries->append(sId, *pStr);
+ }
+ }
+ else
+ {
+ m_xLBEntries->set_sensitive(false);
+ m_xPBEntries->set_sensitive(false);
+ }
+
+ CheckHdl(*m_xCBActiv);
+ CheckHdl(*m_xCBCollect);
+}
+
+void OfaAutoCompleteTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
+}
+
+IMPL_LINK_NOARG(OfaAutoCompleteTabPage, DeleteHdl, weld::Button&, void)
+{
+ auto rows = m_xLBEntries->get_selected_rows();
+ std::sort(rows.begin(), rows.end());
+ while (!rows.empty())
+ {
+ sal_Int32 nPos = rows.back();
+ OUString* pStr = weld::fromId<OUString*>(m_xLBEntries->get_id(nPos));
+ m_xLBEntries->remove(nPos);
+ editeng::IAutoCompleteString hack(*pStr); // UGLY
+ m_pAutoCompleteList->erase(&hack);
+ rows.pop_back();
+ }
+}
+
+IMPL_LINK(OfaAutoCompleteTabPage, CheckHdl, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = rBox.get_active();
+ if (&rBox == m_xCBActiv.get())
+ {
+ m_xCBAppendSpace->set_sensitive(bEnable);
+ m_xCBAppendSpace->set_sensitive(bEnable);
+ m_xCBAsTip->set_sensitive(bEnable);
+ m_xDCBExpandKey->set_sensitive(bEnable);
+ }
+ else if (&rBox == m_xCBCollect.get())
+ m_xCBRemoveList->set_sensitive(bEnable);
+}
+
+void OfaAutoCompleteTabPage::CopyToClipboard() const
+{
+ auto rows = m_xLBEntries->get_selected_rows();
+ if (!m_pAutoCompleteList || rows.empty())
+ return;
+
+ rtl::Reference<TransferDataContainer> pCntnr = new TransferDataContainer;
+
+ OStringBuffer sData;
+
+ rtl_TextEncoding nEncode = osl_getThreadTextEncoding();
+
+ for (auto a : rows)
+ {
+ sData.append(OUStringToOString(m_xLBEntries->get_text(a), nEncode));
+#if defined(_WIN32)
+ sData.append("\015\012");
+#else
+ sData.append("\012");
+#endif
+ }
+ pCntnr->CopyByteString( SotClipboardFormatId::STRING, sData.makeStringAndClear() );
+ pCntnr->CopyToClipboard(m_xLBEntries->get_clipboard());
+}
+
+IMPL_LINK(OfaAutoCompleteTabPage, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
+{
+ bool bHandled = false;
+ const vcl::KeyCode& rKeyCode = rEvent.GetKeyCode();
+ switch (rKeyCode.GetModifier() | rKeyCode.GetCode())
+ {
+ case KEY_DELETE:
+ DeleteHdl(*m_xPBEntries);
+ bHandled = true;
+ break;
+ default:
+ if (KeyFuncType::COPY == rKeyCode.GetFunction())
+ {
+ CopyToClipboard();
+ bHandled = true;
+ }
+ break;
+ }
+ return bHandled;
+}
+
+// class OfaSmartTagOptionsTabPage ---------------------------------------------
+
+OfaSmartTagOptionsTabPage::OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pPage, pController, "cui/ui/smarttagoptionspage.ui", "SmartTagOptionsPage", &rSet)
+ , m_xMainCB(m_xBuilder->weld_check_button("main"))
+ , m_xSmartTagTypesLB(m_xBuilder->weld_tree_view("list"))
+ , m_xPropertiesPB(m_xBuilder->weld_button("properties"))
+{
+ m_xSmartTagTypesLB->set_size_request(m_xSmartTagTypesLB->get_approximate_digit_width() * 50,
+ m_xSmartTagTypesLB->get_height_rows(6));
+
+ m_xSmartTagTypesLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ // set the handlers:
+ m_xMainCB->connect_toggled(LINK(this, OfaSmartTagOptionsTabPage, CheckHdl));
+ m_xPropertiesPB->connect_clicked(LINK(this, OfaSmartTagOptionsTabPage, ClickHdl));
+ m_xSmartTagTypesLB->connect_changed(LINK(this, OfaSmartTagOptionsTabPage, SelectHdl));
+}
+
+OfaSmartTagOptionsTabPage::~OfaSmartTagOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaSmartTagOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaSmartTagOptionsTabPage>(pPage, pController, *rSet);
+}
+
+namespace {
+
+/** This struct is used to associate list box entries with smart tag data
+*/
+struct ImplSmartTagLBUserData
+{
+ OUString maSmartTagType;
+ uno::Reference< smarttags::XSmartTagRecognizer > mxRec;
+ sal_Int32 mnSmartTagIdx;
+
+ ImplSmartTagLBUserData( OUString aSmartTagType,
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec,
+ sal_Int32 nSmartTagIdx ) :
+ maSmartTagType(std::move( aSmartTagType )),
+ mxRec(std::move( xRec )),
+ mnSmartTagIdx( nSmartTagIdx ) {}
+};
+
+}
+
+/** Clears m_xSmartTagTypesLB
+*/
+void OfaSmartTagOptionsTabPage::ClearListBox()
+{
+ const int nCount = m_xSmartTagTypesLB->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i));
+ delete pUserData;
+ }
+
+ m_xSmartTagTypesLB->clear();
+}
+
+/** Inserts items into m_xSmartTagTypesLB
+*/
+void OfaSmartTagOptionsTabPage::FillListBox( const SmartTagMgr& rSmartTagMgr )
+{
+ // first we have to clear the list box:
+ ClearListBox();
+
+ // fill list box:
+ const sal_uInt32 nNumberOfRecognizers = rSmartTagMgr.NumberOfRecognizers();
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+
+ for ( sal_uInt32 i = 0; i < nNumberOfRecognizers; ++i )
+ {
+ const uno::Reference< smarttags::XSmartTagRecognizer >& xRec = rSmartTagMgr.GetRecognizer(i);
+
+ const OUString aName = xRec->getName( aLocale );
+ const sal_Int32 nNumberOfSupportedSmartTags = xRec->getSmartTagCount();
+
+ for ( sal_Int32 j = 0; j < nNumberOfSupportedSmartTags; ++j )
+ {
+ const OUString aSmartTagType = xRec->getSmartTagName(j);
+ OUString aSmartTagCaption = rSmartTagMgr.GetSmartTagCaption( aSmartTagType, aLocale );
+
+ if ( aSmartTagCaption.isEmpty() )
+ aSmartTagCaption = aSmartTagType;
+
+ const OUString aLBEntry = aSmartTagCaption + " (" + aName + ")";
+
+ m_xSmartTagTypesLB->append();
+ const int nRow = m_xSmartTagTypesLB->n_children() - 1;
+ const bool bCheck = rSmartTagMgr.IsSmartTagTypeEnabled( aSmartTagType );
+ m_xSmartTagTypesLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xSmartTagTypesLB->set_text(nRow, aLBEntry, 0);
+ m_xSmartTagTypesLB->set_id(nRow, weld::toId(new ImplSmartTagLBUserData(aSmartTagType, xRec, j)));
+ }
+ }
+}
+
+/** Handler for the push button
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, ClickHdl, weld::Button&, void)
+{
+ const int nPos = m_xSmartTagTypesLB->get_selected_index();
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos));
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
+ const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
+
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+ if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
+ xRec->displayPropertyPage( nSmartTagIdx, aLocale );
+}
+
+/** Handler for the check box
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, CheckHdl, weld::Toggleable&, void)
+{
+ const bool bEnable = m_xMainCB->get_active();
+ m_xSmartTagTypesLB->set_sensitive(bEnable);
+ m_xPropertiesPB->set_sensitive(false);
+
+ // if the controls are currently enabled, we still have to check
+ // if the properties button should be disabled because the currently
+ // selected smart tag type does not have a properties dialog.
+ // We do this by calling SelectHdl:
+ if (bEnable)
+ SelectHdl(*m_xSmartTagTypesLB);
+}
+
+/** Handler for the list box
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, SelectHdl, weld::TreeView&, void)
+{
+ const int nPos = m_xSmartTagTypesLB->get_selected_index();
+ if (nPos == -1)
+ return;
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos));
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
+ const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
+
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+ if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
+ m_xPropertiesPB->set_sensitive(true);
+ else
+ m_xPropertiesPB->set_sensitive(false);
+}
+
+/** Propagates the current settings to the smart tag manager.
+*/
+bool OfaSmartTagOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
+
+ // robust!
+ if ( !pSmartTagMgr )
+ return false;
+
+ bool bModifiedSmartTagTypes = false;
+ std::vector< OUString > aDisabledSmartTagTypes;
+
+ const int nCount = m_xSmartTagTypesLB->n_children();
+
+ for (int i = 0; i < nCount; ++i)
+ {
+ const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i));
+ const bool bChecked = m_xSmartTagTypesLB->get_toggle(i) == TRISTATE_TRUE;
+ const bool bIsCurrentlyEnabled = pSmartTagMgr->IsSmartTagTypeEnabled( pUserData->maSmartTagType );
+
+ bModifiedSmartTagTypes = bModifiedSmartTagTypes || ( !bChecked != !bIsCurrentlyEnabled );
+
+ if ( !bChecked )
+ aDisabledSmartTagTypes.push_back( pUserData->maSmartTagType );
+
+ delete pUserData;
+ }
+
+ const bool bModifiedRecognize = ( !m_xMainCB->get_active() != !pSmartTagMgr->IsLabelTextWithSmartTags() );
+ if ( bModifiedSmartTagTypes || bModifiedRecognize )
+ {
+ bool bLabelTextWithSmartTags = m_xMainCB->get_active();
+ pSmartTagMgr->WriteConfiguration( bModifiedRecognize ? &bLabelTextWithSmartTags : nullptr,
+ bModifiedSmartTagTypes ? &aDisabledSmartTagTypes : nullptr );
+ }
+
+ return true;
+}
+
+/** Sets the controls based on the current settings at SmartTagMgr.
+*/
+void OfaSmartTagOptionsTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ const SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
+
+ // robust, should not happen!
+ if ( !pSmartTagMgr )
+ return;
+
+ FillListBox(*pSmartTagMgr);
+ m_xSmartTagTypesLB->select(0);
+ m_xMainCB->set_active(pSmartTagMgr->IsLabelTextWithSmartTags());
+ CheckHdl(*m_xMainCB);
+}
+
+void OfaSmartTagOptionsTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/backgrnd.cxx b/cui/source/tabpages/backgrnd.cxx
new file mode 100644
index 000000000..14269ad3c
--- /dev/null
+++ b/cui/source/tabpages/backgrnd.cxx
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/colritem.hxx>
+#include <backgrnd.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/flagsdef.hxx>
+#include <svl/intitem.hxx>
+#include <svx/unobrushitemhelper.hxx>
+
+using namespace css;
+
+// table background
+#define TBL_DEST_CELL 0
+#define TBL_DEST_ROW 1
+#define TBL_DEST_TBL 2
+
+const WhichRangesContainer SvxBkgTabPage::pPageRanges(svl::Items<
+ SID_ATTR_BRUSH, SID_ATTR_BRUSH,
+ SID_ATTR_BRUSH_CHAR, SID_ATTR_BRUSH_CHAR
+>);
+
+static sal_uInt16 lcl_GetTableDestSlot(sal_Int32 nTblDest)
+{
+ switch (nTblDest)
+ {
+ default:
+ case TBL_DEST_CELL:
+ {
+ return SID_ATTR_BRUSH;
+ }
+ case TBL_DEST_ROW:
+ {
+ return SID_ATTR_BRUSH_ROW;
+ }
+ case TBL_DEST_TBL:
+ {
+ return SID_ATTR_BRUSH_TABLE;
+ }
+ }
+}
+
+SvxBkgTabPage::SvxBkgTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxAreaTabPage(pPage, pController, rInAttrs),
+ bHighlighting(false),
+ bCharBackColor(false),
+ maSet(rInAttrs)
+{
+ m_xBtnGradient->hide();
+ m_xBtnHatch->hide();
+ m_xBtnBitmap->hide();
+ m_xBtnPattern->hide();
+
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ XColorListRef pColorTable;
+ if ( pDocSh )
+ if (auto pItem = pDocSh->GetItem( SID_COLOR_TABLE ))
+ pColorTable = pItem->GetColorList();
+
+ if ( !pColorTable.is() )
+ pColorTable = XColorList::CreateStdColorList();
+
+ XBitmapListRef pBitmapList;
+ if ( pDocSh )
+ if (auto pItem = pDocSh->GetItem( SID_BITMAP_LIST ) )
+ pBitmapList = pItem->GetBitmapList();
+
+ SetColorList(pColorTable);
+ SetBitmapList(pBitmapList);
+}
+
+SvxBkgTabPage::~SvxBkgTabPage()
+{
+ m_xTblLBox.reset();
+}
+
+void SvxBkgTabPage::ActivatePage( const SfxItemSet& )
+{
+ SvxAreaTabPage::ActivatePage( maSet );
+}
+
+DeactivateRC SvxBkgTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( DeactivateRC::KeepPage == SvxAreaTabPage::DeactivatePage( &maSet ) )
+ return DeactivateRC::KeepPage;
+
+ if ( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBkgTabPage::Reset( const SfxItemSet* )
+{
+ maSet.Set( *m_pResetSet );
+ if ( m_xTblLBox && m_xTblLBox->get_visible() )
+ {
+ m_nActPos = -1;
+ if ( const SfxUInt16Item* pDestItem = m_pResetSet->GetItemIfSet( SID_BACKGRND_DESTINATION, false ) )
+ {
+ sal_uInt16 nDestValue = pDestItem->GetValue();
+ m_xTblLBox->set_active( nDestValue );
+ TblDestinationHdl_Impl( *m_xTblLBox );
+ }
+ m_xTblLBox->save_value();
+ }
+ SvxAreaTabPage::Reset( &maSet );
+}
+
+bool SvxBkgTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ sal_uInt16 nSlot = SID_ATTR_BRUSH;
+ if (m_xTblLBox && m_xTblLBox->get_visible())
+ nSlot = lcl_GetTableDestSlot(m_xTblLBox->get_active());
+ else if ( bHighlighting )
+ nSlot = SID_ATTR_BRUSH_CHAR;
+ else if( bCharBackColor )
+ nSlot = SID_ATTR_CHAR_BACK_COLOR;
+
+ sal_uInt16 nWhich = GetWhich(nSlot);
+
+ drawing::FillStyle eFillType = maSet.Get( XATTR_FILLSTYLE ).GetValue();
+ switch( eFillType )
+ {
+ case drawing::FillStyle_NONE:
+ {
+ if ( IsBtnClicked() )
+ {
+ if ( SID_ATTR_CHAR_BACK_COLOR == nSlot )
+ {
+ maSet.Put( SvxColorItem( COL_TRANSPARENT, nWhich ) );
+ rCoreSet->Put( SvxColorItem( COL_TRANSPARENT, nWhich ) );
+ }
+ else
+ {
+ maSet.Put( SvxBrushItem( COL_TRANSPARENT, nWhich ) );
+ rCoreSet->Put( SvxBrushItem( COL_TRANSPARENT, nWhich ) );
+ }
+ }
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ XFillColorItem aColorItem( maSet.Get( XATTR_FILLCOLOR ) );
+ if ( SID_ATTR_CHAR_BACK_COLOR == nSlot )
+ {
+ maSet.Put( SvxColorItem( aColorItem.GetColorValue(), nWhich ) );
+ rCoreSet->Put( SvxColorItem( aColorItem.GetColorValue(), nWhich ) );
+ }
+ else
+ {
+ maSet.Put( SvxBrushItem( aColorItem.GetColorValue(), nWhich ) );
+ rCoreSet->Put( SvxBrushItem( aColorItem.GetColorValue(), nWhich ) );
+ }
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ std::unique_ptr<SvxBrushItem> aBrushItem( getSvxBrushItemFromSourceSet( maSet, nWhich ) );
+ if ( GraphicType::NONE != aBrushItem->GetGraphicObject()->GetType() )
+ rCoreSet->Put( std::move(aBrushItem) );
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!m_xTblLBox || !m_xTblLBox->get_visible())
+ return true;
+
+ if (nSlot != SID_ATTR_BRUSH)
+ {
+ nWhich = maSet.GetPool()->GetWhich(SID_ATTR_BRUSH);
+ if (SfxItemState::SET == maSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ rCoreSet->Put(aBrushItem);
+ }
+ }
+ if (nSlot != SID_ATTR_BRUSH_ROW)
+ {
+ if (SfxItemState::SET == maSet.GetItemState(SID_ATTR_BRUSH_ROW))
+ {
+ SvxBrushItem aBrushItem(maSet.Get(SID_ATTR_BRUSH_ROW));
+ rCoreSet->Put(aBrushItem);
+ }
+ }
+ if (nSlot != SID_ATTR_BRUSH_TABLE)
+ {
+ if (SfxItemState::SET == maSet.GetItemState(SID_ATTR_BRUSH_TABLE))
+ {
+ SvxBrushItem aBrushItem(maSet.Get(SID_ATTR_BRUSH_TABLE));
+ rCoreSet->Put(aBrushItem);
+ }
+ }
+
+ if (m_xTblLBox->get_value_changed_from_saved())
+ {
+ rCoreSet->Put(SfxUInt16Item(SID_BACKGRND_DESTINATION, m_xTblLBox->get_active()));
+ }
+
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxBkgTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxBkgTabPage>(pPage, pController, *rAttrs);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+void SvxBkgTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ SvxBackgroundTabFlags nFlags = static_cast<SvxBackgroundTabFlags>(pFlagItem->GetValue());
+ if ( nFlags & SvxBackgroundTabFlags::SHOW_TBLCTL )
+ {
+ m_xBtnBitmap->show();
+ m_xTblLBox = m_xBuilder->weld_combo_box("tablelb");
+ m_xTblLBox->connect_changed(LINK(this, SvxBkgTabPage, TblDestinationHdl_Impl));
+ m_xTblLBox->show();
+ }
+ if ((nFlags & SvxBackgroundTabFlags::SHOW_HIGHLIGHTING) ||
+ (nFlags & SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR))
+ {
+ bHighlighting = bool(nFlags & SvxBackgroundTabFlags::SHOW_HIGHLIGHTING);
+ bCharBackColor = bool(nFlags & SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR);
+ }
+ if (nFlags & SvxBackgroundTabFlags::SHOW_SELECTOR)
+ m_xBtnBitmap->show();
+ SetOptimalSize(GetDialogController());
+ }
+
+ if ( bCharBackColor )
+ {
+ sal_uInt16 nWhich(maSet.GetPool()->GetWhich(SID_ATTR_CHAR_BACK_COLOR));
+ Color aBackColor(static_cast<const SvxColorItem&>(maSet.Get(nWhich)).GetValue());
+ SvxBrushItem aBrushItem(SvxBrushItem(aBackColor, SID_ATTR_BRUSH_CHAR));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, maSet);
+ }
+ else
+ {
+ sal_uInt16 nWhich(maSet.GetPool()->GetWhich(bHighlighting ? SID_ATTR_BRUSH_CHAR : SID_ATTR_BRUSH));
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, maSet);
+ }
+
+ m_pResetSet = maSet.Clone();
+
+ SvxAreaTabPage::PageCreated(aSet);
+}
+
+IMPL_LINK(SvxBkgTabPage, TblDestinationHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ if (m_nActPos > -1)
+ {
+ // fill local item set with XATTR_FILL settings gathered from tab page
+ // and convert to SvxBrushItem and store in table destination slot Which
+ SvxAreaTabPage::FillItemSet(&maSet);
+ maSet.Put(getSvxBrushItemFromSourceSet(maSet, maSet.GetPool()->GetWhich(lcl_GetTableDestSlot(m_nActPos))));
+ }
+
+ sal_Int32 nSelPos = rBox.get_active();
+ if (m_nActPos == nSelPos)
+ return;
+
+ m_nActPos = nSelPos;
+
+ // fill local item set with XATTR_FILL created from SvxBushItem for table destination slot Which
+ sal_uInt16 nWhich = maSet.GetPool()->GetWhich(lcl_GetTableDestSlot(nSelPos));
+ if (SfxItemState::SET == maSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, maSet);
+ }
+ else
+ {
+ SelectFillType(*m_xBtnNone, &maSet);
+ return;
+ }
+
+ // show tab page
+ drawing::FillStyle eXFS = drawing::FillStyle_NONE;
+ if (maSet.GetItemState(XATTR_FILLSTYLE) != SfxItemState::DONTCARE)
+ {
+ XFillStyleItem aFillStyleItem(maSet.Get(GetWhich( XATTR_FILLSTYLE)));
+ eXFS = aFillStyleItem.GetValue();
+ }
+ switch(eXFS)
+ {
+ default:
+ case drawing::FillStyle_NONE:
+ {
+ SelectFillType(*m_xBtnNone, &maSet);
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ SelectFillType(*m_xBtnColor, &maSet);
+ // color tab page Active and New preview controls are same after SelectFillType
+ // hack to restore color tab page Active preview
+ setSvxBrushItemAsFillAttributesToTargetSet(static_cast<const SvxBrushItem&>(m_pResetSet->Get(nWhich)), *m_pResetSet);
+ static_cast<SvxColorTabPage*>(GetFillTabPage())->SetCtlPreviewOld(*m_pResetSet);
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ SelectFillType(*m_xBtnBitmap, &maSet);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/bbdlg.cxx b/cui/source/tabpages/bbdlg.cxx
new file mode 100644
index 000000000..488fc5283
--- /dev/null
+++ b/cui/source/tabpages/bbdlg.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <bbdlg.hxx>
+#include <border.hxx>
+#include <backgrnd.hxx>
+#include <svx/svxids.hrc>
+#include <svl/intitem.hxx>
+#include <cuitabarea.hxx>
+
+SvxBorderBackgroundDlg::SvxBorderBackgroundDlg(weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableSelector,
+ bool bEnableDrawingLayerFillStyles)
+ : SfxTabDialogController(pParent,
+ bEnableDrawingLayerFillStyles
+ ? OUString("cui/ui/borderareatransparencydialog.ui")
+ : OUString("cui/ui/borderbackgrounddialog.ui"),
+ bEnableDrawingLayerFillStyles
+ ? OString("BorderAreaTransparencyDialog")
+ : OString("BorderBackgroundDialog"),
+ &rCoreSet)
+ , mbEnableBackgroundSelector(bEnableSelector)
+{
+ AddTabPage("borders", SvxBorderTabPage::Create, nullptr );
+ if (bEnableDrawingLayerFillStyles)
+ {
+ // Here we want full DrawingLayer FillStyle access, so add Area and Transparency TabPages
+ AddTabPage("area", SvxAreaTabPage::Create, nullptr);
+ AddTabPage("transparence", SvxTransparenceTabPage::Create, nullptr);
+ }
+ else
+ {
+ AddTabPage("background", SvxBkgTabPage::Create, nullptr );
+ }
+}
+
+void SvxBorderBackgroundDlg::PageCreated(const OString& rPageId, SfxTabPage& rTabPage)
+{
+ if (rPageId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ // allow switching between Color/graphic
+ if (mbEnableBackgroundSelector)
+ aSet.Put(SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
+ rTabPage.PageCreated(aSet);
+ }
+ // inits for Area and Transparency TabPages
+ // The selection attribute lists (XPropertyList derivates, e.g. XColorList for
+ // the color table) need to be added as items (e.g. SvxColorTableItem) to make
+ // these pages find the needed attributes for fill style suggestions.
+ // These are added in SwDocStyleSheet::GetItemSet() for the SfxStyleFamily::Para on
+ // demand, but could also be directly added from the DrawModel.
+ else if (rPageId == "area")
+ {
+ SfxItemSetFixed<SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_OFFER_IMPORT, SID_OFFER_IMPORT>
+ aNew(*GetInputSetImpl()->GetPool());
+
+ aNew.Put(*GetInputSetImpl());
+
+ // add flag for direct graphic content selection
+ aNew.Put(SfxBoolItem(SID_OFFER_IMPORT, true));
+
+ rTabPage.PageCreated(aNew);
+ }
+ else if (rPageId == "transparence")
+ {
+ rTabPage.PageCreated(*GetInputSetImpl());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
new file mode 100644
index 000000000..30313dfce
--- /dev/null
+++ b/cui/source/tabpages/border.cxx
@@ -0,0 +1,1704 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <sfx2/objsh.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+
+#include <editeng/boxitem.hxx>
+#include <editeng/lineitem.hxx>
+#include <border.hxx>
+#include <svx/dlgutil.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/flagsdef.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/ilstitem.hxx>
+#include <svl/int64item.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <comphelper/lok.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace ::editeng;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::UNO_QUERY;
+
+
+/*
+ * [Description:]
+ * TabPage for setting the border attributes.
+ * Needs
+ * a SvxShadowItem: shadow
+ * a SvxBoxItem: lines left, right, top, bottom,
+ * a SvxBoxInfo: lines vertical, horizontal, distance, flags
+ *
+ * Lines can have three conditions:
+ * 1. Show ( -> valid values )
+ * 2. Hide ( -> NULL-Pointer )
+ * 3. DontCare ( -> special Valid-Flags in the InfoItem )
+ */
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxBorderTabPage::pRanges(
+ svl::Items<
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW,
+ SID_ATTR_ALIGN_MARGIN, SID_ATTR_ALIGN_MARGIN,
+ SID_ATTR_BORDER_CONNECT, SID_ATTR_BORDER_CONNECT,
+ SID_SW_COLLAPSING_BORDERS, SID_SW_COLLAPSING_BORDERS,
+ SID_ATTR_BORDER_DIAG_TLBR, SID_ATTR_BORDER_DIAG_BLTR>);
+
+namespace
+{
+int lcl_twipsToPt(sal_Int64 nTwips)
+{
+ return vcl::ConvertDoubleValue(nTwips, 0, FieldUnit::TWIP, MapUnit::MapPoint) * 100;
+}
+}
+
+const std::vector<int> SvxBorderTabPage::m_aLineWidths = {
+ lcl_twipsToPt(SvxBorderLineWidth::Hairline),
+ lcl_twipsToPt(SvxBorderLineWidth::VeryThin),
+ lcl_twipsToPt(SvxBorderLineWidth::Thin),
+ lcl_twipsToPt(SvxBorderLineWidth::Medium),
+ lcl_twipsToPt(SvxBorderLineWidth::Thick),
+ lcl_twipsToPt(SvxBorderLineWidth::ExtraThick),
+ -1
+};
+
+static void lcl_SetDecimalDigitsTo1(weld::MetricSpinButton& rField)
+{
+ auto nMin = rField.denormalize(rField.get_min(FieldUnit::TWIP));
+ rField.set_digits(1);
+ rField.set_min(rField.normalize(nMin), FieldUnit::TWIP);
+}
+
+// returns in pt
+static sal_Int64 lcl_GetMinLineWidth(SvxBorderLineStyle aStyle)
+{
+ switch (aStyle)
+ {
+ case SvxBorderLineStyle::NONE:
+ return 0;
+
+ case SvxBorderLineStyle::SOLID:
+ case SvxBorderLineStyle::DOTTED:
+ case SvxBorderLineStyle::DASHED:
+ case SvxBorderLineStyle::FINE_DASHED:
+ case SvxBorderLineStyle::DASH_DOT:
+ case SvxBorderLineStyle::DASH_DOT_DOT:
+ return 15;
+
+ // Double lines
+ case SvxBorderLineStyle::DOUBLE: return 15;
+ case SvxBorderLineStyle::DOUBLE_THIN: return 15;
+ case SvxBorderLineStyle::THINTHICK_SMALLGAP: return 20;
+ case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: return 15;
+ case SvxBorderLineStyle::THINTHICK_LARGEGAP: return 15;
+ case SvxBorderLineStyle::THICKTHIN_SMALLGAP: return 20;
+ case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: return 15;
+ case SvxBorderLineStyle::THICKTHIN_LARGEGAP: return 15;
+
+ case SvxBorderLineStyle::EMBOSSED: return 15;
+ case SvxBorderLineStyle::ENGRAVED: return 15;
+
+ case SvxBorderLineStyle::OUTSET: return 10;
+ case SvxBorderLineStyle::INSET: return 10;
+
+ default:
+ return 15;
+ }
+}
+
+// number of preset images to show
+const sal_uInt16 BORDER_PRESET_COUNT = 5;
+
+// number of shadow images to show
+const sal_uInt16 BORDER_SHADOW_COUNT = 5;
+
+ShadowControlsWrapper::ShadowControlsWrapper(ValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor)
+ : mrVsPos(rVsPos)
+ , mrMfSize(rMfSize)
+ , mrLbColor(rLbColor)
+{
+}
+
+SvxShadowItem ShadowControlsWrapper::GetControlValue(const SvxShadowItem& rItem) const
+{
+ SvxShadowItem aItem(rItem);
+ if (!mrVsPos.IsNoSelection())
+ {
+ switch (mrVsPos.GetSelectedItemId())
+ {
+ case 1:
+ aItem.SetLocation(SvxShadowLocation::NONE);
+ break;
+ case 2:
+ aItem.SetLocation(SvxShadowLocation::BottomRight);
+ break;
+ case 3:
+ aItem.SetLocation(SvxShadowLocation::TopRight);
+ break;
+ case 4:
+ aItem.SetLocation(SvxShadowLocation::BottomLeft);
+ break;
+ case 5:
+ aItem.SetLocation(SvxShadowLocation::TopLeft);
+ break;
+ default:
+ aItem.SetLocation(SvxShadowLocation::NONE);
+ break;
+ }
+ }
+ // Default value was saved; so don't change the aItem's width if the control
+ // has not changed its value, to avoid round-trip errors (like twip->cm->twip)
+ // E.g., initial 100 twip will become 0.18 cm, which will return as 102 twip
+ if (mrMfSize.get_value_changed_from_saved())
+ aItem.SetWidth(mrMfSize.denormalize(mrMfSize.get_value(FieldUnit::TWIP)));
+ if (!mrLbColor.IsNoSelection())
+ aItem.SetColor(mrLbColor.GetSelectEntryColor());
+ return aItem;
+}
+
+void ShadowControlsWrapper::SetControlValue(const SvxShadowItem& rItem)
+{
+ switch (rItem.GetLocation())
+ {
+ case SvxShadowLocation::NONE:
+ mrVsPos.SelectItem(1);
+ break;
+ case SvxShadowLocation::BottomRight:
+ mrVsPos.SelectItem(2);
+ break;
+ case SvxShadowLocation::TopRight:
+ mrVsPos.SelectItem(3);
+ break;
+ case SvxShadowLocation::BottomLeft:
+ mrVsPos.SelectItem(4);
+ break;
+ case SvxShadowLocation::TopLeft:
+ mrVsPos.SelectItem(5);
+ break;
+ default:
+ mrVsPos.SetNoSelection();
+ break;
+ }
+ mrVsPos.SaveValue();
+ mrMfSize.set_value(mrMfSize.normalize(rItem.GetWidth()), FieldUnit::TWIP);
+ mrMfSize.save_value();
+ mrLbColor.SelectEntry(rItem.GetColor());
+ mrLbColor.SaveValue();
+}
+
+bool ShadowControlsWrapper::get_value_changed_from_saved() const
+{
+ return mrVsPos.IsValueChangedFromSaved() ||
+ mrMfSize.get_value_changed_from_saved() ||
+ mrLbColor.IsValueChangedFromSaved();
+}
+
+void ShadowControlsWrapper::SetControlDontKnow()
+{
+ mrVsPos.SetNoSelection();
+ mrMfSize.set_text("");
+ mrLbColor.SetNoSelection();
+}
+
+MarginControlsWrapper::MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
+ weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom)
+ : mrLeftWrp(rMfLeft)
+ , mrRightWrp(rMfRight)
+ , mrTopWrp(rMfTop)
+ , mrBottomWrp(rMfBottom)
+{
+}
+
+SvxMarginItem MarginControlsWrapper::GetControlValue(const SvxMarginItem &rItem) const
+{
+ SvxMarginItem aItem(rItem);
+ if (mrLeftWrp.get_sensitive())
+ aItem.SetLeftMargin(mrLeftWrp.denormalize(mrLeftWrp.get_value(FieldUnit::TWIP)));
+ if (mrRightWrp.get_sensitive())
+ aItem.SetRightMargin(mrRightWrp.denormalize(mrRightWrp.get_value(FieldUnit::TWIP)));
+ if (mrTopWrp.get_sensitive())
+ aItem.SetTopMargin(mrTopWrp.denormalize(mrTopWrp.get_value(FieldUnit::TWIP)));
+ if (mrBottomWrp.get_sensitive())
+ aItem.SetBottomMargin(mrBottomWrp.denormalize(mrBottomWrp.get_value(FieldUnit::TWIP)));
+ return aItem;
+}
+
+bool MarginControlsWrapper::get_value_changed_from_saved() const
+{
+ return mrLeftWrp.get_value_changed_from_saved() ||
+ mrRightWrp.get_value_changed_from_saved() ||
+ mrTopWrp.get_value_changed_from_saved() ||
+ mrBottomWrp.get_value_changed_from_saved();
+}
+
+void MarginControlsWrapper::SetControlValue(const SvxMarginItem& rItem)
+{
+ mrLeftWrp.set_value(mrLeftWrp.normalize(rItem.GetLeftMargin()), FieldUnit::TWIP);
+ mrRightWrp.set_value(mrRightWrp.normalize(rItem.GetRightMargin()), FieldUnit::TWIP);
+ mrTopWrp.set_value(mrTopWrp.normalize(rItem.GetTopMargin()), FieldUnit::TWIP);
+ mrBottomWrp.set_value(mrBottomWrp.normalize(rItem.GetBottomMargin()), FieldUnit::TWIP);
+ mrLeftWrp.save_value();
+ mrRightWrp.save_value();
+ mrTopWrp.save_value();
+ mrBottomWrp.save_value();
+}
+
+void MarginControlsWrapper::SetControlDontKnow()
+{
+ const OUString sEmpty;
+ mrLeftWrp.set_text(sEmpty);
+ mrRightWrp.set_text(sEmpty);
+ mrTopWrp.set_text(sEmpty);
+ mrBottomWrp.set_text(sEmpty);
+}
+
+SvxBorderTabPage::SvxBorderTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/borderpage.ui", "BorderPage", &rCoreAttrs)
+ , nMinValue(0)
+ , nSWMode(SwBorderModes::NONE)
+ , mnBoxSlot(SID_ATTR_BORDER_OUTER)
+ , mnShadowSlot(SID_ATTR_BORDER_SHADOW)
+ , mbHorEnabled(false)
+ , mbVerEnabled(false)
+ , mbTLBREnabled(false)
+ , mbBLTREnabled(false)
+ , mbUseMarginItem(false)
+ , mbLeftModified(false)
+ , mbRightModified(false)
+ , mbTopModified(false)
+ , mbBottomModified(false)
+ , mbSync(true)
+ , mbRemoveAdjacentCellBorders(false)
+ , bIsCalcDoc(false)
+ , m_xWndPresets(new ValueSet(nullptr))
+ , m_xWndPresetsWin(new weld::CustomWeld(*m_xBuilder, "presets", *m_xWndPresets))
+ , m_xUserDefFT(m_xBuilder->weld_label("userdefft"))
+ , m_xFrameSelWin(new weld::CustomWeld(*m_xBuilder, "framesel", m_aFrameSel))
+ , m_xLbLineStyle(new SvtLineListBox(m_xBuilder->weld_menu_button("linestylelb")))
+ , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xLineWidthLB(m_xBuilder->weld_combo_box("linewidthlb"))
+ , m_xLineWidthMF(m_xBuilder->weld_metric_spin_button("linewidthmf", FieldUnit::POINT))
+ , m_xSpacingFrame(m_xBuilder->weld_container("spacing"))
+ , m_xLeftFT(m_xBuilder->weld_label("leftft"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("leftmf", FieldUnit::MM))
+ , m_xRightFT(m_xBuilder->weld_label("rightft"))
+ , m_xRightMF(m_xBuilder->weld_metric_spin_button("rightmf", FieldUnit::MM))
+ , m_xTopFT(m_xBuilder->weld_label("topft"))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("topmf", FieldUnit::MM))
+ , m_xBottomFT(m_xBuilder->weld_label("bottomft"))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottommf", FieldUnit::MM))
+ , m_xSynchronizeCB(m_xBuilder->weld_check_button("sync"))
+ , m_xShadowFrame(m_xBuilder->weld_container("shadow"))
+ , m_xWndShadows(new ValueSet(nullptr))
+ , m_xWndShadowsWin(new weld::CustomWeld(*m_xBuilder, "shadows", *m_xWndShadows))
+ , m_xFtShadowSize(m_xBuilder->weld_label("distanceft"))
+ , m_xEdShadowSize(m_xBuilder->weld_metric_spin_button("distancemf", FieldUnit::MM))
+ , m_xFtShadowColor(m_xBuilder->weld_label("shadowcolorft"))
+ , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("shadowcolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xPropertiesFrame(m_xBuilder->weld_container("properties"))
+ , m_xMergeWithNextCB(m_xBuilder->weld_check_button("mergewithnext"))
+ , m_xMergeAdjacentBordersCB(m_xBuilder->weld_check_button("mergeadjacent"))
+ , m_xRemoveAdjacentCellBordersCB(m_xBuilder->weld_check_button("rmadjcellborders"))
+ , m_xRemoveAdjacentCellBordersFT(m_xBuilder->weld_label("rmadjcellbordersft"))
+{
+ static std::vector<OUString> aBorderImageIds;
+
+ if (aBorderImageIds.empty())
+ {
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_CELL_NONE_32,
+ RID_SVXBMP_CELL_ALL_32,
+ RID_SVXBMP_CELL_LR_32,
+ RID_SVXBMP_CELL_TB_32,
+ RID_SVXBMP_CELL_L_32,
+ RID_SVXBMP_CELL_DIAG_32
+ });
+ }
+ else
+ {
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_CELL_NONE,
+ RID_SVXBMP_CELL_ALL,
+ RID_SVXBMP_CELL_LR,
+ RID_SVXBMP_CELL_TB,
+ RID_SVXBMP_CELL_L,
+ RID_SVXBMP_CELL_DIAG
+ });
+ }
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_HOR_NONE,
+ RID_SVXBMP_HOR_OUTER,
+ RID_SVXBMP_HOR_HOR,
+ RID_SVXBMP_HOR_ALL,
+ RID_SVXBMP_HOR_OUTER2,
+ RID_SVXBMP_VER_NONE,
+ RID_SVXBMP_VER_OUTER,
+ RID_SVXBMP_VER_VER,
+ RID_SVXBMP_VER_ALL,
+ RID_SVXBMP_VER_OUTER2,
+ RID_SVXBMP_TABLE_NONE,
+ RID_SVXBMP_TABLE_OUTER,
+ RID_SVXBMP_TABLE_OUTERH,
+ RID_SVXBMP_TABLE_ALL,
+ RID_SVXBMP_TABLE_OUTER2
+ });
+ }
+
+ for (auto const & rImageId : aBorderImageIds)
+ m_aBorderImgVec.emplace_back(StockImage::Yes, rImageId);
+
+ static std::vector<OUString> aShadowImageIds;
+ if (aShadowImageIds.empty())
+ {
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ aShadowImageIds.insert(aShadowImageIds.end(), {
+ RID_SVXBMP_SHADOWNONE_32,
+ RID_SVXBMP_SHADOW_BOT_RIGHT_32,
+ RID_SVXBMP_SHADOW_TOP_RIGHT_32,
+ RID_SVXBMP_SHADOW_BOT_LEFT_32,
+ RID_SVXBMP_SHADOW_TOP_LEFT_32
+ });
+ }
+ else
+ {
+ aShadowImageIds.insert(aShadowImageIds.end(), {
+ RID_SVXBMP_SHADOWNONE,
+ RID_SVXBMP_SHADOW_BOT_RIGHT,
+ RID_SVXBMP_SHADOW_TOP_RIGHT,
+ RID_SVXBMP_SHADOW_BOT_LEFT,
+ RID_SVXBMP_SHADOW_TOP_LEFT
+ });
+ }
+ }
+
+ for (auto const & rImageId : aShadowImageIds)
+ m_aShadowImgVec.emplace_back(StockImage::Yes, rImageId);
+
+ assert(m_aShadowImgVec.size() == BORDER_SHADOW_COUNT);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ /* Use SvxMarginItem instead of margins from SvxBoxItem, if present.
+ -> Remember this state in mbUseMarginItem, because other special handling
+ is needed across various functions... */
+ mbUseMarginItem = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_ALIGN_MARGIN)) != SfxItemState::UNKNOWN;
+
+ if (const SfxIntegerListItem* p = rCoreAttrs.GetItemIfSet(SID_ATTR_BORDER_STYLES))
+ {
+ std::vector<sal_Int32> aUsedStyles = p->GetList();
+ for (int aUsedStyle : aUsedStyles)
+ maUsedBorderStyles.insert(static_cast<SvxBorderLineStyle>(aUsedStyle));
+ }
+
+ if (const SfxInt64Item* p = rCoreAttrs.GetItemIfSet(SID_ATTR_BORDER_DEFAULT_WIDTH))
+ {
+ // The caller specifies default line width. Honor it.
+ SetLineWidth(p->GetValue());
+ }
+
+ // set metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rCoreAttrs );
+
+ if( mbUseMarginItem )
+ {
+ // copied from SvxAlignmentTabPage
+ switch ( eFUnit )
+ {
+ // #103396# the default value (1pt) can't be accurately represented in
+ // inches or pica with two decimals, so point is used instead.
+ case FieldUnit::PICA:
+ case FieldUnit::INCH:
+ case FieldUnit::FOOT:
+ case FieldUnit::MILE:
+ eFUnit = FieldUnit::POINT;
+ break;
+
+ case FieldUnit::CM:
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ }
+ else
+ {
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ; //prevent warning
+ }
+ }
+
+ SetFieldUnit(*m_xEdShadowSize, eFUnit);
+
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_BORDER_INNER, false );
+ bool bIsDontCare = true;
+
+ if ( rCoreAttrs.GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ // paragraph or table
+ const SvxBoxInfoItem* pBoxInfo =
+ static_cast<const SvxBoxInfoItem*>(&( rCoreAttrs.Get( nWhich ) ));
+
+ mbHorEnabled = pBoxInfo->IsHorEnabled();
+ mbVerEnabled = pBoxInfo->IsVerEnabled();
+ mbTLBREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_TLBR)) != SfxItemState::UNKNOWN;
+ mbBLTREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_BLTR)) != SfxItemState::UNKNOWN;
+
+ if(pBoxInfo->IsDist())
+ {
+ SetFieldUnit(*m_xLeftMF, eFUnit);
+ SetFieldUnit(*m_xRightMF, eFUnit);
+ SetFieldUnit(*m_xTopMF, eFUnit);
+ SetFieldUnit(*m_xBottomMF, eFUnit);
+ m_xSynchronizeCB->connect_toggled(LINK(this, SvxBorderTabPage, SyncHdl_Impl));
+ m_xLeftMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xRightMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xTopMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xBottomMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ }
+ else
+ {
+ m_xSpacingFrame->hide();
+ }
+ bIsDontCare = !pBoxInfo->IsValid( SvxBoxInfoItemValidFlags::DISABLE );
+ }
+ if(!mbUseMarginItem && eFUnit == FieldUnit::MM && MapUnit::MapTwip == rCoreAttrs.GetPool()->GetMetric( GetWhich( SID_ATTR_BORDER_INNER ) ))
+ {
+ //#i91548# changing the number of decimal digits changes the minimum values, too
+ lcl_SetDecimalDigitsTo1(*m_xLeftMF);
+ lcl_SetDecimalDigitsTo1(*m_xRightMF);
+ lcl_SetDecimalDigitsTo1(*m_xTopMF);
+ lcl_SetDecimalDigitsTo1(*m_xBottomMF);
+ lcl_SetDecimalDigitsTo1(*m_xEdShadowSize);
+ }
+
+ FrameSelFlags nFlags = FrameSelFlags::Outer;
+ if( mbHorEnabled )
+ nFlags |= FrameSelFlags::InnerHorizontal;
+ if( mbVerEnabled )
+ nFlags |= FrameSelFlags::InnerVertical;
+ if( mbTLBREnabled )
+ nFlags |= FrameSelFlags::DiagonalTLBR;
+ if( mbBLTREnabled )
+ nFlags |= FrameSelFlags::DiagonalBLTR;
+ if( bIsDontCare )
+ nFlags |= FrameSelFlags::DontCare;
+ m_aFrameSel.Initialize( nFlags );
+
+ m_aFrameSel.SetSelectHdl(LINK(this, SvxBorderTabPage, LinesChanged_Impl));
+ m_xLbLineStyle->SetSelectHdl( LINK( this, SvxBorderTabPage, SelStyleHdl_Impl ) );
+ m_xLbLineColor->SetSelectHdl( LINK( this, SvxBorderTabPage, SelColHdl_Impl ) );
+ m_xLineWidthLB->connect_changed(LINK(this, SvxBorderTabPage, ModifyWidthLBHdl_Impl));
+ m_xLineWidthMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyWidthMFHdl_Impl));
+ m_xWndPresets->SetSelectHdl( LINK( this, SvxBorderTabPage, SelPreHdl_Impl ) );
+ m_xWndShadows->SetSelectHdl( LINK( this, SvxBorderTabPage, SelSdwHdl_Impl ) );
+
+ FillValueSets();
+ FillLineListBox_Impl();
+
+ // Reapply line width: probably one of predefined values should be selected
+ SetLineWidth(m_xLineWidthMF->get_value(FieldUnit::NONE));
+
+ // connections
+ const SfxPoolItem* pItem = nullptr;
+ if (rCoreAttrs.HasItem(GetWhich(SID_ATTR_PARA_GRABBAG), &pItem))
+ {
+ const SfxGrabBagItem* pGrabBag = static_cast<const SfxGrabBagItem*>(pItem);
+ auto it = pGrabBag->GetGrabBag().find("DialogUseCharAttr");
+ if (it != pGrabBag->GetGrabBag().end())
+ {
+ bool bDialogUseCharAttr = false;
+ it->second >>= bDialogUseCharAttr;
+ if (bDialogUseCharAttr)
+ {
+ mnShadowSlot = SID_ATTR_CHAR_SHADOW;
+ mnBoxSlot = SID_ATTR_CHAR_BOX;
+ }
+ }
+ }
+
+ bool bSupportsShadow = !SfxItemPool::IsSlot(GetWhich(mnShadowSlot));
+ if( bSupportsShadow )
+ m_xShadowControls.reset(new ShadowControlsWrapper(*m_xWndShadows, *m_xEdShadowSize, *m_xLbShadowColor));
+ else
+ HideShadowControls();
+
+ if (mbUseMarginItem)
+ m_xMarginControls.reset(new MarginControlsWrapper(*m_xLeftMF, *m_xRightMF, *m_xTopMF, *m_xBottomMF));
+
+ // checkbox "Merge with next paragraph" only visible for Writer dialog format.paragraph
+ m_xMergeWithNextCB->hide();
+ // checkbox "Merge adjacent line styles" only visible for Writer dialog format.table
+ m_xMergeAdjacentBordersCB->hide();
+
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
+ if ( xSI.is() )
+ bIsCalcDoc = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ if( bIsCalcDoc )
+ {
+ m_xRemoveAdjacentCellBordersCB->connect_toggled(LINK(this, SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl));
+ m_xRemoveAdjacentCellBordersCB->show();
+ m_xRemoveAdjacentCellBordersCB->set_sensitive(false);
+ }
+ else
+ {
+ m_xRemoveAdjacentCellBordersCB->hide();
+ m_xRemoveAdjacentCellBordersFT->hide();
+ }
+}
+
+SvxBorderTabPage::~SvxBorderTabPage()
+{
+ m_xLbShadowColor.reset();
+ m_xWndShadowsWin.reset();
+ m_xWndShadows.reset();
+ m_xLbLineColor.reset();
+ m_xLbLineStyle.reset();
+ m_xFrameSelWin.reset();
+ m_xWndPresetsWin.reset();
+ m_xWndPresets.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBorderTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxBorderTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBorderTabPage::ResetFrameLine_Impl( svx::FrameBorderType eBorder, const SvxBorderLine* pCoreLine, bool bValid )
+{
+ if( m_aFrameSel.IsBorderEnabled( eBorder ) )
+ {
+ if( bValid )
+ m_aFrameSel.ShowBorder( eBorder, pCoreLine );
+ else
+ m_aFrameSel.SetBorderDontCare( eBorder );
+ }
+}
+
+bool SvxBorderTabPage::IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) const
+{
+ if (maUsedBorderStyles.empty())
+ // All border styles are allowed.
+ return true;
+
+ return maUsedBorderStyles.count(nStyle) > 0;
+}
+
+void SvxBorderTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR))
+ {
+ sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_TLBR);
+ if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
+ m_aFrameSel.ShowBorder(svx::FrameBorderType::TLBR, pLineItem->GetLine());
+ else
+ m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::TLBR);
+ }
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR))
+ {
+ sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_BLTR);
+ if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
+ m_aFrameSel.ShowBorder(svx::FrameBorderType::BLTR, pLineItem->GetLine());
+ else
+ m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::BLTR);
+ }
+
+ if (m_xShadowControls)
+ {
+ sal_uInt16 nShadowId = pPool->GetWhich(mnShadowSlot);
+ const SfxPoolItem* pItem = rSet->GetItem(nShadowId);
+ if (pItem)
+ m_xShadowControls->SetControlValue(*static_cast<const SvxShadowItem*>(pItem));
+ else
+ m_xShadowControls->SetControlDontKnow();
+ }
+
+ if (m_xMarginControls)
+ {
+ sal_uInt16 nAlignMarginId = pPool->GetWhich(SID_ATTR_ALIGN_MARGIN);
+ const SfxPoolItem* pItem = rSet->GetItem(nAlignMarginId);
+ if (pItem)
+ m_xMarginControls->SetControlValue(*static_cast<const SvxMarginItem*>(pItem));
+ else
+ m_xMarginControls->SetControlDontKnow();
+ }
+
+ sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
+ const SfxBoolItem *pMergeAdjacentBorders = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeAdjacentBordersId));
+ if (!pMergeAdjacentBorders)
+ m_xMergeAdjacentBordersCB->set_state(TRISTATE_INDET);
+ else
+ m_xMergeAdjacentBordersCB->set_active(pMergeAdjacentBorders->GetValue());
+ m_xMergeAdjacentBordersCB->save_state();
+
+ sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
+ const SfxBoolItem *pMergeWithNext = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeWithNextId));
+ if (!pMergeWithNext)
+ m_xMergeWithNextCB->set_state(TRISTATE_INDET);
+ else
+ m_xMergeWithNextCB->set_active(pMergeWithNext->GetValue());
+ m_xMergeWithNextCB->save_state();
+
+ const SvxBoxItem* pBoxItem;
+ const SvxBoxInfoItem* pBoxInfoItem;
+ sal_uInt16 nWhichBox = GetWhich(mnBoxSlot);
+ MapUnit eCoreUnit;
+
+ pBoxItem = static_cast<const SvxBoxItem*>(GetItem( *rSet, mnBoxSlot ));
+
+ pBoxInfoItem = GetItem( *rSet, SID_ATTR_BORDER_INNER, false );
+
+ eCoreUnit = pPool->GetMetric( nWhichBox );
+
+ if ( pBoxItem && pBoxInfoItem ) // -> Don't Care
+ {
+ ResetFrameLine_Impl( svx::FrameBorderType::Left, pBoxItem->GetLeft(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Right, pBoxItem->GetRight(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Top, pBoxItem->GetTop(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Bottom, pBoxItem->GetBottom(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Vertical, pBoxInfoItem->GetVert(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Horizontal, pBoxInfoItem->GetHori(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI ) );
+
+
+ // distance inside
+
+ if( !mbUseMarginItem )
+ {
+ if (m_xLeftMF->get_visible())
+ {
+ SetMetricValue(*m_xLeftMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xRightMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xTopMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xBottomMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+
+ nMinValue = m_xLeftMF->get_value(FieldUnit::NONE);
+
+ if ( pBoxInfoItem->IsDist() )
+ {
+ if( rSet->GetItemState( nWhichBox ) >= SfxItemState::DEFAULT )
+ {
+ bool bIsAnyBorderVisible = m_aFrameSel.IsAnyBorderVisible();
+ if( !bIsAnyBorderVisible || !pBoxInfoItem->IsMinDist() )
+ {
+ m_xLeftMF->set_min(0, FieldUnit::NONE);
+ m_xRightMF->set_min(0, FieldUnit::NONE);
+ m_xTopMF->set_min(0, FieldUnit::NONE);
+ m_xBottomMF->set_min(0, FieldUnit::NONE);
+ }
+ tools::Long nLeftDist = pBoxItem->GetDistance( SvxBoxItemLine::LEFT);
+ SetMetricValue(*m_xLeftMF, nLeftDist, eCoreUnit);
+ tools::Long nRightDist = pBoxItem->GetDistance( SvxBoxItemLine::RIGHT);
+ SetMetricValue(*m_xRightMF, nRightDist, eCoreUnit);
+ tools::Long nTopDist = pBoxItem->GetDistance( SvxBoxItemLine::TOP);
+ SetMetricValue( *m_xTopMF, nTopDist, eCoreUnit );
+ tools::Long nBottomDist = pBoxItem->GetDistance( SvxBoxItemLine::BOTTOM);
+ SetMetricValue( *m_xBottomMF, nBottomDist, eCoreUnit );
+
+ // if the distance is set with no active border line
+ // or it is null with an active border line
+ // no automatic changes should be made
+ const tools::Long nDefDist = bIsAnyBorderVisible ? pBoxInfoItem->GetDefDist() : 0;
+ bool bDiffDist = (nDefDist != nLeftDist ||
+ nDefDist != nRightDist ||
+ nDefDist != nTopDist ||
+ nDefDist != nBottomDist);
+ if ((pBoxItem->GetSmallestDistance() || bIsAnyBorderVisible) && bDiffDist )
+ {
+ mbLeftModified = true;
+ mbRightModified = true;
+ mbTopModified = true;
+ mbBottomModified = true;
+ }
+ }
+ else
+ {
+ // #106224# different margins -> do not fill the edits
+ m_xLeftMF->set_text( OUString() );
+ m_xRightMF->set_text( OUString() );
+ m_xTopMF->set_text( OUString() );
+ m_xBottomMF->set_text( OUString() );
+ }
+ }
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ }
+ }
+ }
+ else
+ {
+ // avoid ResetFrameLine-calls:
+ m_aFrameSel.HideAllBorders();
+ }
+
+ if( !m_aFrameSel.IsAnyBorderVisible() )
+ m_aFrameSel.DeselectAllBorders();
+
+ // depict line (color) in controllers if unambiguous:
+
+ {
+ // Do all visible lines show the same line widths?
+ tools::Long nWidth;
+ SvxBorderLineStyle nStyle;
+ bool bWidthEq = m_aFrameSel.GetVisibleWidth( nWidth, nStyle );
+ if( bWidthEq )
+ {
+ // Determine the width first as some styles can be missing depending on it
+ sal_Int64 nWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ sal_Int64( nWidth ), m_xLineWidthMF->get_digits(),
+ MapUnit::MapTwip, FieldUnit::POINT ));
+ SetLineWidth(nWidthPt);
+ m_xLbLineStyle->SetWidth(nWidth);
+
+ // then set the style
+ m_xLbLineStyle->SelectEntry( nStyle );
+ }
+ else
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+
+ // Do all visible lines show the same line color?
+ Color aColor;
+ bool bColorEq = m_aFrameSel.GetVisibleColor( aColor );
+ if( !bColorEq )
+ aColor = COL_BLACK;
+
+ m_xLbLineColor->SelectEntry(aColor);
+ auto nTextColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
+ m_xLbLineStyle->SetColor(nTextColor);
+
+ // Select all visible lines, if they are all equal.
+ if( bWidthEq && bColorEq )
+ m_aFrameSel.SelectAllVisibleBorders();
+
+ // set the current style and color (caches style in control even if nothing is selected)
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ SelColHdl_Impl(*m_xLbLineColor);
+ }
+
+ bool bEnable = m_xWndShadows->GetSelectedItemId() > 1 ;
+ m_xFtShadowSize->set_sensitive(bEnable);
+ m_xEdShadowSize->set_sensitive(bEnable);
+ m_xFtShadowColor->set_sensitive(bEnable);
+ m_xLbShadowColor->set_sensitive(bEnable);
+
+ m_xWndPresets->SetNoSelection();
+
+ // - no line - should not be selected
+
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
+ {
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ }
+
+ const SfxUInt16Item* pHtmlModeItem = rSet->GetItemIfSet(SID_HTML_MODE, false);
+ if(!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if(pHtmlModeItem)
+ {
+ sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ // there are no shadows in Html-mode and only complete borders
+ m_xShadowFrame->set_sensitive(false);
+
+ if( !(nSWMode & SwBorderModes::TABLE) )
+ {
+ m_xUserDefFT->set_sensitive(false);
+ m_xFrameSelWin->set_sensitive(false);
+ m_xWndPresets->RemoveItem(3);
+ m_xWndPresets->RemoveItem(4);
+ m_xWndPresets->RemoveItem(5);
+ }
+ }
+ }
+
+ LinesChanged_Impl( nullptr );
+ if (m_xLeftMF->get_value(FieldUnit::NONE) == m_xRightMF->get_value(FieldUnit::NONE) &&
+ m_xTopMF->get_value(FieldUnit::NONE) == m_xBottomMF->get_value(FieldUnit::NONE) &&
+ m_xTopMF->get_value(FieldUnit::NONE) == m_xLeftMF->get_value(FieldUnit::NONE))
+ {
+ mbSync = true;
+ }
+ else
+ mbSync = false;
+ m_xSynchronizeCB->set_active(mbSync);
+
+ mbRemoveAdjacentCellBorders = false;
+ m_xRemoveAdjacentCellBordersCB->set_active(false);
+ m_xRemoveAdjacentCellBordersCB->set_sensitive(false);
+}
+
+void SvxBorderTabPage::ChangesApplied()
+{
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ m_xMergeWithNextCB->save_state();
+ m_xMergeAdjacentBordersCB->save_state();
+}
+
+DeactivateRC SvxBorderTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
+{
+ bool bAttrsChanged = false;
+
+ SfxItemPool* pPool = rCoreAttrs->GetPool();
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR) &&
+ m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::TLBR) != svx::FrameBorderState::DontCare)
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_TLBR))
+ {
+ SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem));
+ aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::TLBR));
+ rCoreAttrs->Put(aLineItem);
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR) &&
+ m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::BLTR) != svx::FrameBorderState::DontCare)
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_BLTR))
+ {
+ SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(pOldItem));
+ aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::BLTR));
+ rCoreAttrs->Put(aLineItem);
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_xShadowControls && m_xShadowControls->get_value_changed_from_saved())
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, mnShadowSlot))
+ {
+ const SvxShadowItem& rOldShadowItem = *static_cast<const SvxShadowItem*>(pOldItem);
+ rCoreAttrs->Put(m_xShadowControls->GetControlValue(rOldShadowItem));
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_xMarginControls && m_xMarginControls->get_value_changed_from_saved())
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_ALIGN_MARGIN))
+ {
+ const SvxMarginItem& rOldMarginItem = *static_cast<const SvxMarginItem*>(pOldItem);
+ rCoreAttrs->Put(m_xMarginControls->GetControlValue(rOldMarginItem));
+ bAttrsChanged = true;
+ }
+ }
+
+ if (m_xMergeAdjacentBordersCB->get_state_changed_from_saved())
+ {
+ auto nState = m_xMergeAdjacentBordersCB->get_state();
+ if (nState == TRISTATE_INDET)
+ {
+ sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
+ rCoreAttrs->ClearItem(nMergeAdjacentBordersId);
+ }
+ else
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_SW_COLLAPSING_BORDERS))
+ {
+ std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
+ xNewItem->SetValue(static_cast<bool>(nState));
+ rCoreAttrs->Put(std::move(xNewItem));
+ }
+ }
+ bAttrsChanged = true;
+ }
+
+ if (m_xMergeWithNextCB->get_state_changed_from_saved())
+ {
+ auto nState = m_xMergeWithNextCB->get_state();
+ if (nState == TRISTATE_INDET)
+ {
+ sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
+ rCoreAttrs->ClearItem(nMergeWithNextId);
+ }
+ else
+ {
+ if (const SfxPoolItem* pOldItem = GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_CONNECT))
+ {
+ std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(pOldItem->Clone()));
+ xNewItem->SetValue(static_cast<bool>(nState));
+ rCoreAttrs->Put(std::move(xNewItem));
+ }
+ }
+ bAttrsChanged = true;
+ }
+
+ bool bPut = true;
+ sal_uInt16 nBoxWhich = GetWhich( mnBoxSlot );
+ sal_uInt16 nBoxInfoWhich = pPool->GetWhich( SID_ATTR_BORDER_INNER, false );
+ const SfxItemSet& rOldSet = GetItemSet();
+ SvxBoxItem aBoxItem ( nBoxWhich );
+ SvxBoxInfoItem aBoxInfoItem ( nBoxInfoWhich );
+ const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( *rCoreAttrs, mnBoxSlot ));
+
+ MapUnit eCoreUnit = rOldSet.GetPool()->GetMetric( nBoxWhich );
+
+
+ // outer border:
+
+ std::pair<svx::FrameBorderType,SvxBoxItemLine> eTypes1[] = {
+ { svx::FrameBorderType::Top,SvxBoxItemLine::TOP },
+ { svx::FrameBorderType::Bottom,SvxBoxItemLine::BOTTOM },
+ { svx::FrameBorderType::Left,SvxBoxItemLine::LEFT },
+ { svx::FrameBorderType::Right,SvxBoxItemLine::RIGHT },
+ };
+
+ for (std::pair<svx::FrameBorderType,SvxBoxItemLine> const & i : eTypes1)
+ aBoxItem.SetLine( m_aFrameSel.GetFrameBorderStyle( i.first ), i.second );
+
+
+ aBoxItem.SetRemoveAdjacentCellBorder( mbRemoveAdjacentCellBorders );
+ // border hor/ver and TableFlag
+
+ std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> eTypes2[] = {
+ { svx::FrameBorderType::Horizontal,SvxBoxInfoItemLine::HORI },
+ { svx::FrameBorderType::Vertical,SvxBoxInfoItemLine::VERT }
+ };
+ for (std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> const & j : eTypes2)
+ aBoxInfoItem.SetLine( m_aFrameSel.GetFrameBorderStyle( j.first ), j.second );
+
+ aBoxInfoItem.EnableHor( mbHorEnabled );
+ aBoxInfoItem.EnableVer( mbVerEnabled );
+
+
+ // inner distance
+
+ if (m_xLeftMF->get_visible())
+ {
+ // #i40405# enable distance controls for next dialog call
+ aBoxInfoItem.SetDist( true );
+
+ if( !mbUseMarginItem )
+ {
+ // #106224# all edits empty: do nothing
+ if( !m_xLeftMF->get_text().isEmpty() || !m_xRightMF->get_text().isEmpty() ||
+ !m_xTopMF->get_text().isEmpty() || !m_xBottomMF->get_text().isEmpty() )
+ {
+ const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER );
+ if (
+ !pOldBoxItem ||
+ m_xLeftMF->get_value_changed_from_saved() ||
+ m_xRightMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() ||
+ m_xBottomMF->get_value_changed_from_saved() ||
+ nMinValue == m_xLeftMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xRightMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xTopMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xBottomMF->get_value(FieldUnit::NONE) ||
+ (pOldBoxInfoItem && !pOldBoxInfoItem->IsValid(SvxBoxInfoItemValidFlags::DISTANCE))
+ )
+ {
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xLeftMF, eCoreUnit )), SvxBoxItemLine::LEFT );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xRightMF, eCoreUnit )), SvxBoxItemLine::RIGHT );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xTopMF, eCoreUnit )), SvxBoxItemLine::TOP );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xBottomMF, eCoreUnit )), SvxBoxItemLine::BOTTOM);
+ }
+ else
+ {
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::LEFT ), SvxBoxItemLine::LEFT);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::RIGHT), SvxBoxItemLine::RIGHT);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::TOP ), SvxBoxItemLine::TOP);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::BOTTOM), SvxBoxItemLine::BOTTOM);
+ }
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
+ }
+ }
+ }
+
+
+ // note Don't Care Status in the Info-Item:
+
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::TOP, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::LEFT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::RIGHT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::HORI, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Horizontal ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::VERT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Vertical ) != svx::FrameBorderState::DontCare );
+
+
+ // Put or Clear of the border?
+
+ bPut = true;
+
+ if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxWhich, false ))
+ {
+ bPut = aBoxItem != static_cast<const SvxBoxItem&>(rOldSet.Get(nBoxWhich));
+ }
+ if( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxInfoWhich, false ) )
+ {
+ const SvxBoxInfoItem& rOldBoxInfo = static_cast<const SvxBoxInfoItem&>(
+ rOldSet.Get(nBoxInfoWhich));
+
+ aBoxInfoItem.SetMinDist( rOldBoxInfo.IsMinDist() );
+ aBoxInfoItem.SetDefDist( rOldBoxInfo.GetDefDist() );
+ bPut |= (aBoxInfoItem != rOldBoxInfo );
+ }
+
+ if ( bPut )
+ {
+ if ( !pOldBoxItem || *pOldBoxItem != aBoxItem )
+ {
+ rCoreAttrs->Put( aBoxItem );
+ bAttrsChanged = true;
+ }
+ const SfxPoolItem* pOld = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER, false );
+
+ if ( !pOld || *static_cast<const SvxBoxInfoItem*>(pOld) != aBoxInfoItem )
+ {
+ rCoreAttrs->Put( aBoxInfoItem );
+ bAttrsChanged = true;
+ }
+ }
+ else
+ {
+ rCoreAttrs->ClearItem( nBoxWhich );
+ rCoreAttrs->ClearItem( nBoxInfoWhich );
+ }
+
+ return bAttrsChanged;
+}
+
+void SvxBorderTabPage::HideShadowControls()
+{
+ m_xShadowFrame->hide();
+}
+
+#define IID_PRE_CELL_NONE 1
+#define IID_PRE_CELL_ALL 2
+#define IID_PRE_CELL_LR 3
+#define IID_PRE_CELL_TB 4
+#define IID_PRE_CELL_L 5
+#define IID_PRE_CELL_DIAG 6
+#define IID_PRE_HOR_NONE 7
+#define IID_PRE_HOR_OUTER 8
+#define IID_PRE_HOR_HOR 9
+#define IID_PRE_HOR_ALL 10
+#define IID_PRE_HOR_OUTER2 11
+#define IID_PRE_VER_NONE 12
+#define IID_PRE_VER_OUTER 13
+#define IID_PRE_VER_VER 14
+#define IID_PRE_VER_ALL 15
+#define IID_PRE_VER_OUTER2 16
+#define IID_PRE_TABLE_NONE 17
+#define IID_PRE_TABLE_OUTER 18
+#define IID_PRE_TABLE_OUTERH 19
+#define IID_PRE_TABLE_ALL 20
+#define IID_PRE_TABLE_OUTER2 21
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void)
+{
+ const svx::FrameBorderState SHOW = svx::FrameBorderState::Show;
+ const svx::FrameBorderState HIDE = svx::FrameBorderState::Hide;
+ const svx::FrameBorderState DONT = svx::FrameBorderState::DontCare;
+
+ static const svx::FrameBorderState ppeStates[][ svx::FRAMEBORDERTYPE_COUNT ] =
+ { /* Left Right Top Bot Hor Ver TLBR BLTR */
+/* ---------------------+--------------------------------------------------- */
+/* IID_PRE_CELL_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_LR */ { SHOW, SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_TB */ { HIDE, HIDE, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_L */ { SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_DIAG */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, SHOW, SHOW },
+/* IID_PRE_HOR_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_HOR */ { HIDE, HIDE, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_VER */ { SHOW, SHOW, HIDE, HIDE, HIDE, SHOW, HIDE, HIDE },
+/* IID_PRE_VER_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, SHOW, HIDE, HIDE },
+/* IID_PRE_VER_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, HIDE, DONT, HIDE, HIDE },
+/* IID_PRE_TABLE_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTERH */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, DONT, HIDE, HIDE }
+ };
+
+ // first hide and deselect all frame borders
+ m_aFrameSel.HideAllBorders();
+ m_aFrameSel.DeselectAllBorders();
+
+ // Using image ID to find correct line in table above.
+ sal_uInt16 nLine = GetPresetImageId( m_xWndPresets->GetSelectedItemId() ) - 1;
+
+ // Apply all styles from the table
+ for( int nBorder = 0; nBorder < svx::FRAMEBORDERTYPE_COUNT; ++nBorder )
+ {
+ svx::FrameBorderType eBorder = svx::GetFrameBorderTypeFromIndex( nBorder );
+ switch( ppeStates[ nLine ][ nBorder ] )
+ {
+ case SHOW: m_aFrameSel.SelectBorder( eBorder ); break;
+ case HIDE: /* nothing to do */ break;
+ case DONT: m_aFrameSel.SetBorderDontCare( eBorder ); break;
+ }
+ }
+
+ // Show all lines that have been selected above
+ if( m_aFrameSel.IsAnyBorderSelected() )
+ {
+ // any visible style, but "no-line" in line list box? -> use hair-line
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+
+ // set current style to all previously selected lines
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ SelColHdl_Impl(*m_xLbLineColor);
+ }
+
+ // Presets ValueSet does not show a selection (used as push buttons).
+ m_xWndPresets->SetNoSelection();
+
+ LinesChanged_Impl( nullptr );
+ UpdateRemoveAdjCellBorderCB( nLine + 1 );
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelSdwHdl_Impl, ValueSet*, void)
+{
+ bool bEnable = m_xWndShadows->GetSelectedItemId() > 1;
+ m_xFtShadowSize->set_sensitive(bEnable);
+ m_xEdShadowSize->set_sensitive(bEnable);
+ m_xFtShadowColor->set_sensitive(bEnable);
+ m_xLbShadowColor->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ Color aColor = rColorBox.GetSelectEntryColor();
+ m_aFrameSel.SetColorToSelection(aColor);
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthLBHdl_Impl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = m_xLineWidthLB->get_active();
+ sal_Int32 nRemovedType = 0;
+ if (m_xLineWidthLB->get_values_changed_from_saved()) {
+ nRemovedType = m_aLineWidths.size() - m_xLineWidthLB->get_count();
+ }
+
+ SetLineWidth(m_aLineWidths[nPos + nRemovedType], nRemovedType);
+
+ // Call the spinner handler to trigger all related modifications
+ ModifyWidthMFHdl_Impl(*m_xLineWidthMF);
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthMFHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+
+ // for DOUBLE_THIN line style we cannot allow thinner line width then 1.10pt
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN)
+ m_xLineWidthMF->set_min(110, FieldUnit::NONE);
+ else
+ m_xLineWidthMF->set_min(5, FieldUnit::NONE);
+
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nVal,
+ m_xLineWidthMF->get_digits(),
+ FieldUnit::POINT, MapUnit::MapTwip ));
+ m_xLbLineStyle->SetWidth( nVal );
+
+ m_aFrameSel.SetStyleToSelection( nVal,
+ m_xLbLineStyle->GetSelectEntryStyle() );
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelStyleHdl_Impl, SvtLineListBox&, void)
+{
+ sal_Int64 nOldWidth = m_xLineWidthMF->get_value(FieldUnit::NONE);
+
+ // for DOUBLE_THIN line style we cannot allow thinner line width then 1.10pt
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN)
+ m_xLineWidthMF->set_min(110, FieldUnit::NONE);
+ else
+ m_xLineWidthMF->set_min(5, FieldUnit::NONE);
+
+ nOldWidth = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nOldWidth,
+ m_xLineWidthMF->get_digits(),
+ FieldUnit::POINT,
+ MapUnit::MapTwip));
+
+ const sal_Int64 nOldMinWidth = lcl_GetMinLineWidth(m_aFrameSel.getCurrentStyleLineStyle());
+ const sal_Int64 nNewMinWidth = lcl_GetMinLineWidth(m_xLbLineStyle->GetSelectEntryStyle());
+
+ // auto change line-width if it doesn't correspond to minimal value
+ // let's change only in case when user has not changed the line-width into some custom value
+ sal_Int64 nNewWidth = (nOldMinWidth == nOldWidth) ? nNewMinWidth : nOldWidth;
+
+ // if we had selected a predefined border width under SvxBorderLineWidth::Medium set the Medium as default
+ // otherwise if we had a cusom border width under 1.10pt then set the spinner to the maximum allowed value for double border styles
+ bool bNewDoubleHairline = m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN && !m_xLineWidthMF->get_visible() &&
+ (nOldWidth == SvxBorderLineWidth::Hairline || nOldWidth == SvxBorderLineWidth::VeryThin || nOldWidth == SvxBorderLineWidth::Thin);
+ if (bNewDoubleHairline && nNewWidth < SvxBorderLineWidth::Medium)
+ nNewWidth = SvxBorderLineWidth::Medium;
+
+ // set value inside edit box
+ if (nOldWidth != nNewWidth)
+ {
+ const sal_Int64 nNewWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nNewWidth,
+ m_xLineWidthMF->get_digits(),
+ MapUnit::MapTwip,
+ FieldUnit::POINT));
+ SetLineWidth(nNewWidthPt);
+ }
+
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::DOUBLE_THIN)
+ {
+ for (size_t i = 0; i < 3; i++)
+ {
+ m_xLineWidthLB->save_values_by_id(OUString::number(i));
+ m_xLineWidthLB->remove_id(OUString::number(i));
+ }
+ if (m_xLineWidthLB->get_active_id().isEmpty())
+ m_xLineWidthLB->set_active_id("3");
+ }
+ else
+ {
+ if (m_xLineWidthLB->get_values_changed_from_saved())
+ {
+ for (size_t i = 0; i < 3; i++)
+ m_xLineWidthLB->append(i, OUString::number(i), m_xLineWidthLB->get_saved_values(i));
+ m_xLineWidthLB->removeSavedValues();
+ }
+ }
+
+ // set value inside style box
+ m_aFrameSel.SetStyleToSelection( nNewWidth,
+ m_xLbLineStyle->GetSelectEntryStyle() );
+}
+
+
+// ValueSet handling
+sal_uInt16 SvxBorderTabPage::GetPresetImageId( sal_uInt16 nValueSetIdx ) const
+{
+ // table with all sets of predefined border styles
+ static const sal_uInt16 ppnImgIds[][ BORDER_PRESET_COUNT ] =
+ {
+ // simple cell without diagonal frame borders
+ { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_L },
+ // simple cell with diagonal frame borders
+ { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_DIAG },
+ // with horizontal inner frame border
+ { IID_PRE_HOR_NONE, IID_PRE_HOR_OUTER, IID_PRE_HOR_HOR, IID_PRE_HOR_ALL, IID_PRE_HOR_OUTER2 },
+ // with vertical inner frame border
+ { IID_PRE_VER_NONE, IID_PRE_VER_OUTER, IID_PRE_VER_VER, IID_PRE_VER_ALL, IID_PRE_VER_OUTER2 },
+ // with horizontal and vertical inner frame borders
+ { IID_PRE_TABLE_NONE, IID_PRE_TABLE_OUTER, IID_PRE_TABLE_OUTERH, IID_PRE_TABLE_ALL, IID_PRE_TABLE_OUTER2 }
+ };
+
+ // find correct set of presets
+ int nLine = 0;
+ if( !mbHorEnabled && !mbVerEnabled )
+ nLine = (mbTLBREnabled || mbBLTREnabled) ? 1 : 0;
+ else if( mbHorEnabled && !mbVerEnabled )
+ nLine = 2;
+ else if( !mbHorEnabled && mbVerEnabled )
+ nLine = 3;
+ else
+ nLine = 4;
+
+ DBG_ASSERT( (1 <= nValueSetIdx) && (nValueSetIdx <= BORDER_PRESET_COUNT),
+ "SvxBorderTabPage::GetPresetImageId - wrong index" );
+ return ppnImgIds[ nLine ][ nValueSetIdx - 1 ];
+}
+
+TranslateId SvxBorderTabPage::GetPresetStringId( sal_uInt16 nValueSetIdx ) const
+{
+ // string resource IDs for each image (in order of the IID_PRE_* image IDs)
+ static const TranslateId pnStrIds[] =
+ {
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_PARA_PRESET_ALL,
+ RID_SVXSTR_PARA_PRESET_LEFTRIGHT,
+ RID_SVXSTR_PARA_PRESET_TOPBOTTOM,
+ RID_SVXSTR_PARA_PRESET_ONLYLEFT,
+ RID_SVXSTR_PARA_PRESET_DIAGONAL,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_HOR_PRESET_ONLYHOR,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_VER_PRESET_ONLYVER,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_TABLE_PRESET_OUTERHORI,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER
+ };
+ return pnStrIds[ GetPresetImageId( nValueSetIdx ) - 1 ];
+}
+
+void SvxBorderTabPage::FillPresetVS()
+{
+ // basic initialization of the ValueSet
+ m_xWndPresets->SetStyle( m_xWndPresets->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
+ m_xWndPresets->SetColCount( BORDER_PRESET_COUNT );
+
+ // insert images and help texts
+ for( sal_uInt16 nVSIdx = 1; nVSIdx <= BORDER_PRESET_COUNT; ++nVSIdx )
+ {
+ m_xWndPresets->InsertItem( nVSIdx );
+ m_xWndPresets->SetItemImage(nVSIdx, m_aBorderImgVec[GetPresetImageId(nVSIdx) - 1]);
+ m_xWndPresets->SetItemText( nVSIdx, SvxResId( GetPresetStringId( nVSIdx ) ) );
+ }
+
+ // show the control
+ m_xWndPresets->SetNoSelection();
+ m_xWndPresets->SetOptimalSize();
+ m_xWndPresets->Show();
+}
+
+void SvxBorderTabPage::FillShadowVS()
+{
+ // basic initialization of the ValueSet
+ m_xWndShadows->SetStyle( m_xWndShadows->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
+ m_xWndShadows->SetColCount( BORDER_SHADOW_COUNT );
+
+ // string resource IDs for each image
+ static const TranslateId pnStrIds[ BORDER_SHADOW_COUNT ] =
+ { RID_CUISTR_SHADOW_STYLE_NONE, RID_CUISTR_SHADOW_STYLE_BOTTOMRIGHT, RID_CUISTR_SHADOW_STYLE_TOPRIGHT, RID_CUISTR_SHADOW_STYLE_BOTTOMLEFT, RID_CUISTR_SHADOW_STYLE_TOPLEFT };
+
+ // insert images and help texts
+ for( sal_uInt16 nVSIdx = 1; nVSIdx <= BORDER_SHADOW_COUNT; ++nVSIdx )
+ {
+ m_xWndShadows->InsertItem( nVSIdx );
+ m_xWndShadows->SetItemImage(nVSIdx, m_aShadowImgVec[nVSIdx-1]);
+ m_xWndShadows->SetItemText( nVSIdx, CuiResId( pnStrIds[ nVSIdx - 1 ] ) );
+ }
+
+ // show the control
+ m_xWndShadows->SelectItem( 1 );
+ m_xWndShadows->SetOptimalSize();
+ m_xWndShadows->Show();
+}
+
+
+void SvxBorderTabPage::FillValueSets()
+{
+ FillPresetVS();
+ FillShadowVS();
+}
+
+void SvxBorderTabPage::SetLineWidth( sal_Int64 nWidth, sal_Int32 nRemovedType )
+{
+ if ( nWidth >= 0 )
+ m_xLineWidthMF->set_value( nWidth, FieldUnit::POINT );
+
+ auto it = std::find_if( m_aLineWidths.begin(), m_aLineWidths.end(),
+ [nWidth](const int val) -> bool { return val == nWidth; } );
+
+ if ( it != m_aLineWidths.end() && *it >= 0 )
+ {
+ // Select predefined value in combobox
+ m_xLineWidthMF->hide();
+ m_xLineWidthLB->set_active(std::distance(m_aLineWidths.begin(), it) - nRemovedType);
+ }
+ else
+ {
+ // This is not one of predefined values. Show spinner
+ m_xLineWidthLB->set_active(m_aLineWidths.size() - nRemovedType -1);
+ m_xLineWidthMF->show();
+ }
+}
+
+static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
+{
+ return SvxBorderLine::threeDMediumColor( aMain );
+}
+
+void SvxBorderTabPage::FillLineListBox_Impl()
+{
+ using namespace ::com::sun::star::table::BorderLineStyle;
+
+ static struct {
+ SvxBorderLineStyle mnStyle;
+ SvtLineListBox::ColorFunc mpColor1Fn;
+ SvtLineListBox::ColorFunc mpColor2Fn;
+ SvtLineListBox::ColorDistFunc mpColorDistFn;
+ } const aLines[] = {
+ // Simple lines
+ { SvxBorderLineStyle::SOLID, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DOTTED, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASHED, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::FINE_DASHED, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASH_DOT, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASH_DOT_DOT, &sameColor, &sameColor, &sameDistColor },
+
+ // Double lines
+ { SvxBorderLineStyle::DOUBLE, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DOUBLE_THIN, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_SMALLGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_MEDIUMGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_LARGEGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_SMALLGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_MEDIUMGAP, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_LARGEGAP, &sameColor, &sameColor, &sameDistColor },
+
+ { SvxBorderLineStyle::EMBOSSED, &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor, &lcl_mediumColor },
+ { SvxBorderLineStyle::ENGRAVED, &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor, &lcl_mediumColor },
+
+ { SvxBorderLineStyle::OUTSET, &SvxBorderLine::lightColor, &SvxBorderLine::darkColor, &sameDistColor },
+ { SvxBorderLineStyle::INSET, &SvxBorderLine::darkColor, &SvxBorderLine::lightColor, &sameDistColor }
+ };
+
+ m_xLbLineStyle->SetSourceUnit( FieldUnit::TWIP );
+
+ for (size_t i = 0; i < std::size(aLines); ++i)
+ {
+ if (!IsBorderLineStyleAllowed(aLines[i].mnStyle))
+ continue;
+
+ m_xLbLineStyle->InsertEntry(
+ SvxBorderLine::getWidthImpl(aLines[i].mnStyle),
+ aLines[i].mnStyle,
+ lcl_GetMinLineWidth(aLines[i].mnStyle),
+ aLines[i].mpColor1Fn,
+ aLines[i].mpColor2Fn,
+ aLines[i].mpColorDistFn);
+ }
+
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(nVal, m_xLineWidthMF->get_digits(),
+ m_xLineWidthMF->get_unit(), MapUnit::MapTwip));
+ m_xLbLineStyle->SetWidth( nVal );
+}
+
+
+IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl, LinkParamNone*, void)
+{
+ if (!mbUseMarginItem && m_xLeftMF->get_visible())
+ {
+ bool bLineSet = m_aFrameSel.IsAnyBorderVisible();
+ bool bSpaceModified = mbLeftModified ||
+ mbRightModified ||
+ mbTopModified ||
+ mbBottomModified;
+
+ if(bLineSet)
+ {
+ if(!bSpaceModified)
+ {
+ m_xLeftMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xRightMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xTopMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xBottomMF->set_value(nMinValue, FieldUnit::NONE);
+ }
+ }
+ else
+ {
+ m_xLeftMF->set_min(0, FieldUnit::NONE);
+ m_xRightMF->set_min(0, FieldUnit::NONE);
+ m_xTopMF->set_min(0, FieldUnit::NONE);
+ m_xBottomMF->set_min(0, FieldUnit::NONE);
+ }
+ // for tables everything is allowed
+ SvxBoxInfoItemValidFlags nValid = SvxBoxInfoItemValidFlags::TOP|SvxBoxInfoItemValidFlags::BOTTOM|SvxBoxInfoItemValidFlags::LEFT|SvxBoxInfoItemValidFlags::RIGHT;
+
+ m_xLeftFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
+ m_xRightFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
+ m_xTopFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
+ m_xBottomFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
+ m_xLeftMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
+ m_xRightMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
+ m_xTopMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
+ m_xBottomMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
+ m_xSynchronizeCB->set_sensitive(m_xRightMF->get_sensitive() || m_xTopMF->get_sensitive() ||
+ m_xBottomMF->get_sensitive() || m_xLeftMF->get_sensitive());
+ }
+ UpdateRemoveAdjCellBorderCB( SAL_MAX_UINT16 );
+}
+
+
+IMPL_LINK( SvxBorderTabPage, ModifyDistanceHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ if (&rField == m_xLeftMF.get())
+ mbLeftModified = true;
+ else if (&rField == m_xRightMF.get())
+ mbRightModified = true;
+ else if (&rField == m_xTopMF.get())
+ mbTopModified = true;
+ else if (&rField == m_xBottomMF.get())
+ mbBottomModified = true;
+
+ if (mbSync)
+ {
+ const auto nVal = rField.get_value(FieldUnit::NONE);
+ if (&rField != m_xLeftMF.get())
+ m_xLeftMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xRightMF.get())
+ m_xRightMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xTopMF.get())
+ m_xTopMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xBottomMF.get())
+ m_xBottomMF->set_value(nVal, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK( SvxBorderTabPage, SyncHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ mbSync = rBox.get_active();
+}
+
+IMPL_LINK( SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ mbRemoveAdjacentCellBorders = rBox.get_active();
+}
+
+void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset )
+{
+ if( !bIsCalcDoc )
+ return;
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( rOldSet, SID_ATTR_BORDER_INNER );
+ const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( rOldSet, mnBoxSlot ));
+ if( !pOldBoxInfoItem || !pOldBoxItem )
+ return;
+ std::pair<svx::FrameBorderType, SvxBoxInfoItemValidFlags> eTypes1[] = {
+ { svx::FrameBorderType::Top,SvxBoxInfoItemValidFlags::TOP },
+ { svx::FrameBorderType::Bottom,SvxBoxInfoItemValidFlags::BOTTOM },
+ { svx::FrameBorderType::Left,SvxBoxInfoItemValidFlags::LEFT },
+ { svx::FrameBorderType::Right,SvxBoxInfoItemValidFlags::RIGHT },
+ };
+ SvxBoxItemLine const eTypes2[] = {
+ SvxBoxItemLine::TOP,
+ SvxBoxItemLine::BOTTOM,
+ SvxBoxItemLine::LEFT,
+ SvxBoxItemLine::RIGHT,
+ };
+
+ // Check if current selection involves deletion of at least one border
+ bool bBorderDeletionReq = false;
+ for ( size_t i=0; i < std::size( eTypes1 ); ++i )
+ {
+ if( pOldBoxItem->GetLine( eTypes2[i] ) || !( pOldBoxInfoItem->IsValid( eTypes1[i].second ) ) )
+ {
+ if( m_aFrameSel.GetFrameBorderState( eTypes1[i].first ) == svx::FrameBorderState::Hide )
+ {
+ bBorderDeletionReq = true;
+ break;
+ }
+ }
+ }
+
+ if( !bBorderDeletionReq && ( nPreset == IID_PRE_CELL_NONE || nPreset == IID_PRE_TABLE_NONE ) )
+ bBorderDeletionReq = true;
+
+ m_xRemoveAdjacentCellBordersCB->set_sensitive(bBorderDeletionReq);
+
+ if( !bBorderDeletionReq )
+ {
+ mbRemoveAdjacentCellBorders = false;
+ m_xRemoveAdjacentCellBordersCB->set_active(false);
+ }
+}
+
+void SvxBorderTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pSWModeItem = aSet.GetItem<SfxUInt16Item>(SID_SWMODE_TYPE, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pSWModeItem)
+ {
+ nSWMode = static_cast<SwBorderModes>(pSWModeItem->GetValue());
+ // #i43593#
+ // show checkbox <m_xMergeWithNextCB> for format.paragraph
+ if ( nSWMode == SwBorderModes::PARA )
+ {
+ m_xMergeWithNextCB->show();
+ m_xPropertiesFrame->show();
+ }
+ // show checkbox <m_xMergeAdjacentBordersCB> for format.paragraph
+ else if ( nSWMode == SwBorderModes::TABLE )
+ {
+ m_xMergeAdjacentBordersCB->show();
+ m_xPropertiesFrame->show();
+ }
+ }
+ if (pFlagItem)
+ if ( ( pFlagItem->GetValue() & SVX_HIDESHADOWCTL ) == SVX_HIDESHADOWCTL )
+ HideShadowControls();
+}
+
+void SvxBorderTabPage::SetTableMode()
+{
+ nSWMode = SwBorderModes::TABLE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
new file mode 100644
index 000000000..5bf0975bb
--- /dev/null
+++ b/cui/source/tabpages/chardlg.cxx
@@ -0,0 +1,3230 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/idle.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <chardlg.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/autokernitem.hxx>
+#include <editeng/colritem.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <cui/cuicharmap.hxx>
+#include "chardlg.h"
+#include <editeng/emphasismarkitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <strings.hrc>
+#include <twolines.hrc>
+#include <svl/intitem.hxx>
+#include <svx/flagsdef.hxx>
+#include <FontFeatures.hxx>
+#include <FontFeaturesDialog.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <o3tl/unit_conversion.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxCharNamePage::pNameRanges(svl::Items<
+ SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_WEIGHT,
+ SID_ATTR_CHAR_FONTHEIGHT, SID_ATTR_CHAR_FONTHEIGHT,
+ SID_ATTR_CHAR_COLOR, SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_LANGUAGE, SID_ATTR_CHAR_LANGUAGE,
+ SID_ATTR_CHAR_CJK_FONT, SID_ATTR_CHAR_CJK_WEIGHT,
+ SID_ATTR_CHAR_CTL_FONT, SID_ATTR_CHAR_CTL_WEIGHT
+>);
+
+const WhichRangesContainer SvxCharEffectsPage::pEffectsRanges(svl::Items<
+ SID_ATTR_CHAR_SHADOWED, SID_ATTR_CHAR_UNDERLINE,
+ SID_ATTR_CHAR_COLOR, SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_CASEMAP, SID_ATTR_CHAR_CASEMAP,
+ SID_ATTR_FLASH, SID_ATTR_FLASH,
+ SID_ATTR_CHAR_EMPHASISMARK, SID_ATTR_CHAR_EMPHASISMARK,
+ SID_ATTR_CHAR_RELIEF, SID_ATTR_CHAR_RELIEF,
+ SID_ATTR_CHAR_HIDDEN, SID_ATTR_CHAR_HIDDEN,
+ SID_ATTR_CHAR_OVERLINE, SID_ATTR_CHAR_OVERLINE
+>);
+
+const WhichRangesContainer SvxCharPositionPage::pPositionRanges(svl::Items<
+ SID_ATTR_CHAR_KERNING, SID_ATTR_CHAR_KERNING,
+ SID_ATTR_CHAR_ESCAPEMENT, SID_ATTR_CHAR_ESCAPEMENT,
+ SID_ATTR_CHAR_AUTOKERN, SID_ATTR_CHAR_AUTOKERN,
+ SID_ATTR_CHAR_ROTATED, SID_ATTR_CHAR_SCALEWIDTH,
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE
+>);
+
+const WhichRangesContainer SvxCharTwoLinesPage::pTwoLinesRanges(svl::Items<
+ SID_ATTR_CHAR_TWO_LINES, SID_ATTR_CHAR_TWO_LINES
+>);
+
+// C-Function ------------------------------------------------------------
+
+static bool StateToAttr( TriState aState )
+{
+ return ( TRISTATE_TRUE == aState );
+}
+
+namespace
+{
+ void setPrevFontEscapement(SvxFont& _rFont,sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+ {
+ _rFont.SetPropr( nProp );
+ _rFont.SetProprRel( nEscProp );
+ _rFont.SetEscapement( nEsc );
+ }
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewFont()
+{
+ return m_aPreviewWin.GetFont();
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewCJKFont()
+{
+ return m_aPreviewWin.GetCJKFont();
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewCTLFont()
+{
+ return m_aPreviewWin.GetCTLFont();
+}
+
+SvxCharBasePage::SvxCharBasePage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rItemset)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, &rItemset)
+ , m_bPreviewBackgroundToCharacter( false )
+{
+}
+
+SvxCharBasePage::~SvxCharBasePage()
+{
+}
+
+void SvxCharBasePage::ActivatePage(const SfxItemSet& rSet)
+{
+ m_aPreviewWin.SetFromItemSet(rSet, m_bPreviewBackgroundToCharacter);
+}
+
+void SvxCharBasePage::SetPrevFontWidthScale( const SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if (rSet.GetItemState(nWhich)>=SfxItemState::DEFAULT)
+ {
+ const SvxCharScaleWidthItem &rItem = static_cast<const SvxCharScaleWidthItem&>( rSet.Get( nWhich ) );
+ m_aPreviewWin.SetFontWidthScale(rItem.GetValue());
+ }
+}
+
+void SvxCharBasePage::SetPrevFontEscapement( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+{
+ setPrevFontEscapement(GetPreviewFont(),nProp,nEscProp,nEsc);
+ setPrevFontEscapement(GetPreviewCJKFont(),nProp,nEscProp,nEsc);
+ setPrevFontEscapement(GetPreviewCTLFont(),nProp,nEscProp,nEsc);
+ m_aPreviewWin.Invalidate();
+}
+
+
+// SvxCharNamePage_Impl --------------------------------------------------
+
+struct SvxCharNamePage_Impl
+{
+ Idle m_aUpdateIdle { "cui SvxCharNamePage_Impl m_aUpdateIdle" };
+ OUString m_aNoStyleText;
+ std::unique_ptr<FontList> m_pFontList;
+ int m_nExtraEntryPos;
+ bool m_bInSearchMode;
+
+ SvxCharNamePage_Impl()
+ : m_nExtraEntryPos(std::numeric_limits<int>::max())
+ , m_bInSearchMode(false)
+
+ {
+ m_aUpdateIdle.SetPriority( TaskPriority::LOWEST );
+ }
+};
+
+// class SvxCharNamePage -------------------------------------------------
+
+SvxCharNamePage::SvxCharNamePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/charnamepage.ui", "CharNamePage", rInSet)
+ , m_pImpl(new SvxCharNamePage_Impl)
+ // Western
+ , m_xWestern(m_xBuilder->weld_notebook("nbWestern"))
+ , m_xWestFontNameFT(m_xBuilder->weld_label("lbWestFontname"))
+ , m_xWestFontStyleFT(m_xBuilder->weld_label("lbWestStyle"))
+ , m_xWestFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("cbWestStyle")))
+ , m_xWestFontSizeFT(m_xBuilder->weld_label("lbWestSize"))
+ , m_xWestFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("cbWestSize")))
+ , m_xWestFontLanguageFT(m_xBuilder->weld_label("lbWestLanguage"))
+ , m_xWestFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("cbWestLanguage")))
+ , m_xWestFontFeaturesButton(m_xBuilder->weld_button("btnWestFeatures"))
+ , m_xWestFontTypeFT(m_xBuilder->weld_label("lbWestFontinfo"))
+ , m_xCJK_CTL(m_xBuilder->weld_notebook("nbCJKCTL"))
+ // CJK
+ , m_xEastFontNameFT(m_xBuilder->weld_label("lbCJKFontname"))
+ , m_xEastFontStyleFT(m_xBuilder->weld_label("lbCJKStyle"))
+ , m_xEastFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("cbCJKStyle")))
+ , m_xEastFontSizeFT(m_xBuilder->weld_label("lbCJKSize"))
+ , m_xEastFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("cbCJKSize")))
+ , m_xEastFontLanguageFT(m_xBuilder->weld_label("lbCJKLanguage"))
+ , m_xEastFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("cbCJKLanguage")))
+ , m_xEastFontFeaturesButton(m_xBuilder->weld_button("btnCJKFeatures"))
+ , m_xEastFontTypeFT(m_xBuilder->weld_label("lbCJKFontinfo"))
+ // CTL
+ , m_xCTLFontNameFT(m_xBuilder->weld_label("lbCTLFontname"))
+ // tree
+ , m_xCTLFontStyleFT(m_xBuilder->weld_label("lbCTLStyle"))
+ , m_xCTLFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("cbCTLStyle")))
+ , m_xCTLFontSizeFT(m_xBuilder->weld_label("lbCTLSize"))
+ , m_xCTLFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("cbCTLSize")))
+ , m_xCTLFontLanguageFT(m_xBuilder->weld_label("lbCTLLanguage"))
+ , m_xCTLFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("cbCTLLanguage")))
+ , m_xCTLFontFeaturesButton(m_xBuilder->weld_button("btnCTLFeatures"))
+ , m_xCTLFontTypeFT(m_xBuilder->weld_label("lbCTLFontinfo"))
+
+ , m_xVDev(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT, DeviceFormat::DEFAULT)
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ m_pImpl->m_aNoStyleText = CuiResId( RID_CUISTR_CHARNAME_NOSTYLE );
+
+ std::unique_ptr<weld::EntryTreeView> xWestFontName = m_xBuilder->weld_entry_tree_view("gdWestern", "edWestFontName", "trWestFontName");
+ std::unique_ptr<weld::EntryTreeView> xCJKFontName = m_xBuilder->weld_entry_tree_view("gdCJK", "edCJKFontName", "trCJKFontName");
+ std::unique_ptr<weld::EntryTreeView> xCTLFontName = m_xBuilder->weld_entry_tree_view("gdCTL", "edCTLFontName", "trCTLFontName");
+
+ // 7 lines in the treeview
+ xWestFontName->set_height_request_by_rows(7);
+ xCJKFontName->set_height_request_by_rows(7);
+ xCTLFontName->set_height_request_by_rows(7);
+
+ m_xWestFontNameLB = std::move(xWestFontName);
+ m_xEastFontNameLB = std::move(xCJKFontName);
+ m_xCTLFontNameLB = std::move(xCTLFontName);
+
+ SvtCTLOptions aCTLLanguageOptions;
+ bool bShowCJK = SvtCJKOptions::IsCJKFontEnabled();
+ bool bShowCTL = aCTLLanguageOptions.IsCTLFontEnabled();
+ bool bShowNonWestern = bShowCJK || bShowCTL;
+ if (!bShowNonWestern)
+ {
+ m_xCJK_CTL->hide();
+ m_xWestern->set_show_tabs(false); //hide single tab in case of Western only
+ }
+ else if (!bShowCJK) m_xCJK_CTL->remove_page("nbCJK");
+ else if (!bShowCTL) m_xCJK_CTL->remove_page("nbCTL");
+
+
+ //In MacOSX the standard dialogs name font-name, font-style as
+ //Family, Typeface
+ //In GNOME the standard dialogs name font-name, font-style as
+ //Family, Style
+ //In Windows the standard dialogs name font-name, font-style as
+ //Font, Style
+#ifdef _WIN32
+ OUString sFontFamilyString(CuiResId(RID_CUISTR_CHARNAME_FONT));
+#else
+ OUString sFontFamilyString(CuiResId(RID_CUISTR_CHARNAME_FAMILY));
+#endif
+ m_xWestFontNameFT->set_label(sFontFamilyString);
+ m_xCTLFontNameFT->set_label(sFontFamilyString);
+ m_xEastFontNameFT->set_label(sFontFamilyString);
+
+#ifdef MACOSX
+ OUString sFontStyleString(CuiResId(RID_CUISTR_CHARNAME_TYPEFACE));
+#else
+ OUString sFontStyleString(CuiResId(RID_CUISTR_CHARNAME_STYLE));
+#endif
+ m_xWestFontStyleFT->set_label(sFontStyleString);
+ m_xEastFontStyleFT->set_label(sFontStyleString);
+ m_xCTLFontStyleFT->set_label(sFontStyleString);
+
+ m_xWestFontLanguageLB->SetLanguageList(SvxLanguageListFlags::WESTERN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
+ m_xEastFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CJK, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
+ m_xCTLFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CTL, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
+ int nVisibleChars = 15;
+ // read-only combobox / HasEntry asserts on set_width_char()
+ m_xWestFontLanguageLB->set_width_chars(nVisibleChars);
+ m_xEastFontLanguageLB->set_width_chars(nVisibleChars);
+ m_xCTLFontLanguageLB->set_width_chars(nVisibleChars);
+
+ Initialize();
+}
+
+SvxCharNamePage::~SvxCharNamePage()
+{
+ m_pImpl.reset();
+ m_xCTLFontStyleLB.reset();
+ m_xEastFontLanguageLB.reset();
+ m_xWestFontStyleLB.reset();
+ m_xCTLFontSizeLB.reset();
+ m_xEastFontSizeLB.reset();
+ m_xWestFontSizeLB.reset();
+ m_xWestFontLanguageLB.reset();
+ m_xPreviewWin.reset();
+ m_xCTLFontLanguageLB.reset();
+ m_xEastFontLanguageLB.reset();
+}
+
+void SvxCharNamePage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ Link<weld::ComboBox&,void> aLink = LINK(this, SvxCharNamePage, FontModifyComboBoxHdl_Impl);
+ m_xWestFontNameLB->connect_changed(aLink);
+ m_xWestFontStyleLB->connect_changed(aLink);
+ m_xWestFontSizeLB->connect_changed(aLink);
+ m_xWestFontLanguageLB->connect_changed(aLink);
+
+ m_xWestFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_xEastFontNameLB->connect_changed(aLink);
+ m_xEastFontStyleLB->connect_changed(aLink);
+ m_xEastFontSizeLB->connect_changed(aLink);
+ m_xEastFontLanguageLB->connect_changed(aLink);
+ m_xEastFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_xCTLFontNameLB->connect_changed(aLink);
+ m_xCTLFontStyleLB->connect_changed(aLink);
+ m_xCTLFontSizeLB->connect_changed(aLink);
+ m_xCTLFontLanguageLB->connect_changed(aLink);
+ m_xCTLFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_pImpl->m_aUpdateIdle.SetInvokeHandler( LINK( this, SvxCharNamePage, UpdateHdl_Impl ) );
+}
+
+const FontList* SvxCharNamePage::GetFontList() const
+{
+ if ( !m_pImpl->m_pFontList )
+ {
+ /* #110771# SvxFontListItem::GetFontList can return NULL */
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
+ if ( pItem != nullptr )
+ {
+ DBG_ASSERT(nullptr != static_cast<const SvxFontListItem*>(pItem)->GetFontList(),
+ "Where is the font list?");
+ m_pImpl->m_pFontList = static_cast<const SvxFontListItem*>(pItem )->GetFontList()->Clone();
+ }
+ }
+ if(!m_pImpl->m_pFontList)
+ {
+ m_pImpl->m_pFontList.reset(new FontList( Application::GetDefaultDevice() ));
+ }
+ }
+
+ return m_pImpl->m_pFontList.get();
+}
+
+
+namespace
+{
+ FontMetric calcFontMetrics( SvxFont& _rFont,
+ SvxCharNamePage const * _pPage,
+ const weld::ComboBox* _pFontNameLB,
+ const FontStyleBox* _pFontStyleLB,
+ const FontSizeBox* _pFontSizeLB,
+ const SvxLanguageBox* _pLanguageLB,
+ const FontList* _pFontList,
+ sal_uInt16 _nFontWhich,
+ sal_uInt16 _nFontHeightWhich)
+ {
+ Size aSize = _rFont.GetFontSize();
+ aSize.setWidth( 0 );
+ FontMetric aFontMetrics;
+ OUString sFontName(_pFontNameLB->get_active_text());
+ bool bFontAvailable = _pFontList->IsAvailable( sFontName );
+ if (bFontAvailable || _pFontNameLB->get_value_changed_from_saved())
+ aFontMetrics = _pFontList->Get(sFontName, _pFontStyleLB->get_active_text());
+ else
+ {
+ //get the font from itemset
+ SfxItemState eState = _pPage->GetItemSet().GetItemState( _nFontWhich );
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(&( _pPage->GetItemSet().Get( _nFontWhich ) ));
+ aFontMetrics.SetFamilyName(pFontItem->GetFamilyName());
+ aFontMetrics.SetStyleName(pFontItem->GetStyleName());
+ aFontMetrics.SetFamily(pFontItem->GetFamily());
+ aFontMetrics.SetPitch(pFontItem->GetPitch());
+ aFontMetrics.SetCharSet(pFontItem->GetCharSet());
+ }
+ }
+ if ( _pFontSizeLB->IsRelative() )
+ {
+ DBG_ASSERT( _pPage->GetItemSet().GetParent(), "No parent set" );
+ const SvxFontHeightItem& rOldItem = static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nFontHeightWhich ));
+
+ // old value, scaled
+ tools::Long nHeight;
+ if ( _pFontSizeLB->IsPtRelative() )
+ nHeight = rOldItem.GetHeight()
+ + o3tl::convert(_pFontSizeLB->get_value(), o3tl::Length::pt,
+ o3tl::Length::twip) / 10;
+ else
+ nHeight = static_cast<tools::Long>(rOldItem.GetHeight() * _pFontSizeLB->get_value() / 100);
+
+ // conversion twips for the example-window
+ aSize.setHeight(
+ ItemToControl( nHeight, _pPage->GetItemSet().GetPool()->GetMetric( _nFontHeightWhich ), FieldUnit::TWIP ) );
+ }
+ else if ( !_pFontSizeLB->get_active_text().isEmpty() )
+ aSize.setHeight(o3tl::convert(_pFontSizeLB->get_value(), o3tl::Length::pt,
+ o3tl::Length::twip) / 10);
+ else
+ aSize.setHeight( 200 ); // default 10pt
+ aFontMetrics.SetFontSize( aSize );
+
+ _rFont.SetLanguage(_pLanguageLB->get_active_id());
+
+ _rFont.SetFamily( aFontMetrics.GetFamilyType() );
+ _rFont.SetFamilyName( aFontMetrics.GetFamilyName() );
+ _rFont.SetStyleName( aFontMetrics.GetStyleName() );
+ _rFont.SetPitch( aFontMetrics.GetPitch() );
+ _rFont.SetCharSet( aFontMetrics.GetCharSet() );
+ _rFont.SetWeight( aFontMetrics.GetWeight() );
+ _rFont.SetItalic( aFontMetrics.GetItalic() );
+ _rFont.SetFontSize( aFontMetrics.GetFontSize() );
+
+ return aFontMetrics;
+ }
+}
+
+
+void SvxCharNamePage::UpdatePreview_Impl()
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ // Font
+ const FontList* pFontList = GetFontList();
+
+ FontMetric aWestFontMetric = calcFontMetrics(rFont, this, m_xWestFontNameLB.get(),
+ m_xWestFontStyleLB.get(), m_xWestFontSizeLB.get(), m_xWestFontLanguageLB.get(),
+ pFontList, GetWhich(SID_ATTR_CHAR_FONT),
+ GetWhich(SID_ATTR_CHAR_FONTHEIGHT));
+
+ m_xWestFontTypeFT->set_label(pFontList->GetFontMapText(aWestFontMetric));
+
+ FontMetric aEastFontMetric = calcFontMetrics(rCJKFont, this, m_xEastFontNameLB.get(),
+ m_xEastFontStyleLB.get(), m_xEastFontSizeLB.get(), m_xEastFontLanguageLB.get(),
+ pFontList, GetWhich(SID_ATTR_CHAR_CJK_FONT),
+ GetWhich(SID_ATTR_CHAR_CJK_FONTHEIGHT));
+
+ m_xEastFontTypeFT->set_label(pFontList->GetFontMapText(aEastFontMetric));
+
+ FontMetric aCTLFontMetric = calcFontMetrics(rCTLFont,
+ this, m_xCTLFontNameLB.get(), m_xCTLFontStyleLB.get(), m_xCTLFontSizeLB.get(),
+ m_xCTLFontLanguageLB.get(), pFontList, GetWhich(SID_ATTR_CHAR_CTL_FONT),
+ GetWhich(SID_ATTR_CHAR_CTL_FONTHEIGHT));
+
+ m_xCTLFontTypeFT->set_label(pFontList->GetFontMapText(aCTLFontMetric));
+
+ m_aPreviewWin.Invalidate();
+}
+void SvxCharNamePage::EnableFeatureButton(const weld::Widget& rNameBox)
+{
+ OUString sFontName;
+ weld::Button* pButton= nullptr;
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ sFontName = m_xWestFontNameLB->get_active_text();
+ pButton= m_xWestFontFeaturesButton.get();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ sFontName = m_xEastFontNameLB->get_active_text();
+ pButton=m_xEastFontFeaturesButton.get();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ sFontName = m_xCTLFontNameLB->get_active_text();
+ pButton= m_xCTLFontFeaturesButton.get();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ bool bEnable = !getFontFeatureList(sFontName, *m_xVDev).empty();
+
+ pButton->set_sensitive(bEnable);
+}
+
+void SvxCharNamePage::FillStyleBox_Impl(const weld::Widget& rNameBox)
+{
+ const FontList* pFontList = GetFontList();
+ DBG_ASSERT( pFontList, "no fontlist" );
+
+ FontStyleBox* pStyleBox = nullptr;
+ OUString sFontName;
+
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xWestFontStyleLB.get();
+ sFontName = m_xWestFontNameLB->get_active_text();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xEastFontStyleLB.get();
+ sFontName = m_xEastFontStyleLB->get_active_text();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xCTLFontStyleLB.get();
+ sFontName = m_xCTLFontNameLB->get_active_text();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ pStyleBox->Fill(sFontName, pFontList);
+
+ if ( !m_pImpl->m_bInSearchMode )
+ return;
+
+ // additional entries for the search:
+ // "not bold" and "not italic"
+ OUString aEntry = m_pImpl->m_aNoStyleText;
+ const char sS[] = "%1";
+ aEntry = aEntry.replaceFirst( sS, pFontList->GetBoldStr() );
+ m_pImpl->m_nExtraEntryPos = pStyleBox->get_count();
+ pStyleBox->append_text( aEntry );
+ aEntry = m_pImpl->m_aNoStyleText;
+ aEntry = aEntry.replaceFirst( sS, pFontList->GetItalicStr() );
+ pStyleBox->append_text(aEntry);
+}
+
+void SvxCharNamePage::FillSizeBox_Impl(const weld::Widget& rNameBox)
+{
+ const FontList* pFontList = GetFontList();
+ DBG_ASSERT( pFontList, "no fontlist" );
+
+ FontSizeBox* pSizeBox = nullptr;
+
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ pSizeBox = m_xWestFontSizeLB.get();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ pSizeBox = m_xEastFontSizeLB.get();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ pSizeBox = m_xCTLFontSizeLB.get();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ pSizeBox->Fill( pFontList );
+}
+
+namespace
+{
+ void FillFontNames(weld::ComboBox& rBox, const FontList& rList)
+ {
+ // insert fonts
+ sal_uInt16 nFontCount = rList.GetFontNameCount();
+ std::vector<weld::ComboBoxEntry> aVector;
+ aVector.reserve(nFontCount);
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = rList.GetFontName(i);
+ aVector.emplace_back(rFontMetric.GetFamilyName());
+ }
+ rBox.insert_vector(aVector, false);
+ }
+}
+
+void SvxCharNamePage::Reset_Impl( const SfxItemSet& rSet, LanguageGroup eLangGrp )
+{
+ weld::ComboBox* pNameBox = nullptr;
+ weld::Label* pStyleLabel = nullptr;
+ FontStyleBox* pStyleBox = nullptr;
+ weld::Label* pSizeLabel = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ weld::Label* pLangFT = nullptr;
+ SvxLanguageBox* pLangBox = nullptr;
+ sal_uInt16 nWhich = 0;
+
+ switch ( eLangGrp )
+ {
+ case Western :
+ pNameBox = m_xWestFontNameLB.get();
+ pStyleLabel = m_xWestFontStyleFT.get();
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeLabel = m_xWestFontSizeFT.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ pLangFT = m_xWestFontLanguageFT.get();
+ pLangBox = m_xWestFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_FONT );
+ break;
+
+ case Asian :
+ pNameBox = m_xEastFontNameLB.get();
+ pStyleLabel = m_xEastFontStyleFT.get();
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeLabel = m_xEastFontSizeFT.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ pLangFT = m_xEastFontLanguageFT.get();
+ pLangBox = m_xEastFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONT );
+ break;
+
+ case Ctl :
+ pNameBox = m_xCTLFontNameLB.get();
+ pStyleLabel = m_xCTLFontStyleFT.get();
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeLabel = m_xCTLFontSizeFT.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ pLangFT = m_xCTLFontLanguageFT.get();
+ pLangBox = m_xCTLFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONT );
+ break;
+ }
+
+ const FontList* pFontList = GetFontList();
+ FillFontNames(*pNameBox, *pFontList);
+
+ const SvxFontItem* pFontItem = nullptr;
+ SfxItemState eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ pFontItem = static_cast<const SvxFontItem*>(&( rSet.Get( nWhich ) ));
+ const OUString &rName = pFontItem->GetFamilyName();
+ int nIndex = pNameBox->find_text(rName);
+ pNameBox->set_active(nIndex);
+ // tdf#122992 if it didn't exist in the list, set the entry text to it anyway
+ if (nIndex == -1)
+ pNameBox->set_entry_text(rName);
+ }
+ else
+ {
+ pNameBox->set_active_text( OUString() );
+ }
+
+ FillStyleBox_Impl(*pNameBox);
+
+ bool bStyle = false;
+ bool bStyleAvailable = true;
+ FontItalic eItalic = ITALIC_NONE;
+ FontWeight eWeight = WEIGHT_NORMAL;
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_POSTURE ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_POSTURE ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_POSTURE ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(rSet.Get( nWhich ));
+ eItalic = rItem.GetValue();
+ bStyle = true;
+ }
+ bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
+
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_WEIGHT ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_WEIGHT ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_WEIGHT ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(rSet.Get( nWhich ));
+ eWeight = rItem.GetValue();
+ }
+ else
+ bStyle = false;
+ bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
+
+ // currently chosen font
+ if ( bStyle && pFontItem )
+ {
+ FontMetric aFontMetric = pFontList->Get( pFontItem->GetFamilyName(), eWeight, eItalic );
+ pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
+ }
+ else if ( !m_pImpl->m_bInSearchMode || !bStyle )
+ {
+ pStyleBox->set_active_text( OUString() );
+ }
+ else if ( bStyle )
+ {
+ FontMetric aFontMetric = pFontList->Get( OUString(), eWeight, eItalic );
+ pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
+ }
+ if (!bStyleAvailable)
+ {
+ pStyleBox->set_sensitive(false);
+ pStyleLabel->set_sensitive(false);
+ }
+
+ FillSizeBox_Impl(*pNameBox);
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_FONTHEIGHT ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( pSizeBox->IsRelativeMode() )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
+
+ if( rItem.GetProp() != 100 || MapUnit::MapRelative != rItem.GetPropUnit() )
+ {
+ bool bPtRel = MapUnit::MapPoint == rItem.GetPropUnit();
+ pSizeBox->SetPtRelative( bPtRel );
+ pSizeBox->set_value( bPtRel ? static_cast<short>(rItem.GetProp()) * 10 : rItem.GetProp() );
+ }
+ else
+ {
+ pSizeBox->SetRelative(false);
+ pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
+ }
+ }
+ else if ( eState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
+ pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
+ }
+ else
+ {
+ pSizeBox->set_active_or_entry_text(OUString());
+ if ( eState <= SfxItemState::DISABLED )
+ {
+ pSizeBox->set_sensitive(false);
+ pSizeLabel->set_sensitive(false);
+ }
+ }
+
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_LANGUAGE ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_LANGUAGE ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_LANGUAGE ); break;
+ }
+ pLangBox->set_active(-1);
+ eState = rSet.GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ pLangFT->hide();
+ pLangBox->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ pLangFT->set_sensitive(false);
+ pLangBox->set_sensitive(false);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxLanguageItem& rItem = static_cast<const SvxLanguageItem&>(rSet.Get( nWhich ));
+ LanguageType eLangType = rItem.GetValue();
+ DBG_ASSERT( eLangType != LANGUAGE_SYSTEM, "LANGUAGE_SYSTEM not allowed" );
+ if (eLangType != LANGUAGE_DONTKNOW)
+ pLangBox->set_active_id(eLangType);
+ break;
+ }
+ case SfxItemState::DONTCARE:
+ break;
+ }
+
+ OUString sMapText(pFontList->GetFontMapText(
+ pFontList->Get(pNameBox->get_active_text(), pStyleBox->get_active_text())));
+
+ switch (eLangGrp)
+ {
+ case Western:
+ m_xWestFontTypeFT->set_label(sMapText);
+ break;
+ case Asian:
+ m_xEastFontTypeFT->set_label(sMapText);
+ break;
+ case Ctl:
+ m_xCTLFontTypeFT->set_label(sMapText);
+ break;
+ }
+
+ EnableFeatureButton(*pNameBox);
+
+ // save these settings
+ pNameBox->save_value();
+ pStyleBox->save_value();
+ pSizeBox->save_value();
+ pLangBox->save_active_id();
+}
+
+bool SvxCharNamePage::FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp )
+{
+ bool bModified = false;
+
+ weld::ComboBox* pNameBox = nullptr;
+ FontStyleBox* pStyleBox = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ SvxLanguageBox* pLangBox = nullptr;
+ sal_uInt16 nWhich = 0;
+ sal_uInt16 nSlot = 0;
+
+ switch ( eLangGrp )
+ {
+ case Western :
+ pNameBox = m_xWestFontNameLB.get();
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ pLangBox = m_xWestFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_FONT;
+ break;
+
+ case Asian :
+ pNameBox = m_xEastFontNameLB.get();
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ pLangBox = m_xEastFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_CJK_FONT;
+ break;
+
+ case Ctl :
+ pNameBox = m_xCTLFontNameLB.get();
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ pLangBox = m_xCTLFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_CTL_FONT;
+ break;
+ }
+
+ nWhich = GetWhich( nSlot );
+ const SfxPoolItem* pItem = nullptr;
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SfxPoolItem* pOld = nullptr;
+
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+
+ bool bChanged = true;
+ const OUString& rFontName = pNameBox->get_active_text();
+ const FontList* pFontList = GetFontList();
+ OUString aStyleBoxText = pStyleBox->get_active_text();
+ int nEntryPos = pStyleBox->find_text(aStyleBoxText);
+ if (nEntryPos >= m_pImpl->m_nExtraEntryPos)
+ aStyleBoxText.clear();
+ FontMetric aInfo( pFontList->Get( rFontName, aStyleBoxText ) );
+ SvxFontItem aFontItem( aInfo.GetFamilyType(), aInfo.GetFamilyName(), aInfo.GetStyleName(),
+ aInfo.GetPitch(), aInfo.GetCharSet(), nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxFontItem& rItem = *static_cast<const SvxFontItem*>(pOld);
+
+ if ( rItem.GetFamilyName() == aFontItem.GetFamilyName() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ bChanged = pNameBox->get_saved_value().isEmpty();
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxFontItem*>(pItem)->GetFamilyName() != aFontItem.GetFamilyName() )
+ bChanged = true;
+
+ if ( bChanged && !rFontName.isEmpty() )
+ {
+ rSet.Put( aFontItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.ClearItem( nWhich );
+
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_WEIGHT; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_WEIGHT; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_WEIGHT; break;
+ }
+ nWhich = GetWhich( nSlot );
+ FontWeight eWeight = aInfo.GetWeight();
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ eWeight = WEIGHT_NORMAL;
+ SvxWeightItem aWeightItem( eWeight, nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxWeightItem& rItem = *static_cast<const SvxWeightItem*>(pOld);
+
+ if ( rItem.GetValue() == aWeightItem.GetValue() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ {
+ bChanged = pStyleBox->get_saved_value().isEmpty();
+
+ if ( m_pImpl->m_bInSearchMode && bChanged &&
+ aInfo.GetWeight() == WEIGHT_NORMAL && aInfo.GetItalic() != ITALIC_NONE )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxWeightItem*>(pItem)->GetValue() != aWeightItem.GetValue() )
+ bChanged = true;
+
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ bChanged = ( nEntryPos == m_pImpl->m_nExtraEntryPos );
+
+ OUString aText( pStyleBox->get_active_text() ); // Tristate, then text empty
+
+ if ( bChanged && !aText.isEmpty() )
+ {
+ rSet.Put( aWeightItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_POSTURE; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_POSTURE; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_POSTURE; break;
+ }
+ nWhich = GetWhich( nSlot );
+ FontItalic eItalic = aInfo.GetItalic();
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ eItalic = ITALIC_NONE;
+ SvxPostureItem aPostureItem( eItalic, nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxPostureItem& rItem = *static_cast<const SvxPostureItem*>(pOld);
+
+ if ( rItem.GetValue() == aPostureItem.GetValue() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ {
+ bChanged = pStyleBox->get_saved_value().isEmpty();
+
+ if ( m_pImpl->m_bInSearchMode && bChanged &&
+ aInfo.GetItalic() == ITALIC_NONE && aInfo.GetWeight() != WEIGHT_NORMAL )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxPostureItem*>(pItem)->GetValue() != aPostureItem.GetValue() )
+ bChanged = true;
+
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ bChanged = ( nEntryPos == ( m_pImpl->m_nExtraEntryPos + 1 ) );
+
+ if ( bChanged && !aText.isEmpty() )
+ {
+ rSet.Put( aPostureItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ // FontSize
+ tools::Long nSize = pSizeBox->get_value();
+
+ if ( pSizeBox->get_active_text().isEmpty() ) // GetValue() returns the min-value
+ nSize = 0;
+ tools::Long nSavedSize = pSizeBox->get_saved_value();
+ const bool bRel = pSizeBox->IsRelative();
+
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_FONTHEIGHT; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_FONTHEIGHT; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_FONTHEIGHT; break;
+ }
+ nWhich = GetWhich( nSlot );
+ const SvxFontHeightItem* pOldHeight = static_cast<const SvxFontHeightItem*>(GetOldItem( rSet, nSlot ));
+ bChanged = ( nSize != nSavedSize );
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET )
+ {
+ float fSize = static_cast<float>(nSize) / 10;
+ tools::Long nVal = CalcToUnit( fSize, rSet.GetPool()->GetMetric( nWhich ) );
+ if ( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != static_cast<sal_uInt32>(nVal) )
+ bChanged = true;
+ }
+
+ if ( bChanged || !pOldHeight ||
+ bRel != ( MapUnit::MapRelative != pOldHeight->GetPropUnit() || 100 != pOldHeight->GetProp() ) )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ if ( pSizeBox->IsRelative() )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No parent set" );
+ const SvxFontHeightItem& rOldItem =
+ static_cast<const SvxFontHeightItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ SvxFontHeightItem aHeight( 240, 100, nWhich );
+ if ( pSizeBox->IsPtRelative() )
+ aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>( nSize / 10 ), MapUnit::MapPoint, eUnit );
+ else
+ aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>(nSize) );
+ rSet.Put( aHeight );
+ }
+ else
+ {
+ float fSize = static_cast<float>(nSize) / 10;
+ rSet.Put( SvxFontHeightItem( CalcToUnit( fSize, eUnit ), 100, nWhich ) );
+ }
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_LANGUAGE; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_LANGUAGE; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_LANGUAGE; break;
+ }
+ nWhich = GetWhich( nSlot );
+ pOld = GetOldItem( rSet, nSlot );
+
+ // For language list boxes acting as ComboBox, check for, add and select an
+ // edited entry.
+ if (pLangBox == m_xWestFontLanguageLB.get())
+ {
+ switch (pLangBox->GetEditedAndValid())
+ {
+ case SvxLanguageBox::EditedAndValid::No:
+ ; // nothing to do
+ break;
+ case SvxLanguageBox::EditedAndValid::Valid:
+ {
+ const int nPos = pLangBox->SaveEditedAsEntry();
+ if (nPos != -1)
+ pLangBox->set_active(nPos);
+ }
+ break;
+ case SvxLanguageBox::EditedAndValid::Invalid:
+ pLangBox->set_active_id(pLangBox->get_saved_active_id());
+ break;
+ }
+ }
+
+ int nLangPos = pLangBox->get_active();
+ LanguageType eLangType = pLangBox->get_active_id();
+
+ if (pOld)
+ {
+ const SvxLanguageItem& rItem = *static_cast<const SvxLanguageItem*>(pOld);
+ if (nLangPos == -1 || eLangType == rItem.GetValue())
+ bChanged = false;
+ }
+
+ if (!bChanged)
+ bChanged = pLangBox->get_active_id_changed_from_saved();
+
+ if (bChanged && nLangPos != -1)
+ {
+ rSet.Put(SvxLanguageItem(eLangType, nWhich));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+IMPL_LINK_NOARG(SvxCharNamePage, UpdateHdl_Impl, Timer *, void)
+{
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharNamePage, FontModifyComboBoxHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ FontModifyHdl_Impl(rBox);
+}
+
+IMPL_LINK(SvxCharNamePage, FontFeatureButtonClicked, weld::Button&, rButton, void)
+{
+ OUString sFontName;
+ weld::ComboBox* pNameBox = nullptr;
+
+ if (&rButton == m_xWestFontFeaturesButton.get())
+ {
+ pNameBox = m_xWestFontNameLB.get();
+ sFontName = GetPreviewFont().GetFamilyName();
+ }
+ else if (&rButton == m_xEastFontFeaturesButton.get())
+ {
+ pNameBox = m_xEastFontNameLB.get();
+ sFontName = GetPreviewCJKFont().GetFamilyName();
+ }
+ else if (&rButton == m_xCTLFontFeaturesButton.get())
+ {
+ pNameBox = m_xCTLFontNameLB.get();
+ sFontName = GetPreviewCTLFont().GetFamilyName();
+ }
+
+ if (!sFontName.isEmpty() && pNameBox)
+ {
+ cui::FontFeaturesDialog aDialog(GetFrameWeld(), sFontName);
+ if (aDialog.run() == RET_OK)
+ {
+ pNameBox->set_entry_text(aDialog.getResultFontName());
+ UpdatePreview_Impl();
+ }
+ }
+}
+
+void SvxCharNamePage::FontModifyHdl_Impl(const weld::Widget& rNameBox)
+{
+ m_pImpl->m_aUpdateIdle.Start();
+
+ if (m_xWestFontNameLB.get() == &rNameBox || m_xEastFontNameLB.get() == &rNameBox || m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ FillStyleBox_Impl(rNameBox);
+ FillSizeBox_Impl(rNameBox);
+ EnableFeatureButton(rNameBox);
+ }
+}
+
+void SvxCharNamePage::ActivatePage( const SfxItemSet& rSet )
+{
+ SvxCharBasePage::ActivatePage( rSet );
+
+ UpdatePreview_Impl(); // instead of asynchronous calling in ctor
+}
+
+DeactivateRC SvxCharNamePage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharNamePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharNamePage>(pPage, pController, *rSet );
+}
+
+void SvxCharNamePage::Reset( const SfxItemSet* rSet )
+{
+ Reset_Impl( *rSet, Western );
+ Reset_Impl( *rSet, Asian );
+ Reset_Impl( *rSet, Ctl );
+
+ SetPrevFontWidthScale( *rSet );
+ UpdatePreview_Impl();
+}
+
+void SvxCharNamePage::ChangesApplied()
+{
+ m_xWestFontNameLB->save_value();
+ m_xWestFontStyleLB->save_value();
+ m_xWestFontSizeLB->save_value();
+ m_xWestFontLanguageLB->save_active_id();
+ m_xEastFontNameLB->save_value();
+ m_xEastFontStyleLB->save_value();
+ m_xEastFontSizeLB->save_value();
+ m_xEastFontLanguageLB->save_active_id();
+ m_xCTLFontNameLB->save_value();
+ m_xCTLFontStyleLB->save_value();
+ m_xCTLFontSizeLB->save_value();
+ m_xCTLFontLanguageLB->save_active_id();
+}
+
+bool SvxCharNamePage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = FillItemSet_Impl( *rSet, Western );
+ bModified |= FillItemSet_Impl( *rSet, Asian );
+ bModified |= FillItemSet_Impl( *rSet, Ctl );
+ return bModified;
+}
+
+void SvxCharNamePage::SetFontList( const SvxFontListItem& rItem )
+{
+ m_pImpl->m_pFontList = rItem.GetFontList()->Clone();
+}
+
+namespace
+{
+ void enableRelativeMode( SvxCharNamePage const * _pPage, FontSizeBox* _pFontSizeLB, sal_uInt16 _nHeightWhich )
+ {
+ _pFontSizeLB->EnableRelativeMode( 5, 995 ); // min 5%, max 995%, step 5
+
+ const SvxFontHeightItem& rHeightItem =
+ static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nHeightWhich ));
+ MapUnit eUnit = _pPage->GetItemSet().GetPool()->GetMetric( _nHeightWhich );
+ short nCurHeight =
+ static_cast< short >( CalcToPoint( rHeightItem.GetHeight(), eUnit, 1 ) * 10 );
+
+ // based on the current height:
+ // - negative until minimum of 2 pt
+ // - positive until maximum of 999 pt
+ _pFontSizeLB->EnablePtRelativeMode( sal::static_int_cast< short >(-(nCurHeight - 20)), (9999 - nCurHeight) );
+ }
+}
+
+void SvxCharNamePage::EnableRelativeMode()
+{
+ DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no ParentSet!" );
+ enableRelativeMode(this,m_xWestFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_FONTHEIGHT ));
+ enableRelativeMode(this,m_xEastFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ));
+ enableRelativeMode(this,m_xCTLFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ));
+}
+
+void SvxCharNamePage::EnableSearchMode()
+{
+ m_pImpl->m_bInSearchMode = true;
+}
+
+void SvxCharNamePage::DisableControls( sal_uInt16 nDisable )
+{
+ if ( DISABLE_HIDE_LANGUAGE & nDisable )
+ {
+ if ( m_xWestFontLanguageFT ) m_xWestFontLanguageFT->hide();
+ if ( m_xWestFontLanguageLB ) m_xWestFontLanguageLB->hide();
+ if ( m_xEastFontLanguageFT ) m_xEastFontLanguageFT->hide();
+ if ( m_xEastFontLanguageLB ) m_xEastFontLanguageLB->hide();
+ if ( m_xCTLFontLanguageFT ) m_xCTLFontLanguageFT->hide();
+ if ( m_xCTLFontLanguageLB ) m_xCTLFontLanguageLB->hide();
+ }
+}
+
+void SvxCharNamePage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxFontListItem* pFontListItem = aSet.GetItem<SvxFontListItem>(SID_ATTR_CHAR_FONTLIST, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ const SfxUInt16Item* pDisableItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
+ if (pFontListItem)
+ SetFontList(*pFontListItem);
+
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_RELATIVE_MODE ) == SVX_RELATIVE_MODE )
+ EnableRelativeMode();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+ if (pDisableItem)
+ DisableControls(pDisableItem->GetValue());
+}
+// class SvxCharEffectsPage ----------------------------------------------
+
+SvxCharEffectsPage::SvxCharEffectsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/effectspage.ui", "EffectsPage", rInSet)
+ , m_bOrigFontColor(false)
+ , m_bNewFontColor(false)
+ , m_bEnableNoneFontColor(false)
+ , m_xFontColorFT(m_xBuilder->weld_label("fontcolorft"))
+ , m_xFontColorLB(new ColorListBox(m_xBuilder->weld_menu_button("fontcolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xFontTransparencyFT(m_xBuilder->weld_label("fonttransparencyft"))
+ , m_xFontTransparencyMtr(
+ m_xBuilder->weld_metric_spin_button("fonttransparencymtr", FieldUnit::PERCENT))
+ , m_xEffectsFT(m_xBuilder->weld_label("effectsft"))
+ , m_xEffectsLB(m_xBuilder->weld_combo_box("effectslb"))
+ , m_xReliefFT(m_xBuilder->weld_label("reliefft"))
+ , m_xReliefLB(m_xBuilder->weld_combo_box("relieflb"))
+ , m_xOutlineBtn(m_xBuilder->weld_check_button("outlinecb"))
+ , m_xShadowBtn(m_xBuilder->weld_check_button("shadowcb"))
+ , m_xHiddenBtn(m_xBuilder->weld_check_button("hiddencb"))
+ , m_xOverlineLB(m_xBuilder->weld_combo_box("overlinelb"))
+ , m_xOverlineColorFT(m_xBuilder->weld_label("overlinecolorft"))
+ , m_xOverlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("overlinecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xStrikeoutLB(m_xBuilder->weld_combo_box("strikeoutlb"))
+ , m_xUnderlineLB(m_xBuilder->weld_combo_box("underlinelb"))
+ , m_xUnderlineColorFT(m_xBuilder->weld_label("underlinecolorft"))
+ , m_xUnderlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("underlinecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xIndividualWordsBtn(m_xBuilder->weld_check_button("individualwordscb"))
+ , m_xEmphasisFT(m_xBuilder->weld_label("emphasisft"))
+ , m_xEmphasisLB(m_xBuilder->weld_combo_box("emphasislb"))
+ , m_xPositionFT(m_xBuilder->weld_label("positionft"))
+ , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
+ , m_xA11yWarningFT(m_xBuilder->weld_label("a11ywarning"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xOverlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xUnderlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ Initialize();
+}
+
+void SvxCharEffectsPage::EnableNoneFontColor()
+{
+ m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR, true);
+ m_bEnableNoneFontColor = true;
+}
+
+SvxCharEffectsPage::~SvxCharEffectsPage()
+{
+ m_xUnderlineColorLB.reset();
+ m_xOverlineColorLB.reset();
+ m_xFontTransparencyMtr.reset();
+ m_xFontColorLB.reset();
+}
+
+void SvxCharEffectsPage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ // HTML-Mode
+ const SfxUInt16Item* pHtmlModeItem = GetItemSet().GetItemIfSet( SID_HTML_MODE, false );
+ if ( !pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem( SID_HTML_MODE );
+ }
+ if (pHtmlModeItem)
+ {
+ m_nHtmlMode = pHtmlModeItem->GetValue();
+ if ( ( m_nHtmlMode & HTMLMODE_ON ) == HTMLMODE_ON )
+ {
+ //!!! hide some controls please
+ }
+ }
+
+ m_xFontColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xFontTransparencyMtr->connect_value_changed(
+ LINK(this, SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl));
+
+ // handler
+ Link<weld::ComboBox&,void> aLink = LINK( this, SvxCharEffectsPage, SelectListBoxHdl_Impl );
+ m_xUnderlineLB->connect_changed( aLink );
+ m_xUnderlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xOverlineLB->connect_changed( aLink );
+ m_xOverlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xStrikeoutLB->connect_changed( aLink );
+ m_xEmphasisLB->connect_changed( aLink );
+ m_xPositionLB->connect_changed( aLink );
+ m_xEffectsLB->connect_changed( aLink );
+ m_xReliefLB->connect_changed( aLink );
+
+ m_xUnderlineLB->set_active( 0 );
+ m_xOverlineLB->set_active( 0 );
+ m_xStrikeoutLB->set_active( 0 );
+ m_xEmphasisLB->set_active( 0 );
+ m_xPositionLB->set_active( 0 );
+ SelectHdl_Impl(nullptr);
+ SelectHdl_Impl(m_xEmphasisLB.get());
+
+ m_xEffectsLB->set_active( 0 );
+
+ m_xHiddenBtn->connect_toggled(LINK(this, SvxCharEffectsPage, HiddenBtnClickHdl));
+ m_xIndividualWordsBtn->connect_toggled(LINK(this, SvxCharEffectsPage, CbClickHdl_Impl));
+ m_xOutlineBtn->connect_toggled(LINK(this, SvxCharEffectsPage, OutlineBtnClickHdl));
+ m_xShadowBtn->connect_toggled(LINK(this, SvxCharEffectsPage, ShadowBtnClickHdl));
+
+ if ( !SvtCJKOptions::IsAsianTypographyEnabled() )
+ {
+ m_xEmphasisFT->hide();
+ m_xEmphasisLB->hide();
+ m_xPositionFT->hide();
+ m_xPositionLB->hide();
+ }
+
+ m_xA11yWarningFT->set_visible(officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get());
+}
+
+void SvxCharEffectsPage::UpdatePreview_Impl()
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ const Color& rSelectedColor = m_xFontColorLB->GetSelectEntryColor();
+ rFont.SetColor(rSelectedColor);
+ rCJKFont.SetColor(rSelectedColor);
+ rCTLFont.SetColor(rSelectedColor);
+ m_aPreviewWin.AutoCorrectFontColor(); // handle color COL_AUTO
+
+ FontLineStyle eUnderline = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
+ FontLineStyle eOverline = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
+ FontStrikeout eStrikeout = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
+ rFont.SetUnderline( eUnderline );
+ rCJKFont.SetUnderline( eUnderline );
+ rCTLFont.SetUnderline( eUnderline );
+ m_aPreviewWin.SetTextLineColor( m_xUnderlineColorLB->GetSelectEntryColor() );
+ rFont.SetOverline( eOverline );
+ rCJKFont.SetOverline( eOverline );
+ rCTLFont.SetOverline( eOverline );
+ m_aPreviewWin.SetOverlineColor( m_xOverlineColorLB->GetSelectEntryColor() );
+ rFont.SetStrikeout( eStrikeout );
+ rCJKFont.SetStrikeout( eStrikeout );
+ rCTLFont.SetStrikeout( eStrikeout );
+
+ auto nEmphasis = m_xEmphasisLB->get_active();
+ if (nEmphasis != -1)
+ {
+ bool bUnder = (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32());
+ FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nEmphasis);
+ eMark |= bUnder ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
+ rFont.SetEmphasisMark( eMark );
+ rCJKFont.SetEmphasisMark( eMark );
+ rCTLFont.SetEmphasisMark( eMark );
+ }
+
+ auto nRelief = m_xReliefLB->get_active();
+ if (nRelief != -1)
+ {
+ rFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ rCJKFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ rCTLFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ }
+
+ rFont.SetOutline( StateToAttr( m_xOutlineBtn->get_state() ) );
+ rCJKFont.SetOutline( rFont.IsOutline() );
+ rCTLFont.SetOutline( rFont.IsOutline() );
+
+ rFont.SetShadow( StateToAttr( m_xShadowBtn->get_state() ) );
+ rCJKFont.SetShadow( rFont.IsShadow() );
+ rCTLFont.SetShadow( rFont.IsShadow() );
+
+ auto nCapsPos = m_xEffectsLB->get_active();
+ if (nCapsPos != -1)
+ {
+ SvxCaseMap eCaps = static_cast<SvxCaseMap>(nCapsPos);
+ rFont.SetCaseMap( eCaps );
+ rCJKFont.SetCaseMap( eCaps );
+ // #i78474# small caps do not exist in CTL fonts
+ rCTLFont.SetCaseMap( eCaps == SvxCaseMap::SmallCaps ? SvxCaseMap::NotMapped : eCaps );
+ }
+
+ bool bWordLine = StateToAttr( m_xIndividualWordsBtn->get_state() );
+ rFont.SetWordLineMode( bWordLine );
+ rCJKFont.SetWordLineMode( bWordLine );
+ rCTLFont.SetWordLineMode( bWordLine );
+
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharEffectsPage::SetCaseMap_Impl( SvxCaseMap eCaseMap )
+{
+ if ( SvxCaseMap::End > eCaseMap )
+ m_xEffectsLB->set_active(
+ sal::static_int_cast< sal_Int32 >( eCaseMap ) );
+ else
+ {
+ // not mapped
+ m_xEffectsLB->set_active(-1);
+ }
+
+ UpdatePreview_Impl();
+}
+
+void SvxCharEffectsPage::ResetColor_Impl( const SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
+ SfxItemState eState = rSet.GetItemState( nWhich );
+
+ m_bOrigFontColor = false;
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xFontColorFT->hide();
+ m_xFontColorLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_xFontColorFT->set_sensitive(false);
+ m_xFontColorLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ //Related: tdf#106080 if there is no font color, then allow "none"
+ //as a color so the listbox can display that state.
+ EnableNoneFontColor();
+ m_xFontColorLB->SetNoSelection();
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ const SvxColorItem& rItem = static_cast<const SvxColorItem&>(rSet.Get( nWhich ));
+ Color aColor = rItem.GetValue();
+ rFont.SetColor(aColor);
+ rCJKFont.SetColor(aColor);
+ rCTLFont.SetColor(aColor);
+ m_aPreviewWin.AutoCorrectFontColor(); // handle color COL_AUTO
+
+ m_aPreviewWin.Invalidate();
+
+ Color aRGBColor = aColor;
+ if (aRGBColor.IsTransparent() && aColor != COL_AUTO)
+ {
+ aRGBColor.SetAlpha(255);
+ }
+ m_xFontColorLB->SelectEntry(aRGBColor);
+
+ if (m_xFontTransparencyMtr->get_visible() && aColor != COL_AUTO)
+ {
+ double fTransparency = (255 - aColor.GetAlpha()) * 100.0 / 255;
+ m_xFontTransparencyMtr->set_value(basegfx::fround(fTransparency),
+ FieldUnit::PERCENT);
+ }
+
+ m_aOrigFontColor = aColor;
+ m_bOrigFontColor = true;
+ break;
+ }
+ }
+ m_bNewFontColor = false;
+}
+
+bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ svx::NamedThemedColor aSelectedColor;
+ bool bChanged = m_bNewFontColor;
+
+ if (bChanged)
+ {
+ aSelectedColor = m_xFontColorLB->GetSelectedEntryThemedColor();
+
+ if (m_xFontTransparencyMtr->get_value_changed_from_saved())
+ {
+ double fTransparency
+ = m_xFontTransparencyMtr->get_value(FieldUnit::PERCENT) * 255.0 / 100;
+ aSelectedColor.m_aColor.SetAlpha(255 - static_cast<sal_uInt8>(basegfx::fround(fTransparency)));
+ }
+
+ if (m_bOrigFontColor)
+ bChanged = aSelectedColor.m_aColor != m_aOrigFontColor;
+ if (m_bEnableNoneFontColor && bChanged && aSelectedColor.m_aColor == COL_NONE_COLOR)
+ bChanged = false;
+ }
+
+ if (bChanged)
+ {
+ SvxColorItem aItem( aSelectedColor.m_aColor, nWhich );
+
+ if (aSelectedColor.m_nThemeIndex != -1)
+ {
+ // The color was picked from the theme palette, remember its index.
+ aItem.GetThemeColor().SetThemeIndex(aSelectedColor.m_nThemeIndex);
+ aItem.GetThemeColor().SetLumMod(aSelectedColor.m_nLumMod);
+ aItem.GetThemeColor().SetLumOff(aSelectedColor.m_nLumOff);
+ }
+
+ rSet.Put(aItem);
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ return bChanged;
+}
+
+IMPL_LINK( SvxCharEffectsPage, SelectListBoxHdl_Impl, weld::ComboBox&, rBox, void )
+{
+ SelectHdl_Impl(&rBox);
+}
+
+void SvxCharEffectsPage::SelectHdl_Impl(const weld::ComboBox* pBox)
+{
+ if (m_xEmphasisLB.get() == pBox)
+ {
+ auto nEPos = m_xEmphasisLB->get_active();
+ bool bEnable = nEPos > 0;
+ m_xPositionFT->set_sensitive( bEnable );
+ m_xPositionLB->set_sensitive( bEnable );
+ }
+ else if (m_xReliefLB.get() == pBox)
+ {
+ bool bEnable = ( pBox->get_active() == 0 );
+ m_xOutlineBtn->set_sensitive( bEnable );
+ m_xShadowBtn->set_sensitive( bEnable );
+ }
+ else if (m_xPositionLB.get() != pBox)
+ {
+ auto nUPos = m_xUnderlineLB->get_active();
+ bool bUEnable = nUPos > 0;
+ m_xUnderlineColorFT->set_sensitive(bUEnable);
+ m_xUnderlineColorLB->set_sensitive(bUEnable);
+
+ auto nOPos = m_xOverlineLB->get_active();
+ bool bOEnable = nOPos > 0;
+ m_xOverlineColorFT->set_sensitive(bOEnable);
+ m_xOverlineColorLB->set_sensitive(bOEnable);
+
+ auto nSPos = m_xStrikeoutLB->get_active();
+ m_xIndividualWordsBtn->set_sensitive( bUEnable || bOEnable || nSPos > 0);
+ }
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, CbClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ m_aIndividualWordsState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ColorBoxSelectHdl_Impl, ColorListBox&, rBox, void)
+{
+ if (m_xFontColorLB.get() == &rBox)
+ m_bNewFontColor = true;
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK_NOARG(SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ m_bNewFontColor = true;
+}
+
+DeactivateRC SvxCharEffectsPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharEffectsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxCharEffectsPage>( pPage, pController, *rSet );
+}
+
+void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ bool bEnable = false;
+
+ // Underline
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
+ rFont.SetUnderline( LINESTYLE_NONE );
+ rCJKFont.SetUnderline( LINESTYLE_NONE );
+ rCTLFont.SetUnderline( LINESTYLE_NONE );
+
+ m_xUnderlineLB->set_active( 0 );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xUnderlineLB->set_active(-1);
+ else
+ {
+ const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(rSet->Get( nWhich ));
+ FontLineStyle eUnderline = rItem.GetValue();
+ rFont.SetUnderline( eUnderline );
+ rCJKFont.SetUnderline( eUnderline );
+ rCTLFont.SetUnderline( eUnderline );
+
+ if ( eUnderline != LINESTYLE_NONE )
+ {
+ auto nPos = m_xUnderlineLB->find_id(OUString::number(eUnderline));
+ if (nPos != -1)
+ {
+ m_xUnderlineLB->set_active(nPos);
+ bEnable = true;
+ }
+ Color aColor = rItem.GetColor();
+ m_xUnderlineColorLB->SelectEntry(aColor);
+ }
+ else
+ {
+ m_xUnderlineColorLB->SelectEntry(COL_AUTO);
+ m_xUnderlineColorLB->set_sensitive(false);
+ }
+ }
+ }
+
+ // Overline
+ nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
+ rFont.SetOverline( LINESTYLE_NONE );
+ rCJKFont.SetOverline( LINESTYLE_NONE );
+ rCTLFont.SetOverline( LINESTYLE_NONE );
+
+ m_xOverlineLB->set_active( 0 );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xOverlineLB->set_active(-1);
+ else
+ {
+ const SvxOverlineItem& rItem = static_cast<const SvxOverlineItem&>(rSet->Get( nWhich ));
+ FontLineStyle eOverline = rItem.GetValue();
+ rFont.SetOverline( eOverline );
+ rCJKFont.SetOverline( eOverline );
+ rCTLFont.SetOverline( eOverline );
+
+ if ( eOverline != LINESTYLE_NONE )
+ {
+ auto nPos = m_xOverlineLB->find_id(OUString::number(eOverline));
+ if (nPos != -1)
+ {
+ m_xOverlineLB->set_active(nPos);
+ bEnable = true;
+ }
+ Color aColor = rItem.GetColor();
+ m_xOverlineColorLB->SelectEntry(aColor);
+ }
+ else
+ {
+ m_xOverlineColorLB->SelectEntry(COL_AUTO);
+ m_xOverlineColorLB->set_sensitive(false);
+ }
+ }
+ }
+
+ // Strikeout
+ nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ rCJKFont.SetStrikeout( STRIKEOUT_NONE );
+ rCTLFont.SetStrikeout( STRIKEOUT_NONE );
+
+ m_xStrikeoutLB->set_active( 0 );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xStrikeoutLB->set_active(-1);
+ else
+ {
+ const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>(rSet->Get( nWhich ));
+ FontStrikeout eStrikeout = rItem.GetValue();
+ rFont.SetStrikeout( eStrikeout );
+ rCJKFont.SetStrikeout( eStrikeout );
+ rCTLFont.SetStrikeout( eStrikeout );
+
+ if ( eStrikeout != STRIKEOUT_NONE )
+ {
+ auto nPos = m_xStrikeoutLB->find_id(OUString::number(eStrikeout));
+ if (nPos != -1)
+ {
+ m_xStrikeoutLB->set_active(nPos);
+ bEnable = true;
+ }
+ }
+ }
+ }
+
+ // WordLineMode
+ nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aIndividualWordsState.bTriStateEnabled = true;
+ m_xIndividualWordsBtn->set_state( TRISTATE_INDET );
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxWordLineModeItem& rItem = static_cast<const SvxWordLineModeItem&>(rSet->Get( nWhich ));
+ rFont.SetWordLineMode( rItem.GetValue() );
+ rCJKFont.SetWordLineMode( rItem.GetValue() );
+ rCTLFont.SetWordLineMode( rItem.GetValue() );
+
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->set_active(rItem.GetValue());
+ m_xIndividualWordsBtn->set_sensitive(bEnable);
+ break;
+ }
+ }
+
+ // Emphasis
+ nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxEmphasisMarkItem& rItem = static_cast<const SvxEmphasisMarkItem&>(rSet->Get( nWhich ));
+ FontEmphasisMark eMark = rItem.GetEmphasisMark();
+ rFont.SetEmphasisMark( eMark );
+ rCJKFont.SetEmphasisMark( eMark );
+ rCTLFont.SetEmphasisMark( eMark );
+
+ m_xEmphasisLB->set_active( static_cast<sal_Int32>(FontEmphasisMark( eMark & FontEmphasisMark::Style )) );
+ eMark &= ~FontEmphasisMark::Style;
+ int nEntryData = ( eMark == FontEmphasisMark::PosAbove )
+ ? CHRDLG_POSITION_OVER
+ : ( eMark == FontEmphasisMark::PosBelow ) ? CHRDLG_POSITION_UNDER : 0;
+
+ auto nPos = m_xPositionLB->find_id(OUString::number(nEntryData));
+ if (nPos != -1)
+ m_xPositionLB->set_active(nPos);
+ }
+ else if ( eState == SfxItemState::DONTCARE )
+ m_xEmphasisLB->set_active(-1);
+ else if ( eState == SfxItemState::UNKNOWN )
+ {
+ m_xEmphasisFT->hide();
+ m_xEmphasisLB->hide();
+ }
+ else // SfxItemState::DISABLED
+ {
+ m_xEmphasisFT->set_sensitive(false);
+ m_xEmphasisLB->set_sensitive(false);
+ }
+
+ // the select handler for the underline/overline/strikeout list boxes
+ SelectHdl_Impl(m_xUnderlineLB.get());
+
+ // the select handler for the emphasis listbox
+ SelectHdl_Impl(m_xEmphasisLB.get());
+
+ // Effects
+ SvxCaseMap eCaseMap = SvxCaseMap::End;
+ nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xEffectsFT->hide();
+ m_xEffectsLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_xEffectsFT->set_sensitive(false);
+ m_xEffectsLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_xEffectsLB->set_active(-1);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCaseMapItem& rItem = static_cast<const SvxCaseMapItem&>(rSet->Get( nWhich ));
+ eCaseMap = rItem.GetValue();
+ break;
+ }
+ }
+ SetCaseMap_Impl( eCaseMap );
+
+ //Relief
+ nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xReliefFT->hide();
+ m_xReliefLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_xReliefFT->set_sensitive(false);
+ m_xReliefLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_xReliefLB->set_active(-1);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCharReliefItem& rItem = static_cast<const SvxCharReliefItem&>(rSet->Get( nWhich ));
+ m_xReliefLB->set_active(static_cast<sal_Int32>(rItem.GetValue()));
+ SelectHdl_Impl(m_xReliefLB.get());
+ break;
+ }
+ }
+
+ // Outline
+ nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aOutlineState.bTriStateEnabled = true;
+ m_xOutlineBtn->set_state(TRISTATE_INDET);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxContourItem& rItem = static_cast<const SvxContourItem&>(rSet->Get( nWhich ));
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->set_state(static_cast<TriState>(rItem.GetValue()));
+ break;
+ }
+ }
+
+ // Shadow
+ nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aShadowState.bTriStateEnabled = true;
+ m_xShadowBtn->set_state( TRISTATE_INDET );
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxShadowedItem& rItem = static_cast<const SvxShadowedItem&>(rSet->Get( nWhich ));
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
+ break;
+ }
+ }
+
+ // Hidden
+ nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aHiddenState.bTriStateEnabled = true;
+ m_xHiddenBtn->set_state(TRISTATE_INDET);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCharHiddenItem& rItem = static_cast<const SvxCharHiddenItem&>(rSet->Get( nWhich ));
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->set_state(static_cast<TriState>(rItem.GetValue()));
+ break;
+ }
+ }
+
+ SetPrevFontWidthScale( *rSet );
+ ResetColor_Impl( *rSet );
+
+ // preview update
+ m_aPreviewWin.Invalidate();
+
+ // save this settings
+ ChangesApplied();
+}
+
+IMPL_LINK(SvxCharEffectsPage, HiddenBtnClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aHiddenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(SvxCharEffectsPage, OutlineBtnClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aOutlineState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ShadowBtnClickHdl, weld::Toggleable&, rToggle, void)
+{
+ m_aShadowState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+void SvxCharEffectsPage::ChangesApplied()
+{
+ m_xUnderlineLB->save_value();
+ m_xOverlineLB->save_value();
+ m_xStrikeoutLB->save_value();
+ m_xIndividualWordsBtn->save_state();
+ m_xEmphasisLB->save_value();
+ m_xPositionLB->save_value();
+ m_xEffectsLB->save_value();
+ m_xReliefLB->save_value();
+ m_xOutlineBtn->save_state();
+ m_xShadowBtn->save_state();
+ m_xHiddenBtn->save_state();
+ m_xFontTransparencyMtr->save_value();
+}
+
+bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxPoolItem* pOld = nullptr;
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false;
+ bool bChanged = true;
+
+ // Underline
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_UNDERLINE );
+ auto nPos = m_xUnderlineLB->get_active();
+ FontLineStyle eUnder = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different underline styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the underline style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxUnderlineItem& rItem = *static_cast<const SvxUnderlineItem*>(pOld);
+ if ( rItem.GetValue() == eUnder &&
+ ( LINESTYLE_NONE == eUnder || rItem.GetColor() == m_xUnderlineColorLB->GetSelectEntryColor() ) &&
+ ! bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ SvxUnderlineItem aNewItem( eUnder, nWhich );
+ aNewItem.SetColor( m_xUnderlineColorLB->GetSelectEntryColor() );
+ rSet->Put( aNewItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Overline
+ nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_OVERLINE );
+ nPos = m_xOverlineLB->get_active();
+ FontLineStyle eOver = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different underline styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the underline style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxOverlineItem& rItem = *static_cast<const SvxOverlineItem*>(pOld);
+ if ( rItem.GetValue() == eOver &&
+ ( LINESTYLE_NONE == eOver || rItem.GetColor() == m_xOverlineColorLB->GetSelectEntryColor() ) &&
+ ! bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ SvxOverlineItem aNewItem( eOver, nWhich );
+ aNewItem.SetColor( m_xOverlineColorLB->GetSelectEntryColor() );
+ rSet->Put( aNewItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Strikeout
+ nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_STRIKEOUT );
+ nPos = m_xStrikeoutLB->get_active();
+ FontStrikeout eStrike = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different strikeout styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the strikeout style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxCrossedOutItem& rItem = *static_cast<const SvxCrossedOutItem*>(pOld);
+ if ( !m_xStrikeoutLB->get_sensitive()
+ || (rItem.GetValue() == eStrike && !bAllowChg) )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxCrossedOutItem( eStrike, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Individual words
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_WORDLINEMODE );
+ TriState eState = m_xIndividualWordsBtn->get_state();
+ const SfxPoolItem* pItem;
+
+ if ( pOld )
+ {
+ const SvxWordLineModeItem& rItem = *static_cast<const SvxWordLineModeItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xIndividualWordsBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxWordLineModeItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxWordLineModeItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Emphasis
+ nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_EMPHASISMARK );
+ int nMarkPos = m_xEmphasisLB->get_active();
+ OUString sMarkPos = m_xEmphasisLB->get_active_text();
+ OUString sPosPos = m_xPositionLB->get_active_text();
+ FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nMarkPos);
+ if (m_xPositionLB->get_sensitive())
+ {
+ eMark |= (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32())
+ ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
+ }
+
+ if ( pOld )
+ {
+ if( rOldSet.GetItemState( nWhich ) != SfxItemState::DONTCARE )
+ {
+ const SvxEmphasisMarkItem& rItem = *static_cast<const SvxEmphasisMarkItem*>(pOld);
+ if ( rItem.GetEmphasisMark() == eMark )
+ bChanged = false;
+ }
+ }
+
+ if (rOldSet.GetItemState( nWhich ) == SfxItemState::DONTCARE &&
+ m_xEmphasisLB->get_saved_value() == sMarkPos && m_xPositionLB->get_saved_value() == sPosPos)
+ {
+ bChanged = false;
+ }
+
+ if (bChanged)
+ {
+ rSet->Put( SvxEmphasisMarkItem( eMark, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Effects
+ nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CASEMAP );
+ SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
+ bool bChecked = false;
+ auto nCapsPos = m_xEffectsLB->get_active();
+ if (nCapsPos != -1)
+ {
+ eCaseMap = static_cast<SvxCaseMap>(nCapsPos);
+ bChecked = true;
+ }
+
+ if ( pOld )
+ {
+ //! if there are different effect styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the effect style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxCaseMapItem& rItem = *static_cast<const SvxCaseMapItem*>(pOld);
+ if ( rItem.GetValue() == eCaseMap && !bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged && bChecked )
+ {
+ rSet->Put( SvxCaseMapItem( eCaseMap, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ //Relief
+ nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
+ if (m_xReliefLB->get_value_changed_from_saved())
+ {
+ m_xReliefLB->save_value();
+ SvxCharReliefItem aRelief(static_cast<FontRelief>(m_xReliefLB->get_active()), nWhich);
+ rSet->Put(aRelief);
+ }
+
+ // Outline
+ nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CONTOUR );
+ eState = m_xOutlineBtn->get_state();
+
+ if ( pOld )
+ {
+ const SvxContourItem& rItem = *static_cast<const SvxContourItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xOutlineBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxContourItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxContourItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Shadow
+ nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_SHADOWED );
+ eState = m_xShadowBtn->get_state();
+
+ if ( pOld )
+ {
+ const SvxShadowedItem& rItem = *static_cast<const SvxShadowedItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xShadowBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxShadowedItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxShadowedItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Hidden
+ nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_HIDDEN );
+ eState = m_xHiddenBtn->get_state();
+ bChanged = true;
+
+ if ( pOld )
+ {
+ const SvxCharHiddenItem& rItem = *static_cast<const SvxCharHiddenItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xHiddenBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxCharHiddenItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxCharHiddenItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bModified |= FillItemSetColor_Impl( *rSet );
+
+ return bModified;
+}
+
+void SvxCharEffectsPage::DisableControls( sal_uInt16 nDisable )
+{
+ if ( ( DISABLE_CASEMAP & nDisable ) == DISABLE_CASEMAP )
+ {
+ m_xEffectsFT->set_sensitive(false);
+ m_xEffectsLB->set_sensitive(false);
+ }
+}
+
+void SvxCharEffectsPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pDisableCtlItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pDisableCtlItem)
+ DisableControls(pDisableCtlItem->GetValue());
+
+ if (!pFlagItem)
+ return;
+
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ if ((nFlags & SVX_ENABLE_CHAR_TRANSPARENCY) != SVX_ENABLE_CHAR_TRANSPARENCY)
+ {
+ // Only show these in case client code explicitly wants this.
+ m_xFontTransparencyFT->hide();
+ m_xFontTransparencyMtr->hide();
+ }
+}
+
+// class SvxCharPositionPage ---------------------------------------------
+
+SvxCharPositionPage::SvxCharPositionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/positionpage.ui", "PositionPage", rInSet)
+ , m_nSuperEsc(short(DFLT_ESC_SUPER))
+ , m_nSubEsc(short(DFLT_ESC_SUB))
+ , m_nScaleWidthItemSetVal(100)
+ , m_nScaleWidthInitialVal(100)
+ , m_nSuperProp(sal_uInt8(DFLT_ESC_PROP))
+ , m_nSubProp(sal_uInt8(DFLT_ESC_PROP))
+ , m_xHighPosBtn(m_xBuilder->weld_radio_button("superscript"))
+ , m_xNormalPosBtn(m_xBuilder->weld_radio_button("normal"))
+ , m_xLowPosBtn(m_xBuilder->weld_radio_button("subscript"))
+ , m_xHighLowFT(m_xBuilder->weld_label("raiselower"))
+ , m_xHighLowMF(m_xBuilder->weld_metric_spin_button("raiselowersb", FieldUnit::PERCENT))
+ , m_xHighLowRB(m_xBuilder->weld_check_button("automatic"))
+ , m_xFontSizeFT(m_xBuilder->weld_label("relativefontsize"))
+ , m_xFontSizeMF(m_xBuilder->weld_metric_spin_button("fontsizesb", FieldUnit::PERCENT))
+ , m_xRotationContainer(m_xBuilder->weld_widget("rotationcontainer"))
+ , m_xScalingFT(m_xBuilder->weld_label("scale"))
+ , m_xScalingAndRotationFT(m_xBuilder->weld_label("rotateandscale"))
+ , m_x0degRB(m_xBuilder->weld_radio_button("0deg"))
+ , m_x90degRB(m_xBuilder->weld_radio_button("90deg"))
+ , m_x270degRB(m_xBuilder->weld_radio_button("270deg"))
+ , m_xFitToLineCB(m_xBuilder->weld_check_button("fittoline"))
+ , m_xScaleWidthMF(m_xBuilder->weld_metric_spin_button("scalewidthsb", FieldUnit::PERCENT))
+ , m_xKerningMF(m_xBuilder->weld_metric_spin_button("kerningsb", FieldUnit::POINT))
+ , m_xPairKerningBtn(m_xBuilder->weld_check_button("pairkerning"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ Initialize();
+}
+
+SvxCharPositionPage::~SvxCharPositionPage()
+{
+}
+
+
+void SvxCharPositionPage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ GetPreviewFont().SetFontSize( Size( 0, 240 ) );
+ GetPreviewCJKFont().SetFontSize( Size( 0, 240 ) );
+ GetPreviewCTLFont().SetFontSize( Size( 0, 240 ) );
+
+ m_xNormalPosBtn->set_active(true);
+ PositionHdl_Impl(*m_xNormalPosBtn);
+
+ Link<weld::Toggleable&,void> aLink2 = LINK(this, SvxCharPositionPage, PositionHdl_Impl);
+ m_xHighPosBtn->connect_toggled(aLink2);
+ m_xNormalPosBtn->connect_toggled(aLink2);
+ m_xLowPosBtn->connect_toggled(aLink2);
+
+ aLink2 = LINK( this, SvxCharPositionPage, RotationHdl_Impl );
+ m_x0degRB->connect_toggled(aLink2);
+ m_x90degRB->connect_toggled(aLink2);
+ m_x270degRB->connect_toggled(aLink2);
+
+ Link<weld::MetricSpinButton&,void> aLink3 = LINK(this, SvxCharPositionPage, ValueChangedHdl_Impl);
+ m_xHighLowMF->connect_value_changed(aLink3);
+ m_xFontSizeMF->connect_value_changed(aLink3);
+
+ m_xHighLowRB->connect_toggled(LINK(this, SvxCharPositionPage, AutoPositionHdl_Impl));
+ m_xFitToLineCB->connect_toggled(LINK(this, SvxCharPositionPage, FitToLineHdl_Impl));
+ m_xKerningMF->connect_value_changed(LINK(this, SvxCharPositionPage, KerningModifyHdl_Impl));
+ m_xScaleWidthMF->connect_value_changed(LINK(this, SvxCharPositionPage, ScaleWidthModifyHdl_Impl));
+}
+
+void SvxCharPositionPage::UpdatePreview_Impl( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+{
+ SetPrevFontEscapement( nProp, nEscProp, nEsc );
+}
+
+
+void SvxCharPositionPage::SetEscapement_Impl( SvxEscapement nEsc )
+{
+ SvxEscapementItem aEscItm( nEsc, SID_ATTR_CHAR_ESCAPEMENT );
+
+ if ( SvxEscapement::Superscript == nEsc )
+ {
+ aEscItm.GetEsc() = m_nSuperEsc;
+ aEscItm.GetProportionalHeight() = m_nSuperProp;
+ }
+ else if ( SvxEscapement::Subscript == nEsc )
+ {
+ aEscItm.GetEsc() = m_nSubEsc;
+ aEscItm.GetProportionalHeight() = m_nSubProp;
+ }
+
+ short nFac = aEscItm.GetEsc() < 0 ? -1 : 1;
+
+ m_xHighLowMF->set_value(aEscItm.GetEsc() * nFac, FieldUnit::PERCENT);
+ m_xFontSizeMF->set_value(aEscItm.GetProportionalHeight(), FieldUnit::PERCENT);
+
+ if ( SvxEscapement::Off == nEsc )
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ m_xFontSizeFT->set_sensitive(false);
+ m_xFontSizeMF->set_sensitive(false);
+ m_xHighLowRB->set_sensitive(false);
+ }
+ else
+ {
+ m_xFontSizeFT->set_sensitive(true);
+ m_xFontSizeMF->set_sensitive(true);
+ m_xHighLowRB->set_sensitive(true);
+
+ if (!m_xHighLowRB->get_active())
+ {
+ m_xHighLowFT->set_sensitive(true);
+ m_xHighLowMF->set_sensitive(true);
+ }
+ else
+ AutoPositionHdl_Impl(*m_xHighLowRB);
+ }
+
+ UpdatePreview_Impl( 100, aEscItm.GetProportionalHeight(), aEscItm.GetEsc() );
+}
+
+
+IMPL_LINK_NOARG(SvxCharPositionPage, PositionHdl_Impl, weld::Toggleable&, void)
+{
+ SvxEscapement nEsc = SvxEscapement::Off; // also when pBtn == NULL
+
+ if (m_xHighPosBtn->get_active())
+ nEsc = SvxEscapement::Superscript;
+ else if (m_xLowPosBtn->get_active())
+ nEsc = SvxEscapement::Subscript;
+
+ SetEscapement_Impl( nEsc );
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, RotationHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnable = false;
+ if (m_x90degRB->get_active() || m_x270degRB->get_active())
+ bEnable = true;
+ else
+ OSL_ENSURE(m_x0degRB->get_active(), "unexpected button");
+ m_xFitToLineCB->set_sensitive(bEnable);
+}
+
+void SvxCharPositionPage::FontModifyHdl_Impl()
+{
+ sal_uInt8 nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ short nEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
+ nEsc *= m_xLowPosBtn->get_active() ? -1 : 1;
+ UpdatePreview_Impl( 100, nEscProp, nEsc );
+}
+
+IMPL_LINK(SvxCharPositionPage, AutoPositionHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ }
+ else
+ PositionHdl_Impl(m_xHighPosBtn->get_active() ? *m_xHighPosBtn
+ : m_xLowPosBtn->get_active() ? *m_xLowPosBtn
+ : *m_xNormalPosBtn);
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, FitToLineHdl_Impl, weld::Toggleable&, void)
+{
+ sal_uInt16 nVal = m_nScaleWidthInitialVal;
+ if (m_xFitToLineCB->get_active())
+ nVal = m_nScaleWidthItemSetVal;
+ m_xScaleWidthMF->set_value(nVal, FieldUnit::PERCENT);
+ m_aPreviewWin.SetFontWidthScale( nVal );
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, KerningModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ tools::Long nVal = static_cast<tools::Long>(m_xKerningMF->get_value(FieldUnit::POINT));
+ nVal = o3tl::convert(nVal, o3tl::Length::pt, o3tl::Length::twip);
+
+ tools::Long nKern = static_cast<short>(m_xKerningMF->denormalize(nVal));
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ rFont.SetFixKerning( static_cast<short>(nKern) );
+ rCJKFont.SetFixKerning( static_cast<short>(nKern) );
+ rCTLFont.SetFixKerning( static_cast<short>(nKern) );
+ m_aPreviewWin.Invalidate();
+}
+
+IMPL_LINK(SvxCharPositionPage, ValueChangedHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bHigh = m_xHighPosBtn->get_active();
+ bool bLow = m_xLowPosBtn->get_active();
+ DBG_ASSERT( bHigh || bLow, "normal position is not valid" );
+
+ if (m_xHighLowMF.get() == &rField)
+ {
+ if ( bLow )
+ m_nSubEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT)) * -1;
+ else
+ m_nSuperEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
+ }
+ else if (m_xFontSizeMF.get() == &rField)
+ {
+ if ( bLow )
+ m_nSubProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ else
+ m_nSuperProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ }
+
+ FontModifyHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, ScaleWidthModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ m_aPreviewWin.SetFontWidthScale(sal_uInt16(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)));
+}
+
+DeactivateRC SvxCharPositionPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharPositionPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharPositionPage>(pPage, pController, *rSet);
+}
+
+void SvxCharPositionPage::Reset( const SfxItemSet* rSet )
+{
+ OUString sUser = GetUserData();
+
+ if ( !sUser.isEmpty() )
+ {
+ sal_Int32 nIdx {0};
+ m_nSuperEsc = static_cast<short>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+ m_nSubEsc = static_cast<short>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+ m_nSuperProp = static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+ m_nSubProp = static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(sUser, 0, ';', nIdx )));
+
+ m_xHighLowMF->set_max(MAX_ESC_POS, FieldUnit::PERCENT);
+
+ //fdo#75307 validate all the entries and discard all of them if any are
+ //out of range
+ bool bValid = true;
+ if (m_nSuperEsc < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSuperEsc > m_xHighLowMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSubEsc*-1 < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSubEsc*-1 > m_xHighLowMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSuperProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSuperProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSubProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSubProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+
+ if (!bValid)
+ {
+ m_nSuperEsc = DFLT_ESC_SUPER;
+ m_nSubEsc = DFLT_ESC_SUB;
+ m_nSuperProp = DFLT_ESC_PROP;
+ m_nSubProp = DFLT_ESC_PROP;
+ }
+ }
+
+ short nEsc = 0;
+ sal_uInt8 nEscProp = 100;
+
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ m_xFontSizeFT->set_sensitive(false);
+ m_xFontSizeMF->set_sensitive(false);
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxEscapementItem& rItem = static_cast<const SvxEscapementItem&>(rSet->Get( nWhich ));
+ nEsc = rItem.GetEsc();
+ nEscProp = rItem.GetProportionalHeight();
+
+ if ( nEsc != 0 )
+ {
+ m_xHighLowFT->set_sensitive(true);
+ m_xHighLowMF->set_sensitive(true);
+ m_xFontSizeFT->set_sensitive(true);
+ m_xFontSizeMF->set_sensitive(true);
+
+ short nFac;
+ bool bAutomatic(false);
+
+ if ( nEsc > 0 )
+ {
+ nFac = 1;
+ m_xHighPosBtn->set_active(true);
+ if ( nEsc == DFLT_ESC_AUTO_SUPER )
+ {
+ nEsc = .8 * (100 - nEscProp); //approximation of actual percentage used
+ bAutomatic = true;
+ }
+ }
+ else
+ {
+ nFac = -1;
+ m_xLowPosBtn->set_active(true);
+ if ( nEsc == DFLT_ESC_AUTO_SUB )
+ {
+ nEsc = .2 * -(100 - nEscProp); //approximation of actual percentage used
+ bAutomatic = true;
+ }
+ }
+ if (!m_xHighLowRB->get_sensitive())
+ {
+ m_xHighLowRB->set_sensitive(true);
+ }
+ m_xHighLowRB->set_active(bAutomatic);
+
+ if (m_xHighLowRB->get_active())
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ }
+ m_xHighLowMF->set_value(m_xHighLowMF->normalize(nFac * nEsc), FieldUnit::PERCENT);
+ }
+ else
+ {
+ m_xNormalPosBtn->set_active(true);
+ m_xHighLowRB->set_active(true);
+ PositionHdl_Impl(*m_xNormalPosBtn);
+ }
+ //the height has to be set after the handler is called to keep the value also if the escapement is zero
+ m_xFontSizeMF->set_value(m_xFontSizeMF->normalize(nEscProp), FieldUnit::PERCENT);
+ }
+ else
+ {
+ m_xHighPosBtn->set_active(false);
+ m_xNormalPosBtn->set_active(false);
+ m_xLowPosBtn->set_active(false);
+ }
+
+ // set BspFont
+ SetPrevFontEscapement( 100, nEscProp, nEsc );
+
+ // Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxKerningItem& rItem = static_cast<const SvxKerningItem&>(rSet->Get( nWhich ));
+ MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
+ tools::Long nBig = static_cast<tools::Long>(m_xKerningMF->normalize( static_cast<tools::Long>(rItem.GetValue()) ));
+ tools::Long nKerning = OutputDevice::LogicToLogic(nBig, eUnit, MapUnit::MapPoint);
+
+ // set Kerning at the Font, convert into Twips before
+ tools::Long nKern = OutputDevice::LogicToLogic(rItem.GetValue(), eUnit, MapUnit::MapTwip);
+ rFont.SetFixKerning( static_cast<short>(nKern) );
+ rCJKFont.SetFixKerning( static_cast<short>(nKern) );
+ rCTLFont.SetFixKerning( static_cast<short>(nKern) );
+
+ //the attribute value must be displayed also if it's above/below the maximum allowed value
+ tools::Long nVal = static_cast<tools::Long>(m_xKerningMF->get_max(FieldUnit::POINT));
+ if(nVal < nKerning)
+ m_xKerningMF->set_max(nKerning, FieldUnit::POINT);
+ nVal = static_cast<tools::Long>(m_xKerningMF->get_min(FieldUnit::POINT));
+ if (nVal > nKerning)
+ m_xKerningMF->set_min(nKerning, FieldUnit::POINT);
+ m_xKerningMF->set_value(nKerning, FieldUnit::POINT);
+ }
+ else
+ m_xKerningMF->set_text(OUString());
+
+ // Pair kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxAutoKernItem& rItem = static_cast<const SvxAutoKernItem&>(rSet->Get( nWhich ));
+ m_xPairKerningBtn->set_active(rItem.GetValue());
+ }
+ else
+ m_xPairKerningBtn->set_active(false);
+
+ // Scale Width
+ nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxCharScaleWidthItem& rItem = static_cast<const SvxCharScaleWidthItem&>( rSet->Get( nWhich ) );
+ m_nScaleWidthInitialVal = rItem.GetValue();
+ m_xScaleWidthMF->set_value(m_nScaleWidthInitialVal, FieldUnit::PERCENT);
+ }
+ else
+ m_xScaleWidthMF->set_value(100, FieldUnit::PERCENT);
+
+ if ( rSet->GetItemState( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ) >= SfxItemState::DEFAULT )
+ m_nScaleWidthItemSetVal = static_cast<const SfxUInt16Item&>( rSet->Get( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE )).GetValue();
+
+ // Rotation
+ nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+ if( SfxItemState::UNKNOWN == eState )
+ {
+ m_xRotationContainer->hide();
+ m_xScalingAndRotationFT->hide();
+ m_xScalingFT->show();
+ }
+ else
+ {
+ m_xRotationContainer->show();
+ m_xScalingAndRotationFT->show();
+ m_xScalingFT->hide();
+
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxCharRotateItem& rItem =
+ static_cast<const SvxCharRotateItem&>( rSet->Get( nWhich ));
+ if (rItem.IsBottomToTop())
+ m_x90degRB->set_active(true);
+ else if (rItem.IsTopToBottom())
+ m_x270degRB->set_active(true);
+ else
+ {
+ DBG_ASSERT( 0_deg10 == rItem.GetValue(), "incorrect value" );
+ m_x0degRB->set_active(true);
+ }
+ m_xFitToLineCB->set_active(rItem.IsFitToLine());
+ }
+ else
+ {
+ if( eState == SfxItemState::DONTCARE )
+ {
+ m_x0degRB->set_active(false);
+ m_x90degRB->set_active(false);
+ m_x270degRB->set_active(false);
+ }
+ else
+ m_x0degRB->set_active(true);
+
+ m_xFitToLineCB->set_active(false);
+ }
+ m_xFitToLineCB->set_sensitive(!m_x0degRB->get_active());
+
+ // is this value set?
+ if( SfxItemState::UNKNOWN == rSet->GetItemState(
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ))
+ m_xFitToLineCB->hide();
+ }
+ ChangesApplied();
+}
+
+void SvxCharPositionPage::ChangesApplied()
+{
+ m_xHighPosBtn->save_state();
+ m_xNormalPosBtn->save_state();
+ m_xLowPosBtn->save_state();
+ m_xHighLowRB->save_state();
+ m_x0degRB->save_state();
+ m_x90degRB->save_state();
+ m_x270degRB->save_state();
+ m_xFitToLineCB->save_state();
+ m_xScaleWidthMF->save_value();
+ m_xKerningMF->save_value();
+ m_xPairKerningBtn->save_state();
+}
+
+bool SvxCharPositionPage::FillItemSet( SfxItemSet* rSet )
+{
+ // Position (high, normal or low)
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false, bChanged = true;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
+ const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_ESCAPEMENT );
+ const bool bHigh = m_xHighPosBtn->get_active();
+ short nEsc;
+ sal_uInt8 nEscProp;
+
+ if (bHigh || m_xLowPosBtn->get_active())
+ {
+ if (m_xHighLowRB->get_active())
+ nEsc = bHigh ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
+ else
+ {
+ nEsc = static_cast<short>(m_xHighLowMF->denormalize(m_xHighLowMF->get_value(FieldUnit::PERCENT)));
+ nEsc *= (bHigh ? 1 : -1);
+ }
+ nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->denormalize(m_xFontSizeMF->get_value(FieldUnit::PERCENT)));
+ }
+ else
+ {
+ nEsc = 0;
+ nEscProp = 100;
+ }
+
+ if ( pOld )
+ {
+ const SvxEscapementItem& rItem = *static_cast<const SvxEscapementItem*>(pOld);
+ if (rItem.GetEsc() == nEsc && rItem.GetProportionalHeight() == nEscProp)
+ bChanged = false;
+ }
+
+ if ( !bChanged && !m_xHighPosBtn->get_saved_state() &&
+ !m_xNormalPosBtn->get_saved_state() && !m_xLowPosBtn->get_saved_state() )
+ bChanged = true;
+
+ if ( bChanged &&
+ ( m_xHighPosBtn->get_active() || m_xNormalPosBtn->get_active() || m_xLowPosBtn->get_active() ) )
+ {
+ rSet->Put( SvxEscapementItem( nEsc, nEscProp, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_KERNING );
+ short nKerning = 0;
+ MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
+
+ tools::Long nTmp = static_cast<tools::Long>(m_xKerningMF->get_value(FieldUnit::POINT));
+ tools::Long nVal = OutputDevice::LogicToLogic(nTmp, MapUnit::MapPoint, eUnit);
+ nKerning = static_cast<short>(m_xKerningMF->denormalize( nVal ));
+
+ SfxItemState eOldKernState = rOldSet.GetItemState( nWhich, false );
+ if ( pOld )
+ {
+ const SvxKerningItem& rItem = *static_cast<const SvxKerningItem*>(pOld);
+ if ( (eOldKernState >= SfxItemState::DEFAULT || m_xKerningMF->get_text().isEmpty()) && rItem.GetValue() == nKerning )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxKerningItem( nKerning, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == eOldKernState )
+ rSet->InvalidateItem(nWhich);
+
+ // Pair-Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
+
+ if (m_xPairKerningBtn->get_state_changed_from_saved())
+ {
+ rSet->Put( SvxAutoKernItem( m_xPairKerningBtn->get_active(), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ // Scale Width
+ nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if (m_xScaleWidthMF->get_value_changed_from_saved())
+ {
+ rSet->Put(SvxCharScaleWidthItem(static_cast<sal_uInt16>(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)), nWhich));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ // Rotation
+ nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
+ if ( m_x0degRB->get_state_changed_from_saved() ||
+ m_x90degRB->get_state_changed_from_saved() ||
+ m_x270degRB->get_state_changed_from_saved() ||
+ m_xFitToLineCB->get_state_changed_from_saved() )
+ {
+ SvxCharRotateItem aItem( 0_deg10, m_xFitToLineCB->get_active(), nWhich );
+ if (m_x90degRB->get_active())
+ aItem.SetBottomToTop();
+ else if (m_x270degRB->get_active())
+ aItem.SetTopToBottom();
+ rSet->Put( aItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+
+void SvxCharPositionPage::FillUserData()
+{
+ static const OUStringLiteral cTok( u";" );
+
+ OUString sUser = OUString::number( m_nSuperEsc ) + cTok +
+ OUString::number( m_nSubEsc ) + cTok +
+ OUString::number( m_nSuperProp ) + cTok +
+ OUString::number( m_nSubProp );
+ SetUserData( sUser );
+}
+
+
+void SvxCharPositionPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+}
+// class SvxCharTwoLinesPage ------------------------------------------------
+
+SvxCharTwoLinesPage::SvxCharTwoLinesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/twolinespage.ui", "TwoLinesPage", rInSet)
+ , m_nStartBracketPosition( 0 )
+ , m_nEndBracketPosition( 0 )
+ , m_xTwoLinesBtn(m_xBuilder->weld_check_button("twolines"))
+ , m_xEnclosingFrame(m_xBuilder->weld_widget("enclosing"))
+ , m_xStartBracketLB(m_xBuilder->weld_tree_view("startbracket"))
+ , m_xEndBracketLB(m_xBuilder->weld_tree_view("endbracket"))
+{
+ for (size_t i = 0; i < std::size(TWOLINE_OPEN); ++i)
+ m_xStartBracketLB->append(OUString::number(TWOLINE_OPEN[i].second), CuiResId(TWOLINE_OPEN[i].first));
+ for (size_t i = 0; i < std::size(TWOLINE_CLOSE); ++i)
+ m_xEndBracketLB->append(OUString::number(TWOLINE_CLOSE[i].second), CuiResId(TWOLINE_CLOSE[i].first));
+
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ Initialize();
+}
+
+SvxCharTwoLinesPage::~SvxCharTwoLinesPage()
+{
+}
+
+void SvxCharTwoLinesPage::Initialize()
+{
+ m_xTwoLinesBtn->set_active(false);
+ TwoLinesHdl_Impl(*m_xTwoLinesBtn);
+
+ m_xTwoLinesBtn->connect_toggled(LINK(this, SvxCharTwoLinesPage, TwoLinesHdl_Impl));
+
+ Link<weld::TreeView&,void> aLink = LINK(this, SvxCharTwoLinesPage, CharacterMapHdl_Impl);
+ m_xStartBracketLB->connect_changed(aLink);
+ m_xEndBracketLB->connect_changed(aLink);
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ rFont.SetFontSize( Size( 0, 220 ) );
+ rCJKFont.SetFontSize( Size( 0, 220 ) );
+ rCTLFont.SetFontSize( Size( 0, 220 ) );
+}
+
+void SvxCharTwoLinesPage::SelectCharacter(weld::TreeView* pBox)
+{
+ bool bStart = pBox == m_xStartBracketLB.get();
+ SvxCharacterMap aDlg(GetFrameWeld(), nullptr, nullptr);
+ aDlg.DisableFontSelection();
+
+ if (aDlg.run() == RET_OK)
+ {
+ sal_Unicode cChar = static_cast<sal_Unicode>(aDlg.GetChar());
+ SetBracket( cChar, bStart );
+ }
+ else
+ {
+ pBox->select(bStart ? m_nStartBracketPosition : m_nEndBracketPosition);
+ }
+}
+
+
+void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket, bool bStart )
+{
+ int nEntryPos = 0;
+ weld::TreeView* pBox = bStart ? m_xStartBracketLB.get() : m_xEndBracketLB.get();
+ if (cBracket == 0)
+ pBox->select(0);
+ else
+ {
+ bool bFound = false;
+ for (int i = 1; i < pBox->n_children(); ++i)
+ {
+ if (pBox->get_id(i).toInt32() != CHRDLG_ENCLOSE_SPECIAL_CHAR)
+ {
+ const sal_Unicode cChar = pBox->get_text(i)[0];
+ if (cChar == cBracket)
+ {
+ pBox->select(i);
+ nEntryPos = i;
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!bFound)
+ {
+ pBox->append_text(OUString(cBracket));
+ nEntryPos = pBox->n_children() - 1;
+ pBox->select(nEntryPos);
+ }
+ }
+ if (bStart)
+ m_nStartBracketPosition = nEntryPos;
+ else
+ m_nEndBracketPosition = nEntryPos;
+}
+
+IMPL_LINK_NOARG(SvxCharTwoLinesPage, TwoLinesHdl_Impl, weld::Toggleable&, void)
+{
+ bool bChecked = m_xTwoLinesBtn->get_active();
+ m_xEnclosingFrame->set_sensitive(bChecked);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharTwoLinesPage, CharacterMapHdl_Impl, weld::TreeView&, rBox, void)
+{
+ int nPos = rBox.get_selected_index();
+ if (rBox.get_id(nPos).toInt32() == CHRDLG_ENCLOSE_SPECIAL_CHAR)
+ SelectCharacter( &rBox );
+ else
+ {
+ bool bStart = &rBox == m_xStartBracketLB.get();
+ if (bStart)
+ m_nStartBracketPosition = nPos;
+ else
+ m_nEndBracketPosition = nPos;
+ }
+ UpdatePreview_Impl();
+}
+
+void SvxCharTwoLinesPage::ActivatePage( const SfxItemSet& rSet )
+{
+ SvxCharBasePage::ActivatePage(rSet);
+}
+
+DeactivateRC SvxCharTwoLinesPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharTwoLinesPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharTwoLinesPage>(pPage, pController, *rSet);
+}
+
+void SvxCharTwoLinesPage::Reset( const SfxItemSet* rSet )
+{
+ m_xTwoLinesBtn->set_active(false);
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ const SvxTwoLinesItem& rItem = static_cast<const SvxTwoLinesItem&>(rSet->Get( nWhich ));
+ m_xTwoLinesBtn->set_active(rItem.GetValue());
+
+ if ( rItem.GetValue() )
+ {
+ SetBracket( rItem.GetStartBracket(), true );
+ SetBracket( rItem.GetEndBracket(), false );
+ }
+ }
+ TwoLinesHdl_Impl(*m_xTwoLinesBtn);
+
+ SetPrevFontWidthScale( *rSet );
+}
+
+bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false, bChanged = true;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
+ const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_TWO_LINES );
+ bool bOn = m_xTwoLinesBtn->get_active();
+ sal_Unicode cStart = ( bOn && m_xStartBracketLB->get_selected_index() > 0 )
+ ? m_xStartBracketLB->get_selected_text()[0] : 0;
+ sal_Unicode cEnd = ( bOn && m_xEndBracketLB->get_selected_index() > 0 )
+ ? m_xEndBracketLB->get_selected_text()[0] : 0;
+
+ if ( pOld )
+ {
+ const SvxTwoLinesItem& rItem = *static_cast<const SvxTwoLinesItem*>(pOld);
+ if ( rItem.GetValue() == bOn &&
+ ( !bOn || ( rItem.GetStartBracket() == cStart && rItem.GetEndBracket() == cEnd ) ) )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxTwoLinesItem( bOn, cStart, cEnd, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+void SvxCharTwoLinesPage::UpdatePreview_Impl()
+{
+ sal_Unicode cStart = m_xStartBracketLB->get_selected_index() > 0
+ ? m_xStartBracketLB->get_selected_text()[0] : 0;
+ sal_Unicode cEnd = m_xEndBracketLB->get_selected_index() > 0
+ ? m_xEndBracketLB->get_selected_text()[0] : 0;
+ m_aPreviewWin.SetBrackets(cStart, cEnd);
+ m_aPreviewWin.SetTwoLines(m_xTwoLinesBtn->get_active());
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharTwoLinesPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/chardlg.h b/cui/source/tabpages/chardlg.h
new file mode 100644
index 000000000..4a52cb24b
--- /dev/null
+++ b/cui/source/tabpages/chardlg.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+// define ----------------------------------------------------------------
+
+#define CHRDLG_POSITION_OVER 0
+#define CHRDLG_POSITION_UNDER 1
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/connect.cxx b/cui/source/tabpages/connect.cxx
new file mode 100644
index 000000000..d668a2a6b
--- /dev/null
+++ b/cui/source/tabpages/connect.cxx
@@ -0,0 +1,415 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <svx/connctrl.hxx>
+#include <svx/svxids.hrc>
+#include <svx/dlgutil.hxx>
+#include <svx/ofaitem.hxx>
+
+#include <svx/svdview.hxx>
+#include <svx/sxekitm.hxx>
+#include <svx/sxelditm.hxx>
+#include <svx/sxenditm.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <connect.hxx>
+
+const WhichRangesContainer SvxConnectionPage::pRanges(
+ svl::Items<SDRATTR_EDGE_FIRST, SDRATTR_EDGE_LAST>);
+
+/*************************************************************************
+|*
+|* dialog for changing connectors
+|*
+\************************************************************************/
+SvxConnectionDialog::SvxConnectionDialog(weld::Window* pParent, const SfxItemSet& rInAttrs, const SdrView* pSdrView)
+ : SfxSingleTabDialogController(pParent, &rInAttrs)
+{
+ auto xPage = std::make_unique<SvxConnectionPage>(get_content_area(), this, rInAttrs);
+
+ xPage->SetView(pSdrView);
+ xPage->Construct();
+
+ SetTabPage(std::move(xPage));
+ m_xDialog->set_title(CuiResId(RID_CUISTR_CONNECTOR));
+}
+
+/*************************************************************************
+|*
+|* page for changing connectors
+|*
+\************************************************************************/
+
+SvxConnectionPage::SvxConnectionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/connectortabpage.ui", "ConnectorTabPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aAttrSet(*rInAttrs.GetPool())
+ , pView(nullptr)
+ , m_xLbType(m_xBuilder->weld_combo_box("LB_TYPE"))
+ , m_xFtLine1(m_xBuilder->weld_label("FT_LINE_1"))
+ , m_xMtrFldLine1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_1", FieldUnit::CM))
+ , m_xFtLine2(m_xBuilder->weld_label("FT_LINE_2"))
+ , m_xMtrFldLine2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_2", FieldUnit::CM))
+ , m_xFtLine3(m_xBuilder->weld_label("FT_LINE_3"))
+ , m_xMtrFldLine3(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_3", FieldUnit::CM))
+ , m_xMtrFldHorz1(m_xBuilder->weld_metric_spin_button("MTR_FLD_HORZ_1", FieldUnit::MM))
+ , m_xMtrFldVert1(m_xBuilder->weld_metric_spin_button("MTR_FLD_VERT_1", FieldUnit::MM))
+ , m_xMtrFldHorz2(m_xBuilder->weld_metric_spin_button("MTR_FLD_HORZ_2", FieldUnit::MM))
+ , m_xMtrFldVert2(m_xBuilder->weld_metric_spin_button("MTR_FLD_VERT_2", FieldUnit::MM))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool" );
+ eUnit = pPool->GetMetric( SDRATTR_EDGENODE1HORZDIST );
+
+ FillTypeLB();
+
+ const FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldHorz1, eFUnit );
+ SetFieldUnit( *m_xMtrFldHorz2, eFUnit );
+ SetFieldUnit( *m_xMtrFldVert1, eFUnit );
+ SetFieldUnit( *m_xMtrFldVert2, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine1, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine2, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine3, eFUnit );
+ if( eFUnit == FieldUnit::MM )
+ {
+ m_xMtrFldHorz1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHorz2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldVert1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldVert2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine3->set_increments(50, 500, FieldUnit::NONE);
+ }
+
+ Link<weld::MetricSpinButton&,void> aLink(LINK(this, SvxConnectionPage, ChangeAttrEditHdl_Impl));
+ m_xMtrFldHorz1->connect_value_changed(aLink);
+ m_xMtrFldVert1->connect_value_changed(aLink);
+ m_xMtrFldHorz2->connect_value_changed(aLink);
+ m_xMtrFldVert2->connect_value_changed(aLink);
+ m_xMtrFldLine1->connect_value_changed(aLink);
+ m_xMtrFldLine2->connect_value_changed(aLink);
+ m_xMtrFldLine3->connect_value_changed(aLink);
+ m_xLbType->connect_changed(LINK(this, SvxConnectionPage, ChangeAttrListBoxHdl_Impl));
+}
+
+SvxConnectionPage::~SvxConnectionPage()
+{
+ m_xCtlPreview.reset();
+}
+
+/*************************************************************************
+|*
+|* reads passed Item-Set
+|*
+\************************************************************************/
+
+void SvxConnectionPage::Reset( const SfxItemSet* rAttrs )
+{
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_EDGENODE1HORZDIST );
+ const SfxItemPool* pPool = rAttrs->GetPool();
+
+ // SdrEdgeNode1HorzDistItem
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE1HORZDIST );
+ SetMetricValue(*m_xMtrFldHorz1, static_cast<const SdrEdgeNode1HorzDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHorz1->save_value();
+
+ // SdrEdgeNode2HorzDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGENODE2HORZDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE2HORZDIST );
+ SetMetricValue(*m_xMtrFldHorz2, static_cast<const SdrEdgeNode2HorzDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHorz2->save_value();
+
+ // SdrEdgeNode1VertDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGENODE1VERTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE1VERTDIST );
+ SetMetricValue(*m_xMtrFldVert1, static_cast<const SdrEdgeNode1VertDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldVert1->save_value();
+
+ // SdrEdgeNode2VertDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGENODE2VERTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE2VERTDIST );
+ SetMetricValue(*m_xMtrFldVert2, static_cast<const SdrEdgeNode2VertDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldVert2->save_value();
+
+ // SdrEdgeLine1DeltaItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINE1DELTA );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINE1DELTA );
+ SetMetricValue(*m_xMtrFldLine1, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLine1->save_value();
+
+ // SdrEdgeLine2DeltaItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINE2DELTA );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINE2DELTA );
+ SetMetricValue(*m_xMtrFldLine2, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLine2->save_value();
+
+ // SdrEdgeLine3DeltaItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINE3DELTA );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINE3DELTA );
+ SetMetricValue(*m_xMtrFldLine3, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLine3->save_value();
+
+ // SdrEdgeLineDeltaAnzItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINEDELTACOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINEDELTACOUNT );
+ switch (static_cast<const SdrEdgeLineDeltaCountItem*>(pItem)->GetValue())
+ {
+ case 0:
+ m_xFtLine1->set_sensitive(false);
+ m_xMtrFldLine1->set_sensitive(false);
+ m_xMtrFldLine1->set_text("");
+ [[fallthrough]];
+ case 1:
+ m_xFtLine2->set_sensitive(false);
+ m_xMtrFldLine2->set_sensitive(false);
+ m_xMtrFldLine2->set_text("");
+ [[fallthrough]];
+ case 2:
+ m_xFtLine3->set_sensitive(false);
+ m_xMtrFldLine3->set_sensitive(false);
+ m_xMtrFldLine3->set_text("");
+ break;
+ }
+
+ // SdrEdgeKindItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGEKIND );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGEKIND );
+ m_xLbType->set_active(
+ sal::static_int_cast<sal_uInt16>(static_cast<const SdrEdgeKindItem*>(pItem)->GetValue()));
+ m_xLbType->save_value();
+}
+
+/*************************************************************************
+|*
+|* fills the passed Item-Set width Dialogbox attributes
+|*
+\************************************************************************/
+
+bool SvxConnectionPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ sal_Int32 nValue;
+
+ if (m_xMtrFldHorz1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldHorz1, eUnit);
+ rAttrs->Put( SdrEdgeNode1HorzDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldHorz2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldHorz2, eUnit);
+ rAttrs->Put( SdrEdgeNode2HorzDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldVert1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldVert1, eUnit);
+ rAttrs->Put( SdrEdgeNode1VertDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldVert2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldVert2, eUnit);
+ rAttrs->Put( SdrEdgeNode2VertDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine1, eUnit);
+ rAttrs->Put( makeSdrEdgeLine1DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine2, eUnit);
+ rAttrs->Put( makeSdrEdgeLine2DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine3->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine3, eUnit);
+ rAttrs->Put( makeSdrEdgeLine3DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ int nPos = m_xLbType->get_active();
+ if (m_xLbType->get_value_changed_from_saved())
+ {
+ if (nPos != -1)
+ {
+ rAttrs->Put( SdrEdgeKindItem( static_cast<SdrEdgeKind>(nPos) ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+void SvxConnectionPage::Construct()
+{
+ DBG_ASSERT( pView, "No valid View transfer!" );
+
+ m_aCtlPreview.SetView(pView);
+ m_aCtlPreview.Construct();
+}
+
+/*************************************************************************
+|*
+|* creates the page
+|*
+\************************************************************************/
+std::unique_ptr<SfxTabPage> SvxConnectionPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxConnectionPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxConnectionPage, ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xLbType->get_active();
+ if (nPos != -1)
+ {
+ aAttrSet.Put( SdrEdgeKindItem( static_cast<SdrEdgeKind>(nPos) ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+
+ // get the number of line displacements
+ sal_uInt16 nCount = m_aCtlPreview.GetLineDeltaCount();
+
+ m_xFtLine3->set_sensitive( nCount > 2 );
+ m_xMtrFldLine3->set_sensitive( nCount > 2 );
+ if( nCount > 2 )
+ m_xMtrFldLine3->set_value(m_xMtrFldLine3->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine3->set_text("");
+
+ m_xFtLine2->set_sensitive( nCount > 1 );
+ m_xMtrFldLine2->set_sensitive( nCount > 1 );
+ if( nCount > 1 )
+ m_xMtrFldLine2->set_value(m_xMtrFldLine2->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine2->set_text("");
+
+ m_xFtLine1->set_sensitive( nCount > 0 );
+ m_xMtrFldLine1->set_sensitive( nCount > 0 );
+ if( nCount > 0 )
+ m_xMtrFldLine1->set_value(m_xMtrFldLine1->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine1->set_text("");
+}
+
+IMPL_LINK(SvxConnectionPage, ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, r, void)
+{
+ if (&r == m_xMtrFldHorz1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldHorz1, eUnit);
+ aAttrSet.Put( SdrEdgeNode1HorzDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldHorz2.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHorz2, eUnit );
+ aAttrSet.Put( SdrEdgeNode2HorzDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldVert1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldVert1, eUnit);
+ aAttrSet.Put( SdrEdgeNode1VertDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldVert2.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldVert2, eUnit);
+ aAttrSet.Put( SdrEdgeNode2VertDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine1, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine1DeltaItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine2.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine2, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine2DeltaItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine3.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine3, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine3DeltaItem( nValue ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+}
+
+void SvxConnectionPage::FillTypeLB()
+{
+ // fill ListBox with connector names
+ const SfxPoolItem* pItem = GetItem( rOutAttrs, SDRATTR_EDGEKIND );
+ const SfxItemPool* pPool = rOutAttrs.GetPool();
+
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGEKIND );
+ const SdrEdgeKindItem* pEdgeKindItem = static_cast<const SdrEdgeKindItem*>(pItem);
+ const sal_uInt16 nCount = pEdgeKindItem->GetValueCount();
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ {
+ OUString aStr = SdrEdgeKindItem::GetValueTextByPos(i);
+ m_xLbType->append_text(aStr);
+ }
+}
+void SvxConnectionPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const OfaPtrItem* pOfaPtrItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+ if (pOfaPtrItem)
+ SetView( static_cast<SdrView *>(pOfaPtrItem->GetValue()) );
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/grfpage.cxx b/cui/source/tabpages/grfpage.cxx
new file mode 100644
index 000000000..1bbc73c3a
--- /dev/null
+++ b/cui/source/tabpages/grfpage.cxx
@@ -0,0 +1,806 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <grfpage.hxx>
+#include <svx/grfcrop.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/debug.hxx>
+#include <tools/fract.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/unitconv.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <o3tl/unit_conversion.hxx>
+
+constexpr auto CM_1_TO_TWIP = o3tl::convert(1, o3tl::Length::cm, o3tl::Length::twip); // 567
+
+
+static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit)
+{
+ return rMetric.denormalize(rMetric.get_value(eUnit));
+}
+
+/*--------------------------------------------------------------------
+ description: crop graphic
+ --------------------------------------------------------------------*/
+
+SvxGrfCropPage::SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/croppage.ui", "CropPage", &rSet)
+ , m_nOldWidth(0)
+ , m_nOldHeight(0)
+ , m_bSetOrigSize(false)
+ , m_aPreferredDPI(0)
+ , m_xCropFrame(m_xBuilder->weld_widget("cropframe"))
+ , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale"))
+ , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
+ , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
+ , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe"))
+ , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT))
+ , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT))
+ , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid"))
+ , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft"))
+ , m_xOrigSizePB(m_xBuilder->weld_button("origsize"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+{
+ SetExchangeSupport();
+
+ // set the correct metric
+ const FieldUnit eMetric = GetModuleFieldUnit( rSet );
+
+ SetFieldUnit( *m_xWidthMF, eMetric );
+ SetFieldUnit( *m_xHeightMF, eMetric );
+ SetFieldUnit( *m_xLeftMF, eMetric );
+ SetFieldUnit( *m_xRightMF, eMetric );
+ SetFieldUnit( *m_xTopMF , eMetric );
+ SetFieldUnit( *m_xBottomMF, eMetric );
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxGrfCropPage, SizeHdl);
+ m_xWidthMF->connect_value_changed( aLk );
+ m_xHeightMF->connect_value_changed( aLk );
+
+ aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
+ m_xWidthZoomMF->connect_value_changed( aLk );
+ m_xHeightZoomMF->connect_value_changed( aLk );
+
+ aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
+ m_xLeftMF->connect_value_changed( aLk );
+ m_xRightMF->connect_value_changed( aLk );
+ m_xTopMF->connect_value_changed( aLk );
+ m_xBottomMF->connect_value_changed( aLk );
+
+ m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl));
+}
+
+SvxGrfCropPage::~SvxGrfCropPage()
+{
+ m_xExampleWN.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxGrfCropPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SvxGrfCropPage>(pPage, pController, *rSet);
+}
+
+void SvxGrfCropPage::Reset( const SfxItemSet *rSet )
+{
+ const SfxPoolItem* pItem;
+ const SfxItemPool& rPool = *rSet->GetPool();
+
+ if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich(
+ SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem ))
+ {
+ if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
+ m_xZoomConstRB->set_active(true);
+ else
+ m_xSizeConstRB->set_active(true);
+ m_xZoomConstRB->save_state();
+ }
+
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
+ if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem))
+ {
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem);
+
+ m_aExampleWN.SetLeft(pCrop->GetLeft());
+ m_aExampleWN.SetRight(pCrop->GetRight());
+ m_aExampleWN.SetTop(pCrop->GetTop());
+ m_aExampleWN.SetBottom(pCrop->GetBottom());
+
+ m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit );
+ m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit );
+ m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit );
+ m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit );
+ }
+ else
+ {
+ m_xLeftMF->set_value(0, FieldUnit::NONE);
+ m_xRightMF->set_value(0, FieldUnit::NONE);
+ m_xTopMF->set_value(0, FieldUnit::NONE);
+ m_xBottomMF->set_value(0, FieldUnit::NONE);
+ }
+
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+
+ nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
+ if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) )
+ {
+ // orientation and size from the PageItem
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ m_aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ auto nMin = m_xWidthMF->normalize( 23 );
+ auto nMax = m_xHeightMF->normalize(m_aPageSize.Height());
+ m_xHeightMF->set_range(nMin, nMax, eUnit);
+ nMax = m_xWidthMF->normalize(m_aPageSize.Width());
+ m_xWidthMF->set_range(nMin, nMax, eUnit);
+ }
+ else
+ {
+ m_aPageSize = OutputDevice::LogicToLogic(
+ Size( CM_1_TO_TWIP, CM_1_TO_TWIP ),
+ MapMode( MapUnit::MapTwip ),
+ MapMode( rSet->GetPool()->GetMetric( nW ) ) );
+ }
+
+ bool bFound = false;
+ if( const SvxBrushItem* pGraphicItem = rSet->GetItemIfSet( SID_ATTR_GRAF_GRAPHIC, false ) )
+ {
+ OUString referer;
+ SfxStringItem const * it = static_cast<SfxStringItem const *>(
+ rSet->GetItem(SID_REFERER));
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = pGraphicItem->GetGraphic(referer);
+ if( pGrf )
+ {
+ m_aOrigSize = GetGrfOrigSize( *pGrf );
+ if (pGrf->GetType() == GraphicType::Bitmap && m_aOrigSize.Width() && m_aOrigSize.Height())
+ {
+ m_aOrigPixelSize = pGrf->GetSizePixel();
+ }
+
+ if( m_aOrigSize.Width() && m_aOrigSize.Height() )
+ {
+ CalcMinMaxBorder();
+ m_aExampleWN.SetGraphic( *pGrf );
+ m_aExampleWN.SetFrameSize( m_aOrigSize );
+
+ bFound = true;
+ if( !pGraphicItem->GetGraphicLink().isEmpty() )
+ m_aGraphicName = pGraphicItem->GetGraphicLink();
+ }
+ }
+ }
+
+ GraphicHasChanged( bFound );
+ ActivatePage( *rSet );
+}
+
+bool SvxGrfCropPage::FillItemSet(SfxItemSet *rSet)
+{
+ const SfxItemPool& rPool = *rSet->GetPool();
+ bool bModified = false;
+ if( m_xWidthMF->get_value_changed_from_saved() ||
+ m_xHeightMF->get_value_changed_from_saved() )
+ {
+ constexpr TypedWhichId<SvxSizeItem> nW = SID_ATTR_GRAF_FRMSIZE;
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW));
+
+ // size could already have been set from another page
+ const SfxItemSet* pExSet = GetDialogExampleSet();
+ const SvxSizeItem* pSizeItem = nullptr;
+ if( pExSet && (pSizeItem = pExSet->GetItemIfSet( nW, false )) )
+ {
+ aSz.reset(pSizeItem->Clone());
+ }
+ else
+ {
+ aSz.reset(GetItemSet().Get(nW).Clone());
+ }
+
+ Size aTmpSz( aSz->GetSize() );
+ if( m_xWidthMF->get_value_changed_from_saved() )
+ aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) );
+ if( m_xHeightMF->get_value_changed_from_saved() )
+ aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) );
+ aSz->SetSize( aTmpSz );
+ m_xWidthMF->save_value();
+ m_xHeightMF->save_value();
+
+ bModified |= nullptr != rSet->Put( *aSz );
+
+ if (m_bSetOrigSize)
+ {
+ bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich(
+ SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
+ }
+ }
+ if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() )
+ {
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+ std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone()));
+
+ pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) );
+ pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) );
+ pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) );
+ pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) );
+ bModified |= nullptr != rSet->Put( std::move(pNew) );
+ }
+
+ if( m_xZoomConstRB->get_state_changed_from_saved() )
+ {
+ bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich(
+ SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) );
+ }
+
+ return bModified;
+}
+
+void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet)
+{
+#ifdef DBG_UTIL
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+#endif
+
+ auto& aProperties = getAdditionalProperties();
+ auto aIterator = aProperties.find("PreferredDPI");
+ if (aIterator != aProperties.end())
+ m_aPreferredDPI = aIterator->second.get<sal_Int32>();
+
+ m_bSetOrigSize = false;
+
+ // Size
+ Size aSize;
+ if( const SvxSizeItem* pFrmSizeItem = rSet.GetItemIfSet( SID_ATTR_GRAF_FRMSIZE, false ) )
+ aSize = pFrmSizeItem->GetSize();
+
+ m_nOldWidth = aSize.Width();
+ m_nOldHeight = aSize.Height();
+
+ auto nWidth = m_xWidthMF->normalize(m_nOldWidth);
+ auto nHeight = m_xHeightMF->normalize(m_nOldHeight);
+
+ if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP))
+ m_xWidthMF->set_value(nWidth, FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+
+ if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP))
+ m_xHeightMF->set_value(nHeight, FieldUnit::TWIP);
+ m_xHeightMF->save_value();
+
+ if( const SvxBrushItem* pBrushItem = rSet.GetItemIfSet( SID_ATTR_GRAF_GRAPHIC, false ) )
+ {
+ if( !pBrushItem->GetGraphicLink().isEmpty() &&
+ m_aGraphicName != pBrushItem->GetGraphicLink() )
+ m_aGraphicName = pBrushItem->GetGraphicLink();
+
+ OUString referer;
+ SfxStringItem const * it = static_cast<SfxStringItem const *>(
+ rSet.GetItem(SID_REFERER));
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = pBrushItem->GetGraphic(referer);
+ if( pGrf )
+ {
+ m_aExampleWN.SetGraphic( *pGrf );
+ m_aOrigSize = GetGrfOrigSize( *pGrf );
+ if (pGrf->GetType() == GraphicType::Bitmap && m_aOrigSize.Width() > 1 && m_aOrigSize.Height() > 1) {
+ m_aOrigPixelSize = pGrf->GetSizePixel();
+ }
+ m_aExampleWN.SetFrameSize(m_aOrigSize);
+ GraphicHasChanged( m_aOrigSize.Width() && m_aOrigSize.Height() );
+ CalcMinMaxBorder();
+ }
+ else
+ GraphicHasChanged( false );
+ }
+
+ CalcZoom();
+}
+
+DeactivateRC SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+/*--------------------------------------------------------------------
+ description: scale changed, adjust size
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ if (&rField == m_xWidthZoomMF.get())
+ {
+ tools::Long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit)
+ +lcl_GetValue(*m_xRightMF, eUnit);
+ m_xWidthMF->set_value( m_xWidthMF->normalize(
+ ((m_aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100),
+ eUnit);
+ }
+ else
+ {
+ tools::Long nULBorders = lcl_GetValue(*m_xTopMF, eUnit)
+ +lcl_GetValue(*m_xBottomMF, eUnit);
+ m_xHeightMF->set_value( m_xHeightMF->normalize(
+ ((m_aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) ,
+ eUnit );
+ }
+}
+
+/*--------------------------------------------------------------------
+ description: change size, adjust scale
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, SizeHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ Size aSize( lcl_GetValue(*m_xWidthMF, eUnit),
+ lcl_GetValue(*m_xHeightMF, eUnit) );
+
+ if(&rField == m_xWidthMF.get())
+ {
+ tools::Long nWidth = m_aOrigSize.Width() -
+ ( lcl_GetValue(*m_xLeftMF, eUnit) +
+ lcl_GetValue(*m_xRightMF, eUnit) );
+ if(!nWidth)
+ nWidth++;
+ sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth);
+ m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
+ }
+ else
+ {
+ tools::Long nHeight = m_aOrigSize.Height() -
+ ( lcl_GetValue(*m_xTopMF, eUnit) +
+ lcl_GetValue(*m_xBottomMF, eUnit));
+ if(!nHeight)
+ nHeight++;
+ sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight);
+ m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
+ }
+}
+
+/*--------------------------------------------------------------------
+ description: evaluate border
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ bool bZoom = m_xZoomConstRB->get_active();
+ if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get())
+ {
+ tools::Long nLeft = lcl_GetValue( *m_xLeftMF, eUnit );
+ tools::Long nRight = lcl_GetValue( *m_xRightMF, eUnit );
+ tools::Long nWidthZoom = static_cast<tools::Long>(m_xWidthZoomMF->get_value(FieldUnit::NONE));
+ if (bZoom && nWidthZoom != 0 && ( ( ( m_aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
+ / 100 >= m_aPageSize.Width() ) )
+ {
+ if (&rField == m_xLeftMF.get())
+ {
+ nLeft = m_aOrigSize.Width() -
+ ( m_aPageSize.Width() * 100 / nWidthZoom + nRight );
+ m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit );
+ }
+ else
+ {
+ nRight = m_aOrigSize.Width() -
+ ( m_aPageSize.Width() * 100 / nWidthZoom + nLeft );
+ m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit );
+ }
+ }
+ if (AllSettings::GetLayoutRTL())
+ {
+ m_aExampleWN.SetLeft(nRight);
+ m_aExampleWN.SetRight(nLeft);
+ }
+ else
+ {
+ m_aExampleWN.SetLeft(nLeft);
+ m_aExampleWN.SetRight(nRight);
+ }
+ if(bZoom)
+ {
+ // scale stays, recompute width
+ ZoomHdl(*m_xWidthZoomMF);
+ }
+ }
+ else
+ {
+ tools::Long nTop = lcl_GetValue( *m_xTopMF, eUnit );
+ tools::Long nBottom = lcl_GetValue( *m_xBottomMF, eUnit );
+ tools::Long nHeightZoom = static_cast<tools::Long>(m_xHeightZoomMF->get_value(FieldUnit::NONE));
+ if(bZoom && ( ( ( m_aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
+ / 100 >= m_aPageSize.Height()))
+ {
+ assert(nHeightZoom && "div-by-zero");
+ if(&rField == m_xTopMF.get())
+ {
+ nTop = m_aOrigSize.Height() -
+ ( m_aPageSize.Height() * 100 / nHeightZoom + nBottom);
+ m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit );
+ }
+ else
+ {
+ nBottom = m_aOrigSize.Height() -
+ ( m_aPageSize.Height() * 100 / nHeightZoom + nTop);
+ m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit );
+ }
+ }
+ m_aExampleWN.SetTop( nTop );
+ m_aExampleWN.SetBottom( nBottom );
+ if(bZoom)
+ {
+ // scale stays, recompute height
+ ZoomHdl(*m_xHeightZoomMF);
+ }
+ }
+ m_aExampleWN.Invalidate();
+ // size and border changed -> recompute scale
+ if(!bZoom)
+ CalcZoom();
+ CalcMinMaxBorder();
+}
+/*--------------------------------------------------------------------
+ description: set original size
+ --------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button&, void)
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ tools::Long nWidth = m_aOrigSize.Width() -
+ lcl_GetValue( *m_xLeftMF, eUnit ) -
+ lcl_GetValue( *m_xRightMF, eUnit );
+ m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit );
+ tools::Long nHeight = m_aOrigSize.Height() -
+ lcl_GetValue( *m_xTopMF, eUnit ) -
+ lcl_GetValue( *m_xBottomMF, eUnit );
+ m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit );
+ m_xWidthZoomMF->set_value(100, FieldUnit::NONE);
+ m_xHeightZoomMF->set_value(100, FieldUnit::NONE);
+ m_bSetOrigSize = true;
+}
+/*--------------------------------------------------------------------
+ description: compute scale
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::CalcZoom()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ tools::Long nWidth = lcl_GetValue( *m_xWidthMF, eUnit );
+ tools::Long nHeight = lcl_GetValue( *m_xHeightMF, eUnit );
+ tools::Long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) +
+ lcl_GetValue( *m_xRightMF, eUnit );
+ tools::Long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) +
+ lcl_GetValue( *m_xBottomMF, eUnit );
+ sal_uInt16 nZoom = 0;
+ tools::Long nDen;
+ if( (nDen = m_aOrigSize.Width() - nLRBorders) > 0)
+ nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10);
+ m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
+ if( (nDen = m_aOrigSize.Height() - nULBorders) > 0)
+ nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10);
+ else
+ nZoom = 0;
+ m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
+}
+
+/*--------------------------------------------------------------------
+ description: set minimum/maximum values for the margins
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::CalcMinMaxBorder()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+ tools::Long nR = lcl_GetValue(*m_xRightMF, eUnit );
+ tools::Long nMinWidth = (m_aOrigSize.Width() * 10) /11;
+ tools::Long nMin = nMinWidth - (nR >= 0 ? nR : 0);
+ m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit );
+
+ tools::Long nL = lcl_GetValue(*m_xLeftMF, eUnit );
+ nMin = nMinWidth - (nL >= 0 ? nL : 0);
+ m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit );
+
+ tools::Long nUp = lcl_GetValue( *m_xTopMF, eUnit );
+ tools::Long nMinHeight = (m_aOrigSize.Height() * 10) /11;
+ nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
+ m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit );
+
+ tools::Long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
+ nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
+ m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit );
+}
+/*--------------------------------------------------------------------
+ description: set spinsize to 1/20 of the original size,
+ fill FixedText with the original size
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::GraphicHasChanged( bool bFound )
+{
+ if( bFound )
+ {
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ));
+
+ sal_Int64 nSpin = m_xLeftMF->normalize(m_aOrigSize.Width()) / 20;
+ nSpin = vcl::ConvertValue( nSpin, m_aOrigSize.Width(), 0,
+ eUnit, m_xLeftMF->get_unit());
+
+ // if the margin is too big, it is set to 1/3 on both pages
+ tools::Long nR = lcl_GetValue( *m_xRightMF, eUnit );
+ tools::Long nL = lcl_GetValue( *m_xLeftMF, eUnit );
+ if((nL + nR) < - m_aOrigSize.Width())
+ {
+ tools::Long nVal = m_aOrigSize.Width() / -3;
+ m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit );
+ m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit );
+ m_aExampleWN.SetLeft(nVal);
+ m_aExampleWN.SetRight(nVal);
+ }
+ tools::Long nUp = lcl_GetValue(*m_xTopMF, eUnit );
+ tools::Long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
+ if((nUp + nLow) < - m_aOrigSize.Height())
+ {
+ tools::Long nVal = m_aOrigSize.Height() / -3;
+ m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit );
+ m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit );
+ m_aExampleWN.SetTop(nVal);
+ m_aExampleWN.SetBottom(nVal);
+ }
+
+ m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ nSpin = m_xTopMF->normalize(m_aOrigSize.Height()) / 20;
+ nSpin = vcl::ConvertValue( nSpin, m_aOrigSize.Width(), 0,
+ eUnit, m_xLeftMF->get_unit() );
+ m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+
+ // display original size
+ const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
+
+ OUString sTemp;
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/spinbox.ui"));
+ std::unique_ptr<weld::Dialog> xTopLevel(xBuilder->weld_dialog("SpinDialog"));
+ std::unique_ptr<weld::MetricSpinButton> xFld(xBuilder->weld_metric_spin_button("spin", FieldUnit::CM));
+ SetFieldUnit( *xFld, eMetric );
+ xFld->set_digits(m_xWidthMF->get_digits());
+ xFld->set_max(INT_MAX - 1, FieldUnit::NONE);
+
+ xFld->set_value(xFld->normalize(m_aOrigSize.Width()), eUnit);
+ sTemp = xFld->get_text();
+ xFld->set_value(xFld->normalize(m_aOrigSize.Height()), eUnit);
+ // multiplication sign (U+00D7)
+ sTemp += u"\u00D7" + xFld->get_text();
+ }
+
+ if ( m_aOrigPixelSize.Width() && m_aOrigPixelSize.Height() ) {
+ sal_Int32 ax = 0.5 + m_aOrigPixelSize.Width() /
+ o3tl::convert<double>(m_aOrigSize.Width(), o3tl::Length::twip,
+ o3tl::Length::in);
+ sal_Int32 ay = 0.5 + m_aOrigPixelSize.Height() /
+ o3tl::convert<double>(m_aOrigSize.Height(), o3tl::Length::twip,
+ o3tl::Length::in);
+ OUString sPPI = OUString::number(ax);
+ if (abs(ax - ay) > 1) {
+ sPPI += u"\u00D7" + OUString::number(ay);
+ }
+ sTemp += " " + CuiResId(RID_CUISTR_PPI).replaceAll("%1", sPPI);
+ }
+ sTemp += "\n" + OUString::number(m_aOrigPixelSize.Width()) + u"\u00D7" + OUString::number(m_aOrigPixelSize.Height()) + " px";
+ m_xOrigSizeFT->set_label(sTemp);
+ }
+
+ m_xCropFrame->set_sensitive(bFound);
+ m_xScaleFrame->set_sensitive(bFound);
+ m_xSizeFrame->set_sensitive(bFound);
+ m_xOrigSizeGrid->set_sensitive(bFound);
+ m_xZoomConstRB->set_sensitive(bFound);
+}
+
+Size SvxGrfCropPage::GetGrfOrigSize(const Graphic& rGrf)
+{
+ Size aSize;
+
+ if (m_aPreferredDPI > 0)
+ {
+ Size aPixelSize = rGrf.GetSizePixel();
+ double fWidth = aPixelSize.Width() / double(m_aPreferredDPI);
+ double fHeight = aPixelSize.Height() / double(m_aPreferredDPI);
+ fWidth = o3tl::convert(fWidth, o3tl::Length::in, o3tl::Length::twip);
+ fHeight = o3tl::convert(fHeight, o3tl::Length::in, o3tl::Length::twip);
+ aSize = Size(fWidth, fHeight);
+ }
+ else
+ {
+ const MapMode aMapTwip( MapUnit::MapTwip );
+ aSize = rGrf.GetPrefSize();
+ if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
+ aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapTwip);
+ else
+ aSize = OutputDevice::LogicToLogic( aSize,
+ rGrf.GetPrefMapMode(), aMapTwip );
+ }
+ return aSize;
+}
+
+/*****************************************************************/
+
+SvxCropExample::SvxCropExample()
+ : m_aTopLeft(0, 0)
+ , m_aBottomRight(0, 0)
+{
+}
+
+void SvxCropExample::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+ Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+
+ m_aMapMode = rDevice.GetMapMode();
+ m_aFrameSize = OutputDevice::LogicToLogic(
+ Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2),
+ MapMode(MapUnit::MapTwip), m_aMapMode);
+}
+
+void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.Push(vcl::PushFlags::MAPMODE);
+ rRenderContext.SetMapMode(m_aMapMode);
+
+ // Win BG
+ const Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+ rRenderContext.SetLineColor();
+ rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
+ rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
+
+ // use AA, the Graphic may be a metafile/svg and would then look ugly
+ rRenderContext.SetAntialiasing(AntialiasingFlags::Enable);
+
+ // draw Graphic
+ ::tools::Rectangle aRect(
+ Point((aWinSize.Width() - m_aFrameSize.Width())/2, (aWinSize.Height() - m_aFrameSize.Height())/2),
+ m_aFrameSize);
+ m_aGrf.Draw(rRenderContext, aRect.TopLeft(), aRect.GetSize());
+
+ // Remove one more case that uses XOR paint (RasterOp::Invert).
+ // Get colors and logic DashLength from settings, use equal to
+ // PolygonMarkerPrimitive2D, may be changed to that primitive later.
+ // Use this to guarantee good visibility - that was the purpose of
+ // the former used XOR paint.
+ const Color aColA(SvtOptionsDrawinglayer::GetStripeColorA().getBColor());
+ const Color aColB(SvtOptionsDrawinglayer::GetStripeColorB().getBColor());
+ const double fStripeLength(SvtOptionsDrawinglayer::GetStripeLength());
+ const basegfx::B2DVector aDashVector(rRenderContext.GetInverseViewTransformation() * basegfx::B2DVector(fStripeLength, 0.0));
+ const double fLogicDashLength(aDashVector.getX());
+
+ // apply current crop settings
+ aRect.AdjustLeft(m_aTopLeft.Y());
+ aRect.AdjustTop(m_aTopLeft.X());
+ aRect.AdjustRight(-m_aBottomRight.Y());
+ aRect.AdjustBottom(-m_aBottomRight.X());
+
+ // apply dash with direct paint callbacks
+ basegfx::utils::applyLineDashing(
+ basegfx::utils::createPolygonFromRect(
+ basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom())),
+ std::vector< double >(2, fLogicDashLength),
+ [&aColA,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+ {
+ rRenderContext.SetLineColor(aColA);
+ rRenderContext.DrawPolyLine(rSnippet);
+ },
+ [&aColB,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+ {
+ rRenderContext.SetLineColor(aColB);
+ rRenderContext.DrawPolyLine(rSnippet);
+ },
+ 2.0 * fLogicDashLength);
+
+ rRenderContext.Pop();
+}
+
+void SvxCropExample::Resize()
+{
+ SetFrameSize(m_aFrameSize);
+}
+
+void SvxCropExample::SetFrameSize( const Size& rSz )
+{
+ m_aFrameSize = rSz;
+ if (!m_aFrameSize.Width())
+ m_aFrameSize.setWidth( 1 );
+ if (!m_aFrameSize.Height())
+ m_aFrameSize.setHeight( 1 );
+ Size aWinSize( GetOutputSizePixel() );
+ Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 );
+ Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 );
+
+ if( aYScale < aXScale )
+ aXScale = aYScale;
+
+ m_aMapMode.SetScaleX(aXScale);
+ m_aMapMode.SetScaleY(aXScale);
+
+ Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/labdlg.cxx b/cui/source/tabpages/labdlg.cxx
new file mode 100644
index 000000000..cb048426c
--- /dev/null
+++ b/cui/source/tabpages/labdlg.cxx
@@ -0,0 +1,507 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swpossizetabpage.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <svx/svddef.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svx/sxcgitm.hxx>
+#include <svx/sxcllitm.hxx>
+#include <svx/sxctitm.hxx>
+
+#include <svx/dlgutil.hxx>
+#include <labdlg.hxx>
+#include <transfrm.hxx>
+#include <bitmaps.hlst>
+
+// define ----------------------------------------------------------------
+
+#define EXT_OPTIMAL 0
+#define EXT_FROM_TOP 1
+#define EXT_FROM_LEFT 2
+#define EXT_HORIZONTAL 3
+#define EXT_VERTICAL 4
+
+#define POS_TOP 0
+#define POS_MIDDLE 1
+#define POS_BOTTOM 2
+
+#define BMP_CAPTTYPE_1 1
+#define BMP_CAPTTYPE_2 2
+#define BMP_CAPTTYPE_3 3
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxCaptionTabPage::pCaptionRanges(
+ svl::Items<
+ SDRATTR_CAPTIONTYPE, SDRATTR_CAPTIONFIXEDANGLE,
+ SDRATTR_CAPTIONANGLE, SDRATTR_CAPTIONGAP,
+ SDRATTR_CAPTIONESCDIR, SDRATTR_CAPTIONESCISREL,
+ SDRATTR_CAPTIONESCREL, SDRATTR_CAPTIONESCABS,
+ SDRATTR_CAPTIONLINELEN, SDRATTR_CAPTIONFITLINELEN>);
+
+SvxCaptionTabPage::SvxCaptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/calloutpage.ui", "CalloutPage", &rInAttrs)
+ , nCaptionType(SdrCaptionType::Type1)
+ , nGap(0)
+ , nEscDir(SdrCaptionEscDir::Horizontal)
+ , bEscRel(false)
+ , nEscAbs(0)
+ , nEscRel(0)
+ , nLineLen(0)
+ , bFitLineLen(false)
+ , nPosition(0)
+ , nExtension(0)
+ , rOutAttrs(rInAttrs)
+ , pView(nullptr)
+ , m_xMF_SPACING(m_xBuilder->weld_metric_spin_button("spacing", FieldUnit::MM))
+ , m_xLB_EXTENSION(m_xBuilder->weld_combo_box("extension"))
+ , m_xFT_BYFT(m_xBuilder->weld_label("byft"))
+ , m_xMF_BY(m_xBuilder->weld_metric_spin_button("by", FieldUnit::MM))
+ , m_xFT_POSITIONFT(m_xBuilder->weld_label("positionft"))
+ , m_xLB_POSITION(m_xBuilder->weld_combo_box("position"))
+ , m_xLineTypes(m_xBuilder->weld_combo_box("linetypes"))
+ , m_xFT_LENGTHFT(m_xBuilder->weld_label("lengthft"))
+ , m_xMF_LENGTH(m_xBuilder->weld_metric_spin_button("length", FieldUnit::MM))
+ , m_xCB_OPTIMAL(m_xBuilder->weld_check_button("optimal"))
+ , m_xCT_CAPTTYPE(new ValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xCT_CAPTTYPEWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xCT_CAPTTYPE))
+{
+ Size aSize(m_xCT_CAPTTYPE->GetDrawingArea()->get_ref_device().LogicToPixel(Size(187, 38), MapMode(MapUnit::MapAppFont)));
+ m_xCT_CAPTTYPEWin->set_size_request(aSize.Width(), aSize.Height());
+
+ assert(m_xLB_POSITION->get_count() == 6);
+ for (int i = 0; i < 3; ++i)
+ m_aStrHorzList.push_back(m_xLB_POSITION->get_text(i));
+ for (int i = 3; i < 6; ++i)
+ m_aStrVertList.push_back(m_xLB_POSITION->get_text(i));
+ m_xLB_POSITION->clear();
+
+ assert(m_xLineTypes->get_count() == 3);
+ std::vector<OUString> aLineTypes;
+ aLineTypes.reserve(3);
+ for (int i = 0; i < 3; ++i)
+ aLineTypes.push_back(m_xLineTypes->get_text(i));
+
+ static_assert(CAPTYPE_BITMAPS_COUNT == 3, "unexpected");
+ m_aBmpCapTypes[0] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP1);
+ m_aBmpCapTypes[1] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP2);
+ m_aBmpCapTypes[2] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP3);
+
+ //------------install ValueSet--------------------------
+ m_xCT_CAPTTYPE->SetStyle( m_xCT_CAPTTYPE->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER | WB_NAMEFIELD );
+ m_xCT_CAPTTYPE->SetColCount(5);//XXX
+ m_xCT_CAPTTYPE->SetLineCount(1);
+ m_xCT_CAPTTYPE->SetSelectHdl(LINK( this, SvxCaptionTabPage, SelectCaptTypeHdl_Impl));
+
+ Image aImage;
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_1, aImage, aLineTypes[0]);
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_2, aImage, aLineTypes[1]);
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_3, aImage, aLineTypes[2]);
+
+ FillValueSet();
+
+ m_xLB_EXTENSION->connect_changed(LINK(this, SvxCaptionTabPage, ExtensionSelectHdl_Impl));
+ m_xLB_POSITION->connect_changed(LINK(this, SvxCaptionTabPage, PositionSelectHdl_Impl));
+ m_xCB_OPTIMAL->connect_toggled(LINK(this, SvxCaptionTabPage, LineOptHdl_Impl));
+}
+
+SvxCaptionTabPage::~SvxCaptionTabPage()
+{
+ m_xCT_CAPTTYPEWin.reset();
+ m_xCT_CAPTTYPE.reset();
+}
+
+void SvxCaptionTabPage::Construct()
+{
+ // set rectangle and working area
+ DBG_ASSERT( pView, "No valid View transferred!" );
+}
+
+bool SvxCaptionTabPage::FillItemSet( SfxItemSet* _rOutAttrs)
+{
+ SfxItemPool* pPool = _rOutAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ MapUnit eUnit;
+
+ nCaptionType = static_cast<SdrCaptionType>(m_xCT_CAPTTYPE->GetSelectedItemId()-1);
+
+ _rOutAttrs->Put( SdrCaptionTypeItem( nCaptionType ) );
+
+ if (m_xMF_SPACING->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONGAP ) );
+ _rOutAttrs->Put( SdrCaptionGapItem( GetCoreValue(*m_xMF_SPACING, eUnit ) ) );
+ }
+
+ // special treatment!!! XXX
+ if( nCaptionType==SdrCaptionType::Type1 )
+ {
+ switch( nEscDir )
+ {
+ case SdrCaptionEscDir::Horizontal: nEscDir=SdrCaptionEscDir::Vertical;break;
+ case SdrCaptionEscDir::Vertical: nEscDir=SdrCaptionEscDir::Horizontal;break;
+ default: break;
+ }
+ }
+
+ _rOutAttrs->Put( SdrCaptionEscDirItem( nEscDir ) );
+
+ bEscRel = m_xLB_POSITION->get_visible();
+ _rOutAttrs->Put( SdrCaptionEscIsRelItem( bEscRel ) );
+
+ if( bEscRel )
+ {
+ tools::Long nVal = 0;
+
+ switch (m_xLB_POSITION->get_active())
+ {
+ case POS_TOP: nVal=0;break;
+ case POS_MIDDLE: nVal=5000;break;
+ case POS_BOTTOM: nVal=10000;break;
+ }
+ _rOutAttrs->Put( SdrCaptionEscRelItem( nVal ) );
+ }
+ else
+ {
+ if (m_xMF_BY->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONESCABS ) );
+ _rOutAttrs->Put( SdrCaptionEscAbsItem( GetCoreValue(*m_xMF_BY, eUnit ) ) );
+ }
+ }
+
+ bFitLineLen = m_xCB_OPTIMAL->get_active();
+ _rOutAttrs->Put( SdrCaptionFitLineLenItem( bFitLineLen ) );
+
+ if( ! bFitLineLen )
+ {
+ if (m_xMF_LENGTH->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONLINELEN ) );
+ _rOutAttrs->Put( SdrCaptionLineLenItem( GetCoreValue(*m_xMF_LENGTH, eUnit ) ) );
+ }
+ }
+
+//NYI-------------the angles have to be added here!!! XXX----------------------
+
+ return true;
+}
+
+void SvxCaptionTabPage::Reset( const SfxItemSet* )
+{
+
+ //------------set metric-----------------------------
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rOutAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::CM:
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMF_SPACING, eFUnit );
+ SetFieldUnit( *m_xMF_BY, eFUnit );
+ SetFieldUnit( *m_xMF_LENGTH, eFUnit );
+
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ sal_uInt16 nWhich;
+ MapUnit eUnit;
+
+ nWhich = GetWhich( SDRATTR_CAPTIONESCABS );
+ eUnit = pPool->GetMetric( nWhich );
+ nEscAbs = static_cast<const SdrCaptionEscAbsItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_BY, nEscAbs, eUnit );
+ nEscAbs = m_xMF_BY->get_value(FieldUnit::NONE);
+
+ nWhich = GetWhich( SDRATTR_CAPTIONESCREL );
+ nEscRel = static_cast<tools::Long>(static_cast<const SdrCaptionEscRelItem&>( rOutAttrs.Get( nWhich ) ).GetValue());
+
+ //------- line length ----------
+ nWhich = GetWhich( SDRATTR_CAPTIONLINELEN );
+ eUnit = pPool->GetMetric( nWhich );
+ nLineLen = static_cast<const SdrCaptionLineLenItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_LENGTH, nLineLen, eUnit );
+ nLineLen = m_xMF_LENGTH->get_value(FieldUnit::NONE);
+
+ //------- distance to box ----------
+ nWhich = GetWhich( SDRATTR_CAPTIONGAP );
+ eUnit = pPool->GetMetric( nWhich );
+ nGap = static_cast<const SdrCaptionGapItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_SPACING, nGap, eUnit );
+ nGap = m_xMF_SPACING->get_value(FieldUnit::NONE);
+
+ nCaptionType = rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONTYPE ) ).GetValue();
+ bFitLineLen = static_cast<const SfxBoolItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONFITLINELEN ) ) ).GetValue();
+ nEscDir = rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONESCDIR ) ).GetValue();
+ bEscRel = static_cast<const SfxBoolItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONESCISREL ) ) ).GetValue();
+
+ // special treatment!!! XXX
+ if( nCaptionType==SdrCaptionType::Type1 )
+ {
+ switch( nEscDir )
+ {
+ case SdrCaptionEscDir::Horizontal: nEscDir=SdrCaptionEscDir::Vertical;break;
+ case SdrCaptionEscDir::Vertical: nEscDir=SdrCaptionEscDir::Horizontal;break;
+ default: break;
+ }
+ }
+
+ nPosition = POS_MIDDLE;
+ nExtension = EXT_OPTIMAL;
+
+ m_xMF_SPACING->set_value(nGap, FieldUnit::NONE);
+
+ if( nEscDir == SdrCaptionEscDir::Horizontal )
+ {
+ if( bEscRel )
+ {
+ if( nEscRel < 3333 )
+ nPosition = POS_TOP;
+ if( nEscRel > 6666 )
+ nPosition = POS_BOTTOM;
+ nExtension = EXT_HORIZONTAL;
+ }
+ else
+ {
+ nExtension = EXT_FROM_TOP;
+ m_xMF_BY->set_value(nEscAbs, FieldUnit::NONE);
+ }
+ }
+ else if( nEscDir == SdrCaptionEscDir::Vertical )
+ {
+ if( bEscRel )
+ {
+ if( nEscRel < 3333 )
+ nPosition = POS_TOP;
+ if( nEscRel > 6666 )
+ nPosition = POS_BOTTOM;
+ nExtension = EXT_VERTICAL;
+ }
+ else
+ {
+ nExtension = EXT_FROM_LEFT;
+ m_xMF_BY->set_value(nEscAbs, FieldUnit::NONE);
+ }
+ }
+ else if( nEscDir == SdrCaptionEscDir::BestFit )
+ {
+ nExtension = EXT_OPTIMAL;
+ }
+
+ m_xCB_OPTIMAL->set_active(bFitLineLen);
+ m_xMF_LENGTH->set_value(nLineLen, FieldUnit::NONE);
+
+ m_xLB_EXTENSION->set_active(nExtension);
+
+ SetupExtension_Impl( nExtension );
+ m_xCT_CAPTTYPE->SelectItem( static_cast<int>(nCaptionType)+1 ); // Enum starts at 0!
+ SetupType_Impl( nCaptionType );
+}
+
+std::unique_ptr<SfxTabPage> SvxCaptionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxCaptionTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxCaptionTabPage::SetupExtension_Impl( sal_uInt16 nType )
+{
+ switch( nType )
+ {
+ case EXT_OPTIMAL:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::BestFit;
+ break;
+
+ case EXT_FROM_TOP:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::Horizontal;
+ break;
+
+ case EXT_FROM_LEFT:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::Vertical;
+ break;
+
+ case EXT_HORIZONTAL:
+ m_xLB_POSITION->clear();
+ for (const OUString & i : m_aStrHorzList)
+ m_xLB_POSITION->append_text(i);
+ m_xLB_POSITION->set_active(nPosition);
+
+ m_xMF_BY->hide();
+ m_xFT_BYFT->hide();
+ m_xFT_POSITIONFT->show();
+ m_xLB_POSITION->show();
+ nEscDir = SdrCaptionEscDir::Horizontal;
+ break;
+
+ case EXT_VERTICAL:
+ m_xLB_POSITION->clear();
+ for (const OUString & i : m_aStrVertList)
+ m_xLB_POSITION->append_text(i);
+ m_xLB_POSITION->set_active(nPosition);
+
+ m_xMF_BY->hide();
+ m_xFT_BYFT->hide();
+ m_xFT_POSITIONFT->show();
+ m_xLB_POSITION->show();
+ nEscDir = SdrCaptionEscDir::Vertical;
+ break;
+ }
+}
+
+IMPL_LINK(SvxCaptionTabPage, ExtensionSelectHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (&rListBox == m_xLB_EXTENSION.get())
+ {
+ SetupExtension_Impl(m_xLB_EXTENSION->get_active());
+ }
+}
+
+IMPL_LINK(SvxCaptionTabPage, PositionSelectHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (&rListBox == m_xLB_POSITION.get())
+ {
+ nPosition = m_xLB_POSITION->get_active();
+ }
+}
+
+IMPL_LINK( SvxCaptionTabPage, LineOptHdl_Impl, weld::Toggleable&, rButton, void )
+{
+ if (&rButton != m_xCB_OPTIMAL.get())
+ return;
+
+ if (m_xCB_OPTIMAL->get_active() || !m_xCB_OPTIMAL->get_sensitive())
+ {
+ m_xFT_LENGTHFT->set_sensitive(false);
+ m_xMF_LENGTH->set_sensitive(false);
+ }
+ else
+ {
+ m_xFT_LENGTHFT->set_sensitive(true);
+ m_xMF_LENGTH->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxCaptionTabPage, SelectCaptTypeHdl_Impl, ValueSet*, void)
+{
+ SetupType_Impl( static_cast<SdrCaptionType>(m_xCT_CAPTTYPE->GetSelectedItemId()) );
+}
+
+void SvxCaptionTabPage::SetupType_Impl( SdrCaptionType nType )
+{
+ switch( nType )
+ {
+ case SdrCaptionType::Type1:
+ case SdrCaptionType::Type2:
+ m_xFT_LENGTHFT->set_sensitive(false);
+ m_xCB_OPTIMAL->set_sensitive(false);
+ LineOptHdl_Impl(*m_xCB_OPTIMAL);
+ break;
+ case SdrCaptionType::Type3:
+ case SdrCaptionType::Type4:
+ m_xFT_LENGTHFT->set_sensitive(true);
+ m_xCB_OPTIMAL->set_sensitive(true);
+ LineOptHdl_Impl(*m_xCB_OPTIMAL);
+ break;
+ }
+}
+
+void SvxCaptionTabPage::FillValueSet()
+{
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_1, m_aBmpCapTypes[0] );
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_2, m_aBmpCapTypes[1] );
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_3, m_aBmpCapTypes[2] );
+}
+
+SvxCaptionTabDialog::SvxCaptionTabDialog(weld::Window* pParent, const SdrView* pSdrView,
+ SvxAnchorIds nAnchorTypes)
+ : SfxTabDialogController(pParent, "cui/ui/calloutdialog.ui", "CalloutDialog")
+ , pView(pSdrView)
+ , nAnchorCtrls(nAnchorTypes)
+{
+ assert(pView); // No valid View transferred!
+
+ //different positioning page in Writer
+ if (nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
+ {
+ AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create,
+ SvxSwPosSizeTabPage::GetRanges );
+ RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
+ }
+ else
+ {
+ AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create,
+ SvxPositionSizeTabPage::GetRanges );
+ RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
+ }
+ AddTabPage("RID_SVXPAGE_CAPTION", SvxCaptionTabPage::Create,
+ SvxCaptionTabPage::GetRanges );
+}
+
+void SvxCaptionTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_POSITION_SIZE")
+ {
+ static_cast<SvxPositionSizeTabPage&>( rPage ).SetView( pView );
+ static_cast<SvxPositionSizeTabPage&>( rPage ).Construct();
+ if( nAnchorCtrls & SvxAnchorIds::NoResize )
+ static_cast<SvxPositionSizeTabPage&>( rPage ).DisableResize();
+
+ if( nAnchorCtrls & SvxAnchorIds::NoProtect )
+ static_cast<SvxPositionSizeTabPage&>( rPage ).DisableProtect();
+ }
+ else if (rId == "RID_SVXPAGE_SWPOSSIZE")
+ {
+ SvxSwPosSizeTabPage& rSwPage = static_cast<SvxSwPosSizeTabPage&>(rPage);
+ rSwPage.EnableAnchorTypes(nAnchorCtrls);
+ rSwPage.SetValidateFramePosLink( aValidateLink );
+ }
+ else if (rId == "RID_SVXPAGE_CAPTION")
+ {
+ static_cast<SvxCaptionTabPage&>( rPage ).SetView( pView );
+ static_cast<SvxCaptionTabPage&>( rPage ).Construct();
+ }
+}
+
+void SvxCaptionTabDialog::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ aValidateLink = rLink;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/macroass.cxx b/cui/source/tabpages/macroass.cxx
new file mode 100644
index 000000000..e80e471ff
--- /dev/null
+++ b/cui/source/tabpages/macroass.cxx
@@ -0,0 +1,397 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <macroass.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svl/macitem.hxx>
+#include <svx/svxids.hrc>
+#include <tools/debug.hxx>
+#include <vcl/idle.hxx>
+#include <cfgutil.hxx>
+#include <sfx2/evntconf.hxx>
+#include <headertablistbox.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::frame::XFrame;
+
+class SfxMacroTabPage_Impl
+{
+public:
+ SfxMacroTabPage_Impl();
+
+ OUString m_aStaticMacroLBLabel;
+ std::unique_ptr<weld::Button> m_xAssignPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<MacroEventListBox> m_xEventLB;
+ std::unique_ptr<weld::Widget> m_xGroupFrame;
+ std::unique_ptr<CuiConfigGroupListBox> m_xGroupLB;
+ std::unique_ptr<weld::Frame> m_xMacroFrame;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xMacroLB;
+
+ Idle m_aFillGroupIdle { "cui SfxMacroTabPage m_aFillGroupIdle" };
+ bool m_bGotEvents;
+};
+
+SfxMacroTabPage_Impl::SfxMacroTabPage_Impl()
+ : m_bGotEvents(false)
+{
+}
+
+static sal_uInt16 aPageRg[] = {
+ SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
+ 0
+};
+
+static OUString ConvertToUIName_Impl( SvxMacro const *pMacro )
+{
+ OUString aName( pMacro->GetMacName() );
+ if ( pMacro->GetLanguage() != "JavaScript" )
+ {
+ const sal_Int32 nCount = comphelper::string::getTokenCount(aName, '.');
+ OUString aEntry = aName.getToken( nCount-1, '.' );
+ if ( nCount > 2 )
+ {
+ aEntry += OUString::Concat("(") + o3tl::getToken(aName, 0, '.' ) + "." + o3tl::getToken(aName, nCount-2, '.' ) + ")";
+ }
+ return aEntry;
+ }
+ else
+ return aName;
+}
+
+void SfxMacroTabPage::EnableButtons()
+{
+ // don't do anything as long as the eventbox is empty
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rTreeView.get_selected_index();
+ if (nSelected != -1)
+ {
+ // get bound macro
+ const SvxMacro* pM = aTbl.Get(static_cast<SvMacroItemId>(rTreeView.get_selected_id().toInt32()));
+ mpImpl->m_xDeletePB->set_sensitive(nullptr != pM);
+
+ OUString sEventMacro = rTreeView.get_text(nSelected, 1);
+
+ OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ mpImpl->m_xAssignPB->set_sensitive(!sScriptURI.equalsIgnoreAsciiCase(sEventMacro));
+ }
+ else
+ mpImpl->m_xAssignPB->set_sensitive(false);
+}
+
+SfxMacroTabPage::SfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rAttrSet )
+ : SfxTabPage(pPage, pController, "cui/ui/eventassignpage.ui", "EventAssignPage", &rAttrSet)
+{
+ mpImpl.reset(new SfxMacroTabPage_Impl);
+
+ mpImpl->m_aFillGroupIdle.SetInvokeHandler( LINK( this, SfxMacroTabPage, TimeOut_Impl ) );
+ mpImpl->m_aFillGroupIdle.SetPriority( TaskPriority::HIGHEST );
+
+ mpImpl->m_xEventLB.reset(new MacroEventListBox(m_xBuilder->weld_tree_view("assignments")));
+ mpImpl->m_xAssignPB = m_xBuilder->weld_button("assign");
+ mpImpl->m_xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->m_xGroupFrame = m_xBuilder->weld_widget("groupframe");
+ mpImpl->m_xGroupLB.reset(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("libraries")));
+ mpImpl->m_xMacroFrame = m_xBuilder->weld_frame("macroframe");
+ mpImpl->m_aStaticMacroLBLabel = mpImpl->m_xMacroFrame->get_label();
+ mpImpl->m_xMacroLB.reset(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("macros")));
+
+ SetFrame( rxDocumentFrame );
+
+ InitAndSetHandler();
+
+ ScriptChanged();
+}
+
+SfxMacroTabPage::~SfxMacroTabPage()
+{
+ mpImpl.reset();
+}
+
+void SfxMacroTabPage::AddEvent(const OUString& rEventName, SvMacroItemId nEventId)
+{
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ rTreeView.append(OUString::number(static_cast<sal_Int32>(nEventId)), rEventName);
+
+ // if the table is valid already
+ SvxMacro* pM = aTbl.Get(nEventId);
+ if (pM)
+ {
+ OUString sNew(ConvertToUIName_Impl(pM));
+ rTreeView.set_text(rTreeView.n_children() - 1, sNew, 1);
+ }
+}
+
+void SfxMacroTabPage::ScriptChanged()
+{
+ // get new areas and their functions
+ mpImpl->m_xGroupFrame->show();
+ mpImpl->m_xMacroFrame->show();
+
+ EnableButtons();
+}
+
+bool SfxMacroTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
+ const_cast<SvxMacroTableDtor&>(aItem.GetMacroTable()) = aTbl;
+
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemState eState = GetItemSet().GetItemState(aItem.Which(), true, &pItem);
+ if (eState == SfxItemState::DEFAULT && aTbl.empty())
+ {
+ // Don't touch the item set if there was no input and our table is empty.
+ return false;
+ }
+ if (SfxItemState::SET != eState || aItem != *static_cast<const SvxMacroItem*>(pItem))
+ {
+ rSet->Put( aItem );
+ return true;
+ }
+ return false;
+}
+
+void SfxMacroTabPage::LaunchFillGroup()
+{
+ if (! mpImpl->m_aFillGroupIdle.IsActive() )
+ mpImpl->m_aFillGroupIdle.Start();
+}
+
+void SfxMacroTabPage::ActivatePage( const SfxItemSet& )
+{
+ LaunchFillGroup();
+}
+
+void SfxMacroTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ if( mpImpl->m_bGotEvents )
+ return;
+ if( const SfxEventNamesItem* pEventsItem = aSet.GetItemIfSet( SID_EVENTCONFIG ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = pEventsItem->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+}
+
+void SfxMacroTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == rSet->GetItemState( GetWhich( aPageRg[0] ), true, &pItem ))
+ aTbl = static_cast<const SvxMacroItem*>(pItem)->GetMacroTable();
+
+ const SfxEventNamesItem* pEventsItem;
+ if( !mpImpl->m_bGotEvents && (pEventsItem = rSet->GetItemIfSet( SID_EVENTCONFIG ) ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = pEventsItem->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+
+ FillEvents();
+
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ std::unique_ptr<weld::TreeIter> xIter(rListBox.make_iterator());
+ if (rListBox.get_iter_first(*xIter))
+ rListBox.set_cursor(*xIter);
+}
+
+bool SfxMacroTabPage::IsReadOnly() const
+{
+ return false;
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectEvent_Impl, weld::TreeView&, void)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ ScriptChanged();
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectGroup_Impl, weld::TreeView&, void)
+{
+ mpImpl->m_xGroupLB->GroupSelected();
+ const OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ OUString aLabelText;
+ if( !sScriptURI.isEmpty() )
+ aLabelText = mpImpl->m_aStaticMacroLBLabel;
+ mpImpl->m_xMacroFrame->set_label( aLabelText );
+
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectMacro_Impl, weld::TreeView&, void)
+{
+ EnableButtons();
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ AssignDeleteHdl(&rBtn);
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteHdl_Impl, weld::TreeView&, rBtn, bool)
+{
+ AssignDeleteHdl(&rBtn);
+ return true;
+}
+
+void SfxMacroTabPage::AssignDeleteHdl(const weld::Widget* pBtn)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != mpImpl->m_xDeletePB.get() && mpImpl->m_xAssignPB->get_sensitive();
+
+ // remove from the table
+ SvMacroItemId nEvent = static_cast<SvMacroItemId>(rListBox.get_selected_id().toInt32());
+ aTbl.Erase( nEvent );
+
+ OUString sScriptURI;
+ if( bAssEnabled )
+ {
+ sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ if( sScriptURI.startsWith( "vnd.sun.star.script:" ) )
+ {
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_SF ) );
+ }
+ else
+ {
+ OSL_ENSURE( false, "SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_STARBASIC ) );
+ }
+ }
+
+ rListBox.set_text(nSelected, sScriptURI, 1);
+
+ EnableButtons();
+}
+
+IMPL_LINK( SfxMacroTabPage, TimeOut_Impl, Timer*,, void )
+{
+ // FillMacroList() can take a long time -> show wait cursor and disable input
+ weld::Window* pDialog = GetFrameWeld();
+ // perhaps the tabpage is part of a SingleTabDialog then pDialog == nullptr
+ std::unique_ptr<weld::WaitObject> xWait(pDialog ? new weld::WaitObject(pDialog) : nullptr);
+ // fill macro list
+ mpImpl->m_xGroupLB->Init(comphelper::getProcessComponentContext(), GetFrame(),
+ OUString(), false);
+}
+
+void SfxMacroTabPage::InitAndSetHandler()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ Link<weld::TreeView&,bool> aLnk(LINK(this, SfxMacroTabPage, AssignDeleteHdl_Impl));
+ mpImpl->m_xMacroLB->connect_row_activated( aLnk);
+ mpImpl->m_xDeletePB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ mpImpl->m_xAssignPB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ rListBox.connect_row_activated(aLnk);
+
+ rListBox.connect_changed(LINK(this, SfxMacroTabPage, SelectEvent_Impl));
+ mpImpl->m_xGroupLB->connect_changed(LINK(this, SfxMacroTabPage, SelectGroup_Impl));
+ mpImpl->m_xMacroLB->connect_changed(LINK(this, SfxMacroTabPage, SelectMacro_Impl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(rListBox.get_approximate_digit_width() * 35)
+ };
+ rListBox.set_column_fixed_widths(aWidths);
+
+ mpImpl->m_xEventLB->show();
+
+ mpImpl->m_xEventLB->set_sensitive(true);
+ mpImpl->m_xGroupLB->set_sensitive(true);
+ mpImpl->m_xMacroLB->set_sensitive(true);
+
+ mpImpl->m_xGroupLB->SetFunctionListBox(mpImpl->m_xMacroLB.get());
+}
+
+void SfxMacroTabPage::FillEvents()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+
+ int nEntryCnt = rListBox.n_children();
+
+ // get events from the table and fill the EventListBox respectively
+ for (int n = 0 ; n < nEntryCnt; ++n)
+ {
+ OUString sOld = rListBox.get_text(n, 1);
+ OUString sNew;
+ SvMacroItemId nEventId = static_cast<SvMacroItemId>(rListBox.get_id(n).toInt32());
+ if (aTbl.IsKeyValid(nEventId))
+ sNew = ConvertToUIName_Impl(aTbl.Get(nEventId));
+
+ if (sOld == sNew)
+ continue;
+
+ rListBox.set_text(n, sNew, 1);
+ }
+}
+
+namespace
+{
+ std::unique_ptr<SfxMacroTabPage> CreateSfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ {
+ return std::make_unique<SfxMacroTabPage>( pPage, pController, nullptr, rAttrSet );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SfxMacroTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return CreateSfxMacroTabPage(pPage, pController, *rAttrSet);
+}
+
+SfxMacroAssignDlg::SfxMacroAssignDlg(weld::Widget* pParent,
+ const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet,"cui/ui/eventassigndialog.ui",
+ "EventAssignDialog")
+{
+ std::unique_ptr<SfxMacroTabPage> xPage = CreateSfxMacroTabPage(get_content_area(), this, rSet);
+ xPage->SetFrame(rxDocumentFrame);
+ SetTabPage(std::move(xPage));
+ GetTabPage()->LaunchFillGroup();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/measure.cxx b/cui/source/tabpages/measure.cxx
new file mode 100644
index 000000000..fe61ed53a
--- /dev/null
+++ b/cui/source/tabpages/measure.cxx
@@ -0,0 +1,755 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <svx/svxids.hrc>
+#include <svx/dlgutil.hxx>
+#include <svx/measctrl.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/strarray.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sxmbritm.hxx>
+#include <svx/sxmlhitm.hxx>
+#include <svx/sxmtfitm.hxx>
+#include <svx/sxmtpitm.hxx>
+#include <svx/sxmtritm.hxx>
+#include <svx/sxmuitm.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <measure.hxx>
+
+const WhichRangesContainer SvxMeasurePage::pRanges(
+ svl::Items<SDRATTR_MEASURE_FIRST, SDRATTR_MEASURE_LAST>);
+
+/*************************************************************************
+|*
+|* Dialog to change measure-attributes
+|*
+\************************************************************************/
+SvxMeasureDialog::SvxMeasureDialog(weld::Window* pParent, const SfxItemSet& rInAttrs,
+ const SdrView* pSdrView)
+ : SfxSingleTabDialogController(pParent, &rInAttrs)
+{
+ auto xPage = std::make_unique<SvxMeasurePage>(get_content_area(), this, rInAttrs);
+
+ xPage->SetView(pSdrView);
+ xPage->Construct();
+
+ SetTabPage(std::move(xPage));
+ m_xDialog->set_title(CuiResId(RID_CUISTR_DIMENSION_LINE));
+}
+
+/*************************************************************************
+|*
+|* Tabpage for changing measure-attributes
+|*
+\************************************************************************/
+
+SvxMeasurePage::SvxMeasurePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/dimensionlinestabpage.ui", "DimensionLinesTabPage", rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aAttrSet(*rInAttrs.GetPool())
+ , pView(nullptr)
+ , eUnit(MapUnit::Map100thMM)
+ , bPositionModified(false)
+ , m_aCtlPosition(this)
+ , m_xMtrFldLineDist(m_xBuilder->weld_metric_spin_button("MTR_LINE_DIST", FieldUnit::MM))
+ , m_xMtrFldHelplineOverhang(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE_OVERHANG", FieldUnit::MM))
+ , m_xMtrFldHelplineDist(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE_DIST", FieldUnit::MM))
+ , m_xMtrFldHelpline1Len(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE1_LEN", FieldUnit::MM))
+ , m_xMtrFldHelpline2Len(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE2_LEN", FieldUnit::MM))
+ , m_xTsbBelowRefEdge(m_xBuilder->weld_check_button("TSB_BELOW_REF_EDGE"))
+ , m_xMtrFldDecimalPlaces(m_xBuilder->weld_spin_button("MTR_FLD_DECIMALPLACES"))
+ , m_xTsbAutoPosV(m_xBuilder->weld_check_button("TSB_AUTOPOSV"))
+ , m_xTsbAutoPosH(m_xBuilder->weld_check_button("TSB_AUTOPOSH"))
+ , m_xTsbShowUnit(m_xBuilder->weld_check_button("TSB_SHOW_UNIT"))
+ , m_xLbUnit(m_xBuilder->weld_combo_box("LB_UNIT"))
+ , m_xTsbParallel(m_xBuilder->weld_check_button("TSB_PARALLEL"))
+ , m_xFtAutomatic(m_xBuilder->weld_label("STR_MEASURE_AUTOMATIC"))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ m_aCtlPreview.SetAttributes(rInAttrs);
+
+ FillUnitLB();
+
+ const FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldLineDist, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelplineOverhang, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelplineDist, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelpline1Len, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelpline2Len, eFUnit );
+ if( eFUnit == FieldUnit::MM )
+ {
+ m_xMtrFldLineDist->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelplineOverhang->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelplineDist->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelpline1Len->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelpline2Len->set_increments(50, 500, FieldUnit::NONE);
+ }
+
+ m_xTsbAutoPosV->connect_toggled(LINK( this, SvxMeasurePage, ClickAutoPosHdl_Impl));
+ m_xTsbAutoPosH->connect_toggled(LINK(this, SvxMeasurePage, ClickAutoPosHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink(LINK(this, SvxMeasurePage, ChangeAttrEditHdl_Impl));
+ m_xMtrFldLineDist->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldLineDist->connect_value_changed(aLink);
+ m_xMtrFldHelplineOverhang->connect_value_changed(aLink);
+ m_xMtrFldHelplineOverhang->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldHelplineDist->connect_value_changed(aLink);
+ m_xMtrFldHelplineDist->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldHelpline1Len->connect_value_changed(aLink);
+ m_xMtrFldHelpline1Len->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldHelpline2Len->connect_value_changed(aLink);
+ m_xMtrFldHelpline2Len->set_range(-10000, 10000, FieldUnit::MM);
+ m_xMtrFldDecimalPlaces->connect_value_changed(LINK(this, SvxMeasurePage, ChangeAttrSpinHdl_Impl));
+ m_xTsbBelowRefEdge->connect_toggled(LINK(this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xTsbParallel->connect_toggled( LINK( this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xTsbShowUnit->connect_toggled(LINK(this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xLbUnit->connect_changed(LINK(this, SvxMeasurePage, ChangeAttrListBoxHdl_Impl));
+}
+
+SvxMeasurePage::~SvxMeasurePage()
+{
+ m_xCtlPreview.reset();
+ m_xCtlPosition.reset();
+}
+
+/*************************************************************************
+|*
+|* read the delivered Item-Set
+|*
+\************************************************************************/
+
+void SvxMeasurePage::Reset( const SfxItemSet* rAttrs )
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ eUnit = pPool->GetMetric( SDRATTR_MEASURELINEDIST );
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_MEASURELINEDIST );
+
+ // SdrMeasureLineDistItem
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASURELINEDIST );
+ SetMetricValue(*m_xMtrFldLineDist, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLineDist->save_value();
+
+ // SdrMeasureHelplineOverhangItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINEOVERHANG );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINEOVERHANG );
+ SetMetricValue(*m_xMtrFldHelplineOverhang, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelplineOverhang->save_value();
+
+ // SdrMeasureHelplineDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINEDIST );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINEDIST );
+ SetMetricValue(*m_xMtrFldHelplineDist, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelplineDist->save_value();
+
+ // SdrMeasureHelpline1LenItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINE1LEN );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINE1LEN );
+ SetMetricValue(*m_xMtrFldHelpline1Len, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelpline1Len->save_value();
+
+ // SdrMeasureHelpline2LenItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINE2LEN );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINE2LEN );
+ SetMetricValue(*m_xMtrFldHelpline2Len, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelpline2Len->save_value();
+
+ // SdrMeasureBelowRefEdgeItem
+ if( rAttrs->GetItemState( SDRATTR_MEASUREBELOWREFEDGE ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbBelowRefEdge->set_state( rAttrs->Get( SDRATTR_MEASUREBELOWREFEDGE ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbBelowRefEdge->set_state( TRISTATE_INDET );
+ }
+ m_xTsbBelowRefEdge->save_state();
+
+ // SdrMeasureDecimalPlacesItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREDECIMALPLACES );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREDECIMALPLACES );
+ m_xMtrFldDecimalPlaces->set_value(
+ static_cast<const SdrMeasureDecimalPlacesItem*>(pItem)->GetValue());
+ m_xMtrFldDecimalPlaces->save_value();
+
+ // SdrMeasureTextRota90Item
+ // Attention: negate !
+ if( rAttrs->GetItemState( SDRATTR_MEASURETEXTROTA90 ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbParallel->set_state( rAttrs->Get( SDRATTR_MEASURETEXTROTA90 ).
+ GetValue() ? TRISTATE_FALSE : TRISTATE_TRUE );
+ }
+ else
+ {
+ m_xTsbParallel->set_state( TRISTATE_INDET );
+ }
+ m_xTsbParallel->save_state();
+
+ // SdrMeasureShowUnitItem
+ if( rAttrs->GetItemState( SDRATTR_MEASURESHOWUNIT ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbShowUnit->set_state( rAttrs->Get( SDRATTR_MEASURESHOWUNIT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbShowUnit->set_state( TRISTATE_INDET );
+ }
+ m_xTsbShowUnit->save_state();
+
+ // SdrMeasureUnitItem
+ if( rAttrs->GetItemState( SDRATTR_MEASUREUNIT ) != SfxItemState::DONTCARE )
+ {
+ tools::Long nFieldUnit = static_cast<tools::Long>(rAttrs->Get( SDRATTR_MEASUREUNIT ).GetValue());
+
+ for (sal_Int32 i = 0; i < m_xLbUnit->get_count(); ++i)
+ {
+ if (m_xLbUnit->get_id(i).toInt32() == nFieldUnit)
+ {
+ m_xLbUnit->set_active(i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ m_xLbUnit->set_active(-1);
+ }
+ m_xLbUnit->save_value();
+
+ // Position
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTVPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextVertPos eVPos =
+ rAttrs->Get( SDRATTR_MEASURETEXTVPOS ).GetValue();
+ {
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTHPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextHorzPos eHPos =
+ rAttrs->Get( SDRATTR_MEASURETEXTHPOS ).GetValue();
+ RectPoint eRP = RectPoint::MM;
+ switch( eVPos )
+ {
+ case css::drawing::MeasureTextVertPos_EAST:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LT; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MT; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RT; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MT; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_CENTERED:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LM; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MM; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RM; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MM; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_WEST:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LB; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MB; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RB; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MB; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_AUTO:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LM; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MM; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RM; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MM; break;
+ default: break;
+ }
+ break;
+ default: ;//prevent warning
+ }
+
+ CTL_STATE nState = CTL_STATE::NONE;
+
+ if (eHPos == css::drawing::MeasureTextHorzPos_AUTO)
+ {
+ m_xTsbAutoPosH->set_state( TRISTATE_TRUE );
+ nState = CTL_STATE::NOHORZ;
+ }
+
+ if (eVPos == css::drawing::MeasureTextVertPos_AUTO)
+ {
+ m_xTsbAutoPosV->set_state( TRISTATE_TRUE );
+ nState |= CTL_STATE::NOVERT;
+ }
+
+ m_aCtlPosition.SetState(nState);
+ m_aCtlPosition.SetActualRP(eRP);
+ }
+ }
+ }
+ else
+ {
+ m_aCtlPosition.Reset();
+ m_xTsbAutoPosV->set_state( TRISTATE_INDET );
+ m_xTsbAutoPosH->set_state( TRISTATE_INDET );
+ }
+
+ // put the attributes to the preview-control,
+ // otherwise the control don't know about
+ // the settings of the dialog (#67930)
+ ChangeAttrHdl_Impl(m_xTsbShowUnit.get());
+ m_aCtlPreview.SetAttributes(*rAttrs);
+
+ bPositionModified = false;
+}
+
+/*************************************************************************
+|*
+|* Fill the delivered Item-Set with dialogbox-attributes
+|*
+\************************************************************************/
+
+bool SvxMeasurePage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ sal_Int32 nValue;
+ TriState eState;
+
+ if( m_xMtrFldLineDist->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldLineDist, eUnit );
+ rAttrs->Put( makeSdrMeasureLineDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelplineOverhang->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelplineOverhang, eUnit );
+ rAttrs->Put( makeSdrMeasureHelplineOverhangItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelplineDist->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelplineDist, eUnit );
+ rAttrs->Put( makeSdrMeasureHelplineDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelpline1Len->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelpline1Len, eUnit );
+ rAttrs->Put( makeSdrMeasureHelpline1LenItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelpline2Len->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelpline2Len, eUnit );
+ rAttrs->Put( makeSdrMeasureHelpline2LenItem( nValue ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbBelowRefEdge->get_state();
+ if( m_xTsbBelowRefEdge->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrMeasureBelowRefEdgeItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldDecimalPlaces->get_value_changed_from_saved() )
+ {
+ nValue = m_xMtrFldDecimalPlaces->get_value();
+ rAttrs->Put(
+ SdrMeasureDecimalPlacesItem(
+ sal::static_int_cast< sal_Int16 >( nValue ) ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbParallel->get_state();
+ if( m_xTsbParallel->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrMeasureTextRota90Item( TRISTATE_FALSE == eState ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbShowUnit->get_state();
+ if( m_xTsbShowUnit->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrYesNoItem(SDRATTR_MEASURESHOWUNIT, TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ int nPos = m_xLbUnit->get_active();
+ if( m_xLbUnit->get_value_changed_from_saved() )
+ {
+ if (nPos != -1)
+ {
+ sal_uInt16 nFieldUnit = m_xLbUnit->get_id(nPos).toUInt32();
+ FieldUnit _eUnit = static_cast<FieldUnit>(nFieldUnit);
+ rAttrs->Put( SdrMeasureUnitItem( _eUnit ) );
+ bModified = true;
+ }
+ }
+
+ if( bPositionModified )
+ {
+ // Position
+ css::drawing::MeasureTextVertPos eVPos;
+ css::drawing::MeasureTextHorzPos eHPos;
+
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::MT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::RT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ }
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ eHPos = css::drawing::MeasureTextHorzPos_AUTO;
+
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ eVPos = css::drawing::MeasureTextVertPos_AUTO;
+
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTVPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextVertPos eOldVPos = rOutAttrs.Get(SDRATTR_MEASURETEXTVPOS).GetValue();
+ if( eOldVPos != eVPos )
+ {
+ rAttrs->Put( SdrMeasureTextVPosItem( eVPos ) );
+ bModified = true;
+ }
+ }
+ else
+ {
+ rAttrs->Put( SdrMeasureTextVPosItem( eVPos ) );
+ bModified = true;
+ }
+
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTHPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextHorzPos eOldHPos = rOutAttrs.Get( SDRATTR_MEASURETEXTHPOS ).GetValue();
+ if( eOldHPos != eHPos )
+ {
+ rAttrs->Put( SdrMeasureTextHPosItem( eHPos ) );
+ bModified = true;
+ }
+ }
+ else
+ {
+ rAttrs->Put( SdrMeasureTextHPosItem( eHPos ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+/*************************************************************************
+|*
+|* The View have to set at the measure-object to be able to notify
+|* unit and floatingpoint-values
+|*
+\************************************************************************/
+
+void SvxMeasurePage::Construct()
+{
+ DBG_ASSERT( pView, "No valid View transferred!" );
+
+ // TTTT
+ // pMeasureObj is member of SvxXMeasurePreview and can only be accessed due to
+ // SvxMeasurePage being a friend. It has its own SdrModel (also in SvxXMeasurePreview)
+ // and 'setting' the SdrModel is a hack. The comment above about 'notify unit and
+ // floatingpoint-values' is not clear, but has to be done another way - if needed.
+ // Checked on original aw080, is just commented out there, too.
+
+ m_aCtlPreview.Invalidate();
+}
+
+std::unique_ptr<SfxTabPage> SvxMeasurePage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxMeasurePage>(pPage, pController, *rAttrs);
+}
+
+void SvxMeasurePage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint /*eRP*/)
+{
+ ChangeAttrHdl_Impl(pDrawingArea);
+}
+
+IMPL_LINK( SvxMeasurePage, ClickAutoPosHdl_Impl, weld::Toggleable&, rBox, void )
+{
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ {
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::RT:
+ m_aCtlPosition.SetActualRP( RectPoint::MT );
+ break;
+
+ case RectPoint::LM:
+ case RectPoint::RM:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::LB:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::MB );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ {
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::LB:
+ m_aCtlPosition.SetActualRP( RectPoint::LM );
+ break;
+
+ case RectPoint::MT:
+ case RectPoint::MB:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::RT:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::RM );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrClickHdl_Impl, weld::Toggleable&, r, void)
+{
+ ChangeAttrHdl_Impl(&r);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrListBoxHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, rBox, void)
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK( SvxMeasurePage, ChangeAttrSpinHdl_Impl, weld::SpinButton&, rBox, void )
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+void SvxMeasurePage::ChangeAttrHdl_Impl( void const * p )
+{
+ if (p == m_xMtrFldLineDist.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldLineDist, eUnit );
+ aAttrSet.Put( makeSdrMeasureLineDistItem( nValue ) );
+ }
+
+ if (p == m_xMtrFldHelplineOverhang.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelplineOverhang, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelplineOverhangItem( nValue) );
+ }
+
+ if (p == m_xMtrFldHelplineDist.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelplineDist, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelplineDistItem( nValue) );
+ }
+
+ if (p == m_xMtrFldHelpline1Len.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelpline1Len, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelpline1LenItem( nValue ) );
+ }
+
+ if (p == m_xMtrFldHelpline2Len.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelpline2Len, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelpline2LenItem( nValue ) );
+ }
+
+ if (p == m_xTsbBelowRefEdge.get())
+ {
+ TriState eState = m_xTsbBelowRefEdge->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrMeasureBelowRefEdgeItem( TRISTATE_TRUE == eState ) );
+ }
+
+ if (p == m_xMtrFldDecimalPlaces.get())
+ {
+ sal_Int16 nValue = sal::static_int_cast< sal_Int16 >(
+ m_xMtrFldDecimalPlaces->get_value() );
+ aAttrSet.Put( SdrMeasureDecimalPlacesItem( nValue ) );
+ }
+
+ if (p == m_xTsbParallel.get())
+ {
+ TriState eState = m_xTsbParallel->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrMeasureTextRota90Item( TRISTATE_FALSE == eState ) );
+ }
+
+ if (p == m_xTsbShowUnit.get())
+ {
+ TriState eState = m_xTsbShowUnit->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrYesNoItem( SDRATTR_MEASURESHOWUNIT, TRISTATE_TRUE == eState ) );
+ }
+
+ if (p == m_xLbUnit.get())
+ {
+ int nPos = m_xLbUnit->get_active();
+ if (nPos != -1)
+ {
+ sal_uInt16 nFieldUnit = m_xLbUnit->get_id(nPos).toUInt32();
+ FieldUnit _eUnit = static_cast<FieldUnit>(nFieldUnit);
+ aAttrSet.Put( SdrMeasureUnitItem( _eUnit ) );
+ }
+ }
+
+ if (p == m_xTsbAutoPosV.get() || p == m_xTsbAutoPosH.get() || p == m_aCtlPosition.GetDrawingArea())
+ {
+ bPositionModified = true;
+
+ // Position
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ css::drawing::MeasureTextVertPos eVPos;
+ css::drawing::MeasureTextHorzPos eHPos;
+
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::MT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::RT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ }
+
+ CTL_STATE nState = CTL_STATE::NONE;
+
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ {
+ eHPos = css::drawing::MeasureTextHorzPos_AUTO;
+ nState = CTL_STATE::NOHORZ;
+ }
+
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ {
+ eVPos = css::drawing::MeasureTextVertPos_AUTO;
+ nState |= CTL_STATE::NOVERT;
+ }
+
+ if (p == m_xTsbAutoPosV.get() || p == m_xTsbAutoPosH.get())
+ m_aCtlPosition.SetState( nState );
+
+ aAttrSet.Put( SdrMeasureTextVPosItem( eVPos ) );
+ aAttrSet.Put( SdrMeasureTextHPosItem( eHPos ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxMeasurePage::FillUnitLB()
+{
+ // fill ListBox with metrics
+
+ FieldUnit nUnit = FieldUnit::NONE;
+ OUString aStrMetric(m_xFtAutomatic->get_label());
+ m_xLbUnit->append(OUString::number(sal_uInt32(nUnit)), aStrMetric);
+
+ for( sal_uInt32 i = 0; i < SvxFieldUnitTable::Count(); ++i )
+ {
+ aStrMetric = SvxFieldUnitTable::GetString(i);
+ nUnit = SvxFieldUnitTable::GetValue(i);
+ m_xLbUnit->append(OUString::number(sal_uInt32(nUnit)), aStrMetric);
+ }
+}
+
+void SvxMeasurePage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const OfaPtrItem* pOfaPtrItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+
+ if (pOfaPtrItem)
+ SetView( static_cast<SdrView *>(pOfaPtrItem->GetValue()));
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx
new file mode 100644
index 000000000..4e804bc44
--- /dev/null
+++ b/cui/source/tabpages/numfmt.cxx
@@ -0,0 +1,1746 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/safeint.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/outdev.hxx>
+#include <i18nlangtag/lang.h>
+#include <svx/svxids.hrc>
+#include <svtools/colorcfg.hxx>
+
+#include <numcategories.hrc>
+#include <strings.hrc>
+
+#include <svx/numinf.hxx>
+
+#include <numfmt.hxx>
+#include <svx/numfmtsh.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <svx/flagsdef.hxx>
+#include <vector>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <limits>
+#include <memory>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::UNO_QUERY;
+
+#define NUMKEY_UNDEFINED SAL_MAX_UINT32
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxNumberFormatTabPage::pRanges(
+ svl::Items<
+ SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO, // 10085 - 10086
+ SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA, // 10580 - 10580
+ SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE, // 10700 - 10700
+ SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE>); // 10932 - 10932
+
+/*************************************************************************
+#* Method: SvxNumberPreview
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Constructor of the class SvxNumberPreview
+#* Input: Window, Resource-ID
+#* Output: ---
+#*
+#************************************************************************/
+
+SvxNumberPreview::SvxNumberPreview()
+ : mnPos(-1)
+ , mnChar(0x0)
+{
+}
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Function for changing the preview string
+#* Input: String, color
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberPreview::NotifyChange( const OUString& rPrevStr,
+ const Color* pColor )
+{
+ // detect and strip out '*' related placeholders
+ aPrevStr = rPrevStr;
+ mnPos = aPrevStr.indexOf( 0x1B );
+ if ( mnPos != -1 )
+ {
+ // Right during user input the star symbol is the very
+ // last character before the user enters another one.
+ if (mnPos < aPrevStr.getLength() - 1)
+ {
+ mnChar = aPrevStr[ mnPos + 1 ];
+ // delete placeholder and char to repeat
+ aPrevStr = aPrevStr.replaceAt( mnPos, 2, u"" );
+ }
+ else
+ {
+ // delete placeholder
+ aPrevStr = aPrevStr.replaceAt( mnPos, 1, u"" );
+ // do not attempt to draw a 0 fill character
+ mnPos = -1;
+ }
+ }
+ svtools::ColorConfig aColorConfig;
+ Color aWindowTextColor( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
+ aPrevCol = pColor ? *pColor : aWindowTextColor;
+ Invalidate();
+}
+
+/*************************************************************************
+#* Method: Paint
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Function for repainting the window.
+#* Input: ---
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.Push(vcl::PushFlags::ALL);
+
+ svtools::ColorConfig aColorConfig;
+ rRenderContext.SetTextColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor);
+ rRenderContext.SetBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
+
+ vcl::Font aDrawFont = rRenderContext.GetFont();
+ Size aSzWnd(GetOutputSizePixel());
+ OUString aTmpStr(aPrevStr);
+ tools::Long nLeadSpace = (aSzWnd.Width() - rRenderContext.GetTextWidth(aTmpStr)) / 2;
+
+ aDrawFont.SetTransparent(true);
+ aDrawFont.SetColor(aPrevCol);
+ rRenderContext.SetFont(aDrawFont);
+
+ if (mnPos != -1)
+ {
+ tools::Long nCharWidth = rRenderContext.GetTextWidth(OUString(mnChar));
+
+ int nNumCharsToInsert = 0;
+ if (nCharWidth > 0)
+ nNumCharsToInsert = nLeadSpace / nCharWidth;
+
+ if (nNumCharsToInsert > 0)
+ {
+ for (int i = 0; i < nNumCharsToInsert; ++i)
+ aTmpStr = aTmpStr.replaceAt(mnPos, 0, rtl::OUStringChar(mnChar));
+ }
+ }
+
+ tools::Long nX = 0;
+ if (mnPos == -1 && nLeadSpace > 0) //tdf#122120 if it won't fit anyway, then left align it
+ {
+ nX = nLeadSpace;
+ }
+
+ Point aPosText(nX, (aSzWnd.Height() - GetTextHeight()) / 2);
+ rRenderContext.DrawText(aPosText, aTmpStr);
+ rRenderContext.Pop();
+}
+
+// class SvxNumberFormatTabPage ------------------------------------------
+
+#define REMOVE_DONTKNOW() \
+ if (!m_xFtLanguage->get_sensitive()) \
+ { \
+ m_xFtLanguage->set_sensitive(true); \
+ m_xLbLanguage->set_sensitive(true); \
+ m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage()); \
+ }
+
+SvxNumberFormatTabPage::SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingformatpage.ui", "NumberingFormatPage", &rCoreAttrs)
+ , nInitFormat(std::numeric_limits<sal_uInt32>::max())
+ , m_nLbFormatSelPosEdComment(SELPOS_NONE)
+ , bLegacyAutomaticCurrency(false)
+ , sAutomaticLangEntry(CuiResId(RID_CUISTR_AUTO_ENTRY))
+ , m_xFtCategory(m_xBuilder->weld_label("categoryft"))
+ , m_xLbCategory(m_xBuilder->weld_tree_view("categorylb"))
+ , m_xFtFormat(m_xBuilder->weld_label("formatft"))
+ , m_xLbCurrency(m_xBuilder->weld_combo_box("currencylb"))
+ , m_xLbFormat(m_xBuilder->weld_tree_view("formatlb"))
+ , m_xFtLanguage(m_xBuilder->weld_label("languageft"))
+ , m_xCbSourceFormat(m_xBuilder->weld_check_button("sourceformat"))
+ , m_xFtOptions(m_xBuilder->weld_label("optionsft"))
+ , m_xFtDecimals(m_xBuilder->weld_label("decimalsft"))
+ , m_xEdDecimals(m_xBuilder->weld_spin_button("decimalsed"))
+ , m_xFtDenominator(m_xBuilder->weld_label("denominatorft"))
+ , m_xEdDenominator(m_xBuilder->weld_spin_button("denominatored"))
+ , m_xBtnNegRed(m_xBuilder->weld_check_button("negnumred"))
+ , m_xFtLeadZeroes(m_xBuilder->weld_label("leadzerosft"))
+ , m_xEdLeadZeroes(m_xBuilder->weld_spin_button("leadzerosed"))
+ , m_xBtnThousand(m_xBuilder->weld_check_button("thousands"))
+ , m_xBtnEngineering(m_xBuilder->weld_check_button("engineering"))
+ , m_xFormatCodeFrame(m_xBuilder->weld_widget("formatcode"))
+ , m_xEdFormat(m_xBuilder->weld_entry("formatted"))
+ , m_xIbAdd(m_xBuilder->weld_button("add"))
+ , m_xIbInfo(m_xBuilder->weld_button("edit"))
+ , m_xIbRemove(m_xBuilder->weld_button("delete"))
+ , m_xFtComment(m_xBuilder->weld_label("commentft"))
+ , m_xEdComment(m_xBuilder->weld_entry("commented"))
+ , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("languagelb")))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aWndPreview))
+{
+ for (size_t i = 0; i < std::size(NUM_CATEGORIES); ++i)
+ m_xLbCategory->append_text(CuiResId(NUM_CATEGORIES[i]));
+
+ auto nWidth = m_xLbCategory->get_approximate_digit_width() * 22;
+ m_xLbCategory->set_size_request(nWidth, m_xLbCategory->get_height_rows(7));
+ m_xLbFormat->set_size_request(nWidth, m_xLbFormat->get_height_rows(5));
+ m_xLbCurrency->set_size_request(nWidth, -1); // force using (narrower) width of its LbFormat sibling
+
+ // Initially remove the "Automatically" entry.
+ m_xLbCurrency->set_active(-1); // First ensure that nothing is selected.
+ sAutomaticCurrencyEntry = m_xLbCurrency->get_text(0);
+ m_xLbCurrency->remove(0);
+
+ Init_Impl();
+ SetExchangeSupport(); // this page needs ExchangeSupport
+ nFixedCategory=-1;
+}
+
+SvxNumberFormatTabPage::~SvxNumberFormatTabPage()
+{
+ pNumFmtShell.reset();
+ pNumItem.reset();
+ m_xWndPreview.reset();
+ m_xLbLanguage.reset();
+}
+
+void SvxNumberFormatTabPage::Init_Impl()
+{
+ bNumItemFlag=true;
+ bOneAreaFlag=false;
+
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
+
+ m_xEdComment->hide();
+
+ m_xCbSourceFormat->set_active( false );
+ m_xCbSourceFormat->set_sensitive(false);
+ m_xCbSourceFormat->hide();
+
+ Link<weld::TreeView&,void> aLink2 = LINK(this, SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl);
+ Link<weld::ComboBox&,void> aLink3 = LINK(this, SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl);
+ m_xLbCategory->connect_changed(aLink2);
+ m_xLbCategory->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbFormat->connect_changed(aLink2);
+ m_xLbFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbLanguage->connect_changed(aLink3);
+ m_xLbLanguage->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbCurrency->connect_changed(aLink3);
+ m_xLbCurrency->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xCbSourceFormat->connect_toggled(LINK(this, SvxNumberFormatTabPage, SelFormatClickHdl_Impl));
+ m_xCbSourceFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+
+ Link<weld::SpinButton&,void> aLink = LINK( this, SvxNumberFormatTabPage, OptEditHdl_Impl );
+
+ m_xEdDecimals->connect_value_changed(aLink);
+ m_xEdDecimals->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xEdDenominator->connect_value_changed(aLink);
+ m_xEdDenominator->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xEdLeadZeroes->connect_value_changed(aLink);
+ m_xEdLeadZeroes->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+
+ m_xBtnNegRed->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnNegRed->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xBtnThousand->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnThousand->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xBtnEngineering->connect_toggled(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnEngineering->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbFormat->connect_row_activated(LINK(this, SvxNumberFormatTabPage, DoubleClickHdl_Impl));
+ m_xEdFormat->connect_changed(LINK(this, SvxNumberFormatTabPage, EditModifyHdl_Impl));
+ m_xEdFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbAdd->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
+ m_xIbAdd->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbRemove->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
+ m_xIbRemove->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbInfo->connect_clicked(LINK(this, SvxNumberFormatTabPage, ClickHdl_Impl));
+ UpdateThousandEngineeringCheckBox();
+ UpdateDecimalsDenominatorEditBox();
+
+ // initialize language ListBox
+
+ m_xLbLanguage->SetLanguageList(SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
+ false, false, false, true, LANGUAGE_SYSTEM,
+ css::i18n::ScriptType::WEAK);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumberFormatTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxNumberFormatTabPage>(pPage, pController, *rAttrSet);
+}
+
+
+/*************************************************************************
+#* Method: Reset
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: The dialog's attributes are reset
+#* using the Itemset.
+#* Input: SfxItemSet
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::set_active_currency(sal_Int32 nPos)
+{
+ static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
+ if (nPos == 0 && !bLegacyAutomaticCurrency)
+ {
+ // Insert "Automatically" if currently used so it is selectable.
+ m_xLbCurrency->insert_text(0, sAutomaticCurrencyEntry);
+ bLegacyAutomaticCurrency = true;
+ }
+ if (nPos != -1 && !bLegacyAutomaticCurrency)
+ --nPos;
+ m_xLbCurrency->set_active(nPos);
+}
+
+sal_uInt32 SvxNumberFormatTabPage::get_active_currency() const
+{
+ static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
+ sal_Int32 nCurrencyPos = m_xLbCurrency->get_active();
+ if (nCurrencyPos != -1 && !bLegacyAutomaticCurrency)
+ ++nCurrencyPos;
+ return nCurrencyPos;
+}
+
+void SvxNumberFormatTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxUInt32Item* pValFmtAttr = nullptr;
+ const SfxPoolItem* pItem = nullptr;
+ const SfxBoolItem* pAutoEntryAttr = nullptr;
+
+ sal_uInt16 nCatLbSelPos = 0;
+ sal_uInt16 nFmtLbSelPos = 0;
+ LanguageType eLangType = LANGUAGE_DONTKNOW;
+ std::vector<OUString> aFmtEntryList;
+ SvxNumberValueType eValType = SvxNumberValueType::Undefined;
+ double nValDouble = 0;
+ OUString aValString;
+
+ if(const SfxBoolItem* pBoolLangItem = rSet->GetItemIfSet( SID_ATTR_NUMBERFORMAT_NOLANGUAGE ))
+ {
+ if(pBoolLangItem->GetValue())
+ {
+ HideLanguage();
+ }
+ else
+ {
+ HideLanguage(false);
+ }
+
+ }
+
+ SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_INFO ),true,&pItem);
+
+ if(eState==SfxItemState::SET)
+ {
+ if(pNumItem==nullptr)
+ {
+ bNumItemFlag=true;
+ pNumItem.reset( static_cast<SvxNumberInfoItem *>(pItem->Clone()) );
+ }
+ else
+ {
+ bNumItemFlag=false;
+ }
+ }
+ else
+ {
+ bNumItemFlag=false;
+ }
+
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_ONE_AREA ));
+
+ if(eState==SfxItemState::SET)
+ {
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ONE_AREA));
+
+ if(pBoolItem!=nullptr)
+ {
+ bOneAreaFlag= pBoolItem->GetValue();
+ }
+ }
+
+ eState = rSet->GetItemState( SID_ATTR_NUMBERFORMAT_SOURCE );
+
+ if ( eState == SfxItemState::SET )
+ {
+ const SfxBoolItem* pBoolItem =
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_SOURCE );
+ if ( pBoolItem )
+ m_xCbSourceFormat->set_active(pBoolItem->GetValue());
+ else
+ m_xCbSourceFormat->set_active( false );
+ m_xCbSourceFormat->set_sensitive(true);
+ m_xCbSourceFormat->show();
+ }
+ else
+ {
+ bool bInit = false; // set to sal_True for debug test
+ m_xCbSourceFormat->set_active( bInit );
+ m_xCbSourceFormat->set_sensitive( bInit );
+ m_xCbSourceFormat->set_visible( bInit );
+ }
+
+ // pNumItem must have been set from outside!
+ DBG_ASSERT( pNumItem, "No NumberInfo, no NumberFormatter, goodbye. CRASH. :-(" );
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_VALUE ) );
+
+ if ( SfxItemState::DONTCARE != eState )
+ pValFmtAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_VALUE );
+
+ eValType = pNumItem->GetValueType();
+
+ switch ( eValType )
+ {
+ case SvxNumberValueType::String:
+ aValString = pNumItem->GetValueString();
+ break;
+ case SvxNumberValueType::Number:
+ // #50441# string may be set in addition to the value
+ aValString = pNumItem->GetValueString();
+ nValDouble = pNumItem->GetValueDouble();
+ break;
+ case SvxNumberValueType::Undefined:
+ default:
+ break;
+ }
+
+ pNumFmtShell.reset(); // delete old shell if applicable (== reset)
+
+ nInitFormat = pValFmtAttr // memorize init key
+ ? pValFmtAttr->GetValue() // (for FillItemSet())
+ : std::numeric_limits<sal_uInt32>::max(); // == DONT_KNOW
+
+
+ if ( eValType == SvxNumberValueType::String )
+ pNumFmtShell.reset( SvxNumberFormatShell::Create(
+ pNumItem->GetNumberFormatter(),
+ pValFmtAttr ? nInitFormat : 0,
+ eValType,
+ aValString ) );
+ else
+ pNumFmtShell.reset( SvxNumberFormatShell::Create(
+ pNumItem->GetNumberFormatter(),
+ pValFmtAttr ? nInitFormat : 0,
+ eValType,
+ nValDouble,
+ &aValString ) );
+
+
+ bool bUseStarFormat = false;
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ // is this a calc document
+ Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
+ if ( xSI.is() )
+ bUseStarFormat = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ pNumFmtShell->SetUseStarFormat( bUseStarFormat );
+
+ FillCurrencyBox();
+
+ OUString aPrevString;
+ const Color* pDummy = nullptr;
+ pNumFmtShell->GetInitSettings( nCatLbSelPos, eLangType, nFmtLbSelPos,
+ aFmtEntryList, aPrevString, pDummy );
+
+ if (nCatLbSelPos==CAT_CURRENCY)
+ set_active_currency(pNumFmtShell->GetCurrencySymbol());
+
+ nFixedCategory=nCatLbSelPos;
+ if(bOneAreaFlag)
+ {
+ OUString sFixedCategory = m_xLbCategory->get_text(nFixedCategory);
+ m_xLbCategory->clear();
+ m_xLbCategory->append_text(sFixedCategory);
+ SetCategory(0);
+ }
+ else
+ {
+ SetCategory(nCatLbSelPos );
+ }
+ eState = rSet->GetItemState( SID_ATTR_NUMBERFORMAT_ADD_AUTO );
+ if(SfxItemState::SET == eState)
+ pAutoEntryAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ADD_AUTO );
+ // no_NO is an alias for nb_NO and normally isn't listed, we need it for
+ // backwards compatibility, but only if the format passed is of
+ // LanguageType no_NO.
+ if ( eLangType == LANGUAGE_NORWEGIAN )
+ {
+ m_xLbLanguage->remove_id(eLangType); // in case we're already called
+ m_xLbLanguage->InsertLanguage( eLangType );
+ }
+ m_xLbLanguage->set_active_id(eLangType);
+ if(pAutoEntryAttr)
+ AddAutomaticLanguage_Impl(eLangType, pAutoEntryAttr->GetValue());
+ UpdateFormatListBox_Impl(false,true);
+
+//! This spoils everything because it rematches currency formats based on
+//! the selected m_xLbCurrency entry instead of the current format.
+//! Besides that everything seems to be initialized by now, so why call it?
+// SelFormatHdl_Impl(m_xLbCategory.get());
+
+ if ( pValFmtAttr )
+ {
+ EditHdl_Impl(m_xEdFormat.get()); // UpdateOptions_Impl() as a side effect
+ }
+ else // DONT_KNOW
+ {
+ // everything disabled except direct input or changing the category
+ Obstructing();
+ }
+
+ if ( m_xCbSourceFormat->get_active() )
+ {
+ // everything disabled except SourceFormat checkbox
+ EnableBySourceFormat_Impl();
+ }
+}
+
+/*************************************************************************
+#* Method: Obstructing
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Disable the controls except from changing the category
+#* and direct input.
+#* Input: ---
+#* Output: ---
+#*
+#************************************************************************/
+void SvxNumberFormatTabPage::Obstructing()
+{
+ m_xLbFormat->select(-1);
+ m_xLbLanguage->set_active(-1);
+ m_xFtLanguage->set_sensitive(false);
+ m_xLbLanguage->set_sensitive(false);
+
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+
+ m_xBtnNegRed->set_sensitive(false);
+ m_xBtnThousand->set_sensitive(false);
+ m_xBtnEngineering->set_sensitive(false);
+ m_xFtLeadZeroes->set_sensitive(false);
+ m_xFtDecimals->set_sensitive(false);
+ m_xFtDenominator->set_sensitive(false);
+ m_xEdLeadZeroes->set_sensitive(false);
+ m_xEdDecimals->set_sensitive(false);
+ m_xEdDenominator->set_sensitive(false);
+ m_xFtOptions->set_sensitive(false);
+ m_xEdDecimals->set_text( OUString() );
+ m_xEdLeadZeroes->set_text( OUString() );
+ m_xBtnNegRed->set_active( false );
+ m_xBtnThousand->set_active( false );
+ m_xBtnEngineering->set_active( false );
+ m_aWndPreview.NotifyChange( OUString() );
+
+ m_xLbCategory->select(0);
+ m_xEdFormat->set_text( OUString() );
+ m_xFtComment->set_label( OUString() );
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
+
+ m_xEdFormat->grab_focus();
+}
+
+
+/*************************************************************************
+#* Enable/Disable dialog parts depending on the value of the SourceFormat
+#* checkbox.
+#************************************************************************/
+void SvxNumberFormatTabPage::EnableBySourceFormat_Impl()
+{
+ bool bEnable = !m_xCbSourceFormat->get_active();
+ if ( !bEnable )
+ m_xCbSourceFormat->grab_focus();
+ m_xFtCategory->set_sensitive( bEnable );
+ m_xLbCategory->set_sensitive( bEnable );
+ m_xFtFormat->set_sensitive( bEnable );
+ m_xLbCurrency->set_sensitive( bEnable );
+ m_xLbFormat->set_sensitive( bEnable );
+ m_xFtLanguage->set_sensitive( bEnable );
+ m_xLbLanguage->set_sensitive( bEnable );
+ m_xFtDecimals->set_sensitive( bEnable );
+ m_xEdDecimals->set_sensitive( bEnable );
+ m_xFtDenominator->set_sensitive( bEnable );
+ m_xEdDenominator->set_sensitive( bEnable );
+ m_xFtLeadZeroes->set_sensitive( bEnable );
+ m_xEdLeadZeroes->set_sensitive( bEnable );
+ m_xBtnNegRed->set_sensitive( bEnable );
+ m_xBtnThousand->set_sensitive( bEnable );
+ m_xBtnEngineering->set_sensitive( bEnable );
+ m_xFtOptions->set_sensitive( bEnable );
+ m_xFormatCodeFrame->set_sensitive( bEnable );
+}
+
+
+/*************************************************************************
+#* Method: HideLanguage
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Hides the language settings:
+#* Input: sal_Bool nFlag
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::HideLanguage(bool bFlag)
+{
+ m_xFtLanguage->set_visible(!bFlag);
+ m_xLbLanguage->set_visible(!bFlag);
+}
+
+/*************************************************************************
+#* Method: FillItemSet
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Adjusts the attributes in the ItemSet,
+#* and - if bNumItemFlag is not set - the
+#* numItem in the DocShell.
+#* Input: SfxItemSet
+#* Output: ---
+#*
+#************************************************************************/
+
+bool SvxNumberFormatTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
+{
+ bool bDataChanged = m_xFtLanguage->get_sensitive() || m_xCbSourceFormat->get_sensitive();
+ if ( bDataChanged )
+ {
+ const SfxItemSet& rMyItemSet = GetItemSet();
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_VALUE );
+ SfxItemState eItemState = rMyItemSet.GetItemState( nWhich, false );
+
+ // OK chosen - Is format code input entered already taken over?
+ // If not, simulate Add. Upon syntax error ignore input and prevent Put.
+ OUString aFormat = m_xEdFormat->get_text();
+ sal_uInt32 nCurKey = pNumFmtShell->GetCurNumFmtKey();
+
+ if ( m_xIbAdd->get_sensitive() || pNumFmtShell->IsTmpCurrencyFormat(aFormat) )
+ { // #79599# It is not sufficient to just add the format code (or
+ // delete it in case of bOneAreaFlag and resulting category change).
+ // Upon switching tab pages we need all settings to be consistent
+ // in case this page will be redisplayed later.
+ bDataChanged = Click_Impl(*m_xIbAdd);
+ nCurKey = pNumFmtShell->GetCurNumFmtKey();
+ }
+ else if(nCurKey == NUMKEY_UNDEFINED)
+ { // something went wrong, e.g. in Writer #70281#
+ pNumFmtShell->FindEntry(aFormat, &nCurKey);
+ }
+
+
+ // Chosen format:
+
+ if ( bDataChanged )
+ {
+ bDataChanged = ( nInitFormat != nCurKey );
+
+ if (bDataChanged)
+ {
+ rCoreAttrs->Put( SfxUInt32Item( nWhich, nCurKey ) );
+ }
+ else if(SfxItemState::DEFAULT == eItemState)
+ {
+ rCoreAttrs->ClearItem( nWhich );
+ }
+ }
+
+
+ // List of changed user defined formats:
+
+ std::vector<sal_uInt32> const & aDelFormats = pNumFmtShell->GetUpdateData();
+
+ if ( !aDelFormats.empty() )
+ {
+
+ pNumItem->SetDelFormats( std::vector(aDelFormats) );
+
+ if(bNumItemFlag)
+ {
+ rCoreAttrs->Put( *pNumItem );
+ }
+ else
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ DBG_ASSERT( pDocSh, "DocShell not found!" );
+ if (pDocSh)
+ pDocSh->PutItem( *pNumItem );
+ }
+ }
+
+
+ // Whether source format is to be taken or not:
+
+ if ( m_xCbSourceFormat->get_sensitive() )
+ {
+ SfxItemState _eItemState = rMyItemSet.GetItemState( SID_ATTR_NUMBERFORMAT_SOURCE, false );
+ const SfxBoolItem* pBoolItem =
+ GetItem( rMyItemSet, SID_ATTR_NUMBERFORMAT_SOURCE );
+ bool bOld = pBoolItem && pBoolItem->GetValue();
+ rCoreAttrs->Put( SfxBoolItem( SID_ATTR_NUMBERFORMAT_SOURCE, m_xCbSourceFormat->get_active() ) );
+ if ( !bDataChanged )
+ bDataChanged = (bOld != m_xCbSourceFormat->get_active() ||
+ _eItemState != SfxItemState::SET);
+ }
+
+ // FillItemSet is only called on OK, here we can notify the
+ // NumberFormatShell that all new user defined formats are valid.
+ pNumFmtShell->ValidateNewEntries();
+ if(m_xLbLanguage->get_visible() &&
+ m_xLbLanguage->find_text(sAutomaticLangEntry) != -1)
+ rCoreAttrs->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO,
+ m_xLbLanguage->get_active_text() == sAutomaticLangEntry));
+ }
+
+ return bDataChanged;
+}
+
+
+DeactivateRC SvxNumberFormatTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEntries )
+{
+ OUString aEntry;
+ OUString aTmpString;
+ size_t i = 0;
+ short nTmpCatPos;
+
+ m_xLbFormat->clear();
+ if (rEntries.empty())
+ return;
+
+ m_xLbFormat->freeze();
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+ switch (nTmpCatPos)
+ {
+ case CAT_ALL:
+ case CAT_TEXT:
+ case CAT_NUMBER: i=1;
+ aEntry=rEntries[0];
+ if (nTmpCatPos == CAT_TEXT)
+ aTmpString=aEntry;
+ else
+ aTmpString = pNumFmtShell->GetStandardName();
+ m_xLbFormat->append_text(aTmpString);
+ break;
+
+ default: break;
+ }
+
+ if(pNumFmtShell!=nullptr)
+ {
+ for ( ; i < rEntries.size(); ++i )
+ {
+ aEntry = rEntries[i];
+ short aPrivCat = pNumFmtShell->GetCategory4Entry( static_cast<short>(i) );
+ if(aPrivCat!=CAT_TEXT)
+ {
+ const Color* pPreviewColor = nullptr;
+ OUString aPreviewString( GetExpColorString( pPreviewColor, aEntry, aPrivCat ) );
+ m_xLbFormat->append_text(aPreviewString);
+ if (pPreviewColor)
+ m_xLbFormat->set_font_color(m_xLbFormat->n_children() - 1, *pPreviewColor);
+ }
+ else
+ {
+ m_xLbFormat->append_text(aEntry);
+ }
+ }
+ }
+ m_xLbFormat->thaw();
+ rEntries.clear();
+}
+
+/*************************************************************************
+#* Method: UpdateOptions_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Adjusts the options attributes
+#* depending on the selected format.
+#* Input: Flag, whether the category has changed.
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ )
+{
+ OUString theFormat = m_xEdFormat->get_text();
+ sal_Int32 nCurCategory = m_xLbCategory->get_selected_index();
+ sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory);
+ sal_uInt16 nDecimals = 0;
+ sal_uInt16 nZeroes = 0;
+ bool bNegRed = false;
+ bool bThousand = false;
+ sal_Int32 nCurrencyPos = get_active_currency();
+
+ if(bOneAreaFlag)
+ nCurCategory=nFixedCategory;
+
+
+ pNumFmtShell->GetOptions( theFormat,
+ bThousand, bNegRed,
+ nDecimals, nZeroes,
+ nCategory );
+ bool bDoIt=false;
+ if(nCategory==CAT_CURRENCY)
+ {
+ sal_uInt16 nTstPos=pNumFmtShell->FindCurrencyFormat(theFormat);
+ if(nCurrencyPos!=static_cast<sal_Int32>(nTstPos) && nTstPos!=sal_uInt16(-1))
+ {
+ set_active_currency(nTstPos);
+ pNumFmtShell->SetCurrencySymbol(nTstPos);
+ bDoIt=true;
+ }
+ }
+
+ if ( nCategory != nCurCategory || bDoIt)
+ {
+ if ( bCheckCatChange )
+ {
+ if(bOneAreaFlag)
+ SetCategory(0);
+ else
+ SetCategory(nCategory );
+
+ UpdateFormatListBox_Impl( true, false );
+ }
+ }
+ else if ( m_xLbFormat->n_children() > 0 )
+ {
+ sal_uInt32 nCurEntryKey=NUMKEY_UNDEFINED;
+ if(!pNumFmtShell->FindEntry( m_xEdFormat->get_text(),&nCurEntryKey))
+ {
+ m_xLbFormat->select(-1);
+ }
+ }
+ if(bOneAreaFlag)
+ {
+ nCategory=nFixedCategory;
+ }
+
+ UpdateThousandEngineeringCheckBox();
+ UpdateDecimalsDenominatorEditBox();
+ switch ( nCategory )
+ {
+ case CAT_SCIENTIFIC: // bThousand is for Engineering notation
+ {
+ sal_uInt16 nIntDigits = pNumFmtShell->GetFormatIntegerDigits(theFormat);
+ bThousand = (nIntDigits > 0) && (nIntDigits % 3 == 0);
+ m_xBtnEngineering->set_sensitive(true);
+ m_xBtnEngineering->set_active( bThousand );
+ }
+ [[fallthrough]];
+ case CAT_NUMBER:
+ case CAT_PERCENT:
+ case CAT_CURRENCY:
+ case CAT_FRACTION:
+ case CAT_TIME:
+ m_xFtOptions->set_sensitive(true);
+ if ( nCategory == CAT_FRACTION )
+ {
+ m_xFtDenominator->set_sensitive(true);
+ m_xEdDenominator->set_sensitive(true);
+ }
+ else
+ {
+ m_xFtDecimals->set_sensitive(true);
+ m_xEdDecimals->set_sensitive(true);
+ }
+ m_xFtLeadZeroes->set_sensitive( nCategory != CAT_TIME );
+ m_xEdLeadZeroes->set_sensitive( nCategory != CAT_TIME );
+ m_xBtnNegRed->set_sensitive(true);
+ if ( nCategory == CAT_NUMBER && m_xLbFormat->get_selected_index() == 0 )
+ m_xEdDecimals->set_text( "" ); //General format tdf#44399
+ else
+ if ( nCategory == CAT_FRACTION )
+ m_xEdDenominator->set_value( nDecimals );
+ else
+ m_xEdDecimals->set_value( nDecimals );
+ if ( nCategory != CAT_TIME )
+ m_xEdLeadZeroes->set_value( nZeroes );
+ m_xBtnNegRed->set_active( bNegRed );
+ if ( nCategory != CAT_SCIENTIFIC )
+ {
+ m_xBtnThousand->set_sensitive( nCategory != CAT_TIME );
+ m_xBtnThousand->set_active( bThousand && nCategory != CAT_TIME );
+ }
+ break;
+
+ case CAT_ALL:
+ case CAT_USERDEFINED:
+ case CAT_TEXT:
+ case CAT_DATE:
+ case CAT_BOOLEAN:
+ default:
+ m_xFtOptions->set_sensitive(false);
+ m_xFtDecimals->set_sensitive(false);
+ m_xEdDecimals->set_sensitive(false);
+ m_xFtDenominator->set_sensitive(false);
+ m_xEdDenominator->set_sensitive(false);
+ m_xFtLeadZeroes->set_sensitive(false);
+ m_xEdLeadZeroes->set_sensitive(false);
+ m_xBtnNegRed->set_sensitive(false);
+ m_xBtnThousand->set_sensitive(false);
+ m_xBtnEngineering->set_sensitive(false);
+ m_xEdDecimals->set_text( OUString() );
+ m_xEdLeadZeroes->set_text( OUString() );
+ m_xBtnNegRed->set_active( false );
+ m_xBtnThousand->set_active( false );
+ m_xBtnEngineering->set_active( false );
+ }
+}
+
+
+/*************************************************************************
+#* Method: UpdateFormatListBox_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Updates the format listbox and additionally the
+#* string in the editbox is changed depending on
+#* the bUpdateEdit flag.
+#* Input: Flags for category and editbox.
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::UpdateFormatListBox_Impl
+ (
+ bool bCat, // Category or country/language ListBox?
+ bool bUpdateEdit
+ )
+{
+ std::vector<OUString> aEntryList;
+ short nFmtLbSelPos = 0;
+ short nTmpCatPos;
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+
+ if ( bCat )
+ {
+ if(nTmpCatPos!=CAT_CURRENCY)
+ m_xLbCurrency->hide();
+ else
+ m_xLbCurrency->show();
+
+ pNumFmtShell->CategoryChanged(nTmpCatPos,nFmtLbSelPos, aEntryList);
+ }
+ else
+ pNumFmtShell->LanguageChanged(m_xLbLanguage->get_active_id(),
+ nFmtLbSelPos,aEntryList);
+
+ REMOVE_DONTKNOW() // possibly UI-Enable
+
+
+ if ( (!aEntryList.empty()) && (nFmtLbSelPos != SELPOS_NONE) )
+ {
+ if(bUpdateEdit)
+ {
+ OUString aFormat=aEntryList[nFmtLbSelPos];
+ m_xEdFormat->set_text(aFormat);
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ }
+
+ if(!bOneAreaFlag || !bCat)
+ {
+ FillFormatListBox_Impl( aEntryList );
+ m_xLbFormat->select(nFmtLbSelPos);
+
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
+ {
+ m_xFtComment->set_label(m_xLbCategory->get_text(1));
+ }
+ }
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+
+ }
+ else
+ {
+ FillFormatListBox_Impl( aEntryList );
+ if(nFmtLbSelPos != SELPOS_NONE)
+ {
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
+ {
+ m_xFtComment->set_label(m_xLbCategory->get_text(1));
+ }
+ }
+ }
+ else
+ {
+ m_xLbFormat->select(-1);
+ }
+
+ if ( bUpdateEdit )
+ {
+ m_xEdFormat->set_text( OUString() );
+ m_aWndPreview.NotifyChange( OUString() );
+ }
+ }
+
+ aEntryList.clear();
+}
+
+
+/**
+ * Change visible checkbox according to category format
+ * if scientific format "Engineering notation"
+ * else "Thousands separator"
+ */
+
+void SvxNumberFormatTabPage::UpdateThousandEngineeringCheckBox()
+{
+ bool bIsScientific = m_xLbCategory->get_selected_index() == CAT_SCIENTIFIC;
+ m_xBtnThousand->set_visible( !bIsScientific );
+ m_xBtnEngineering->set_visible( bIsScientific );
+}
+
+
+/**
+ * Change visible Edit box and Fixed text according to category format
+ * if fraction format "Denominator places"
+ * else "Decimal places"
+ */
+
+void SvxNumberFormatTabPage::UpdateDecimalsDenominatorEditBox()
+{
+ bool bIsFraction = m_xLbCategory->get_selected_index() == CAT_FRACTION;
+ m_xFtDecimals->set_visible( !bIsFraction );
+ m_xEdDecimals->set_visible( !bIsFraction );
+ m_xFtDenominator->set_visible( bIsFraction );
+ m_xEdDenominator->set_visible( bIsFraction );
+}
+
+
+/*************************************************************************
+#* Handle: DoubleClickHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: On a double click in the format listbox the
+#* value is adopted and the OK button pushed.
+#* Input: Pointer on the Listbox
+#* Output: ---
+#*
+#************************************************************************/
+IMPL_LINK(SvxNumberFormatTabPage, DoubleClickHdl_Impl, weld::TreeView&, rLb, bool)
+{
+ SelFormatHdl_Impl(&rLb);
+
+ SfxOkDialogController* pController = GetDialogController();
+ assert(pController);
+ weld::Button& rOkButton = pController->GetOKButton();
+ rOkButton.clicked();
+
+ return true;
+}
+
+/*************************************************************************
+#* Method: SelFormatHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Is called when the language, the category or the format
+#* is changed. Accordingly the settings are adjusted.
+#* Input: Pointer on the Listbox
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatClickHdl_Impl, weld::Toggleable&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl, weld::TreeView&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl, weld::ComboBox&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+void SvxNumberFormatTabPage::SelFormatHdl_Impl(weld::Widget* pLb)
+{
+ if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ {
+ // Click handler is called before focus change handler, so finish
+ // comment editing of previous format, otherwise a new format will have
+ // the old comment displayed after LostFocusHdl_Impl() is called
+ // later. Also, clicking into another category invalidates the format
+ // list and SvxNumberFormatShell::SetComment4Entry() could either
+ // access a wrong format from aCurEntryList[nEntry] or crash there if
+ // the new vector has less elements.
+ LostFocusHdl_Impl(*pLb);
+ }
+
+ if (pLb == m_xCbSourceFormat.get())
+ {
+ EnableBySourceFormat_Impl(); // enable/disable everything else
+ if ( m_xCbSourceFormat->get_active() )
+ return; // just disabled everything else
+
+ // Reinit options enable/disable for current selection.
+
+ // Current category may be UserDefined with no format entries defined.
+ if (m_xLbFormat->get_selected_index() == -1)
+ pLb = m_xLbCategory.get(); // continue with the current category selected
+ else
+ pLb = m_xLbFormat.get(); // continue with the current format selected
+ }
+
+ sal_Int32 nTmpCatPos;
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+ if (nTmpCatPos==CAT_CURRENCY && pLb == m_xLbCurrency.get())
+ pNumFmtShell->SetCurrencySymbol(get_active_currency());
+
+ // Format-ListBox ----------------------------------------------------
+ if (pLb == m_xLbFormat.get())
+ {
+ int nSelPos = m_xLbFormat->get_selected_index();
+ short nFmtLbSelPos = static_cast<short>(nSelPos);
+
+ OUString aFormat = pNumFmtShell->GetFormat4Entry(nFmtLbSelPos);
+ OUString aComment = pNumFmtShell->GetComment4Entry(nFmtLbSelPos);
+
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(aComment.isEmpty())
+ {
+ aComment = m_xLbCategory->get_text(1);
+ }
+ }
+
+ if ( !aFormat.isEmpty() )
+ {
+ if (!m_xEdFormat->has_focus())
+ m_xEdFormat->set_text( aFormat );
+ m_xFtComment->set_label(aComment);
+ ChangePreviewText( static_cast<sal_uInt16>(nSelPos) );
+ }
+
+ REMOVE_DONTKNOW() // possibly UI-Enable
+
+ if ( pNumFmtShell->FindEntry( aFormat) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bIsUserDef=pNumFmtShell->IsUserDefined( aFormat );
+ m_xIbRemove->set_sensitive(bIsUserDef);
+ m_xIbInfo->set_sensitive(bIsUserDef);
+
+ }
+ else
+ {
+ m_xIbAdd->set_sensitive(true);
+ m_xIbInfo->set_sensitive(true);
+ m_xIbRemove->set_sensitive(false );
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ }
+ UpdateOptions_Impl( false );
+
+ return;
+ }
+
+
+ // category-ListBox -------------------------------------------------
+ if (pLb == m_xLbCategory.get() || pLb == m_xLbCurrency.get())
+ {
+ UpdateFormatListBox_Impl( true, true );
+ EditHdl_Impl( nullptr );
+ UpdateOptions_Impl( false );
+
+ return;
+ }
+
+
+ // language/country-ListBox ----------------------------------------------
+ if (pLb == m_xLbLanguage->get_widget())
+ {
+ UpdateFormatListBox_Impl( false, true );
+ EditHdl_Impl(m_xEdFormat.get());
+
+ return;
+ }
+}
+
+
+/*************************************************************************
+#* Method: ClickHdl_Impl, weld::Button& rIB
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Called when the add or delete button is pushed,
+#* adjusts the number format list.
+#* Input: Toolbox- Button
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( SvxNumberFormatTabPage, ClickHdl_Impl, weld::Button&, rIB, void)
+{
+ Click_Impl(rIB);
+}
+
+bool SvxNumberFormatTabPage::Click_Impl(const weld::Button& rIB)
+{
+ sal_uInt8 nReturn = 0;
+ constexpr sal_uInt8 nReturnChanged = 0x1; // THE boolean return value
+ constexpr sal_uInt8 nReturnAdded = 0x2; // temp: format added
+ constexpr sal_uInt8 nReturnOneArea = 0x4; // temp: one area but category changed => ignored
+
+ if (&rIB == m_xIbAdd.get())
+ { // Also called from FillItemSet() if a temporary currency format has
+ // to be added, not only if the Add button is enabled.
+ OUString aFormat = m_xEdFormat->get_text();
+ std::vector<OUString> aEntryList;
+ std::vector<OUString> a2EntryList;
+ sal_uInt16 nCatLbSelPos = 0;
+ short nFmtLbSelPos = SELPOS_NONE;
+ sal_Int32 nErrPos=0;
+
+ pNumFmtShell->SetCurCurrencyEntry(nullptr);
+ bool bAdded = pNumFmtShell->AddFormat( aFormat, nErrPos,
+ nCatLbSelPos, nFmtLbSelPos,
+ aEntryList);
+ if ( bAdded )
+ nReturn |= nReturnChanged | nReturnAdded;
+
+ if (m_xEdComment->get_visible())
+ {
+ m_xEdFormat->grab_focus();
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ m_xFtComment->set_label(m_xEdComment->get_text());
+ }
+
+ if ( !nErrPos ) // Syntax ok?
+ {
+ // May be sorted under a different locale if LCID was parsed.
+ if (bAdded)
+ m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage());
+
+ if (nCatLbSelPos==CAT_CURRENCY)
+ set_active_currency(pNumFmtShell->GetCurrencySymbol());
+
+ if(bOneAreaFlag && (nFixedCategory!=nCatLbSelPos))
+ {
+ if(bAdded) aEntryList.clear();
+ pNumFmtShell->RemoveFormat( aFormat,
+ nCatLbSelPos,
+ nFmtLbSelPos,
+ a2EntryList);
+ a2EntryList.clear();
+ m_xEdFormat->grab_focus();
+ m_xEdFormat->select_region(0, -1);
+ nReturn |= nReturnOneArea;
+ }
+ else
+ {
+ if ( bAdded && (nFmtLbSelPos != SELPOS_NONE) )
+ {
+ // everything all right
+ if(bOneAreaFlag) //@@ ???
+ SetCategory(0);
+ else
+ SetCategory(nCatLbSelPos );
+
+ FillFormatListBox_Impl( aEntryList );
+ if (m_xEdComment->get_text()!=m_xLbCategory->get_text(1))
+ {
+ pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
+ m_xEdComment->get_text());
+ }
+ else
+ {
+ pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
+ OUString());
+ }
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+ m_xEdFormat->set_text( aFormat );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // String for user defined
+
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+ }
+ }
+ else // syntax error
+ {
+ m_xEdFormat->grab_focus();
+ m_xEdFormat->select_region(nErrPos == -1 ? m_xEdFormat->get_text().getLength() : nErrPos, -1);
+ }
+ EditHdl_Impl(m_xEdFormat.get());
+ nReturn = ((nReturn & nReturnOneArea) ? 0 : (nReturn & nReturnChanged));
+
+ aEntryList.clear();
+ a2EntryList.clear();
+ }
+ else if (&rIB == m_xIbRemove.get())
+ {
+ OUString aFormat = m_xEdFormat->get_text();
+ std::vector<OUString> aEntryList;
+ sal_uInt16 nCatLbSelPos = 0;
+ short nFmtLbSelPos = SELPOS_NONE;
+
+ pNumFmtShell->RemoveFormat( aFormat,
+ nCatLbSelPos,
+ nFmtLbSelPos,
+ aEntryList );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1));
+
+ if( nFmtLbSelPos>=0 && o3tl::make_unsigned(nFmtLbSelPos)<aEntryList.size() )
+ {
+ aFormat = aEntryList[nFmtLbSelPos];
+ }
+
+ FillFormatListBox_Impl( aEntryList );
+
+ if ( nFmtLbSelPos != SELPOS_NONE )
+ {
+ if(bOneAreaFlag) //@@ ???
+ SetCategory(0);
+ else
+ SetCategory(nCatLbSelPos );
+
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+ m_xEdFormat->set_text( aFormat );
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+ else
+ {
+ // set to "all/standard"
+ SetCategory(0);
+ SelFormatHdl_Impl(m_xLbCategory.get());
+ }
+
+ EditHdl_Impl(m_xEdFormat.get());
+
+ aEntryList.clear();
+ }
+ else if (&rIB == m_xIbInfo.get())
+ {
+ if (!m_xEdComment->get_visible())
+ {
+ if (!m_xIbAdd->get_sensitive())
+ // Editing for existing format.
+ m_nLbFormatSelPosEdComment = m_xLbFormat->get_selected_index();
+
+ m_xEdComment->set_text(m_xFtComment->get_label());
+ m_xEdComment->show();
+ m_xFtComment->hide();
+ m_xEdComment->grab_focus();
+ }
+ else
+ {
+ m_xEdFormat->grab_focus();
+ m_xFtComment->set_label( m_xEdComment->get_text());
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ }
+ }
+
+ return nReturn;
+}
+
+
+/*************************************************************************
+#* Method: EditHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: When the entry in the edit field is changed
+#* the preview is updated and
+#* Input: Pointer on Editbox
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditHdl_Impl(&rEdit);
+}
+
+void SvxNumberFormatTabPage::EditHdl_Impl(const weld::Entry* pEdFormat)
+{
+ sal_uInt32 nCurKey = NUMKEY_UNDEFINED;
+
+ if ( m_xEdFormat->get_text().isEmpty() )
+ {
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+ m_xFtComment->set_label(OUString());
+ }
+ else
+ {
+ OUString aFormat = m_xEdFormat->get_text();
+ MakePreviewText( aFormat );
+
+ if ( pNumFmtShell->FindEntry( aFormat, &nCurKey ) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
+
+ m_xIbRemove->set_sensitive(bUserDef);
+ m_xIbInfo->set_sensitive(bUserDef);
+
+ if(bUserDef)
+ {
+ sal_uInt16 nTmpCurPos=pNumFmtShell->FindCurrencyFormat(aFormat );
+ if (nTmpCurPos != sal_uInt16(-1))
+ set_active_currency(nTmpCurPos);
+ }
+ short nPosi=pNumFmtShell->GetListPos4Entry( nCurKey, aFormat);
+ if(nPosi>=0)
+ m_xLbFormat->select(static_cast<sal_uInt16>(nPosi));
+
+ }
+ else
+ {
+
+ m_xIbAdd->set_sensitive(true);
+ m_xIbInfo->set_sensitive(true);
+ m_xIbRemove->set_sensitive(false );
+
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ }
+ }
+
+ if (pEdFormat)
+ {
+ pNumFmtShell->SetCurNumFmtKey( nCurKey );
+ UpdateOptions_Impl( true );
+ }
+}
+
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, OptClickHdl_Impl, weld::Toggleable&, rOptCtrl, void)
+{
+ OptHdl_Impl(&rOptCtrl);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, OptEditHdl_Impl, weld::SpinButton&, rEdit, void)
+{
+ OptHdl_Impl(&rEdit);
+}
+
+void SvxNumberFormatTabPage::OptHdl_Impl(const weld::Widget* pOptCtrl)
+{
+ if ( !(pOptCtrl == m_xEdLeadZeroes.get()
+ || pOptCtrl == m_xEdDecimals.get()
+ || pOptCtrl == m_xEdDenominator.get()
+ || pOptCtrl == m_xBtnNegRed.get()
+ || pOptCtrl == m_xBtnThousand.get()
+ || pOptCtrl == m_xBtnEngineering.get()))
+ return;
+
+ OUString aFormat;
+ bool bThousand = ( m_xBtnThousand->get_visible() && m_xBtnThousand->get_sensitive() && m_xBtnThousand->get_active() )
+ || ( m_xBtnEngineering->get_visible() && m_xBtnEngineering->get_sensitive() && m_xBtnEngineering->get_active() );
+ bool bNegRed = m_xBtnNegRed->get_sensitive() && m_xBtnNegRed->get_active();
+ sal_uInt16 nPrecision = (m_xEdDecimals->get_sensitive() && m_xEdDecimals->get_visible())
+ ? static_cast<sal_uInt16>(m_xEdDecimals->get_value())
+ : ( (m_xEdDenominator->get_sensitive() && m_xEdDenominator->get_visible())
+ ? static_cast<sal_uInt16>(m_xEdDenominator->get_value())
+ : sal_uInt16(0) );
+ sal_uInt16 nLeadZeroes = (m_xEdLeadZeroes->get_sensitive())
+ ? static_cast<sal_uInt16>(m_xEdLeadZeroes->get_value())
+ : sal_uInt16(0);
+ if ( pNumFmtShell->GetStandardName() == m_xEdFormat->get_text() )
+ {
+ m_xEdDecimals->set_value(nPrecision);
+ }
+
+ pNumFmtShell->MakeFormat( aFormat,
+ bThousand, bNegRed,
+ nPrecision, nLeadZeroes,
+ static_cast<sal_uInt16>(m_xLbFormat->get_selected_index()) );
+
+ m_xEdFormat->set_text( aFormat );
+ MakePreviewText( aFormat );
+
+ if ( pNumFmtShell->FindEntry( aFormat ) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
+ m_xIbRemove->set_sensitive(bUserDef);
+ m_xIbInfo->set_sensitive(bUserDef);
+ EditHdl_Impl(m_xEdFormat.get());
+
+ }
+ else
+ {
+ EditHdl_Impl( nullptr );
+ m_xLbFormat->select(-1);
+ }
+}
+
+/*************************************************************************
+#* Method: LostFocusHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK_NOARG(SvxNumberFormatTabPage, LostFocusHdl_Impl, weld::Widget&, void)
+{
+ if (!pNumFmtShell)
+ return;
+
+ const bool bAddSensitive = m_xIbAdd->get_sensitive();
+ if (bAddSensitive || m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ // Comment editing was possible.
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ {
+ // Save edited comment of existing format.
+ pNumFmtShell->SetComment4Entry( m_nLbFormatSelPosEdComment, m_xEdComment->get_text());
+ m_nLbFormatSelPosEdComment = SELPOS_NONE;
+ }
+ if (!bAddSensitive)
+ {
+ // String for user defined, if present
+ OUString sEntry = m_xLbCategory->n_children() > 1 ? m_xLbCategory->get_text(1) : OUString();
+ m_xEdComment->set_text(sEntry);
+ }
+}
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+OUString SvxNumberFormatTabPage::GetExpColorString(
+ const Color*& rpPreviewColor, const OUString& rFormatStr, short nTmpCatPos)
+{
+ SvxNumValCategory i;
+ switch (nTmpCatPos)
+ {
+ case CAT_ALL: i=SvxNumValCategory::Standard; break;
+
+ case CAT_NUMBER: i=SvxNumValCategory::Standard; break;
+
+ case CAT_PERCENT: i=SvxNumValCategory::Percent; break;
+
+ case CAT_CURRENCY: i=SvxNumValCategory::Currency; break;
+
+ case CAT_DATE: i=SvxNumValCategory::Date; break;
+
+ case CAT_TIME: i=SvxNumValCategory::Time; break;
+
+ case CAT_SCIENTIFIC: i=SvxNumValCategory::Scientific; break;
+
+ case CAT_FRACTION: i=SvxNumValCategory::Fraction; break;
+
+ case CAT_BOOLEAN: i=SvxNumValCategory::Boolean; break;
+
+ case CAT_USERDEFINED: i=SvxNumValCategory::Standard; break;
+
+ case CAT_TEXT:
+ default: i=SvxNumValCategory::NoValue;break;
+ }
+ double fVal = fSvxNumValConst[i];
+
+ OUString aPreviewString;
+ pNumFmtShell->MakePrevStringFromVal( rFormatStr, aPreviewString, rpPreviewColor, fVal );
+ return aPreviewString;
+}
+
+void SvxNumberFormatTabPage::MakePreviewText( const OUString& rFormat )
+{
+ OUString aPreviewString;
+ const Color* pPreviewColor = nullptr;
+ pNumFmtShell->MakePreviewString( rFormat, aPreviewString, pPreviewColor );
+ m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
+}
+
+void SvxNumberFormatTabPage::ChangePreviewText( sal_uInt16 nPos )
+{
+ OUString aPreviewString;
+ const Color* pPreviewColor = nullptr;
+ pNumFmtShell->FormatChanged( nPos, aPreviewString, pPreviewColor );
+ m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
+}
+
+void SvxNumberFormatTabPage::FillCurrencyBox()
+{
+ std::vector<OUString> aList;
+
+ sal_uInt16 nSelPos=0;
+ pNumFmtShell->GetCurrencySymbols(aList, &nSelPos);
+
+ m_xLbCurrency->freeze();
+ m_xLbCurrency->clear();
+ bLegacyAutomaticCurrency = false;
+ for (std::vector<OUString>::iterator i = aList.begin() + 1;i != aList.end(); ++i)
+ m_xLbCurrency->append_text(*i);
+ m_xLbCurrency->thaw();
+
+ set_active_currency(nSelPos);
+}
+
+void SvxNumberFormatTabPage::SetCategory(sal_uInt16 nPos)
+{
+ int nCurCategory = m_xLbCategory->get_selected_index();
+ sal_uInt16 nTmpCatPos;
+
+ if (bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=nPos;
+ }
+
+ if(m_xLbCategory->n_children()==1 || nCurCategory!=nPos)
+ {
+ if(nTmpCatPos!=CAT_CURRENCY)
+ m_xLbCurrency->hide();
+ else
+ m_xLbCurrency->show();
+ }
+ m_xLbCategory->select(nPos);
+}
+
+/* to support Writer text field language handling an
+ additional entry needs to be inserted into the ListBox
+ which marks a certain language as automatically detected
+ Additionally the "Default" language is removed
+*/
+void SvxNumberFormatTabPage::AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect)
+{
+ m_xLbLanguage->remove_id(LANGUAGE_SYSTEM);
+ m_xLbLanguage->append(eAutoLang, sAutomaticLangEntry);
+ if (bSelect)
+ m_xLbLanguage->set_active_id(eAutoLang);
+}
+
+void SvxNumberFormatTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxNumberInfoItem* pNumberInfoItem = aSet.GetItem<SvxNumberInfoItem>(SID_ATTR_NUMBERFORMAT_INFO, false);
+ if (pNumberInfoItem && !pNumItem)
+ pNumItem.reset(pNumberInfoItem->Clone());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
new file mode 100644
index 000000000..0c66f69ee
--- /dev/null
+++ b/cui/source/tabpages/numpages.cxx
@@ -0,0 +1,3355 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+
+#include <numpages.hxx>
+#include <dialmgr.hxx>
+#include <tools/mapunit.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <editeng/numitem.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/strarray.hxx>
+#include <svx/gallery.hxx>
+#include <editeng/brushitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/settings.hxx>
+#include <cui/cuicharmap.hxx>
+#include <editeng/flstitem.hxx>
+#include <svx/numvset.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/unitconv.hxx>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
+#include <com/sun/star/text/XNumberingFormatter.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <svx/svxids.hrc>
+#include <o3tl/string_view.hxx>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+#include <sfx2/opengrf.hxx>
+
+#include <strings.hrc>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <sal/log.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <tools/urlobj.hxx>
+#include <o3tl/temporary.hxx>
+#include <osl/diagnose.h>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::text;
+using namespace css::container;
+using namespace css::style;
+
+#define SHOW_NUMBERING 0
+#define SHOW_BULLET 1
+#define SHOW_BITMAP 2
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+#define SEARCHPATH_DELIMITER u';'
+#define SEARCHFILENAME_DELIMITER u'/'
+
+static bool bLastRelative = false;
+
+static SvxNumSettings_Impl* lcl_CreateNumSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
+{
+ const PropertyValue* pValues = rLevelProps.getConstArray();
+ SvxNumSettings_Impl* pNew = new SvxNumSettings_Impl;
+ for(sal_Int32 j = 0; j < rLevelProps.getLength(); j++)
+ {
+ if ( pValues[j].Name == "NumberingType" )
+ {
+ sal_Int16 nTmp;
+ if (pValues[j].Value >>= nTmp)
+ pNew->nNumberType = static_cast<SvxNumType>(nTmp);
+ }
+ else if ( pValues[j].Name == "Prefix" )
+ pValues[j].Value >>= pNew->sPrefix;
+ else if ( pValues[j].Name == "Suffix" )
+ pValues[j].Value >>= pNew->sSuffix;
+ else if ( pValues[j].Name == "ParentNumbering" )
+ pValues[j].Value >>= pNew->nParentNumbering;
+ else if ( pValues[j].Name == "BulletChar" )
+ pValues[j].Value >>= pNew->sBulletChar;
+ else if ( pValues[j].Name == "BulletFontName" )
+ pValues[j].Value >>= pNew->sBulletFont;
+ }
+ return pNew;
+}
+
+// the selection of bullets from the OpenSymbol
+const sal_Unicode aBulletTypes[] =
+{
+ 0x2022,
+ 0x25cf,
+ 0xe00c,
+ 0xe00a,
+ 0x2794,
+ 0x27a2,
+ 0x2717,
+ 0x2714
+};
+
+// Is one of the masked formats set?
+static bool lcl_IsNumFmtSet(SvxNumRule const * pNum, sal_uInt16 nLevelMask)
+{
+ bool bRet = false;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < SVX_MAX_NUM && !bRet; i++ )
+ {
+ if(nLevelMask & nMask)
+ bRet |= nullptr != pNum->Get( i );
+ nMask <<= 1 ;
+ }
+ return bRet;
+}
+
+static const vcl::Font& lcl_GetDefaultBulletFont()
+{
+ static vcl::Font aDefBulletFont = []()
+ {
+ vcl::Font tmp("OpenSymbol", "", Size(0, 14));
+ tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ tmp.SetFamily( FAMILY_DONTKNOW );
+ tmp.SetPitch( PITCH_DONTKNOW );
+ tmp.SetWeight( WEIGHT_DONTKNOW );
+ tmp.SetTransparent( true );
+ return tmp;
+ }();
+ return aDefBulletFont;
+}
+
+SvxSingleNumPickTabPage::SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/picknumberingpage.ui", "PickNumberingPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::SINGLENUM);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxSingleNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxSingleNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence< Sequence< PropertyValue > > aNumberings;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aNumberings =
+ xDefNum->getDefaultContinuousNumberingLevels( rLocale );
+
+
+ sal_Int32 nLength = std::min<sal_Int32>(aNumberings.getLength(), NUM_VALUSET_COUNT);
+
+ const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray();
+ for(sal_Int32 i = 0; i < nLength; i++)
+ {
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(pValuesArr[i]);
+ aNumSettingsArr.push_back(std::unique_ptr<SvxNumSettings_Impl>(pNew));
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetNumberingSettings(aNumberings, xFormat, rLocale);
+}
+
+SvxSingleNumPickTabPage::~SvxSingleNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxSingleNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSingleNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxSingleNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pSaveNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxSingleNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pNumItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pNumItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+
+ bModified = false;
+}
+
+DeactivateRC SvxSingleNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSingleNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ eState = SfxItemState::SET;
+ }
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+ DBG_ASSERT(aNumSettingsArr.size() > nIdx, "wrong index");
+ if(aNumSettingsArr.size() <= nIdx)
+ return;
+ SvxNumSettings_Impl* _pSet = aNumSettingsArr[nIdx].get();
+ SvxNumType eNewType = _pSet->nNumberType;
+ const sal_Unicode cLocalPrefix = !_pSet->sPrefix.isEmpty() ? _pSet->sPrefix[0] : 0;
+ const sal_Unicode cLocalSuffix = !_pSet->sSuffix.isEmpty() ? _pSet->sSuffix[0] : 0;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(eNewType);
+ aFmt.SetListFormat(cLocalPrefix == ' ' ? "" : _pSet->sPrefix,
+ cLocalSuffix == ' ' ? "" : _pSet->sSuffix, i);
+ aFmt.SetCharFormatName("");
+ aFmt.SetBulletRelSize(100);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+SvxBulletPickTabPage::SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickbulletpage.ui", "PickBulletPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::BULLET);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBulletPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBulletPickTabPage, DoubleClickHdl_Impl));
+}
+
+SvxBulletPickTabPage::~SvxBulletPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBulletPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBulletPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxBulletPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxBulletPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBulletPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBulletPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+
+ }
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_Unicode cChar = aBulletTypes[m_xExamplesVS->GetSelectedItemId() - 1];
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetListFormat("", "", i);
+ aFmt.SetBulletFont(&rActBulletFont);
+ aFmt.SetBulletChar(cChar );
+ aFmt.SetCharFormatName(sBulletCharFormatName);
+ aFmt.SetBulletRelSize(45);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxBulletPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+ if (pBulletCharFmt)
+ sBulletCharFormatName = pBulletCharFmt->GetValue();
+}
+
+SvxNumPickTabPage::SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickoutlinepage.ui", "PickOutlinePage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init(NumberingPageType::OUTLINE);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence<Reference<XIndexAccess> > aOutlineAccess;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aOutlineAccess = xDefNum->getDefaultOutlineNumberings( rLocale );
+
+ for(sal_Int32 nItem = 0;
+ nItem < aOutlineAccess.getLength() && nItem < NUM_VALUSET_COUNT;
+ nItem++ )
+ {
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[ nItem ];
+
+ Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
+ for(sal_Int32 nLevel = 0; nLevel < xLevel->getCount() && nLevel < 5; nLevel++)
+ {
+ Any aValueAny = xLevel->getByIndex(nLevel);
+ Sequence<PropertyValue> aLevelProps;
+ aValueAny >>= aLevelProps;
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aLevelProps);
+ rItemArr.push_back( std::unique_ptr<SvxNumSettings_Impl>(pNew) );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetOutlineNumberingSettings(aOutlineAccess, xFormat, rLocale);
+}
+
+SvxNumPickTabPage::~SvxNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+ }
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+
+}
+
+// all levels are changed here
+IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+
+ const FontList* pList = nullptr;
+
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[m_xExamplesVS->GetSelectedItemId() - 1];
+
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+ SvxNumSettings_Impl* pLevelSettings = nullptr;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(rItemArr.size() > i)
+ pLevelSettings = rItemArr[i].get();
+ if(!pLevelSettings)
+ break;
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( pLevelSettings->nNumberType );
+ sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
+ if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
+ {
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetListFormat("", "", i);
+ if( !pLevelSettings->sBulletFont.isEmpty() &&
+ pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName())
+ {
+ //search for the font
+ if(!pList)
+ {
+ if (SfxObjectShell* pCurDocShell = SfxObjectShell::Current())
+ {
+ const SvxFontListItem* pFontListItem =
+ static_cast<const SvxFontListItem*>( pCurDocShell
+ ->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ }
+ }
+ if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
+ {
+ FontMetric aFontMetric = pList->Get(
+ pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE);
+ vcl::Font aFont(aFontMetric);
+ aFmt.SetBulletFont(&aFont);
+ }
+ else
+ {
+ //if it cannot be found then create a new one
+ vcl::Font aCreateFont( pLevelSettings->sBulletFont,
+ OUString(), Size( 0, 14 ) );
+ aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
+ aCreateFont.SetFamily( FAMILY_DONTKNOW );
+ aCreateFont.SetPitch( PITCH_DONTKNOW );
+ aCreateFont.SetWeight( WEIGHT_DONTKNOW );
+ aCreateFont.SetTransparent( true );
+ aFmt.SetBulletFont( &aCreateFont );
+ }
+ }
+ else
+ aFmt.SetBulletFont( &rActBulletFont );
+
+ aFmt.SetBulletChar( !pLevelSettings->sBulletChar.isEmpty()
+ ? pLevelSettings->sBulletChar.iterateCodePoints(
+ &o3tl::temporary(sal_Int32(0)))
+ : 0 );
+ aFmt.SetCharFormatName( sBulletCharFormatName );
+ aFmt.SetBulletRelSize(45);
+ }
+ else
+ {
+ aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? pActNum->GetLevelCount() : 1));
+ aFmt.SetCharFormatName(sNumCharFmtName);
+ aFmt.SetBulletRelSize(100);
+ // #i93908#
+ aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
+ }
+ pActNum->SetLevel(i, aFmt);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxNumPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFormatNames( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+}
+
+SvxBitmapPickTabPage::SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickgraphicpage.ui", "PickGraphicPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xErrorText(m_xBuilder->weld_label("errorft"))
+ , m_xBtBrowseFile(m_xBuilder->weld_button("browseBtn"))
+ , m_xExamplesVS(new SvxBmpNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin", true)))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init();
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBitmapPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBitmapPickTabPage, DoubleClickHdl_Impl));
+ m_xBtBrowseFile->connect_clicked(LINK(this, SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl));
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // determine graphic name
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames);
+
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+
+ INetURLObject aObj(grfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#114070 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ m_xExamplesVS->Invalidate();
+ }
+}
+
+SvxBitmapPickTabPage::~SvxBitmapPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBitmapPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBitmapPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bIsPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nActNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(!aGrfNames.empty() &&
+ (pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBitmapPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBitmapPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if ( aGrfNames.empty() )
+ {
+ return false;
+ }
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ) );
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxBitmapPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+
+ }
+ DBG_ASSERT(pItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(SVX_NUM_BITMAP);
+ aFmt.SetListFormat("", "", i);
+ aFmt.SetCharFormatName( "" );
+
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nIdx, &aGraphic))
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+ SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH );
+ aFmt.SetGraphicBrush( &aBrush, &aSize, &eOrient );
+ }
+ else if(aGrfNames.size() > nIdx)
+ aFmt.SetGraphic( aGrfNames[nIdx] );
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, GetFrameWeld());
+ aFileDialog.SetContext(sfx2::FileDialogHelper::BulletsAddImage);
+ aFileDialog.SetTitle(CuiResId(RID_CUISTR_ADD_IMAGE));
+ if ( aFileDialog.Execute() != ERRCODE_NONE )
+ return;
+
+ OUString aPath = SvtPathOptions().GetGalleryPath();
+ std::u16string_view aPathToken = o3tl::getToken(aPath, 1 , SEARCHPATH_DELIMITER );
+
+ OUString aUserImageURL = aFileDialog.GetPath();
+
+ OUString aFileName;
+ const sal_Int32 nPos {aUserImageURL.lastIndexOf(SEARCHFILENAME_DELIMITER)+1};
+ if (nPos<=0)
+ aFileName = aUserImageURL;
+ else if (nPos<aUserImageURL.getLength())
+ aFileName = aUserImageURL.copy(nPos);
+
+ OUString aUserGalleryURL = OUString::Concat(aPathToken) + "/" + aFileName;
+ INetURLObject aURL( aUserImageURL );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ GraphicDescriptor aDescriptor(aURL);
+ if (!aDescriptor.Detect())
+ return;
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
+ ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
+ if ( !xSimpleFileAccess->exists( aUserImageURL ))
+ return;
+
+ xSimpleFileAccess->copy( aUserImageURL, aUserGalleryURL );
+ INetURLObject gURL( aUserGalleryURL );
+ std::unique_ptr<SvStream> pIn(::utl::UcbStreamHelper::CreateStream(
+ gURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ if ( !pIn )
+ return;
+
+ Graphic aGraphic;
+ GraphicConverter::Import( *pIn, aGraphic );
+
+ BitmapEx aBitmap = aGraphic.GetBitmapEx();
+ tools::Long nPixelX = aBitmap.GetSizePixel().Width();
+ tools::Long nPixelY = aBitmap.GetSizePixel().Height();
+ double ratio = nPixelY/static_cast<double>(nPixelX);
+ if(nPixelX > 30)
+ {
+ nPixelX = 30;
+ nPixelY = static_cast<tools::Long>(nPixelX*ratio);
+ }
+ if(nPixelY > 30)
+ {
+ nPixelY = 30;
+ nPixelX = static_cast<tools::Long>(nPixelY/ratio);
+ }
+
+ aBitmap.Scale( Size( nPixelX, nPixelY ), BmpScaleFlag::Fast );
+ Graphic aScaledGraphic( aBitmap );
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+
+ Sequence< PropertyValue > aFilterData{
+ comphelper::makePropertyValue("Compression", sal_Int32(-1)),
+ comphelper::makePropertyValue("Quality", sal_Int32(1))
+ };
+
+ sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( gURL.GetFileExtension() );
+ rFilter.ExportGraphic( aScaledGraphic, gURL , nFilterFormat, &aFilterData );
+ GalleryExplorer::InsertURL( GALLERY_THEME_BULLETS, aUserGalleryURL );
+
+ aGrfNames.push_back(aUserGalleryURL);
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+ INetURLObject aObj(grfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#114070 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ grfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ }
+}
+
+// tabpage numbering options
+SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingoptionspage.ui", "NumberingOptionsPage", &rSet)
+ , aInvalidateTimer("cui SvxNumOptionsTabPage aInvalidateTimer")
+ , m_pLevelHdlEvent(nullptr)
+ , bLastWidthModified(false)
+ , bModified(false)
+ , bPreset(false)
+ , bAutomaticCharStyles(true)
+ , bHTMLMode(false)
+ , nBullet(0xff)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xGrid(m_xBuilder->weld_widget("grid2"))
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb"))
+ , m_xSeparatorFT(m_xBuilder->weld_label("separator"))
+ , m_xPrefixFT(m_xBuilder->weld_label("prefixft"))
+ , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
+ , m_xSuffixFT(m_xBuilder->weld_label("suffixft"))
+ , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
+ , m_xCharFmtFT(m_xBuilder->weld_label("charstyleft"))
+ , m_xCharFmtLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xBulColorFT(m_xBuilder->weld_label("colorft"))
+ , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft"))
+ , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT))
+ , m_xAllLevelFT(m_xBuilder->weld_label("sublevelsft"))
+ , m_xAllLevelNF(m_xBuilder->weld_spin_button("sublevels"))
+ , m_xStartFT(m_xBuilder->weld_label("startatft"))
+ , m_xStartED(m_xBuilder->weld_spin_button("startat"))
+ , m_xBulletFT(m_xBuilder->weld_label("bulletft"))
+ , m_xBulletPB(m_xBuilder->weld_button("bullet"))
+ , m_xBitmapFT(m_xBuilder->weld_label("bitmapft"))
+ , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap"))
+ , m_xWidthFT(m_xBuilder->weld_label("widthft"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM))
+ , m_xHeightFT(m_xBuilder->weld_label("heightft"))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM))
+ , m_xRatioCB(m_xBuilder->weld_check_button("keepratio"))
+ , m_xOrientFT(m_xBuilder->weld_label("orientft"))
+ , m_xOrientLB(m_xBuilder->weld_combo_box("orientlb"))
+ , m_xAllLevelsFrame(m_xBuilder->weld_widget("levelsframe"))
+ , m_xSameLevelCB(m_xBuilder->weld_check_button("allsame"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
+ m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
+ SetExchangeSupport();
+ aActBulletFont = lcl_GetDefaultBulletFont();
+
+ m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl));
+ m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl));
+ m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl));
+ m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl));
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl));
+ m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl));
+ m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl));
+ m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl));
+ m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl));
+ m_xOrientLB->connect_changed(LINK(this, SvxNumOptionsTabPage, OrientHdl_Impl));
+ m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl));
+ m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl));
+ m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl));
+ aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
+ aInvalidateTimer.SetTimeout(50);
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // Fill ListBox with predefined / translated numbering types.
+ sal_uInt32 nCount = SvxNumberingTypeTable::Count();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ m_xFmtLB->append(OUString::number(SvxNumberingTypeTable::GetValue(i)), SvxNumberingTypeTable::GetString(i));
+ }
+
+ // Get advanced numbering types from the component.
+ // Watch out for the ugly
+ // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN
+ // to not remove that.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering( *m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN));
+
+ m_xFmtLB->set_active(0);
+
+ m_xCharFmtLB->set_size_request(m_xCharFmtLB->get_approximate_digit_width() * 10, -1);
+ Size aSize(m_xGrid->get_preferred_size());
+ m_xGrid->set_size_request(aSize.Width(), -1);
+}
+
+SvxNumOptionsTabPage::~SvxNumOptionsTabPage()
+{
+ m_xPreviewWIN.reset();
+ m_xBulColLB.reset();
+ pActNum.reset();
+ pSaveNum.reset();
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+}
+
+void SvxNumOptionsTabPage::SetMetric(FieldUnit eMetric)
+{
+ if(eMetric == FieldUnit::MM)
+ {
+ m_xWidthMF->set_digits(1);
+ m_xHeightMF->set_digits(1);
+ }
+ m_xWidthMF->set_unit(eMetric);
+ m_xHeightMF->set_unit(eMetric);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumOptionsTabPage>(pPage, pController, *rAttrSet);
+};
+
+void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ sal_uInt16 nTmpNumLvl = 1;
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nTmpNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl)
+ return;
+
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if(nActNumLvl != SAL_MAX_UINT16)
+ {
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ }
+ *pActNum = *pSaveNum;
+
+ InitControls();
+}
+
+DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+};
+
+void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pBulletItem =
+ rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pBulletItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pBulletItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pBulletItem )
+ {
+ pBulletItem = & rSet->Get( nNumItemId );
+ }
+ }
+ DBG_ASSERT(pBulletItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->n_children())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->n_children() - 1);
+
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select( pSaveNum->GetLevelCount() );
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select( i );
+ nMask <<= 1 ;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+ m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering());
+
+ const SfxUInt16Item* pHtmlModeItem =
+ rSet->GetItemIfSet( SID_HTML_MODE, false );
+ if (!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem( SID_HTML_MODE );
+ }
+ if ( pHtmlModeItem )
+ {
+ sal_uInt16 nHtmlMode = pHtmlModeItem->GetValue();
+ bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON);
+ }
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(bCharFmt);
+ m_xCharFmtLB->set_visible(bCharFmt);
+
+ bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+
+ bool bAllLevel = bContinuous && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+
+ m_xAllLevelsFrame->set_visible(bContinuous);
+
+ // again misusage: in Draw there is numeration only until the bitmap
+ // without SVX_NUM_NUMBER_NONE
+ //remove types that are unsupported by Draw/Impress
+ if(!bContinuous)
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if(/*SVX_NUM_NUMBER_NONE == nEntryData ||*/
+ (SVX_NUM_BITMAP|LINK_TOKEN) == nEntryData)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+ //one must be enabled
+ if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+ else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+
+ // MegaHack: because of a not-fixable 'design mistake/error' in Impress
+ // delete all kinds of numeric enumerations
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if( /*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumOptionsTabPage::InitControls()
+{
+ bool bShowBullet = true;
+ bool bShowBitmap = true;
+ bool bSameType = true;
+ bool bSameStart = true;
+ bool bSamePrefix = true;
+ bool bSameSuffix = true;
+ bool bAllLevel = true;
+ bool bSameCharFmt = true;
+ bool bSameVOrient = true;
+ bool bSameSize = true;
+ bool bSameBulColor = true;
+ bool bSameBulRelSize= true;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ OUString sFirstCharFmt;
+ sal_Int16 eFirstOrient = text::VertOrientation::NONE;
+ Size aFirstSize(0,0);
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ sal_uInt16 nHighestLevel = 0;
+
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
+ bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP;
+ if(SAL_MAX_UINT16 == nLvl)
+ {
+ nLvl = i;
+ sFirstCharFmt = aNumFmtArr[i]->GetCharFormatName();
+ eFirstOrient = aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap)
+ aFirstSize = aNumFmtArr[i]->GetGraphicSize();
+ }
+ if( i > nLvl)
+ {
+ bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType();
+ bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart();
+
+ bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix();
+ bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix();
+ bAllLevel &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[nLvl]->GetIncludeUpperLevels();
+ bSameCharFmt &= sFirstCharFmt == aNumFmtArr[i]->GetCharFormatName();
+ bSameVOrient &= eFirstOrient == aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap && bSameSize)
+ bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize;
+ bSameBulColor &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor();
+ bSameBulRelSize &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize();
+ }
+ nHighestLevel = i;
+ }
+ else
+ aNumFmtArr[i] = nullptr;
+
+ nMask <<= 1 ;
+ }
+ SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0);
+
+ sal_uInt16 nNumberingType;
+ if (nLvl != SAL_MAX_UINT16)
+ nNumberingType = aNumFmtArr[nLvl]->GetNumberingType();
+ else
+ {
+ nNumberingType = SVX_NUM_NUMBER_NONE;
+ bAllLevel = false;
+ bSameBulRelSize = false;
+ bSameBulColor = false;
+ bSameStart = false;
+ bSamePrefix = false;
+ bSameSuffix = false;
+ }
+
+ CheckForStartValue_Impl(nNumberingType);
+
+ if(bShowBitmap)
+ {
+ if(!bSameVOrient || eFirstOrient == text::VertOrientation::NONE)
+ m_xOrientLB->set_active(-1);
+ else
+ m_xOrientLB->set_active(
+ sal::static_int_cast< sal_Int32 >(eFirstOrient - 1));
+ // no text::VertOrientation::NONE
+
+ if(bSameSize)
+ {
+ SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
+ SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
+ }
+ else
+ {
+ m_xHeightMF->set_text("");
+ m_xWidthMF->set_text("");
+ }
+ }
+
+ if(bSameType)
+ {
+ sal_uInt16 nLBData = nNumberingType;
+ m_xFmtLB->set_active_id(OUString::number(nLBData));
+ }
+ else
+ m_xFmtLB->set_active(-1);
+
+ m_xAllLevelNF->set_sensitive(nHighestLevel > 0 && !m_xSameLevelCB->get_active());
+ m_xAllLevelNF->set_max(nHighestLevel + 1);
+ if(bAllLevel)
+ {
+ m_xAllLevelNF->set_value(aNumFmtArr[nLvl]->GetIncludeUpperLevels());
+ }
+ else
+ {
+ m_xAllLevelNF->set_text("");
+ }
+
+ if(bBullRelSize)
+ {
+ if(bSameBulRelSize)
+ m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT);
+ else
+ m_xBulRelSizeMF->set_text("");
+ }
+ if(bBullColor)
+ {
+ if(bSameBulColor)
+ m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor());
+ else
+ m_xBulColLB->SetNoSelection();
+ }
+ switch(nBullet)
+ {
+ case SHOW_NUMBERING:
+ if(bSameStart)
+ {
+ m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart());
+ }
+ else
+ m_xStartED->set_text("");
+ break;
+ case SHOW_BULLET:
+ break;
+ case SHOW_BITMAP:
+ break;
+ }
+
+ if(bSamePrefix)
+ m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix());
+ else
+ m_xPrefixED->set_text("");
+ if(bSameSuffix)
+ m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix());
+ else
+ m_xSuffixED->set_text("");
+
+ if(bSameCharFmt)
+ {
+ if (!sFirstCharFmt.isEmpty())
+ m_xCharFmtLB->set_active_text(sFirstCharFmt);
+ else
+ m_xCharFmtLB->set_active(0);
+ }
+ else
+ m_xCharFmtLB->set_active(-1);
+
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+// 0 - Number; 1 - Bullet; 2 - Bitmap
+void SvxNumOptionsTabPage::SwitchNumberType( sal_uInt8 nType )
+{
+ if(nBullet == nType)
+ return;
+ nBullet = nType;
+ bool bBullet = (nType == SHOW_BULLET);
+ bool bBitmap = (nType == SHOW_BITMAP);
+ bool bEnableBitmap = (nType == SHOW_BITMAP);
+ bool bNumeric = !(bBitmap||bBullet);
+ m_xSeparatorFT->set_visible(bNumeric);
+ m_xPrefixFT->set_visible(bNumeric);
+ m_xPrefixED->set_visible(bNumeric);
+ m_xSuffixFT->set_visible(bNumeric);
+ m_xSuffixED->set_visible(bNumeric);
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(!bBitmap && bCharFmt);
+ m_xCharFmtLB->set_visible(!bBitmap && bCharFmt);
+
+ // this is rather misusage, as there is no own flag
+ // for complete numeration
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+
+ m_xStartFT->set_visible(!(bBullet||bBitmap));
+ m_xStartED->set_visible(!(bBullet||bBitmap));
+
+ m_xBulletFT->set_visible(bBullet);
+ m_xBulletPB->set_visible(bBullet);
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ m_xBulColorFT->set_visible(!bBitmap && bBullColor);
+ m_xBulColLB->set_visible(!bBitmap && bBullColor);
+ bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
+ m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
+
+ m_xBitmapFT->set_visible(bBitmap);
+ m_xBitmapMB->set_visible(bBitmap);
+
+ m_xWidthFT->set_visible(bBitmap);
+ m_xWidthMF->set_visible(bBitmap);
+ m_xHeightFT->set_visible(bBitmap);
+ m_xHeightMF->set_visible(bBitmap);
+ m_xRatioCB->set_visible(bBitmap);
+
+ m_xOrientFT->set_visible(bBitmap && bAllLevelFeature);
+ m_xOrientLB->set_visible(bBitmap && bAllLevelFeature);
+
+ m_xWidthFT->set_sensitive(bEnableBitmap);
+ m_xWidthMF->set_sensitive(bEnableBitmap);
+ m_xHeightFT->set_sensitive(bEnableBitmap);
+ m_xHeightMF->set_sensitive(bEnableBitmap);
+ m_xRatioCB->set_sensitive(bEnableBitmap);
+ m_xOrientFT->set_sensitive(bEnableBitmap);
+ m_xOrientLB->set_sensitive(bEnableBitmap);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127112 (borrowing tdf#127120 solution) multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumOptionsTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ InitControls();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void)
+{
+ m_aPreviewWIN.Invalidate();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(e));
+ aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), sal_Int64(e + 1))) );
+ // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
+ aNumFmt.SetListFormat(aNumFmt.GetPrefix(), aNumFmt.GetSuffix(), e);
+ pActNum->SetLevel(e, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ OUString sSelectStyle;
+ bool bShowOrient = false;
+ bool bBmp = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ // PAGEDESC does not exist
+ SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
+ aNumFmt.SetNumberingType(nNumType);
+ sal_uInt16 nNumberingType = aNumFmt.GetNumberingType();
+ if(SVX_NUM_BITMAP == (nNumberingType&(~LINK_TOKEN)))
+ {
+ bBmp |= nullptr != aNumFmt.GetBrush();
+ aNumFmt.SetIncludeUpperLevels( 1 );
+ aNumFmt.SetListFormat("", "", i);
+ if(!bBmp)
+ aNumFmt.SetGraphic("");
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BITMAP);
+ bShowOrient = true;
+ }
+ else if( SVX_NUM_CHAR_SPECIAL == nNumberingType )
+ {
+ aNumFmt.SetIncludeUpperLevels( 1 );
+ aNumFmt.SetListFormat("", "", i);
+ if( !aNumFmt.GetBulletFont() )
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ if( !aNumFmt.GetBulletChar() )
+ aNumFmt.SetBulletChar( SVX_DEF_BULLET );
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BULLET);
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sBulletCharFormatName;
+ }
+ }
+ else
+ {
+ aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
+
+ SwitchNumberType(SHOW_NUMBERING);
+ pActNum->SetLevel(i, aNumFmt);
+ CheckForStartValue_Impl(nNumberingType);
+
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sNumCharFmtName;
+ }
+ }
+ }
+ nMask <<= 1;
+ }
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ if(bShowOrient && bAllLevelFeature)
+ {
+ m_xOrientFT->show();
+ m_xOrientLB->show();
+ }
+ else
+ {
+ m_xOrientFT->hide();
+ m_xOrientLB->hide();
+ }
+ SetModified();
+ if(!sSelectStyle.isEmpty())
+ {
+ m_xCharFmtLB->set_active_text(sSelectStyle);
+ CharFmtHdl_Impl(*m_xCharFmtLB);
+ bAutomaticCharStyles = true;
+ }
+}
+
+void SvxNumOptionsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
+{
+ bool bIsNull = m_xStartED->get_value() == 0;
+ bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
+ SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
+ SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
+ m_xStartED->set_min(bNoZeroAllowed ? 1 : 0);
+ if (bIsNull && bNoZeroAllowed)
+ EditModifyHdl_Impl(*m_xStartED);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+ nPos ++; // no VERT_NONE
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ const Size& rSize = aNumFmt.GetGraphicSize();
+ sal_Int16 eOrient = static_cast<sal_Int16>(nPos);
+ aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bSet = rBox.get_active();
+ pActNum->SetContinuousNumbering(bSet);
+ bool bRepaint = false;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE)
+ {
+ bRepaint = true;
+ break;
+ }
+ }
+ SetModified(bRepaint);
+ InitControls();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ Color nSetColor = rColorBox.GetSelectEntryColor();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletColor(nSetColor);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT);
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletRelSize(nRelSize);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
+{
+ OUString aGrfName;
+ Size aSize;
+ bool bSucc(false);
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
+
+ OString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ auto idx = sNumber.toUInt32();
+ if (idx < aGrfNames.size())
+ {
+ aGrfName = aGrfNames[idx];
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic))
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ else if (rIdent == "fromfile")
+ {
+ aGrfDlg.EnableLink( false );
+ aGrfDlg.AsLink( false );
+ if ( !aGrfDlg.Execute() )
+ {
+ // memorize selected filter
+ aGrfName = aGrfDlg.GetPath();
+
+ Graphic aGraphic;
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ if(!bSucc)
+ return;
+
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetCharFormatName(m_sNumCharFmtName);
+ aNumFmt.SetGraphic(aGrfName);
+
+ // set size for a later comparison
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ // initiate asynchronous loading
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ aInitSize[i] = aNumFmt.GetGraphicSize();
+
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ m_xRatioCB->set_sensitive(true);
+ m_xWidthFT->set_sensitive(true);
+ m_xHeightFT->set_sensitive(true);
+ m_xWidthMF->set_sensitive(true);
+ m_xHeightMF->set_sensitive(true);
+ SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
+ SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
+ m_xOrientFT->set_sensitive(true);
+ m_xOrientLB->set_sensitive(true);
+ SetModified();
+ //needed due to asynchronous loading of graphics in the SvxBrushItem
+ aInvalidateTimer.Start();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xGalleryMenu)
+ return;
+
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+
+ if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
+ return;
+
+ GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
+
+ Graphic aGraphic;
+ OUString sGrfName;
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+ size_t i = 0;
+ for (const auto & grfName : aGrfNames)
+ {
+ sGrfName = grfName;
+ OUString sItemId = "gallery" + OUString::number(i);
+ INetURLObject aObj(sGrfName);
+ if (aObj.GetProtocol() == INetProtocol::File)
+ {
+ // tdf#141334 - only show the last name of the filename without its extension
+ aObj.removeExtension();
+ sGrfName = aObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, i, &aGraphic))
+ {
+ BitmapEx aBitmap(aGraphic.GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH ||
+ aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(sItemId, sGrfName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(sItemId, sGrfName);
+ }
+ ++i;
+ }
+ GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
+{
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+
+ sal_uInt16 nMask = 1;
+ std::optional<vcl::Font> pFmtFont;
+ bool bSameBullet = true;
+ sal_UCS4 cBullet = 0;
+ bool bFirst = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ cBullet = rCurFmt.GetBulletChar();
+ }
+ else if(rCurFmt.GetBulletChar() != cBullet )
+ {
+ bSameBullet = false;
+ break;
+ }
+ if(!pFmtFont)
+ pFmtFont = rCurFmt.GetBulletFont();
+ bFirst = false;
+ }
+ nMask <<= 1;
+
+ }
+
+ if (pFmtFont)
+ aMap.SetCharFont(*pFmtFont);
+ else
+ aMap.SetCharFont(aActBulletFont);
+ if (bSameBullet)
+ aMap.SetChar(cBullet);
+ if (aMap.run() != RET_OK)
+ return;
+
+ // change Font Numrules
+ aActBulletFont = aMap.GetCharFont();
+
+ sal_uInt16 _nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & _nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ aNumFmt.SetBulletChar(aMap.GetChar());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ _nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bWidth = &rField == m_xWidthMF.get();
+ bLastWidthModified = bWidth;
+ bool bRatio = m_xRatioCB->get_active();
+ tools::Long nWidthVal = static_cast<tools::Long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
+ tools::Long nHeightVal = static_cast<tools::Long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic( nWidthVal ,
+ MapUnit::Map100thMM, eCoreUnit );
+ nHeightVal = OutputDevice::LogicToLogic( nHeightVal,
+ MapUnit::Map100thMM, eCoreUnit);
+ double fSizeRatio;
+
+ bool bRepaint = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ Size aSize(aNumFmt.GetGraphicSize() );
+ Size aSaveSize(aSize);
+
+ if (aInitSize[i].Height())
+ fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height());
+ else
+ fSizeRatio = double(1);
+
+ if(bWidth)
+ {
+ tools::Long nDelta = nWidthVal - aInitSize[i].Width();
+ aSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ aSize.setHeight( aInitSize[i].Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ tools::Long nDelta = nHeightVal - aInitSize[i].Height();
+ aSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ aSize.setWidth( aInitSize[i].Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_xWidthMF->set_value(m_xWidthMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ if(aSize != aSaveSize)
+ bRepaint = true;
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(bRepaint);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (bLastWidthModified)
+ SizeHdl_Impl(*m_xWidthMF);
+ else
+ SizeHdl_Impl(*m_xHeightMF);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
+{
+ bAutomaticCharStyles = false;
+ sal_Int32 nEntryPos = m_xCharFmtLB->get_active();
+ OUString sEntry = m_xCharFmtLB->get_active_text();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if( 0 == nEntryPos )
+ aNumFmt.SetCharFormatName("");
+ else
+ {
+ if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ aNumFmt.SetCharFormatName(sEntry);
+ }
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+};
+
+IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditModifyHdl_Impl(&rEdit);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void)
+{
+ EditModifyHdl_Impl(&rSpinButton);
+}
+
+void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
+{
+ bool bPrefixSuffix = (pEdit == m_xPrefixED.get())|| (pEdit == m_xSuffixED.get());
+ bool bStart = pEdit == m_xStartED.get();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if (bPrefixSuffix)
+ aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i);
+ else if(bStart)
+ aNumFmt.SetStart(m_xStartED->get_value());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+static tools::Long lcl_DrawGraphic(VirtualDevice& rVDev, const SvxNumberFormat &rFmt, tools::Long nXStart,
+ tools::Long nYMiddle, tools::Long nDivision)
+{
+ const SvxBrushItem* pBrushItem = rFmt.GetBrush();
+ tools::Long nRet = 0;
+ if(pBrushItem)
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if(pGrf)
+ {
+ Size aGSize( rFmt.GetGraphicSize() );
+ aGSize.setWidth( aGSize.Width() / nDivision );
+ nRet = aGSize.Width();
+ aGSize.setHeight( aGSize.Height() / nDivision );
+ pGrf->Draw(rVDev, Point(nXStart,nYMiddle - ( aGSize.Height() / 2) ),
+ rVDev.PixelToLogic( aGSize ) );
+ }
+ }
+ return nRet;
+
+}
+
+static tools::Long lcl_DrawBullet(VirtualDevice* pVDev,
+ const SvxNumberFormat& rFmt, tools::Long nXStart,
+ tools::Long nYStart, const Size& rSize)
+{
+ vcl::Font aTmpFont(pVDev->GetFont());
+
+ // via Uno it's possible that no font has been set!
+ vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont);
+ Size aTmpSize(rSize);
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ // in case of a height of zero it is drawn in original height
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ aFont.SetTransparent(true);
+ Color aBulletColor = rFmt.GetBulletColor();
+ if(aBulletColor == COL_AUTO)
+ aBulletColor = pVDev->GetFillColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if(aBulletColor == pVDev->GetFillColor())
+ aBulletColor.Invert();
+ aFont.SetColor(aBulletColor);
+ pVDev->SetFont( aFont );
+ sal_UCS4 cChar = rFmt.GetBulletChar();
+ OUString aText(&cChar, 1);
+ tools::Long nY = nYStart;
+ nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
+ pVDev->DrawText( Point(nXStart, nY), aText );
+ tools::Long nRet = pVDev->GetTextWidth(aText);
+
+ pVDev->SetFont(aTmpFont);
+ return nRet;
+}
+
+SvxNumberingPreview::SvxNumberingPreview()
+ : pActNum(nullptr)
+ , bPosition(false)
+ , nActLevel(SAL_MAX_UINT16)
+{
+}
+
+// paint preview of numeration
+void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/)
+{
+ Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+
+ const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
+ const Color aBackColor = rStyleSettings.GetFieldColor();
+ const Color aTextColor = rStyleSettings.GetFieldTextColor();
+
+ ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
+ pVDev->EnableRTL(rRenderContext.IsRTLEnabled());
+ pVDev->SetMapMode(rRenderContext.GetMapMode());
+ pVDev->SetOutputSize(aSize);
+
+ Color aLineColor(COL_LIGHTGRAY);
+ if (aLineColor == aBackColor)
+ aLineColor.Invert();
+ pVDev->SetLineColor(aLineColor);
+ pVDev->SetFillColor(aBackColor);
+
+ if (pActNum)
+ {
+ tools::Long nWidthRelation = 30; // chapter dialog
+
+ // height per level
+ tools::Long nXStep = aSize.Width() / (pActNum->GetLevelCount() > 1 ? 3 * pActNum->GetLevelCount() : 3);
+ if (pActNum->GetLevelCount() < 10)
+ nXStep /= 2;
+ tools::Long nYStart = 4;
+ // the whole height mustn't be used for a single level
+ tools::Long nYStep = (aSize.Height() - 6)/ (pActNum->GetLevelCount() > 1 ? pActNum->GetLevelCount() : 5);
+
+ aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getConfiguredSystemLanguage(), GetDefaultFontFlags::OnlyOne);
+ aStdFont.SetColor(aTextColor);
+ aStdFont.SetFillColor(aBackColor);
+
+ tools::Long nFontHeight = nYStep * 6 / 10;
+ if (bPosition)
+ nFontHeight = nYStep * 15 / 10;
+ aStdFont.SetFontSize(Size( 0, nFontHeight ));
+
+ SvxNodeNum aNum;
+ sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart();
+
+ if (bPosition)
+ {
+ tools::Long nLineHeight = nFontHeight * 8 / 7;
+ sal_uInt8 nStart = 0;
+ while (!(nActLevel & (1<<nStart)))
+ {
+ nStart++;
+ }
+ if (nStart)
+ nStart--;
+ sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), sal_uInt8(pActNum->GetLevelCount()));
+ for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
+
+ tools::Long nXStart( 0 );
+ short nTextOffset( 0 );
+ tools::Long nNumberXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
+ nNumberXPos = nXStart;
+ tools::Long nFirstLineOffset = (-rFmt.GetFirstLineOffset()) / nWidthRelation;
+
+ if (nFirstLineOffset <= nNumberXPos)
+ nNumberXPos = nNumberXPos - nFirstLineOffset;
+ else
+ nNumberXPos = 0;
+ // in draw this is valid
+ if (nTextOffset < 0)
+ nNumberXPos = nNumberXPos + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpNumberXPos((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpNumberXPos < 0)
+ {
+ nNumberXPos = 0;
+ }
+ else
+ {
+ nNumberXPos = nTmpNumberXPos;
+ }
+ }
+
+ tools::Long nBulletWidth = 0;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() &(~LINK_TOKEN)))
+ {
+ tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawGraphic(*pVDev, rFmt, nNumberXPos, nYMiddle, nWidthRelation) : 0;
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawBullet(pVDev.get(), rFmt, nNumberXPos, nYStart, aStdFont.GetFontSize()) : 0;
+ }
+ else
+ {
+ pVDev->SetFont(aStdFont);
+ aNum.SetLevel(nLevel);
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString( aNum ));
+ vcl::Font aSaveFont = pVDev->GetFont();
+ vcl::Font aColorFont(aSaveFont);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = aBackColor.IsDark() ? COL_WHITE : COL_BLACK;
+ else if (aTmpBulletColor == aBackColor)
+ aTmpBulletColor.Invert();
+ aColorFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aColorFont);
+ pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
+ pVDev->SetFont(aSaveFont);
+ nBulletWidth = pVDev->GetTextWidth(aText);
+ nPreNum++;
+ }
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
+ rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ pVDev->SetFont(aStdFont);
+ OUString aText(' ');
+ pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
+ nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText);
+ }
+
+ tools::Long nTextXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nTextXPos = nXStart;
+ if (nTextOffset < 0)
+ nTextXPos = nTextXPos + nTextOffset;
+ if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos)
+ nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ switch (rFmt.GetLabelFollowedBy())
+ {
+ case SvxNumberFormat::LISTTAB:
+ {
+ nTextXPos = rFmt.GetListtabPos() / nWidthRelation;
+ if (nTextXPos < nNumberXPos + nBulletWidth)
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ }
+ break;
+ case SvxNumberFormat::SPACE:
+ case SvxNumberFormat::NOTHING:
+ case SvxNumberFormat::NEWLINE:
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ break;
+ }
+
+ nXStart = rFmt.GetIndentAt() / nWidthRelation;
+ }
+
+ ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2));
+ pVDev->SetFillColor(aBackColor);
+ pVDev->DrawRect(aRect1);
+
+ ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2 ), Size(aSize.Width() / 2, 2));
+ pVDev->DrawRect(aRect2);
+ nYStart += 2 * nLineHeight;
+ }
+ }
+ else
+ {
+ //#i5153# painting gray or black rectangles as 'normal' numbering text
+ tools::Long nWidth = pVDev->GetTextWidth("Preview");
+ tools::Long nTextHeight = pVDev->GetTextHeight();
+ tools::Long nRectHeight = nTextHeight * 2 / 3;
+ tools::Long nTopOffset = nTextHeight - nRectHeight;
+ Color aBlackColor(COL_BLACK);
+ if (aBlackColor == aBackColor)
+ aBlackColor.Invert();
+
+ for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount(); ++nLevel, nYStart = nYStart + nYStep)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[ nLevel ] = rFmt.GetStart();
+ tools::Long nXStart( 0 );
+ pVDev->SetFillColor( aBackColor );
+
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpXStart((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpXStart < 0)
+ {
+ nXStart = 0;
+ }
+ else
+ {
+ nXStart = nTmpXStart;
+ }
+ }
+ nXStart /= 2;
+ nXStart += 2;
+ tools::Long nTextOffset = 2 * nXStep;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nTextOffset = lcl_DrawGraphic(*pVDev, rFmt, nXStart, nYMiddle, nWidthRelation);
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ nTextOffset = lcl_DrawBullet(pVDev.get(), rFmt, nXStart, nYStart, aStdFont.GetFontSize());
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else
+ {
+ vcl::Font aFont(aStdFont);
+ Size aTmpSize(aStdFont.GetFontSize());
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE))
+ {
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ }
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = aBackColor.IsDark() ? COL_WHITE : COL_BLACK;
+ else if (aTmpBulletColor == aBackColor)
+ aTmpBulletColor.Invert();
+ aFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aFont);
+ aNum.SetLevel( nLevel );
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString(aNum));
+ tools::Long nY = nYStart;
+ nY -= (pVDev->GetTextHeight() - nTextHeight - pVDev->GetFontMetric().GetDescent());
+ pVDev->DrawText(Point(nXStart, nY), aText);
+ nTextOffset = pVDev->GetTextWidth(aText);
+ nTextOffset = nTextOffset + nXStep;
+ nPreNum++;
+ pVDev->SetFont(aStdFont);
+ }
+ //#i5153# the selected rectangle(s) should be black
+ if (0 != (nActLevel & (1<<nLevel)))
+ {
+ pVDev->SetFillColor( aBlackColor );
+ pVDev->SetLineColor( aBlackColor );
+ }
+ else
+ {
+ //#i5153# unselected levels are gray
+ pVDev->SetFillColor( aLineColor );
+ pVDev->SetLineColor( aLineColor );
+ }
+ ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart + nTopOffset), Size(nWidth, nRectHeight));
+ pVDev->DrawRect(aRect1);
+ }
+ }
+ }
+ rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev);
+}
+
+
+//See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate
+//dialog to this one, except with a different preview window impl.
+//TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be
+//merged
+SvxNumPositionTabPage::SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingpositionpage.ui", "NumberingPositionPage", &rSet)
+ , m_pLevelHdlEvent(nullptr)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , bInInintControl(false)
+ , bLabelAlignmentPosAndSpaceModeActive(false)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xDistBorderFT(m_xBuilder->weld_label("indent"))
+ , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM))
+ , m_xRelativeCB(m_xBuilder->weld_check_button("relative"))
+ , m_xIndentFT(m_xBuilder->weld_label("numberingwidth"))
+ , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM))
+ , m_xDistNumFT(m_xBuilder->weld_label("numdist"))
+ , m_xDistNumMF(m_xBuilder->weld_metric_spin_button("numdistmf", FieldUnit::CM))
+ , m_xAlignFT(m_xBuilder->weld_label("numalign"))
+ , m_xAlignLB(m_xBuilder->weld_combo_box("numalignlb"))
+ , m_xLabelFollowedByFT(m_xBuilder->weld_label("numfollowedby"))
+ , m_xLabelFollowedByLB(m_xBuilder->weld_combo_box("numfollowedbylb"))
+ , m_xListtabFT(m_xBuilder->weld_label("at"))
+ , m_xListtabMF(m_xBuilder->weld_metric_spin_button("atmf", FieldUnit::CM))
+ , m_xAlign2FT(m_xBuilder->weld_label("num2align"))
+ , m_xAlign2LB(m_xBuilder->weld_combo_box("num2alignlb"))
+ , m_xAlignedAtFT(m_xBuilder->weld_label("alignedat"))
+ , m_xAlignedAtMF(m_xBuilder->weld_metric_spin_button("alignedatmf", FieldUnit::CM))
+ , m_xIndentAtFT(m_xBuilder->weld_label("indentat"))
+ , m_xIndentAtMF(m_xBuilder->weld_metric_spin_button("indentatmf", FieldUnit::CM))
+ , m_xStandardPB(m_xBuilder->weld_button("standard"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ SetExchangeSupport();
+
+ // set metric
+ FieldUnit eFUnit = GetModuleFieldUnit(rSet);
+
+ SetFieldUnit( *m_xDistBorderMF, eFUnit );
+ SetFieldUnit( *m_xIndentMF, eFUnit );
+ SetFieldUnit( *m_xDistNumMF, eFUnit );
+
+ m_xAlignedAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xListtabMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xIndentAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+
+ m_xRelativeCB->set_active(true);
+ m_xAlignLB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ m_xAlign2LB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ for ( sal_Int32 i = 0; i < m_xAlignLB->get_count(); ++i )
+ {
+ m_xAlign2LB->append_text(m_xAlignLB->get_text(i));
+ }
+
+ Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SvxNumPositionTabPage, DistanceHdl_Impl);
+ m_xDistBorderMF->connect_value_changed(aLk3);
+ m_xDistNumMF->connect_value_changed(aLk3);
+ m_xIndentMF->connect_value_changed(aLk3);
+
+ m_xLabelFollowedByLB->connect_changed(LINK(this, SvxNumPositionTabPage, LabelFollowedByHdl_Impl));
+
+ m_xListtabMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, ListtabPosHdl_Impl));
+ m_xAlignedAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, AlignAtHdl_Impl));
+ m_xIndentAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, IndentAtHdl_Impl));
+
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumPositionTabPage, LevelHdl_Impl));
+ m_xRelativeCB->connect_toggled(LINK(this, SvxNumPositionTabPage, RelativeHdl_Impl));
+ m_xStandardPB->connect_clicked(LINK(this, SvxNumPositionTabPage, StandardHdl_Impl));
+
+ m_xRelativeCB->set_active(bLastRelative);
+ m_aPreviewWIN.SetPositionMode();
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+}
+
+SvxNumPositionTabPage::~SvxNumPositionTabPage()
+{
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+ m_xPreviewWIN.reset();
+}
+
+/*-------------------------------------------------------*/
+
+void SvxNumPositionTabPage::InitControls()
+{
+ bInInintControl = true;
+ const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive &&
+ m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active();
+ const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 &&
+ SAL_MAX_UINT16 != nActNumLvl;
+
+ m_xDistBorderMF->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+ m_xDistBorderFT->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+
+ bool bSetDistEmpty = false;
+ bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameDist = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAdjust = true;
+
+ bool bSameLabelFollowedBy = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameListtab = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAlignAt = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndentAt = bLabelAlignmentPosAndSpaceModeActive;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ tools::Long nFirstBorderTextRelative = -1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ if(nActNumLvl & nMask)
+ {
+ if(SAL_MAX_UINT16 == nLvl)
+ nLvl = i;
+
+ if( i > nLvl)
+ {
+ bSameAdjust &= aNumFmtArr[i]->GetNumAdjust() == aNumFmtArr[nLvl]->GetNumAdjust();
+ if ( !bLabelAlignmentPosAndSpaceModeActive )
+ {
+ if(bRelative)
+ {
+ if(nFirstBorderTextRelative == -1)
+ nFirstBorderTextRelative =
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ else
+ bSameDistBorderNum &= nFirstBorderTextRelative ==
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ }
+ else
+ bSameDistBorderNum &=
+ aNumFmtArr[i]->GetAbsLSpace() - aNumFmtArr[i]->GetFirstLineOffset() ==
+ aNumFmtArr[i - 1]->GetAbsLSpace() - aNumFmtArr[i - 1]->GetFirstLineOffset();
+
+ bSameDist &= aNumFmtArr[i]->GetCharTextDistance() == aNumFmtArr[nLvl]->GetCharTextDistance();
+ bSameIndent &= aNumFmtArr[i]->GetFirstLineOffset() == aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ else
+ {
+ bSameLabelFollowedBy &=
+ aNumFmtArr[i]->GetLabelFollowedBy() == aNumFmtArr[nLvl]->GetLabelFollowedBy();
+ bSameListtab &=
+ aNumFmtArr[i]->GetListtabPos() == aNumFmtArr[nLvl]->GetListtabPos();
+ bSameAlignAt &=
+ ( ( aNumFmtArr[i]->GetIndentAt() + aNumFmtArr[i]->GetFirstLineIndent() )
+ == ( aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent() ) );
+ bSameIndentAt &=
+ aNumFmtArr[i]->GetIndentAt() == aNumFmtArr[nLvl]->GetIndentAt();
+ }
+ }
+ }
+ nMask <<= 1;
+
+ }
+ if (SVX_MAX_NUM <= nLvl)
+ {
+ OSL_ENSURE(false, "cannot happen.");
+ return;
+ }
+
+ if(bSameDistBorderNum)
+ {
+ tools::Long nDistBorderNum;
+ if(bRelative)
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ if(nLvl)
+ nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())+ aNumFmtArr[nLvl - 1]->GetFirstLineOffset();
+ }
+ else
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit);
+ }
+ else
+ bSetDistEmpty = true;
+
+ if(bSameDist)
+ SetMetricValue(*m_xDistNumMF, aNumFmtArr[nLvl]->GetCharTextDistance(), eCoreUnit);
+ else
+ m_xDistNumMF->set_text("");
+ if(bSameIndent)
+ SetMetricValue(*m_xIndentMF, - aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit);
+ else
+ m_xIndentMF->set_text("");
+
+ if(bSameAdjust)
+ {
+ sal_Int32 nPos = 1; // centered
+ if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Left)
+ nPos = 0;
+ else if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Right)
+ nPos = 2;
+ m_xAlignLB->set_active(nPos);
+ m_xAlign2LB->set_active(nPos);
+ }
+ else
+ {
+ m_xAlignLB->set_active(-1);
+ m_xAlign2LB->set_active(-1);
+ }
+
+ if ( bSameLabelFollowedBy )
+ {
+ sal_Int32 nPos = 0; // LISTTAB
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ nPos = 1;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
+ {
+ nPos = 2;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
+ {
+ nPos = 3;
+ }
+ m_xLabelFollowedByLB->set_active(nPos);
+ }
+ else
+ {
+ m_xLabelFollowedByLB->set_active(-1);
+ }
+
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
+ {
+ m_xListtabFT->set_sensitive(true);
+ m_xListtabMF->set_sensitive(true);
+ if ( bSameListtab )
+ {
+ SetMetricValue(*m_xListtabMF, aNumFmtArr[nLvl]->GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text("");
+ }
+ }
+ else
+ {
+ m_xListtabFT->set_sensitive(false);
+ m_xListtabMF->set_sensitive(false);
+ m_xListtabMF->set_text("");
+ }
+
+ if ( bSameAlignAt )
+ {
+ SetMetricValue(*m_xAlignedAtMF,
+ aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent(),
+ eCoreUnit);
+ }
+ else
+ {
+ m_xAlignedAtMF->set_text("");
+ }
+
+ if ( bSameIndentAt )
+ {
+ SetMetricValue(*m_xIndentAtMF, aNumFmtArr[nLvl]->GetIndentAt(), eCoreUnit);
+ }
+ else
+ {
+ m_xIndentAtMF->set_text("");
+ }
+
+ if ( bSetDistEmpty )
+ m_xDistBorderMF->set_text("");
+
+ bInInintControl = false;
+}
+
+void SvxNumPositionTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ sal_uInt16 nTmpNumLvl = 1;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(const SfxBoolItem* pPresetItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false))
+ bPreset = pPresetItem->GetValue();
+ if(const SfxUInt16Item* pLevelItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false))
+ nTmpNumLvl = pLevelItem->GetValue();
+ }
+ if(const SvxNumBulletItem* pBulletItem = rSet.GetItemIfSet(nNumItemId, false))
+ {
+ pSaveNum.reset( new SvxNumRule(pBulletItem->GetNumRule()) );
+ }
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pSaveNum != *pActNum ||
+ nActNumLvl != nTmpNumLvl )
+ {
+ *pActNum = *pSaveNum;
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if (nActNumLvl != SAL_MAX_UINT16)
+ for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if (nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ }
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+DeactivateRC SvxNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ {
+ if (m_xDistBorderMF->get_sensitive())
+ DistanceHdl_Impl(*m_xDistBorderMF);
+ DistanceHdl_Impl(*m_xIndentMF);
+ FillItemSet(_pSet);
+ }
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumPositionTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+}
+
+void SvxNumPositionTabPage::Reset( const SfxItemSet* rSet )
+{
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ const SvxNumBulletItem* pItem =
+ rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false);
+ if(!pItem)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ pItem = rSet->GetItemIfSet(nNumItemId, false);
+
+ if( !pItem )
+ {
+ pItem = & rSet->Get( nNumItemId );
+ }
+ }
+ DBG_ASSERT(pItem, "no item found!");
+ pSaveNum.reset( new SvxNumRule(pItem->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->count_selected_rows())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->count_selected_rows() - 1);
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select(pSaveNum->GetLevelCount());
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumPositionTabPage::InitPosAndSpaceMode()
+{
+ if ( pActNum == nullptr )
+ {
+ SAL_WARN( "cui.tabpages",
+ "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of method -> <pAktNum> has to be already set!" );
+ return;
+ }
+
+ SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode =
+ SvxNumberFormat::LABEL_ALIGNMENT;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode();
+ if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ break;
+ }
+ }
+ nMask <<= 1;
+ }
+
+ bLabelAlignmentPosAndSpaceModeActive =
+ ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
+}
+
+void SvxNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode()
+{
+ m_xDistBorderFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistBorderMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xRelativeCB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistNumFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS) );
+ m_xDistNumMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS));
+ m_xAlignFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignLB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+
+ m_xLabelFollowedByFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xLabelFollowedByLB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2FT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2LB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPositionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPositionTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxNumPositionTabPage::SetMetric(FieldUnit eMetric)
+{
+ if (eMetric == FieldUnit::MM)
+ {
+ m_xDistBorderMF->set_digits(1);
+ m_xDistNumMF->set_digits(1);
+ m_xIndentMF->set_digits(1);
+ m_xListtabMF->set_digits(1);
+ m_xAlignedAtMF->set_digits(1);
+ m_xIndentAtMF->set_digits(1);
+ }
+ m_xDistBorderMF->set_unit(eMetric);
+ m_xDistNumMF->set_unit(eMetric);
+ m_xIndentMF->set_unit(eMetric);
+ m_xListtabMF->set_unit(eMetric);
+ m_xAlignedAtMF->set_unit(eMetric);
+ m_xIndentAtMF->set_unit(eMetric);
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+
+ const sal_Int32 nPos = m_xAlignLB->get_visible()
+ ? m_xAlignLB->get_active()
+ : m_xAlign2LB->get_active();
+ SvxAdjust eAdjust = SvxAdjust::Center;
+ if(nPos == 0)
+ eAdjust = SvxAdjust::Left;
+ else if(nPos == 2)
+ eAdjust = SvxAdjust::Right;
+ aNumFmt.SetNumAdjust( eAdjust );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127120 multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+ SetModified();
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+ InitControls();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ if(bInInintControl)
+ return;
+ tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ if (&rFld == m_xDistBorderMF.get())
+ {
+
+ if (m_xRelativeCB->get_active())
+ {
+ if(0 == i)
+ {
+ auto const nTmp = aNumFmt.GetFirstLineOffset();
+ aNumFmt.SetAbsLSpace( nValue - nTmp);
+ }
+ else
+ {
+ tools::Long nTmp = pActNum->GetLevel( i - 1 ).GetAbsLSpace() +
+ pActNum->GetLevel( i - 1 ).GetFirstLineOffset() -
+ pActNum->GetLevel( i ).GetFirstLineOffset();
+
+ aNumFmt.SetAbsLSpace( nValue + nTmp);
+ }
+ }
+ else
+ {
+ aNumFmt.SetAbsLSpace( nValue - aNumFmt.GetFirstLineOffset());
+ }
+ }
+ else if (&rFld == m_xDistNumMF.get())
+ {
+ aNumFmt.SetCharTextDistance( static_cast<short>(nValue) );
+ }
+ else if (&rFld == m_xIndentMF.get())
+ {
+ // together with the FirstLineOffset the AbsLSpace must be changed, too
+ tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset();
+ auto const nAbsLSpace = aNumFmt.GetAbsLSpace();
+ aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff);
+ aNumFmt.SetFirstLineOffset( -nValue );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+ if (!m_xDistBorderMF->get_sensitive())
+ {
+ m_xDistBorderMF->set_text("");
+ }
+}
+
+IMPL_LINK(SvxNumPositionTabPage, RelativeHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bOn = rBox.get_active();
+ bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
+ bool bSetValue = false;
+ tools::Long nValue = 0;
+ if(bOn || bSingleSelection)
+ {
+ sal_uInt16 nMask = 1;
+ bool bFirst = true;
+ bSetValue = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat &rNumFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset();
+ if(bOn && i)
+ nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ }
+ else
+ bSetValue = nValue ==
+ (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) -
+ (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ bFirst = false;
+ }
+ nMask <<= 1;
+ }
+
+ }
+ if(bSetValue)
+ SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit);
+ else
+ m_xDistBorderMF->set_text("");
+ m_xDistBorderMF->set_sensitive(bOn || bSingleSelection);
+ m_xDistBorderFT->set_sensitive(bOn || bSingleSelection);
+ bLastRelative = bOn;
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void)
+{
+ // determine value to be set at the chosen list levels
+ SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB;
+ {
+ const auto nPos = m_xLabelFollowedByLB->get_active();
+ if ( nPos == 1 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::SPACE;
+ }
+ else if ( nPos == 2 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NOTHING;
+ }
+ else if ( nPos == 3 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NEWLINE;
+ }
+ }
+
+ // set value at the chosen list levels
+ bool bSameListtabPos = true;
+ sal_uInt16 nFirstLvl = SAL_MAX_UINT16;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetLabelFollowedBy( eLabelFollowedBy );
+ pActNum->SetLevel( i, aNumFmt );
+
+ if ( nFirstLvl == SAL_MAX_UINT16 )
+ {
+ nFirstLvl = i;
+ }
+ else
+ {
+ bSameListtabPos &= aNumFmt.GetListtabPos() ==
+ pActNum->GetLevel( nFirstLvl ).GetListtabPos();
+ }
+ }
+ nMask <<= 1;
+ }
+
+ // enable/disable metric field for list tab stop position depending on
+ // selected item following the list label.
+ m_xListtabFT->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ m_xListtabMF->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ if ( bSameListtabPos && eLabelFollowedBy == SvxNumberFormat::LISTTAB )
+ {
+ SetMetricValue(*m_xListtabMF, pActNum->GetLevel( nFirstLvl ).GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text(OUString());
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetListtabPos( nValue );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const tools::Long nFirstLineIndent = nValue - aNumFmt.GetIndentAt();
+ aNumFmt.SetFirstLineIndent( nFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const tools::Long nAlignedAt = aNumFmt.GetIndentAt() +
+ aNumFmt.GetFirstLineIndent();
+ aNumFmt.SetIndentAt( nValue );
+ const tools::Long nNewFirstLineIndent = nAlignedAt - nValue;
+ aNumFmt.SetFirstLineIndent( nNewFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nMask = 1;
+ SvxNumRule aTmpNumRule( pActNum->GetFeatureFlags(),
+ pActNum->GetLevelCount(),
+ pActNum->IsContinuousNumbering(),
+ SvxNumRuleType::NUMBERING,
+ pActNum->GetLevel( 0 ).GetPositionAndSpaceMode() );
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ const SvxNumberFormat& aTempFmt(aTmpNumRule.GetLevel( i ));
+ aNumFmt.SetPositionAndSpaceMode( aTempFmt.GetPositionAndSpaceMode() );
+ if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ aNumFmt.SetAbsLSpace( aTempFmt.GetAbsLSpace() );
+ aNumFmt.SetCharTextDistance( aTempFmt.GetCharTextDistance() );
+ aNumFmt.SetFirstLineOffset( aTempFmt.GetFirstLineOffset() );
+ }
+ else if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ aNumFmt.SetNumAdjust( aTempFmt.GetNumAdjust() );
+ aNumFmt.SetLabelFollowedBy( aTempFmt.GetLabelFollowedBy() );
+ aNumFmt.SetListtabPos( aTempFmt.GetListtabPos() );
+ aNumFmt.SetFirstLineIndent( aTempFmt.GetFirstLineIndent() );
+ aNumFmt.SetIndentAt( aTempFmt.GetIndentAt() );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ InitControls();
+ SetModified();
+}
+
+void SvxNumPositionTabPage::SetModified()
+{
+ bModified = true;
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+void SvxNumOptionsTabPage::SetModified(bool bRepaint)
+{
+ bModified = true;
+ if (bRepaint)
+ {
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+ }
+}
+
+void SvxNumOptionsTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringListItem* pListItem = aSet.GetItem<SfxStringListItem>(SID_CHAR_FMT_LIST_BOX, false);
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFmts( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+
+ if (pListItem)
+ {
+ const std::vector<OUString> &aList = pListItem->GetList();
+ sal_uInt32 nCount = aList.size();
+ for(sal_uInt32 i = 0; i < nCount; i++)
+ m_xCharFmtLB->append_text(aList[i]);
+ }
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+void SvxNumPositionTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/page.cxx b/cui/source/tabpages/page.cxx
new file mode 100644
index 000000000..bb4976324
--- /dev/null
+++ b/cui/source/tabpages/page.cxx
@@ -0,0 +1,1667 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <o3tl/unit_conversion.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svtools/unitconv.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sal/macros.h>
+#include <osl/diagnose.h>
+
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <page.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/paperinf.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/editrids.hrc>
+#include <svx/svxids.hrc>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <svl/slstitm.hxx>
+#include <svx/xdef.hxx>
+#include <svx/unobrushitemhelper.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <sal/log.hxx>
+#include <svl/grabbagitem.hxx>
+
+// static ----------------------------------------------------------------
+
+// #i19922# - tdf#126051 see svx/source/dialog/hdft.cxx and sw/source/uibase/sidebar/PageMarginControl.hxx
+constexpr tools::Long MINBODY = o3tl::toTwips(1, o3tl::Length::mm); // 1mm in twips rounded
+
+const WhichRangesContainer SvxPageDescPage::pRanges(
+ svl::Items<
+ SID_ATTR_BORDER_OUTER, SID_ATTR_BORDER_SHADOW,
+ SID_ATTR_LRSPACE, SID_ATTR_PAGE_SHARED,
+ SID_SWREGISTER_COLLECTION, SID_SWREGISTER_MODE>);
+// ------- Mapping page layout ------------------------------------------
+
+const SvxPageUsage aArr[] =
+{
+ SvxPageUsage::All,
+ SvxPageUsage::Mirror,
+ SvxPageUsage::Right,
+ SvxPageUsage::Left
+};
+
+
+static sal_uInt16 PageUsageToPos_Impl( SvxPageUsage nUsage )
+{
+ for ( size_t i = 0; i < std::size(aArr); ++i )
+ if ( aArr[i] == nUsage )
+ return i;
+ return 3;
+}
+
+
+static SvxPageUsage PosToPageUsage_Impl( sal_uInt16 nPos )
+{
+ if ( nPos >= std::size(aArr) )
+ return SvxPageUsage::NONE;
+ return aArr[nPos];
+}
+
+
+static Size GetMinBorderSpace_Impl( const SvxShadowItem& rShadow, const SvxBoxItem& rBox )
+{
+ Size aSz;
+ aSz.setHeight( rShadow.CalcShadowSpace( SvxShadowItemSide::BOTTOM ) + rBox.CalcLineSpace( SvxBoxItemLine::BOTTOM ) );
+ aSz.AdjustHeight(rShadow.CalcShadowSpace( SvxShadowItemSide::TOP ) + rBox.CalcLineSpace( SvxBoxItemLine::TOP ) );
+ aSz.setWidth( rShadow.CalcShadowSpace( SvxShadowItemSide::LEFT ) + rBox.CalcLineSpace( SvxBoxItemLine::LEFT ) );
+ aSz.AdjustWidth(rShadow.CalcShadowSpace( SvxShadowItemSide::RIGHT ) + rBox.CalcLineSpace( SvxBoxItemLine::RIGHT ) );
+ return aSz;
+}
+
+
+static tools::Long ConvertLong_Impl( const tools::Long nIn, MapUnit eUnit )
+{
+ return OutputDevice::LogicToLogic( nIn, eUnit, MapUnit::MapTwip );
+}
+
+static bool IsEqualSize_Impl( const SvxSizeItem* pSize, const Size& rSize )
+{
+ if ( pSize )
+ {
+ Size aSize = pSize->GetSize();
+ tools::Long nDiffW = std::abs( rSize.Width () - aSize.Width () );
+ tools::Long nDiffH = std::abs( rSize.Height() - aSize.Height() );
+ return ( nDiffW < 10 && nDiffH < 10 );
+ }
+ else
+ return false;
+}
+
+
+#define MARGIN_LEFT ( MarginPosition(0x0001) )
+#define MARGIN_RIGHT ( MarginPosition(0x0002) )
+#define MARGIN_TOP ( MarginPosition(0x0004) )
+#define MARGIN_BOTTOM ( MarginPosition(0x0008) )
+
+// class SvxPageDescPage --------------------------------------------------
+
+std::unique_ptr<SfxTabPage> SvxPageDescPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxPageDescPage>(pPage, pController, *rSet);
+}
+
+SvxPageDescPage::SvxPageDescPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/pageformatpage.ui", "PageFormatPage", &rAttr)
+ , bLandscape(false)
+ , eMode(SVX_PAGE_MODE_STANDARD)
+ , ePaperStart(PAPER_A3)
+ , m_nPos(0)
+ , mpDefPrinter(nullptr)
+ , mbDelPrinter(false)
+ , mbEnableDrawingLayerFillStyles(false)
+ , m_xPaperSizeBox(new SvxPaperSizeListBox(m_xBuilder->weld_combo_box("comboPageFormat")))
+ , m_xPaperWidthEdit(m_xBuilder->weld_metric_spin_button("spinWidth", FieldUnit::CM))
+ , m_xPaperHeightEdit(m_xBuilder->weld_metric_spin_button("spinHeight", FieldUnit::CM))
+ , m_xOrientationFT(m_xBuilder->weld_label("labelOrientation"))
+ , m_xPortraitBtn(m_xBuilder->weld_radio_button("radiobuttonPortrait"))
+ , m_xLandscapeBtn(m_xBuilder->weld_radio_button("radiobuttonLandscape"))
+ , m_xTextFlowLbl(m_xBuilder->weld_label("labelTextFlow"))
+ , m_xTextFlowBox(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboTextFlowBox")))
+ , m_xPaperTrayBox(m_xBuilder->weld_combo_box("comboPaperTray"))
+ , m_xLeftMarginLbl(m_xBuilder->weld_label("labelLeftMargin"))
+ , m_xLeftMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargLeft", FieldUnit::CM))
+ , m_xRightMarginLbl(m_xBuilder->weld_label("labelRightMargin"))
+ , m_xRightMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargRight", FieldUnit::CM))
+ , m_xTopMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargTop", FieldUnit::CM))
+ , m_xBottomMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargBot", FieldUnit::CM))
+ , m_xGutterMarginLbl(m_xBuilder->weld_label("labelGutterMargin"))
+ , m_xGutterMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargGut", FieldUnit::CM))
+ , m_xPageText(m_xBuilder->weld_label("labelPageLayout"))
+ , m_xLayoutBox(m_xBuilder->weld_combo_box("comboPageLayout"))
+ , m_xNumberFormatText(m_xBuilder->weld_label("labelPageNumbers"))
+ , m_xNumberFormatBox(new SvxPageNumberListBox(m_xBuilder->weld_combo_box("comboLayoutFormat")))
+ , m_xTblAlignFT(m_xBuilder->weld_label("labelTblAlign"))
+ , m_xHorzBox(m_xBuilder->weld_check_button("checkbuttonHorz"))
+ , m_xVertBox(m_xBuilder->weld_check_button("checkbuttonVert"))
+ , m_xAdaptBox(m_xBuilder->weld_check_button("checkAdaptBox"))
+ , m_xRegisterCB(m_xBuilder->weld_check_button("checkRegisterTrue"))
+ , m_xRegisterFT(m_xBuilder->weld_label("labelRegisterStyle"))
+ , m_xRegisterLB(m_xBuilder->weld_combo_box("comboRegisterStyle"))
+ , m_xGutterPositionFT(m_xBuilder->weld_label("labelGutterPosition"))
+ , m_xGutterPositionLB(m_xBuilder->weld_combo_box("comboGutterPosition"))
+ , m_xRtlGutterCB(m_xBuilder->weld_check_button("checkRtlGutter"))
+ , m_xBackgroundFullSizeCB(m_xBuilder->weld_check_button("checkBackgroundFullSize"))
+ // Strings stored in UI
+ , m_xInsideLbl(m_xBuilder->weld_label("labelInner"))
+ , m_xOutsideLbl(m_xBuilder->weld_label("labelOuter"))
+ , m_xPrintRangeQueryText(m_xBuilder->weld_label("labelMsg"))
+ , m_xBspWin(new weld::CustomWeld(*m_xBuilder, "drawingareaPageDirection", m_aBspWin))
+{
+ m_xRegisterLB->set_size_request(m_xRegisterLB->get_approximate_digit_width() * 20, -1);
+
+ bBorderModified = false;
+ m_aBspWin.EnableRTL(false);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ SvtCTLOptions aCTLLanguageOptions;
+ bool bCJK = SvtCJKOptions::IsAsianTypographyEnabled();
+ bool bCTL = aCTLLanguageOptions.IsCTLFontEnabled();
+ bool bWeb = false;
+
+ const SfxUInt16Item* pHtmlModeItem = rAttr.GetItemIfSet(SID_HTML_MODE, false);
+ if (!pHtmlModeItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pHtmlModeItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if (pHtmlModeItem)
+ bWeb = 0 != (pHtmlModeItem->GetValue() & HTMLMODE_ON);
+
+ // fill text flow listbox with valid entries
+
+ m_xTextFlowBox->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_HORI));
+
+ if (bCTL)
+ m_xTextFlowBox->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_HORI));
+
+
+ // #109989# do not show vertical directions in Writer/Web
+ if( !bWeb && bCJK )
+ {
+ m_xTextFlowBox->append(SvxFrameDirection::Vertical_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_VERT));
+ m_xTextFlowBox->append(SvxFrameDirection::Vertical_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_VERT));
+ }
+
+ // #109989# show the text direction box in Writer/Web too
+ if( (bCJK || bCTL) &&
+ SfxItemState::UNKNOWN < rAttr.GetItemState(GetWhich( SID_ATTR_FRAMEDIRECTION )))
+ {
+ m_xTextFlowLbl->show();
+ m_xTextFlowBox->show();
+ m_xTextFlowBox->connect_changed(LINK(this, SvxPageDescPage, FrameDirectionModify_Impl));
+
+ m_aBspWin.EnableFrameDirection(true);
+ }
+ Init_Impl();
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rAttr );
+ SetFieldUnit( *m_xLeftMarginEdit, eFUnit );
+ SetFieldUnit( *m_xRightMarginEdit, eFUnit );
+ SetFieldUnit( *m_xTopMarginEdit, eFUnit );
+ SetFieldUnit( *m_xBottomMarginEdit, eFUnit );
+ SetFieldUnit(*m_xGutterMarginEdit, eFUnit);
+ SetFieldUnit( *m_xPaperWidthEdit, eFUnit );
+ SetFieldUnit( *m_xPaperHeightEdit, eFUnit );
+
+ if ( SfxViewShell::Current() && SfxViewShell::Current()->GetPrinter() )
+ {
+ mpDefPrinter = SfxViewShell::Current()->GetPrinter();
+ }
+ else
+ {
+ mpDefPrinter = VclPtr<Printer>::Create();
+ mbDelPrinter = true;
+ }
+
+ MapMode aOldMode = mpDefPrinter->GetMapMode();
+ mpDefPrinter->SetMapMode(MapMode(MapUnit::MapTwip));
+
+ // set first- and last-values for the margins
+ Size aPaperSize = mpDefPrinter->GetPaperSize();
+ Size aPrintSize = mpDefPrinter->GetOutputSize();
+
+ /*
+ * To convert a point ( 0,0 ) into logic coordinates
+ * looks like nonsense; but it makes sense when the
+ * coordinate system's origin has been moved.
+ */
+ Point aPrintOffset = mpDefPrinter->GetPageOffset() - mpDefPrinter->PixelToLogic( Point() );
+ mpDefPrinter->SetMapMode( aOldMode );
+
+ nFirstLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(aPrintOffset.X()), FieldUnit::TWIP);
+ nFirstRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(aPaperSize.Width() - aPrintSize.Width() - aPrintOffset.X()), FieldUnit::TWIP);
+ nFirstTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(aPrintOffset.Y() ), FieldUnit::TWIP);
+ nFirstBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(aPaperSize.Height() - aPrintSize.Height() - aPrintOffset.Y()), FieldUnit::TWIP );
+ nLastLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(aPrintOffset.X() + aPrintSize.Width()), FieldUnit::TWIP);
+ nLastRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(aPrintOffset.X() + aPrintSize.Width()), FieldUnit::TWIP);
+ nLastTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(aPrintOffset.Y() + aPrintSize.Height()), FieldUnit::TWIP);
+ nLastBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(aPrintOffset.Y() + aPrintSize.Height()), FieldUnit::TWIP);
+
+ // #i4219# take Maximum now from configuration (1/100th cm)
+ // was: 11900 -> 119 cm ;new value 3 meters -> 300 cm -> 30000
+ m_xPaperWidthEdit->set_max(m_xPaperWidthEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperWidth()), FieldUnit::CM);
+ m_xPaperHeightEdit->set_max(m_xPaperHeightEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperHeight()), FieldUnit::CM);
+
+ // #i4219# also for margins (1/100th cm). Was: 9999, keeping.
+ m_xLeftMarginEdit->set_max(m_xLeftMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperLeftMargin()), FieldUnit::MM);
+ m_xRightMarginEdit->set_max(m_xRightMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperRightMargin()), FieldUnit::MM);
+ m_xTopMarginEdit->set_max(m_xTopMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperTopMargin()), FieldUnit::MM);
+ m_xBottomMarginEdit->set_max(m_xBottomMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperBottomMargin()), FieldUnit::MM);
+ m_xGutterMarginEdit->set_max(
+ m_xGutterMarginEdit->normalize(SvtOptionsDrawinglayer::GetMaximumPaperLeftMargin()),
+ FieldUnit::MM);
+
+ // Get the i18n framework numberings and add them to the listbox.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering(m_xNumberFormatBox->get_widget(), std::numeric_limits<sal_uInt16>::max());
+}
+
+SvxPageDescPage::~SvxPageDescPage()
+{
+ if(mbDelPrinter)
+ {
+ mpDefPrinter.disposeAndClear();
+ mbDelPrinter = false;
+ }
+}
+
+void SvxPageDescPage::Init_Impl()
+{
+ // adjust the handler
+ m_xLayoutBox->connect_changed(LINK(this, SvxPageDescPage, LayoutHdl_Impl));
+ m_xGutterPositionLB->connect_changed(LINK(this, SvxPageDescPage, GutterPositionHdl_Impl));
+
+ m_xPaperSizeBox->connect_changed(LINK(this, SvxPageDescPage, PaperSizeSelect_Impl));
+ m_xPaperWidthEdit->connect_value_changed( LINK(this, SvxPageDescPage, PaperSizeModify_Impl));
+ m_xPaperHeightEdit->connect_value_changed(LINK(this, SvxPageDescPage, PaperSizeModify_Impl));
+ m_xLandscapeBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+ m_xPortraitBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+
+ Link<weld::MetricSpinButton&, void> aLink = LINK(this, SvxPageDescPage, BorderModify_Impl);
+ m_xLeftMarginEdit->connect_value_changed(aLink);
+ m_xRightMarginEdit->connect_value_changed(aLink);
+ m_xTopMarginEdit->connect_value_changed(aLink);
+ m_xBottomMarginEdit->connect_value_changed(aLink);
+ m_xGutterMarginEdit->connect_value_changed(aLink);
+
+ m_xHorzBox->connect_toggled(LINK(this, SvxPageDescPage, CenterHdl_Impl));
+ m_xVertBox->connect_toggled(LINK(this, SvxPageDescPage, CenterHdl_Impl));
+}
+
+void SvxPageDescPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ SAL_WARN_IF(!pPool, "cui.tabpages", "Where is the pool?");
+ MapUnit eUnit = pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) );
+
+ // adjust margins (right/left)
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_LRSPACE );
+
+ if ( pItem )
+ {
+ const SvxLRSpaceItem& rLRSpace = static_cast<const SvxLRSpaceItem&>(*pItem);
+ SetMetricValue( *m_xLeftMarginEdit, rLRSpace.GetLeft(), eUnit );
+ SetMetricValue(*m_xGutterMarginEdit, rLRSpace.GetGutterMargin(), eUnit);
+ m_aBspWin.SetLeft(
+ static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetLeft(), eUnit )) );
+ SetMetricValue( *m_xRightMarginEdit, rLRSpace.GetRight(), eUnit );
+ m_aBspWin.SetRight(
+ static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetRight(), eUnit )) );
+ }
+
+ // adjust margins (top/bottom)
+ pItem = GetItem( *rSet, SID_ATTR_ULSPACE );
+
+ if ( pItem )
+ {
+ const SvxULSpaceItem& rULSpace = static_cast<const SvxULSpaceItem&>(*pItem);
+ SetMetricValue( *m_xTopMarginEdit, rULSpace.GetUpper(), eUnit );
+ m_aBspWin.SetTop(
+ static_cast<sal_uInt16>(ConvertLong_Impl( static_cast<tools::Long>(rULSpace.GetUpper()), eUnit )) );
+ SetMetricValue( *m_xBottomMarginEdit, rULSpace.GetLower(), eUnit );
+ m_aBspWin.SetBottom(
+ static_cast<sal_uInt16>(ConvertLong_Impl( static_cast<tools::Long>(rULSpace.GetLower()), eUnit )) );
+ }
+
+ if (const SfxGrabBagItem* pGragbagItem = rSet->GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+ {
+ bool bGutterAtTop{};
+ auto it = pGragbagItem->GetGrabBag().find("GutterAtTop");
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= bGutterAtTop;
+ }
+
+ if (bGutterAtTop)
+ {
+ m_xGutterPositionLB->set_active(1);
+ }
+ else
+ {
+ // Left.
+ m_xGutterPositionLB->set_active(0);
+ }
+ it = pGragbagItem->GetGrabBag().find("RtlGutter");
+ bool bRtlGutter{};
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= bRtlGutter;
+ m_xRtlGutterCB->set_active(bRtlGutter);
+ m_xRtlGutterCB->show();
+ }
+ it = pGragbagItem->GetGrabBag().find("BackgroundFullSize");
+ bool isBackgroundFullSize{};
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= isBackgroundFullSize;
+ m_xBackgroundFullSizeCB->set_active(isBackgroundFullSize);
+ m_xBackgroundFullSizeCB->show();
+ }
+ }
+
+ // general page data
+ SvxNumType eNumType = SVX_NUM_ARABIC;
+ bLandscape = ( mpDefPrinter->GetOrientation() == Orientation::Landscape );
+ SvxPageUsage nUse = SvxPageUsage::All;
+ pItem = GetItem( *rSet, SID_ATTR_PAGE );
+
+ if ( pItem )
+ {
+ const SvxPageItem& rItem = static_cast<const SvxPageItem&>(*pItem);
+ eNumType = rItem.GetNumType();
+ nUse = rItem.GetPageUsage();
+ bLandscape = rItem.IsLandscape();
+ }
+
+ // alignment
+ m_xLayoutBox->set_active(::PageUsageToPos_Impl(nUse));
+ m_aBspWin.SetUsage( nUse );
+ LayoutHdl_Impl( *m_xLayoutBox );
+
+ //adjust numeration type of the page style
+ m_xNumberFormatBox->set_active_id(eNumType);
+
+ m_xPaperTrayBox->clear();
+ sal_uInt8 nPaperBin = PAPERBIN_PRINTER_SETTINGS;
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_PAPERBIN );
+
+ if ( pItem )
+ {
+ nPaperBin = static_cast<const SvxPaperBinItem*>(pItem)->GetValue();
+
+ if ( nPaperBin >= mpDefPrinter->GetPaperBinCount() )
+ nPaperBin = PAPERBIN_PRINTER_SETTINGS;
+ }
+
+ OUString aBinName;
+
+ if ( PAPERBIN_PRINTER_SETTINGS == nPaperBin )
+ aBinName = EditResId(RID_SVXSTR_PAPERBIN_SETTINGS);
+ else
+ aBinName = mpDefPrinter->GetPaperBinName( static_cast<sal_uInt16>(nPaperBin) );
+
+ m_xPaperTrayBox->append(OUString::number(nPaperBin), aBinName);
+ m_xPaperTrayBox->set_active_text(aBinName);
+ // reset focus handler to default first so know none already connected
+ m_xPaperTrayBox->connect_focus_in(Link<weld::Widget&, void>());
+ // update the list when widget gets focus
+ m_xPaperTrayBox->connect_focus_in(LINK(this, SvxPageDescPage, PaperBinHdl_Impl));
+
+ Size aPaperSize = SvxPaperInfo::GetPaperSize( mpDefPrinter );
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( pItem )
+ aPaperSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ bool bOrientationSupport =
+ mpDefPrinter->HasSupport( PrinterSupport::SetOrientation );
+
+ if ( !bOrientationSupport &&
+ aPaperSize.Width() > aPaperSize.Height() )
+ bLandscape = true;
+
+ // tdf#130548 disable callbacks on the other of a pair of the radiogroup
+ // when toggling its partner
+ m_xLandscapeBtn->connect_toggled(Link<weld::Toggleable&, void>());
+ m_xPortraitBtn->connect_toggled(Link<weld::Toggleable&, void>());
+
+ m_xLandscapeBtn->set_active(bLandscape);
+ m_xPortraitBtn->set_active(!bLandscape);
+
+ m_xLandscapeBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+ m_xPortraitBtn->connect_toggled(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+
+ m_aBspWin.SetSize( Size( ConvertLong_Impl( aPaperSize.Width(), eUnit ),
+ ConvertLong_Impl( aPaperSize.Height(), eUnit ) ) );
+
+ aPaperSize = OutputDevice::LogicToLogic(aPaperSize, MapMode(eUnit), MapMode(MapUnit::Map100thMM));
+ if ( bLandscape )
+ Swap( aPaperSize );
+
+ // Actual Paper Format
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aPaperSize, MapUnit::Map100thMM );
+
+ if ( PAPER_USER != ePaper )
+ aPaperSize = SvxPaperInfo::GetPaperSize( ePaper, MapUnit::Map100thMM );
+
+ if ( bLandscape )
+ Swap( aPaperSize );
+
+ // write values into the edits
+ SetMetricValue( *m_xPaperHeightEdit, aPaperSize.Height(), MapUnit::Map100thMM );
+ SetMetricValue( *m_xPaperWidthEdit, aPaperSize.Width(), MapUnit::Map100thMM );
+ m_xPaperSizeBox->clear();
+
+ m_xPaperSizeBox->FillPaperSizeEntries( ( ePaperStart == PAPER_A3 ) ? PaperSizeApp::Std : PaperSizeApp::Draw );
+ m_xPaperSizeBox->set_active_id( ePaper );
+
+ // application specific
+
+ switch ( eMode )
+ {
+ case SVX_PAGE_MODE_CENTER:
+ {
+ m_xTblAlignFT->show();
+ m_xHorzBox->show();
+ m_xVertBox->show();
+ DisableVerticalPageDir();
+
+ // horizontal alignment
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT1 );
+ m_xHorzBox->set_active(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ // vertical alignment
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT2 );
+ m_xVertBox->set_active(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ // set example window on the table
+ m_aBspWin.SetTable( true );
+ m_aBspWin.SetHorz(m_xHorzBox->get_active());
+ m_aBspWin.SetVert(m_xVertBox->get_active());
+
+ m_xGutterMarginLbl->hide();
+ m_xGutterMarginEdit->hide();
+ m_xGutterPositionFT->hide();
+ m_xGutterPositionLB->hide();
+
+ break;
+ }
+
+ case SVX_PAGE_MODE_PRESENTATION:
+ {
+ DisableVerticalPageDir();
+ m_xAdaptBox->show();
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT1 );
+ m_xAdaptBox->set_active( pItem &&
+ static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+
+ //!!! hidden, because not implemented by StarDraw
+ m_xLayoutBox->hide();
+ m_xPageText->hide();
+
+ m_xGutterMarginLbl->hide();
+ m_xGutterMarginEdit->hide();
+ m_xGutterPositionFT->hide();
+ m_xGutterPositionLB->hide();
+
+ break;
+ }
+ default: ;//prevent warning
+ }
+
+
+ // display background and border in the example
+ ResetBackground_Impl( *rSet );
+//! UpdateExample_Impl();
+ RangeHdl_Impl();
+
+ InitHeadFoot_Impl( *rSet );
+
+ bBorderModified = false;
+ SwapFirstValues_Impl( false );
+ UpdateExample_Impl();
+
+ m_xLeftMarginEdit->save_value();
+ m_xRightMarginEdit->save_value();
+ m_xTopMarginEdit->save_value();
+ m_xBottomMarginEdit->save_value();
+ m_xGutterMarginEdit->save_value();
+ m_xLayoutBox->save_value();
+ m_xNumberFormatBox->save_value();
+ m_xPaperSizeBox->save_value();
+ m_xPaperWidthEdit->save_value();
+ m_xPaperHeightEdit->save_value();
+ m_xPortraitBtn->save_state();
+ m_xLandscapeBtn->save_state();
+ m_xPaperTrayBox->save_value();
+ m_xVertBox->save_state();
+ m_xHorzBox->save_state();
+ m_xAdaptBox->save_state();
+ m_xGutterPositionLB->save_value();
+ m_xRtlGutterCB->save_state();
+ m_xBackgroundFullSizeCB->save_state();
+
+ CheckMarginEdits( true );
+
+
+ if(SfxItemState::SET == rSet->GetItemState(SID_SWREGISTER_MODE))
+ {
+ m_xRegisterCB->set_active(rSet->Get(SID_SWREGISTER_MODE).GetValue());
+ m_xRegisterCB->save_state();
+ RegisterModify(*m_xRegisterCB);
+ }
+ if(SfxItemState::SET == rSet->GetItemState(SID_SWREGISTER_COLLECTION))
+ {
+ m_xRegisterLB->set_active_text(
+ rSet->Get(SID_SWREGISTER_COLLECTION).GetValue());
+ m_xRegisterLB->save_value();
+ }
+
+ SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_FRAMEDIRECTION ),
+ true, &pItem );
+ if( SfxItemState::UNKNOWN != eState )
+ {
+ SvxFrameDirection nVal = SfxItemState::SET == eState
+ ? static_cast<const SvxFrameDirectionItem*>(pItem)->GetValue()
+ : SvxFrameDirection::Horizontal_LR_TB;
+ m_xTextFlowBox->set_active_id(nVal);
+
+ m_xTextFlowBox->save_value();
+ m_aBspWin.SetFrameDirection(nVal);
+ }
+}
+
+void SvxPageDescPage::FillUserData()
+{
+ if (SVX_PAGE_MODE_PRESENTATION == eMode)
+ SetUserData(m_xAdaptBox->get_active() ? OUString("1") : OUString("0")) ;
+
+}
+
+bool SvxPageDescPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ const SfxItemSet& rOldSet = GetItemSet();
+ SfxItemPool* pPool = rOldSet.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ const SfxPoolItem* pOld = nullptr;
+
+ // copy old left and right margins
+ SvxLRSpaceItem aMargin( static_cast<const SvxLRSpaceItem&>(rOldSet.Get( nWhich )) );
+
+ // copy old top and bottom margins
+ nWhich = GetWhich( SID_ATTR_ULSPACE );
+ SvxULSpaceItem aTopMargin( static_cast<const SvxULSpaceItem&>(rOldSet.Get( nWhich )) );
+
+ if (m_xLeftMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetLeft( static_cast<sal_uInt16>(GetCoreValue( *m_xLeftMarginEdit, eUnit )) );
+ bModified = true;
+ }
+
+ if (m_xRightMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetRight( static_cast<sal_uInt16>(GetCoreValue( *m_xRightMarginEdit, eUnit )) );
+ bModified = true;
+ }
+
+ if (m_xGutterMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetGutterMargin(static_cast<sal_uInt16>(GetCoreValue(*m_xGutterMarginEdit, eUnit)));
+ bModified = true;
+ }
+
+ // set left and right margins
+ if (bModified)
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_LRSPACE );
+
+ if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin )
+ rSet->Put( aMargin );
+ else
+ bModified = false;
+ }
+
+ if (rOldSet.HasItem(SID_ATTR_CHAR_GRABBAG))
+ {
+ // Set gutter position.
+ SfxGrabBagItem aGrabBagItem(rOldSet.Get(SID_ATTR_CHAR_GRABBAG));
+ if (m_xGutterPositionLB->get_value_changed_from_saved())
+ {
+ bool bGutterAtTop = m_xGutterPositionLB->get_active() == 1;
+ aGrabBagItem.GetGrabBag()["GutterAtTop"] <<= bGutterAtTop;
+ bModified = true;
+ }
+ if (m_xRtlGutterCB->get_state_changed_from_saved())
+ {
+ bool const bRtlGutter(m_xRtlGutterCB->get_active());
+ aGrabBagItem.GetGrabBag()["RtlGutter"] <<= bRtlGutter;
+ bModified = true;
+ }
+ if (m_xBackgroundFullSizeCB->get_state_changed_from_saved())
+ {
+ bool const isBackgroundFullSize(m_xBackgroundFullSizeCB->get_active());
+ aGrabBagItem.GetGrabBag()["BackgroundFullSize"] <<= isBackgroundFullSize;
+ bModified = true;
+ }
+
+ if (bModified)
+ {
+ pOld = rOldSet.GetItem(SID_ATTR_CHAR_GRABBAG);
+
+ if (!pOld || static_cast<const SfxGrabBagItem&>(*pOld) != aGrabBagItem)
+ rSet->Put(aGrabBagItem);
+ else
+ bModified = false;
+ }
+ }
+
+ bool bMod = false;
+
+ if (m_xTopMarginEdit->get_value_changed_from_saved())
+ {
+ aTopMargin.SetUpper( static_cast<sal_uInt16>(GetCoreValue( *m_xTopMarginEdit, eUnit )) );
+ bMod = true;
+ }
+
+ if (m_xBottomMarginEdit->get_value_changed_from_saved())
+ {
+ aTopMargin.SetLower( static_cast<sal_uInt16>(GetCoreValue( *m_xBottomMarginEdit, eUnit )) );
+ bMod = true;
+ }
+
+ // set top and bottom margins
+
+ if ( bMod )
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_ULSPACE );
+
+ if ( !pOld || *static_cast<const SvxULSpaceItem*>(pOld) != aTopMargin )
+ {
+ bModified = true;
+ rSet->Put( aTopMargin );
+ }
+ }
+
+ // paper tray
+ nWhich = GetWhich( SID_ATTR_PAGE_PAPERBIN );
+ sal_Int32 nPos = m_xPaperTrayBox->get_active();
+ sal_uInt16 nBin = m_xPaperTrayBox->get_id(nPos).toInt32();
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_PAPERBIN );
+
+ if ( !pOld || static_cast<const SvxPaperBinItem*>(pOld)->GetValue() != nBin )
+ {
+ rSet->Put( SvxPaperBinItem( nWhich, static_cast<sal_uInt8>(nBin) ) );
+ bModified = true;
+ }
+
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+ bool bChecked = m_xLandscapeBtn->get_active();
+
+ if ( PAPER_USER == ePaper )
+ {
+ if ( m_xPaperSizeBox->get_value_changed_from_saved() ||
+ m_xPaperWidthEdit->get_value_changed_from_saved() ||
+ m_xPaperHeightEdit->get_value_changed_from_saved() ||
+ m_xLandscapeBtn->get_state_changed_from_saved() )
+ {
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( !pOld || static_cast<const SvxSizeItem*>(pOld)->GetSize() != aSize )
+ {
+ rSet->Put( SvxSizeItem( GetWhich(SID_ATTR_PAGE_SIZE), aSize ) );
+ bModified = true;
+ }
+ }
+ }
+ else
+ {
+ if (m_xPaperSizeBox->get_value_changed_from_saved() || m_xLandscapeBtn->get_state_changed_from_saved())
+ {
+ Size aSize( SvxPaperInfo::GetPaperSize( ePaper, eUnit ) );
+
+ if ( bChecked )
+ Swap( aSize );
+
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( !pOld || static_cast<const SvxSizeItem*>(pOld)->GetSize() != aSize )
+ {
+ rSet->Put( SvxSizeItem( GetWhich(SID_ATTR_PAGE_SIZE), aSize ) );
+ bModified = true;
+ }
+ }
+ }
+
+ nWhich = GetWhich( SID_ATTR_PAGE );
+ SvxPageItem aPage( static_cast<const SvxPageItem&>(rOldSet.Get( nWhich )) );
+ bMod = m_xLayoutBox->get_value_changed_from_saved();
+
+ if ( bMod )
+ aPage.SetPageUsage(::PosToPageUsage_Impl(m_xLayoutBox->get_active()));
+
+ if (m_xLandscapeBtn->get_state_changed_from_saved())
+ {
+ aPage.SetLandscape(bChecked);
+ bMod = true;
+ }
+
+ //Get the NumType value
+ if (m_xNumberFormatBox->get_value_changed_from_saved())
+ {
+ SvxNumType nEntryData = m_xNumberFormatBox->get_active_id();
+ aPage.SetNumType( nEntryData );
+ bMod = true;
+ }
+
+ if ( bMod )
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE );
+
+ if ( !pOld || *static_cast<const SvxPageItem*>(pOld) != aPage )
+ {
+ rSet->Put( aPage );
+ bModified = true;
+ }
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich ) )
+ rSet->ClearItem( nWhich );
+ else
+ rSet->Put( rOldSet.Get( nWhich ) );
+
+ // evaluate mode specific controls
+
+ switch ( eMode )
+ {
+ case SVX_PAGE_MODE_CENTER:
+ {
+ if (m_xHorzBox->get_state_changed_from_saved())
+ {
+ SfxBoolItem aHorz( GetWhich( SID_ATTR_PAGE_EXT1 ),
+ m_xHorzBox->get_active() );
+ rSet->Put( aHorz );
+ bModified = true;
+ }
+
+ if (m_xVertBox->get_state_changed_from_saved())
+ {
+ SfxBoolItem aVert( GetWhich( SID_ATTR_PAGE_EXT2 ),
+ m_xVertBox->get_active() );
+ rSet->Put( aVert );
+ bModified = true;
+ }
+ break;
+ }
+
+ case SVX_PAGE_MODE_PRESENTATION:
+ {
+ // always put so that draw can evaluate this
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_PAGE_EXT1 ),
+ m_xAdaptBox->get_active() ) );
+ bModified = true;
+ break;
+ }
+ default: ;//prevent warning
+
+ }
+
+ if (m_xRegisterCB->get_visible() &&
+ (m_xRegisterCB->get_active() || m_xRegisterCB->get_state_changed_from_saved()))
+ {
+ const SfxBoolItem& rRegItem = rOldSet.Get(SID_SWREGISTER_MODE);
+ std::unique_ptr<SfxBoolItem> pRegItem(rRegItem.Clone());
+ bool bCheck = m_xRegisterCB->get_active();
+ pRegItem->SetValue(bCheck);
+ rSet->Put(std::move(pRegItem));
+ bModified = true;
+ if(bCheck)
+ {
+ bModified = true;
+ rSet->Put(SfxStringItem(SID_SWREGISTER_COLLECTION,
+ m_xRegisterLB->get_active_text()));
+ }
+ }
+
+ if (m_xTextFlowBox->get_visible() && m_xTextFlowBox->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDirection = m_xTextFlowBox->get_active_id();
+ rSet->Put( SvxFrameDirectionItem( eDirection, GetWhich( SID_ATTR_FRAMEDIRECTION ) ) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, LayoutHdl_Impl, weld::ComboBox&, void)
+{
+ // switch inside outside
+ const SvxPageUsage nUsage = PosToPageUsage_Impl(m_xLayoutBox->get_active());
+
+ if (nUsage == SvxPageUsage::Mirror)
+ {
+ m_xLeftMarginLbl->hide();
+ m_xRightMarginLbl->hide();
+ m_xInsideLbl->show();
+ m_xOutsideLbl->show();
+ }
+ else
+ {
+ m_xLeftMarginLbl->show();
+ m_xRightMarginLbl->show();
+ m_xInsideLbl->hide();
+ m_xOutsideLbl->hide();
+ }
+ UpdateExample_Impl( true );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, GutterPositionHdl_Impl, weld::ComboBox&, void)
+{
+ UpdateExample_Impl(true);
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperBinHdl_Impl, weld::Widget&, void)
+{
+ // tdf#124226 disconnect so not called again, unless Reset occurs
+ m_xPaperTrayBox->connect_focus_in(Link<weld::Widget&, void>());
+
+ OUString aOldName = m_xPaperTrayBox->get_active_text();
+ m_xPaperTrayBox->freeze();
+ m_xPaperTrayBox->clear();
+ m_xPaperTrayBox->append(OUString::number(PAPERBIN_PRINTER_SETTINGS), EditResId(RID_SVXSTR_PAPERBIN_SETTINGS));
+ OUString aPaperBin(EditResId(RID_SVXSTR_PAPERBIN));
+ const sal_uInt16 nBinCount = mpDefPrinter->GetPaperBinCount();
+
+ for (sal_uInt16 i = 0; i < nBinCount; ++i)
+ {
+ OUString aName = mpDefPrinter->GetPaperBinName(i);
+ if (aName.isEmpty())
+ {
+ aName = aPaperBin + " " + OUString::number( i+1 );
+ }
+ m_xPaperTrayBox->append(OUString::number(i), aName);
+ }
+ m_xPaperTrayBox->set_active_text(aOldName);
+ m_xPaperTrayBox->thaw();
+
+ // tdf#123650 explicitly grab-focus after the modification otherwise gtk loses track
+ // of there the focus should be
+ m_xPaperTrayBox->grab_focus();
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperSizeSelect_Impl, weld::ComboBox&, void)
+{
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+
+ if ( ePaper == PAPER_USER )
+ return;
+
+ Size aSize( SvxPaperInfo::GetPaperSize( ePaper, MapUnit::Map100thMM ) );
+
+ if (m_xLandscapeBtn->get_active())
+ Swap( aSize );
+
+ if ( aSize.Height() < m_xPaperHeightEdit->get_min( FieldUnit::MM_100TH ) )
+ m_xPaperHeightEdit->set_min(
+ m_xPaperHeightEdit->normalize( aSize.Height() ), FieldUnit::MM_100TH );
+ if ( aSize.Width() < m_xPaperWidthEdit->get_min( FieldUnit::MM_100TH ) )
+ m_xPaperWidthEdit->set_min(
+ m_xPaperWidthEdit->normalize( aSize.Width() ), FieldUnit::MM_100TH );
+ SetMetricValue( *m_xPaperHeightEdit, aSize.Height(), MapUnit::Map100thMM );
+ SetMetricValue( *m_xPaperWidthEdit, aSize.Width(), MapUnit::Map100thMM );
+
+ CalcMargin_Impl();
+
+ RangeHdl_Impl();
+ UpdateExample_Impl( true );
+
+ if ( eMode != SVX_PAGE_MODE_PRESENTATION )
+ return;
+
+ // Draw: if paper format the margin shall be 1 cm
+ tools::Long nTmp = 0;
+ bool bScreen = (( PAPER_SCREEN_4_3 == ePaper )||( PAPER_SCREEN_16_9 == ePaper)||( PAPER_SCREEN_16_10 == ePaper)||( PAPER_WIDESCREEN == ePaper)||( PAPER_ONSCREENSHOW_4_3 == ePaper)||( PAPER_ONSCREENSHOW_16_9 == ePaper)||( PAPER_ONSCREENSHOW_16_10 == ePaper));
+
+ if ( !bScreen )
+ // no margin if screen
+ nTmp = 1; // accordingly 1 cm
+
+ if ( bScreen || m_xRightMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xRightMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xLeftMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xLeftMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xBottomMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xBottomMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xTopMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xTopMarginEdit, nTmp, MapUnit::MapCM );
+ UpdateExample_Impl( true );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperSizeModify_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( nWhich );
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+
+ if ( aSize.Width() > aSize.Height() )
+ {
+ m_xLandscapeBtn->set_active(true);
+ bLandscape = true;
+ }
+ else
+ {
+ m_xPortraitBtn->set_active(true);
+ bLandscape = false;
+ }
+
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aSize, eUnit );
+ m_xPaperSizeBox->set_active_id( ePaper );
+ UpdateExample_Impl( true );
+
+ RangeHdl_Impl();
+}
+
+IMPL_LINK(SvxPageDescPage, SwapOrientation_Impl, weld::Toggleable&, rBtn, void)
+{
+ if (!rBtn.get_active())
+ return;
+
+ bLandscape = m_xLandscapeBtn->get_active();
+
+ const tools::Long lWidth = GetCoreValue( *m_xPaperWidthEdit, MapUnit::Map100thMM );
+ const tools::Long lHeight = GetCoreValue( *m_xPaperHeightEdit, MapUnit::Map100thMM );
+
+ // swap width and height
+ SetMetricValue(*m_xPaperWidthEdit, lHeight, MapUnit::Map100thMM);
+ SetMetricValue(*m_xPaperHeightEdit, lWidth, MapUnit::Map100thMM);
+
+ // recalculate margins if necessary
+ CalcMargin_Impl();
+
+ PaperSizeSelect_Impl(m_xPaperSizeBox->get_widget());
+ RangeHdl_Impl();
+ SwapFirstValues_Impl(bBorderModified);
+ UpdateExample_Impl(true);
+}
+
+void SvxPageDescPage::SwapFirstValues_Impl( bool bSet )
+{
+ MapMode aOldMode = mpDefPrinter->GetMapMode();
+ Orientation eOri = Orientation::Portrait;
+
+ if ( bLandscape )
+ eOri = Orientation::Landscape;
+ Orientation eOldOri = mpDefPrinter->GetOrientation();
+ mpDefPrinter->SetOrientation( eOri );
+ mpDefPrinter->SetMapMode(MapMode(MapUnit::MapTwip));
+
+ // set first- and last-values for margins
+ Size aPaperSize = mpDefPrinter->GetPaperSize();
+ Size aPrintSize = mpDefPrinter->GetOutputSize();
+ /*
+ * To convert a point ( 0,0 ) into logic coordinates
+ * looks like nonsense; but it makes sense if the
+ * coordinate system's origin has been moved.
+ */
+ Point aPrintOffset = mpDefPrinter->GetPageOffset() - mpDefPrinter->PixelToLogic( Point() );
+ mpDefPrinter->SetMapMode( aOldMode );
+ mpDefPrinter->SetOrientation( eOldOri );
+
+ sal_Int64 nSetL = m_xLeftMarginEdit->denormalize(
+ m_xLeftMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetR = m_xRightMarginEdit->denormalize(
+ m_xRightMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetT = m_xTopMarginEdit->denormalize(
+ m_xTopMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetB = m_xBottomMarginEdit->denormalize(
+ m_xBottomMarginEdit->get_value( FieldUnit::TWIP ) );
+
+ tools::Long nNewL = aPrintOffset.X();
+ tools::Long nNewR = aPaperSize.Width() - aPrintSize.Width() - aPrintOffset.X();
+ tools::Long nNewT = aPrintOffset.Y();
+ tools::Long nNewB = aPaperSize.Height() - aPrintSize.Height() - aPrintOffset.Y();
+
+ nFirstLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(nNewL), FieldUnit::TWIP);
+ nFirstRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(nNewR), FieldUnit::TWIP);
+ nFirstTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(nNewT), FieldUnit::TWIP);
+ nFirstBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(nNewB), FieldUnit::TWIP);
+
+ if ( !bSet )
+ return;
+
+ if ( nSetL < nNewL )
+ m_xLeftMarginEdit->set_value( m_xLeftMarginEdit->normalize( nNewL ),
+ FieldUnit::TWIP );
+ if ( nSetR < nNewR )
+ m_xRightMarginEdit->set_value( m_xRightMarginEdit->normalize( nNewR ),
+ FieldUnit::TWIP );
+ if ( nSetT < nNewT )
+ m_xTopMarginEdit->set_value( m_xTopMarginEdit->normalize( nNewT ),
+ FieldUnit::TWIP );
+ if ( nSetB < nNewB )
+ m_xBottomMarginEdit->set_value( m_xBottomMarginEdit->normalize( nNewB ),
+ FieldUnit::TWIP );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, BorderModify_Impl, weld::MetricSpinButton&, void)
+{
+ if ( !bBorderModified )
+ bBorderModified = true;
+ UpdateExample_Impl();
+
+ RangeHdl_Impl();
+}
+
+void SvxPageDescPage::UpdateExample_Impl( bool bResetbackground )
+{
+ // Size
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, MapUnit::MapTwip ),
+ GetCoreValue( *m_xPaperHeightEdit, MapUnit::MapTwip ) );
+
+ m_aBspWin.SetSize( aSize );
+
+ // Margins
+ bool bGutterAtTop = m_xGutterPositionLB->get_active() == 1;
+ tools::Long nTop = GetCoreValue(*m_xTopMarginEdit, MapUnit::MapTwip);
+ if (bGutterAtTop)
+ {
+ nTop += GetCoreValue(*m_xGutterMarginEdit, MapUnit::MapTwip);
+ }
+ m_aBspWin.SetTop(nTop);
+ m_aBspWin.SetBottom( GetCoreValue( *m_xBottomMarginEdit, MapUnit::MapTwip ) );
+ tools::Long nLeft = GetCoreValue(*m_xLeftMarginEdit, MapUnit::MapTwip);
+ if (!bGutterAtTop)
+ {
+ nLeft += GetCoreValue(*m_xGutterMarginEdit, MapUnit::MapTwip);
+ }
+ m_aBspWin.SetLeft(nLeft);
+ m_aBspWin.SetRight( GetCoreValue( *m_xRightMarginEdit, MapUnit::MapTwip ) );
+
+ // Layout
+ m_aBspWin.SetUsage(PosToPageUsage_Impl(m_xLayoutBox->get_active()));
+ if ( bResetbackground )
+ m_aBspWin.ResetBackground();
+ m_aBspWin.Invalidate();
+}
+
+
+void SvxPageDescPage::ResetBackground_Impl(const SfxItemSet& rSet)
+{
+ sal_uInt16 nWhich(GetWhich(SID_ATTR_PAGE_HEADERSET));
+
+ if (SfxItemState::SET == rSet.GetItemState(nWhich, false))
+ {
+ const SvxSetItem& rSetItem = static_cast< const SvxSetItem& >(rSet.Get(nWhich, false));
+ const SfxItemSet& rTmpSet = rSetItem.GetItemSet();
+ const SfxBoolItem& rOn = rTmpSet.Get(GetWhich(SID_ATTR_PAGE_ON));
+
+ if(rOn.GetValue())
+ {
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aHeaderFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rTmpSet);
+ }
+ else
+ {
+ nWhich = GetWhich(SID_ATTR_BRUSH);
+
+ if(SfxItemState::SET == rTmpSet.GetItemState(nWhich))
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rTmpSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rTmpSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setHeaderFillAttributes(aHeaderFillAttributes);
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_PAGE_FOOTERSET);
+
+ if (SfxItemState::SET == rSet.GetItemState(nWhich, false))
+ {
+ const SvxSetItem& rSetItem = static_cast< const SvxSetItem& >(rSet.Get(nWhich,false));
+ const SfxItemSet& rTmpSet = rSetItem.GetItemSet();
+ const SfxBoolItem& rOn = rTmpSet.Get(GetWhich(SID_ATTR_PAGE_ON));
+
+ if(rOn.GetValue())
+ {
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFooterFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rTmpSet);
+ }
+ else
+ {
+ nWhich = GetWhich(SID_ATTR_BRUSH);
+
+ if(SfxItemState::SET == rTmpSet.GetItemState(nWhich))
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rTmpSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rTmpSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setFooterFillAttributes(aFooterFillAttributes);
+ }
+ }
+
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aPageFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aPageFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rSet);
+ }
+ else
+ {
+ const SfxPoolItem* pItem = GetItem(rSet, SID_ATTR_BRUSH);
+
+ if(pItem)
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(*pItem);
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aPageFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setPageFillAttributes(aPageFillAttributes);
+}
+
+void SvxPageDescPage::InitHeadFoot_Impl( const SfxItemSet& rSet )
+{
+ bLandscape = m_xLandscapeBtn->get_active();
+ const SfxPoolItem* pItem = GetItem( rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( pItem )
+ m_aBspWin.SetSize( static_cast<const SvxSizeItem*>(pItem)->GetSize() );
+
+ const SvxSetItem* pSetItem = nullptr;
+
+ // evaluate header attributes
+
+ if ( SfxItemState::SET ==
+ rSet.GetItemState( GetWhich( SID_ATTR_PAGE_HEADERSET ),
+ false, reinterpret_cast<const SfxPoolItem**>(&pSetItem) ) )
+ {
+ const SfxItemSet& rHeaderSet = pSetItem->GetItemSet();
+ const SfxBoolItem& rHeaderOn =
+ rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_ON ) );
+
+ if ( rHeaderOn.GetValue() )
+ {
+ const SvxSizeItem& rSize =
+ rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) );
+ const SvxULSpaceItem& rUL = static_cast<const SvxULSpaceItem&>(
+ rHeaderSet.Get( GetWhich( SID_ATTR_ULSPACE ) ));
+ tools::Long nDist = rUL.GetLower();
+ m_aBspWin.SetHdHeight( rSize.GetSize().Height() - nDist );
+ m_aBspWin.SetHdDist( nDist );
+ const SvxLRSpaceItem& rLR = static_cast<const SvxLRSpaceItem&>(
+ rHeaderSet.Get( GetWhich( SID_ATTR_LRSPACE ) ));
+ m_aBspWin.SetHdLeft( rLR.GetLeft() );
+ m_aBspWin.SetHdRight( rLR.GetRight() );
+ m_aBspWin.SetHeader( true );
+ }
+ else
+ m_aBspWin.SetHeader( false );
+
+ // show background and border in the example
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aHeaderFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rHeaderSet);
+ }
+ else
+ {
+ const sal_uInt16 nWhich(GetWhich(SID_ATTR_BRUSH));
+
+ if(rHeaderSet.GetItemState(nWhich) >= SfxItemState::DEFAULT)
+ {
+ // aBspWin.SetHdColor(rItem.GetColor());
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rHeaderSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rHeaderSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setHeaderFillAttributes(aHeaderFillAttributes);
+ }
+
+ // evaluate footer attributes
+
+ if ( SfxItemState::SET !=
+ rSet.GetItemState( GetWhich( SID_ATTR_PAGE_FOOTERSET ),
+ false, reinterpret_cast<const SfxPoolItem**>(&pSetItem) ) )
+ return;
+
+ const SfxItemSet& rFooterSet = pSetItem->GetItemSet();
+ const SfxBoolItem& rFooterOn =
+ rFooterSet.Get( GetWhich( SID_ATTR_PAGE_ON ) );
+
+ if ( rFooterOn.GetValue() )
+ {
+ const SvxSizeItem& rSize =
+ rFooterSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) );
+ const SvxULSpaceItem& rUL = static_cast<const SvxULSpaceItem&>(
+ rFooterSet.Get( GetWhich( SID_ATTR_ULSPACE ) ));
+ tools::Long nDist = rUL.GetUpper();
+ m_aBspWin.SetFtHeight( rSize.GetSize().Height() - nDist );
+ m_aBspWin.SetFtDist( nDist );
+ const SvxLRSpaceItem& rLR = static_cast<const SvxLRSpaceItem&>(
+ rFooterSet.Get( GetWhich( SID_ATTR_LRSPACE ) ));
+ m_aBspWin.SetFtLeft( rLR.GetLeft() );
+ m_aBspWin.SetFtRight( rLR.GetRight() );
+ m_aBspWin.SetFooter( true );
+ }
+ else
+ m_aBspWin.SetFooter( false );
+
+ // show background and border in the example
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFooterFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rFooterSet);
+ }
+ else
+ {
+ const sal_uInt16 nWhich(GetWhich(SID_ATTR_BRUSH));
+
+ if(rFooterSet.GetItemState(nWhich) >= SfxItemState::DEFAULT)
+ {
+ // aBspWin.SetFtColor(rItem.GetColor());
+ const SvxBrushItem& rItem = static_cast<const SvxBrushItem&>(rFooterSet.Get(nWhich));
+ SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aTempSet(*rFooterSet.GetPool());
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setFooterFillAttributes(aFooterFillAttributes);
+}
+
+void SvxPageDescPage::ActivatePage( const SfxItemSet& rSet )
+{
+ InitHeadFoot_Impl( rSet );
+ UpdateExample_Impl();
+ ResetBackground_Impl( rSet );
+ RangeHdl_Impl();
+}
+
+DeactivateRC SvxPageDescPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ // Inquiry whether the page margins are beyond the printing area.
+ // If not, ask user whether they shall be taken.
+ // If not, stay on the TabPage.
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+
+ if ( ePaper != PAPER_SCREEN_4_3 && ePaper != PAPER_SCREEN_16_9 && ePaper != PAPER_SCREEN_16_10 && ePaper != PAPER_WIDESCREEN && ePaper != PAPER_ONSCREENSHOW_4_3 && ePaper != PAPER_ONSCREENSHOW_16_9 && ePaper != PAPER_ONSCREENSHOW_16_10 && IsMarginOutOfRange() )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_xPrintRangeQueryText->get_label()));
+ xQueryBox->set_default_response(RET_NO);
+ if (xQueryBox->run() == RET_NO)
+ {
+ weld::MetricSpinButton* pField = nullptr;
+ if ( IsPrinterRangeOverflow( *m_xLeftMarginEdit, nFirstLeftMargin, nLastLeftMargin, MARGIN_LEFT ) )
+ pField = m_xLeftMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xRightMarginEdit, nFirstRightMargin, nLastRightMargin, MARGIN_RIGHT )
+ && !pField )
+ pField = m_xRightMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xTopMarginEdit, nFirstTopMargin, nLastTopMargin, MARGIN_TOP )
+ && !pField )
+ pField = m_xTopMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xBottomMarginEdit, nFirstBottomMargin, nLastBottomMargin, MARGIN_BOTTOM )
+ && !pField )
+ pField = m_xBottomMarginEdit.get();
+ if ( pField )
+ pField->grab_focus();
+ UpdateExample_Impl();
+ return DeactivateRC::KeepPage;
+ }
+ else
+ CheckMarginEdits( false );
+ }
+
+ if ( _pSet )
+ {
+ FillItemSet( _pSet );
+
+ // put portray/landscape if applicable
+ sal_uInt16 nWh = GetWhich( SID_ATTR_PAGE_SIZE );
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( nWh );
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+
+ // put, if current size is different to the value in _pSet
+ const SvxSizeItem* pSize = GetItem( *_pSet, SID_ATTR_PAGE_SIZE );
+ if ( aSize.Width() && ( !pSize || !IsEqualSize_Impl( pSize, aSize ) ) )
+ _pSet->Put( SvxSizeItem( nWh, aSize ) );
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxPageDescPage::RangeHdl_Impl()
+{
+ // example window
+ tools::Long nHHeight = m_aBspWin.GetHdHeight();
+ tools::Long nHDist = m_aBspWin.GetHdDist();
+
+ tools::Long nFHeight = m_aBspWin.GetFtHeight();
+ tools::Long nFDist = m_aBspWin.GetFtDist();
+
+ tools::Long nHFLeft = std::max(m_aBspWin.GetHdLeft(), m_aBspWin.GetFtLeft());
+ tools::Long nHFRight = std::max(m_aBspWin.GetHdRight(), m_aBspWin.GetFtRight());
+
+ // current values for page margins
+ tools::Long nBT = static_cast<tools::Long>(m_xTopMarginEdit->denormalize(m_xTopMarginEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nBB = static_cast<tools::Long>(m_xBottomMarginEdit->denormalize(m_xBottomMarginEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nBL = static_cast<tools::Long>(m_xLeftMarginEdit->denormalize(m_xLeftMarginEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nBR = static_cast<tools::Long>(m_xRightMarginEdit->denormalize(m_xRightMarginEdit->get_value(FieldUnit::TWIP)));
+
+ // calculate width of page border
+ const SfxItemSet* _pSet = &GetItemSet();
+ Size aBorder;
+
+ if ( _pSet->GetItemState( GetWhich(SID_ATTR_BORDER_SHADOW) ) >=
+ SfxItemState::DEFAULT &&
+ _pSet->GetItemState( GetWhich(SID_ATTR_BORDER_OUTER) ) >=
+ SfxItemState::DEFAULT )
+ {
+ aBorder = GetMinBorderSpace_Impl(
+ static_cast<const SvxShadowItem&>(_pSet->Get(GetWhich(SID_ATTR_BORDER_SHADOW))),
+ static_cast<const SvxBoxItem&>(_pSet->Get(GetWhich(SID_ATTR_BORDER_OUTER))));
+ }
+
+ // limits paper
+ // maximum is 54 cm
+
+ tools::Long nMin = nHHeight + nHDist + nFDist + nFHeight + nBT + nBB +
+ MINBODY + aBorder.Height();
+ m_xPaperHeightEdit->set_min(m_xPaperHeightEdit->normalize(nMin), FieldUnit::TWIP);
+
+ nMin = MINBODY + nBL + nBR + aBorder.Width();
+ m_xPaperWidthEdit->set_min(m_xPaperWidthEdit->normalize(nMin), FieldUnit::TWIP);
+
+ tools::Long nH = static_cast<tools::Long>(m_xPaperHeightEdit->denormalize(m_xPaperHeightEdit->get_value(FieldUnit::TWIP)));
+ tools::Long nW = static_cast<tools::Long>(m_xPaperWidthEdit->denormalize(m_xPaperWidthEdit->get_value(FieldUnit::TWIP)));
+
+ // Top
+ tools::Long nMax = nH - nBB - aBorder.Height() - MINBODY -
+ nFDist - nFHeight - nHDist - nHHeight;
+
+ m_xTopMarginEdit->set_max(m_xTopMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Bottom
+ nMax = nH - nBT - aBorder.Height() - MINBODY -
+ nFDist - nFHeight - nHDist - nHHeight;
+
+ m_xBottomMarginEdit->set_max(m_xTopMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Left
+ nMax = nW - nBR - MINBODY - aBorder.Width() - nHFLeft - nHFRight;
+ m_xLeftMarginEdit->set_max(m_xLeftMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Right
+ nMax = nW - nBL - MINBODY - aBorder.Width() - nHFLeft - nHFRight;
+ m_xRightMarginEdit->set_max(m_xRightMarginEdit->normalize(nMax), FieldUnit::TWIP);
+}
+
+void SvxPageDescPage::CalcMargin_Impl()
+{
+ // current values for page margins
+ tools::Long nBT = GetCoreValue( *m_xTopMarginEdit, MapUnit::MapTwip );
+ tools::Long nBB = GetCoreValue( *m_xBottomMarginEdit, MapUnit::MapTwip );
+
+ tools::Long nBL = GetCoreValue( *m_xLeftMarginEdit, MapUnit::MapTwip );
+ tools::Long nBR = GetCoreValue( *m_xRightMarginEdit, MapUnit::MapTwip );
+
+ tools::Long nH = GetCoreValue( *m_xPaperHeightEdit, MapUnit::MapTwip );
+ tools::Long nW = GetCoreValue( *m_xPaperWidthEdit, MapUnit::MapTwip );
+
+ tools::Long nWidth = nBL + nBR + MINBODY;
+ tools::Long nHeight = nBT + nBB + MINBODY;
+
+ if ( nWidth <= nW && nHeight <= nH )
+ return;
+
+ if ( nWidth > nW )
+ {
+ tools::Long nTmp = nBL <= nBR ? nBR : nBL;
+ nTmp -= nWidth - nW;
+
+ if ( nBL <= nBR )
+ SetMetricValue( *m_xRightMarginEdit, nTmp, MapUnit::MapTwip );
+ else
+ SetMetricValue( *m_xLeftMarginEdit, nTmp, MapUnit::MapTwip );
+ }
+
+ if ( nHeight > nH )
+ {
+ tools::Long nTmp = nBT <= nBB ? nBB : nBT;
+ nTmp -= nHeight - nH;
+
+ if ( nBT <= nBB )
+ SetMetricValue( *m_xBottomMarginEdit, nTmp, MapUnit::MapTwip );
+ else
+ SetMetricValue( *m_xTopMarginEdit, nTmp, MapUnit::MapTwip );
+ }
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, CenterHdl_Impl, weld::Toggleable&, void)
+{
+ m_aBspWin.SetHorz(m_xHorzBox->get_active());
+ m_aBspWin.SetVert(m_xVertBox->get_active());
+ UpdateExample_Impl();
+}
+
+void SvxPageDescPage::SetCollectionList(const std::vector<OUString> &aList)
+{
+ OSL_ENSURE(!aList.empty(), "Empty string list");
+
+ sStandardRegister = aList[0];
+ m_xRegisterLB->freeze();
+ for (size_t i = 1; i < aList.size(); ++i)
+ m_xRegisterLB->append_text(aList[i]);
+ m_xRegisterLB->thaw();
+
+ m_xRegisterCB->show();
+ m_xRegisterFT->show();
+ m_xRegisterLB->show();
+ m_xRegisterCB->connect_toggled(LINK(this, SvxPageDescPage, RegisterModify));
+}
+
+IMPL_LINK(SvxPageDescPage, RegisterModify, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = false;
+ if (rBox.get_active())
+ {
+ bEnable = true;
+ if (m_xRegisterLB->get_active() == -1)
+ m_xRegisterLB->set_active_text(sStandardRegister);
+ }
+ m_xRegisterFT->set_sensitive(bEnable);
+ m_xRegisterLB->set_sensitive(bEnable);
+}
+
+void SvxPageDescPage::DisableVerticalPageDir()
+{
+ m_xTextFlowBox->remove_id(SvxFrameDirection::Vertical_RL_TB);
+ m_xTextFlowBox->remove_id(SvxFrameDirection::Vertical_LR_TB);
+ if (m_xTextFlowBox->get_count() < 2)
+ {
+ m_xTextFlowLbl->hide();
+ m_xTextFlowBox->hide();
+ m_aBspWin.EnableFrameDirection( false );
+ }
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, FrameDirectionModify_Impl, weld::ComboBox&, void)
+{
+ m_aBspWin.SetFrameDirection(m_xTextFlowBox->get_active_id());
+ m_aBspWin.Invalidate();
+}
+
+bool SvxPageDescPage::IsPrinterRangeOverflow(
+ weld::MetricSpinButton& rField, tools::Long nFirstMargin, tools::Long nLastMargin, MarginPosition nPos )
+{
+ bool bRet = false;
+ bool bCheck = ( ( m_nPos & nPos ) == 0 );
+ tools::Long nValue = rField.get_value(FieldUnit::NONE);
+ if ( bCheck &&
+ ( nValue < nFirstMargin || nValue > nLastMargin ) &&
+ rField.get_value_changed_from_saved() )
+ {
+ rField.set_value(nValue < nFirstMargin ? nFirstMargin : nLastMargin, FieldUnit::NONE);
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+/** Check if a value of a margin edit is outside the printer paper margins
+ and save this information.
+*/
+void SvxPageDescPage::CheckMarginEdits( bool _bClear )
+{
+ if ( _bClear )
+ m_nPos = 0;
+
+ sal_Int64 nValue = m_xLeftMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstLeftMargin || nValue > nLastLeftMargin )
+ m_nPos |= MARGIN_LEFT;
+ nValue = m_xRightMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstRightMargin || nValue > nLastRightMargin )
+ m_nPos |= MARGIN_RIGHT;
+ nValue = m_xTopMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstTopMargin || nValue > nLastTopMargin )
+ m_nPos |= MARGIN_TOP;
+ nValue = m_xBottomMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstBottomMargin || nValue > nLastBottomMargin )
+ m_nPos |= MARGIN_BOTTOM;
+}
+
+bool SvxPageDescPage::IsMarginOutOfRange() const
+{
+ bool bRet = ( ( ( !( m_nPos & MARGIN_LEFT ) &&
+ m_xLeftMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xLeftMarginEdit->get_value(FieldUnit::NONE) < nFirstLeftMargin ||
+ m_xLeftMarginEdit->get_value(FieldUnit::NONE) > nLastLeftMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_RIGHT ) &&
+ m_xRightMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xRightMarginEdit->get_value(FieldUnit::NONE) < nFirstRightMargin ||
+ m_xRightMarginEdit->get_value(FieldUnit::NONE) > nLastRightMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_TOP ) &&
+ m_xTopMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xTopMarginEdit->get_value(FieldUnit::NONE) < nFirstTopMargin ||
+ m_xTopMarginEdit->get_value(FieldUnit::NONE) > nLastTopMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_BOTTOM ) &&
+ m_xBottomMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xBottomMarginEdit->get_value(FieldUnit::NONE) < nFirstBottomMargin ||
+ m_xBottomMarginEdit->get_value(FieldUnit::NONE) > nLastBottomMargin ) ) );
+ return bRet;
+}
+
+void SvxPageDescPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pModeItem = aSet.GetItem(SID_ENUM_PAGE_MODE, false);
+ const SfxUInt16Item* pPaperStartItem = aSet.GetItem(SID_PAPER_START, false);
+ const SfxUInt16Item* pPaperEndItem = aSet.GetItem(SID_PAPER_END, false);
+ const SfxStringListItem* pCollectListItem = aSet.GetItem<SfxStringListItem>(SID_COLLECT_LIST, false);
+ const SfxBoolItem* pSupportDrawingLayerFillStyleItem = aSet.GetItem<SfxBoolItem>(SID_DRAWINGLAYER_FILLSTYLES, false);
+ const SfxBoolItem* pIsImpressDoc = aSet.GetItem<SfxBoolItem>(SID_IMPRESS_DOC, false);
+
+ if (pModeItem)
+ {
+ eMode = static_cast<SvxModeType>(pModeItem->GetValue());
+ }
+
+ if(pPaperStartItem && pPaperEndItem)
+ {
+ SetPaperFormatRanges(static_cast<Paper>(pPaperStartItem->GetValue()));
+ }
+
+ if(pCollectListItem)
+ {
+ SetCollectionList(pCollectListItem->GetList());
+ }
+
+ if(pSupportDrawingLayerFillStyleItem)
+ {
+ const bool bNew(pSupportDrawingLayerFillStyleItem->GetValue());
+
+ mbEnableDrawingLayerFillStyles = bNew;
+ }
+
+ if (pIsImpressDoc)
+ m_xNumberFormatText->set_label(SvxResId(STR_SLIDE_NUMBERS));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx
new file mode 100644
index 000000000..b2cd167a5
--- /dev/null
+++ b/cui/source/tabpages/paragrph.cxx
@@ -0,0 +1,2330 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <osl/diagnose.h>
+#include <svl/style.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/settings.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/svxids.hrc>
+
+#include <svl/cjkoptions.hxx>
+#include <editeng/pgrditem.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <paragrph.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <svx/dlgutil.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+
+const WhichRangesContainer SvxStdParagraphTabPage::pStdRanges(
+ svl::Items<
+ SID_ATTR_PARA_LINESPACE, SID_ATTR_PARA_LINESPACE, // 10033
+ SID_ATTR_LRSPACE, SID_ATTR_ULSPACE, // 10048 - 10049
+ SID_ATTR_PARA_REGISTER, SID_ATTR_PARA_REGISTER // 10413
+ >);
+
+const WhichRangesContainer SvxParaAlignTabPage::pAlignRanges(
+ svl::Items<SID_ATTR_PARA_ADJUST, SID_ATTR_PARA_ADJUST>); // 10027
+
+const WhichRangesContainer SvxExtParagraphTabPage::pExtRanges(svl::Items<
+ SID_ATTR_PARA_PAGEBREAK, SID_ATTR_PARA_WIDOWS, // 10037 - 10041
+ SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP // 10065 - 10066
+>);
+
+#define MAX_DURCH 31680 // tdf#68335: 1584 pt for UX interoperability with Word
+#define FIX_DIST_DEF 283 // standard fix distance 0,5 cm
+
+namespace {
+
+enum LineSpaceList
+{
+ LLINESPACE_1 = 0,
+ LLINESPACE_115 = 1,
+ LLINESPACE_15 = 2,
+ LLINESPACE_2 = 3,
+ LLINESPACE_PROP = 4,
+ LLINESPACE_MIN = 5,
+ LLINESPACE_DURCH= 6,
+ LLINESPACE_FIX = 7
+};
+
+}
+
+static void SetLineSpace_Impl( SvxLineSpacingItem&, int, tools::Long lValue = 0 );
+
+void SetLineSpace_Impl( SvxLineSpacingItem& rLineSpace,
+ int eSpace, tools::Long lValue )
+{
+ switch ( eSpace )
+ {
+ case LLINESPACE_1:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ break;
+
+ case LLINESPACE_115:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 115 );
+ break;
+
+ case LLINESPACE_15:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 150 );
+ break;
+
+ case LLINESPACE_2:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 200 );
+ break;
+
+ case LLINESPACE_PROP:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) );
+ break;
+
+ case LLINESPACE_MIN:
+ rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) );
+ rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ break;
+
+ case LLINESPACE_DURCH:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) );
+ break;
+
+ case LLINESPACE_FIX:
+ rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue));
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix );
+ rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ break;
+ }
+}
+
+static sal_uInt16 GetHtmlMode_Impl(const SfxItemSet& rSet)
+{
+ sal_uInt16 nHtmlMode = 0;
+ const SfxUInt16Item* pItem = rSet.GetItemIfSet(SID_HTML_MODE, false);
+ if (!pItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if(pItem)
+ {
+ nHtmlMode = pItem->GetValue();
+ }
+ return nHtmlMode;
+
+}
+
+void SvxStdParagraphTabPage::ELRLoseFocus()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit =
+ MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) ) );
+
+ sal_Int64 nL = m_xLeftIndent->denormalize(m_xLeftIndent->get_value(eUnit));
+ sal_Int64 nR = m_xRightIndent->denormalize(m_xRightIndent->get_value(eUnit));
+ OUString aTmp = m_xFLineIndent->get_text();
+
+ if (m_xLeftIndent->get_min(FieldUnit::NONE) < 0)
+ m_xFLineIndent->set_min(-99999, FieldUnit::MM);
+ else
+ m_xFLineIndent->set_min(m_xFLineIndent->normalize(-nL), eUnit);
+
+ // Check only for concrete width (Shell)
+ sal_Int64 nTmp = nWidth - nL - nR - MM50;
+ m_xFLineIndent->set_max(m_xFLineIndent->normalize(nTmp), eUnit);
+
+ if (aTmp.isEmpty())
+ m_xFLineIndent->set_text(OUString());
+ // maximum left right
+ aTmp = m_xLeftIndent->get_text();
+ nTmp = nWidth - nR - MM50;
+ m_xLeftIndent->set_max(m_xLeftIndent->normalize(nTmp), eUnit);
+
+ if ( aTmp.isEmpty() )
+ m_xLeftIndent->set_text(OUString());
+ aTmp = m_xRightIndent->get_text();
+ nTmp = nWidth - nL - MM50;
+ m_xRightIndent->set_max(m_xRightIndent->normalize(nTmp), eUnit);
+
+ if ( aTmp.isEmpty() )
+ m_xRightIndent->set_text(OUString());
+
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, ELRLoseFocusHdl, weld::MetricSpinButton&, void)
+{
+ ELRLoseFocus();
+}
+
+std::unique_ptr<SfxTabPage> SvxStdParagraphTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxStdParagraphTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ const SfxPoolItem* pOld = nullptr;
+ SfxItemPool* pPool = rOutSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ bool bModified = false;
+ sal_uInt16 nWhich;
+ int nPos = m_xLineDist->get_active();
+
+ if ( nPos != -1 &&
+ ( m_bLineDistToggled ||
+ m_xLineDist->get_value_changed_from_saved() ||
+ m_xLineDistAtPercentBox->get_value_changed_from_saved() ||
+ m_xLineDistAtMetricBox->get_value_changed_from_saved() ) )
+ {
+ nWhich = GetWhich( SID_ATTR_PARA_LINESPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ SvxLineSpacingItem aSpacing(
+ static_cast<const SvxLineSpacingItem&>(GetItemSet().Get( nWhich )) );
+
+ switch ( nPos )
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ SetLineSpace_Impl( aSpacing, nPos );
+ break;
+
+ case LLINESPACE_PROP:
+ SetLineSpace_Impl( aSpacing, nPos,
+ static_cast<tools::Long>(m_xLineDistAtPercentBox->denormalize(
+ m_xLineDistAtPercentBox->get_value(FieldUnit::NONE) )) );
+ break;
+
+ case LLINESPACE_MIN:
+ case LLINESPACE_DURCH:
+ case LLINESPACE_FIX:
+ SetLineSpace_Impl( aSpacing, nPos,
+ GetCoreValue( *m_xLineDistAtMetricBox, eUnit ) );
+ break;
+
+ default:
+ OSL_FAIL( "unknown LineDist entry" );
+ break;
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_LINESPACE );
+
+ if ( m_bLineDistToggled ||
+ !pOld || !( *static_cast<const SvxLineSpacingItem*>(pOld) == aSpacing ) ||
+ SfxItemState::DONTCARE == GetItemSet().GetItemState( nWhich ) )
+ {
+ rOutSet->Put( aSpacing );
+ bModified = true;
+ }
+ }
+
+ if ( m_xTopDist->get_value_changed_from_saved() || m_xBottomDist->get_value_changed_from_saved()
+ || m_xContextualCB->get_state_changed_from_saved())
+ {
+ nWhich = GetWhich( SID_ATTR_ULSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_ULSPACE );
+ SvxULSpaceItem aMargin( nWhich );
+
+ if ( bRelativeMode )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No ParentSet" );
+
+ const SvxULSpaceItem& rOldItem =
+ static_cast<const SvxULSpaceItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ if ( m_xTopDist->IsRelative() )
+ aMargin.SetUpper( rOldItem.GetUpper(),
+ static_cast<sal_uInt16>(m_xTopDist->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetUpper( static_cast<sal_uInt16>(m_xTopDist->GetCoreValue(eUnit)) );
+
+ if ( m_xBottomDist->IsRelative() )
+ aMargin.SetLower( rOldItem.GetLower(),
+ static_cast<sal_uInt16>(m_xBottomDist->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetLower( static_cast<sal_uInt16>(m_xBottomDist->GetCoreValue(eUnit)) );
+
+ }
+ else
+ {
+ aMargin.SetUpper(static_cast<sal_uInt16>(m_xTopDist->GetCoreValue(eUnit)));
+ aMargin.SetLower(static_cast<sal_uInt16>(m_xBottomDist->GetCoreValue(eUnit)));
+ }
+ aMargin.SetContextValue(m_xContextualCB->get_active());
+
+ if ( !pOld || *static_cast<const SvxULSpaceItem*>(pOld) != aMargin ||
+ SfxItemState::DONTCARE == GetItemSet().GetItemState( nWhich ) )
+ {
+ rOutSet->Put( aMargin );
+ bModified = true;
+ }
+ }
+ bool bNullTab = false;
+
+ if ( m_xLeftIndent->get_value_changed_from_saved() ||
+ m_xFLineIndent->get_value_changed_from_saved() ||
+ m_xRightIndent->get_value_changed_from_saved() ||
+ m_xAutoCB->get_state_changed_from_saved() )
+ {
+ nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ SvxLRSpaceItem aMargin( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_LRSPACE );
+
+ if ( bRelativeMode )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No ParentSet" );
+
+ const SvxLRSpaceItem& rOldItem =
+ static_cast<const SvxLRSpaceItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ if (m_xLeftIndent->IsRelative())
+ aMargin.SetTextLeft( rOldItem.GetTextLeft(),
+ static_cast<sal_uInt16>(m_xLeftIndent->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetTextLeft(m_xLeftIndent->GetCoreValue(eUnit));
+
+ if ( m_xRightIndent->IsRelative() )
+ aMargin.SetRight( rOldItem.GetRight(),
+ static_cast<sal_uInt16>(m_xRightIndent->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetRight(m_xRightIndent->GetCoreValue(eUnit));
+
+ if ( m_xFLineIndent->IsRelative() )
+ aMargin.SetTextFirstLineOffset( rOldItem.GetTextFirstLineOffset(),
+ static_cast<sal_uInt16>(m_xFLineIndent->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_xFLineIndent->GetCoreValue(eUnit)));
+ }
+ else
+ {
+ aMargin.SetTextLeft(m_xLeftIndent->GetCoreValue(eUnit));
+ aMargin.SetRight(m_xRightIndent->GetCoreValue(eUnit));
+ aMargin.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_xFLineIndent->GetCoreValue(eUnit)));
+ }
+ aMargin.SetAutoFirst(m_xAutoCB->get_active());
+ if ( aMargin.GetTextFirstLineOffset() < 0 )
+ bNullTab = true;
+
+ if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin ||
+ SfxItemState::DONTCARE == GetItemSet().GetItemState( nWhich ) )
+ {
+ rOutSet->Put( aMargin );
+ bModified = true;
+ }
+ }
+
+ if ( bNullTab )
+ {
+ MapUnit eUnit = pPool->GetMetric( GetWhich( SID_ATTR_TABSTOP ) );
+ if ( MapUnit::Map100thMM != eUnit )
+ {
+
+ // negative first line indent -> set null default tabstob if applicable
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_TABSTOP );
+ const SfxItemSet& rInSet = GetItemSet();
+
+ if ( rInSet.GetItemState( _nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxTabStopItem& rTabItem =
+ static_cast<const SvxTabStopItem&>(rInSet.Get( _nWhich ));
+ SvxTabStopItem aNullTab( rTabItem );
+ SvxTabStop aNull( 0, SvxTabAdjust::Default );
+ aNullTab.Insert( aNull );
+ rOutSet->Put( aNullTab );
+ }
+ }
+ }
+ if (m_xRegisterCB->get_visible())
+ {
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rOutSet, SID_ATTR_PARA_REGISTER));
+ if (!pBoolItem)
+ return bModified;
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_REGISTER );
+ bool bSet = pBoolItem->GetValue();
+
+ if (m_xRegisterCB->get_active() != bSet)
+ {
+ std::unique_ptr<SfxBoolItem> pRegItem(pBoolItem->Clone());
+ pRegItem->SetValue(!bSet);
+ rOutSet->Put(std::move(pRegItem));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == GetItemSet().GetItemState( _nWhich, false ) )
+ rOutSet->ClearItem(_nWhich);
+ }
+
+ return bModified;
+}
+
+void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
+
+ bool bApplyCharUnit = GetApplyCharUnit( *rSet );
+
+ if(SvtCJKOptions::IsAsianTypographyEnabled() && bApplyCharUnit )
+ eFUnit = FieldUnit::CHAR;
+
+ m_xLeftIndent->SetFieldUnit(eFUnit);
+ m_xRightIndent->SetFieldUnit(eFUnit);
+ m_xFLineIndent->SetFieldUnit(eFUnit);
+ if ( eFUnit == FieldUnit::CHAR )
+ {
+ m_xTopDist->SetFieldUnit(FieldUnit::LINE);
+ m_xBottomDist->SetFieldUnit(FieldUnit::LINE);
+ SetFieldUnit(*m_xLineDistAtMetricBox, FieldUnit::POINT);
+ }
+ else
+ {
+ m_xTopDist->SetFieldUnit(eFUnit);
+ m_xBottomDist->SetFieldUnit(eFUnit);
+ SetFieldUnit(*m_xLineDistAtMetricBox, eFUnit);
+ }
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_LRSPACE );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+
+ if ( bRelativeMode )
+ {
+ const SvxLRSpaceItem& rOldItem =
+ static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich ));
+
+ if ( rOldItem.GetPropLeft() != 100 )
+ {
+ m_xLeftIndent->SetRelative( true );
+ m_xLeftIndent->set_value(rOldItem.GetPropLeft(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xLeftIndent->SetRelative(false);
+ m_xLeftIndent->SetFieldUnit(eFUnit);
+ m_xLeftIndent->SetMetricValue(rOldItem.GetTextLeft(), eUnit);
+ }
+
+ if ( rOldItem.GetPropRight() != 100 )
+ {
+ m_xRightIndent->SetRelative( true );
+ m_xRightIndent->set_value(rOldItem.GetPropRight(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xRightIndent->SetRelative(false);
+ m_xRightIndent->SetFieldUnit(eFUnit);
+ m_xRightIndent->SetMetricValue(rOldItem.GetRight(), eUnit);
+ }
+
+ if ( rOldItem.GetPropTextFirstLineOffset() != 100 )
+ {
+ m_xFLineIndent->SetRelative(true);
+ m_xFLineIndent->set_value(rOldItem.GetPropTextFirstLineOffset(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xFLineIndent->SetRelative(false);
+ m_xFLineIndent->set_min(-9999, FieldUnit::NONE);
+ m_xFLineIndent->SetFieldUnit(eFUnit);
+ m_xFLineIndent->SetMetricValue(rOldItem.GetTextFirstLineOffset(), eUnit);
+ }
+ m_xAutoCB->set_active(rOldItem.IsAutoFirst());
+ }
+ else
+ {
+ const SvxLRSpaceItem& rSpace =
+ static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich ));
+
+ m_xLeftIndent->SetMetricValue(rSpace.GetTextLeft(), eUnit);
+ m_xRightIndent->SetMetricValue(rSpace.GetRight(), eUnit);
+ m_xFLineIndent->SetMetricValue(rSpace.GetTextFirstLineOffset(), eUnit);
+ m_xAutoCB->set_active(rSpace.IsAutoFirst());
+ }
+ AutoHdl_Impl(*m_xAutoCB);
+ }
+ else
+ {
+ m_xLeftIndent->set_text(OUString());
+ m_xRightIndent->set_text(OUString());
+ m_xFLineIndent->set_text(OUString());
+ }
+
+ _nWhich = GetWhich( SID_ATTR_ULSPACE );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+
+ const SvxULSpaceItem& rOldItem =
+ static_cast<const SvxULSpaceItem&>(rSet->Get( _nWhich ));
+ if ( bRelativeMode )
+ {
+
+ if ( rOldItem.GetPropUpper() != 100 )
+ {
+ m_xTopDist->SetRelative( true );
+ m_xTopDist->set_value(rOldItem.GetPropUpper(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xTopDist->SetRelative(false);
+ if (eFUnit == FieldUnit::CHAR)
+ m_xTopDist->SetFieldUnit(FieldUnit::LINE);
+ else
+ m_xTopDist->SetFieldUnit(eFUnit);
+ m_xTopDist->SetMetricValue(rOldItem.GetUpper(), eUnit);
+ }
+
+ if ( rOldItem.GetPropLower() != 100 )
+ {
+ m_xBottomDist->SetRelative( true );
+ m_xBottomDist->set_value(rOldItem.GetPropLower(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xBottomDist->SetRelative(false);
+ if (eFUnit == FieldUnit::CHAR)
+ m_xBottomDist->SetFieldUnit(FieldUnit::LINE);
+ else
+ m_xBottomDist->SetFieldUnit(eFUnit);
+ m_xBottomDist->SetMetricValue(rOldItem.GetLower(), eUnit);
+ }
+ }
+ else
+ {
+ m_xTopDist->SetMetricValue(rOldItem.GetUpper(), eUnit);
+ m_xBottomDist->SetMetricValue(rOldItem.GetLower(), eUnit);
+ }
+ m_xContextualCB->set_active(rOldItem.GetContext());
+ }
+ else
+ {
+ m_xTopDist->set_text(OUString());
+ m_xBottomDist->set_text(OUString());
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_LINESPACE );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ SetLineSpacing_Impl( static_cast<const SvxLineSpacingItem &>(rSet->Get( _nWhich )) );
+ else
+ m_xLineDist->set_active(-1);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_REGISTER );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ m_xRegisterCB->set_active( static_cast<const SfxBoolItem &>(rSet->Get( _nWhich )).GetValue());
+ m_xRegisterCB->save_state();
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl(*rSet);
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_xRegisterCB->hide();
+ m_xAutoCB->hide();
+ }
+
+ // this sets the min/max limits; do this _after_ setting the values,
+ // because for Impress the min of first-line indent depends on value of
+ // left-indent!
+ ELRLoseFocus();
+ ChangesApplied();
+}
+
+void SvxStdParagraphTabPage::ChangesApplied()
+{
+ m_xLeftIndent->save_value();
+ m_xRightIndent->save_value();
+ m_xFLineIndent->save_value();
+ m_xLineDist->save_value();
+ m_xLineDistAtPercentBox->save_value();
+ m_xLineDistAtMetricBox->save_value();
+ m_xRegisterCB->save_state();
+ m_xTopDist->save_value();
+ m_xBottomDist->save_value();
+ m_xContextualCB->save_state();
+ m_xAutoCB->save_state();
+}
+
+void SvxStdParagraphTabPage::EnableRelativeMode()
+{
+ DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no parent-set!" );
+
+ m_xLeftIndent->EnableRelativeMode( 0, 999 );
+ m_xFLineIndent->EnableRelativeMode( 0, 999 );
+ m_xRightIndent->EnableRelativeMode( 0, 999 );
+ m_xTopDist->EnableRelativeMode( 0, 999 );
+ m_xBottomDist->EnableRelativeMode( 0, 999 );
+ bRelativeMode = true;
+}
+
+void SvxStdParagraphTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+ SfxItemState eItemState = rSet.GetItemState( _nWhich );
+
+ if ( eItemState < SfxItemState::DEFAULT )
+ return;
+
+ const SvxAdjustItem& rAdj = static_cast<const SvxAdjustItem&>( rSet.Get( _nWhich ) );
+ SvxAdjust eAdjust = rAdj.GetAdjust();
+ if ( eAdjust == SvxAdjust::Center || eAdjust == SvxAdjust::Block )
+ {
+ _nWhich = GetWhich( SID_ATTR_FRAMEDIRECTION );
+ eItemState = rSet.GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>( rSet.Get( _nWhich ) );
+ SvxFrameDirection eFrameDirection = rFrameDirItem.GetValue();
+
+ m_aExampleWin.EnableRTL( SvxFrameDirection::Horizontal_RL_TB == eFrameDirection );
+
+ if ( eAdjust == SvxAdjust::Block )
+ m_aExampleWin.SetLastLine( rAdj.GetLastBlock() );
+ }
+ }
+ else
+ {
+ m_aExampleWin.EnableRTL( eAdjust == SvxAdjust::Right );
+ eAdjust = SvxAdjust::Left; //required for correct preview display
+ m_aExampleWin.SetLastLine( eAdjust );
+ }
+ m_aExampleWin.SetAdjust( eAdjust );
+
+ UpdateExample_Impl();
+}
+
+DeactivateRC SvxStdParagraphTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ ELRLoseFocus();
+
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+SvxStdParagraphTabPage::SvxStdParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/paraindentspacing.ui", "ParaIndentSpacing", &rAttr)
+ , nWidth(11905 /*567 * 50*/)
+ , nMinFixDist(0)
+ , bRelativeMode(false)
+ , m_xLeftIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_LEFTINDENT", FieldUnit::CM)))
+ , m_xRightLabel(m_xBuilder->weld_label("labelFT_RIGHTINDENT"))
+ , m_xRightIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_RIGHTINDENT", FieldUnit::CM)))
+ , m_xFLineLabel(m_xBuilder->weld_label("labelFT_FLINEINDENT"))
+ , m_xFLineIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_FLINEINDENT", FieldUnit::CM)))
+ , m_xAutoCB(m_xBuilder->weld_check_button("checkCB_AUTO"))
+ , m_xTopDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_TOPDIST", FieldUnit::CM)))
+ , m_xBottomDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_BOTTOMDIST", FieldUnit::CM)))
+ , m_xContextualCB(m_xBuilder->weld_check_button("checkCB_CONTEXTUALSPACING"))
+ , m_xLineDist(m_xBuilder->weld_combo_box("comboLB_LINEDIST"))
+ , m_xLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("spinED_LINEDISTPERCENT", FieldUnit::PERCENT))
+ , m_xLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("spinED_LINEDISTMETRIC", FieldUnit::CM))
+ , m_xLineDistAtLabel(m_xBuilder->weld_label("labelFT_LINEDIST"))
+ , m_xAbsDist(m_xBuilder->weld_label("labelST_LINEDIST_ABS"))
+ , m_xRegisterCB(m_xBuilder->weld_check_button("checkCB_REGISTER"))
+ , m_xExampleWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWin))
+{
+ sAbsDist = m_xAbsDist->get_label();
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ m_xLineDistAtMetricBox->hide();
+
+ Init_Impl();
+ m_xFLineIndent->set_min(-9999, FieldUnit::NONE); // is set to 0 on default
+}
+
+SvxStdParagraphTabPage::~SvxStdParagraphTabPage()
+{
+}
+
+void SvxStdParagraphTabPage::EnableNegativeMode()
+{
+ m_xLeftIndent->set_min(-9999, FieldUnit::NONE);
+ m_xRightIndent->set_min(-9999, FieldUnit::NONE);
+ m_xRightIndent->EnableNegativeMode();
+ m_xLeftIndent->EnableNegativeMode();
+}
+
+void SvxStdParagraphTabPage::SetLineSpacing_Impl
+(
+ const SvxLineSpacingItem &rAttr
+)
+{
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( rAttr.Which() );
+
+ switch( rAttr.GetLineSpaceRule() )
+ {
+ case SvxLineSpaceRule::Auto:
+ {
+ SvxInterLineSpaceRule eInter = rAttr.GetInterLineSpaceRule();
+
+ switch( eInter )
+ {
+ // Default single line spacing
+ case SvxInterLineSpaceRule::Off:
+ m_xLineDist->set_active( LLINESPACE_1 );
+ break;
+
+ // Default single line spacing
+ case SvxInterLineSpaceRule::Prop:
+ if ( 100 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_1 );
+ break;
+ }
+ // 1.15 line spacing
+ if ( 115 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_115 );
+ break;
+ }
+ // 1.5 line spacing
+ if ( 150 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_15 );
+ break;
+ }
+ // double line spacing
+ if ( 200 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_2 );
+ break;
+ }
+ // the set per cent value
+ m_xLineDistAtPercentBox->set_value(m_xLineDistAtPercentBox->normalize(rAttr.GetPropLineSpace()), FieldUnit::NONE);
+ m_xLineDist->set_active( LLINESPACE_PROP );
+ break;
+
+ case SvxInterLineSpaceRule::Fix:
+ SetMetricValue( *m_xLineDistAtMetricBox, rAttr.GetInterLineSpace(), eUnit );
+ m_xLineDist->set_active( LLINESPACE_DURCH );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ break;
+ case SvxLineSpaceRule::Fix:
+ SetMetricValue(*m_xLineDistAtMetricBox, rAttr.GetLineHeight(), eUnit);
+ m_xLineDist->set_active( LLINESPACE_FIX );
+ break;
+
+ case SvxLineSpaceRule::Min:
+ SetMetricValue(*m_xLineDistAtMetricBox, rAttr.GetLineHeight(), eUnit);
+ m_xLineDist->set_active( LLINESPACE_MIN );
+ break;
+ default: ;//prevent warning
+ }
+ LineDistHdl_Impl( *m_xLineDist );
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, LineDistPopupHdl_Impl, weld::ComboBox&, void)
+{
+ m_bLineDistToggled = true;
+}
+
+IMPL_LINK(SvxStdParagraphTabPage, LineDistHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ switch (rBox.get_active())
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ m_xLineDistAtLabel->set_sensitive(false);
+ m_xLineDistAtPercentBox->set_sensitive(false);
+ m_xLineDistAtPercentBox->set_text(OUString());
+ m_xLineDistAtMetricBox->set_sensitive(false);
+ m_xLineDistAtMetricBox->set_text(OUString());
+ break;
+
+ case LLINESPACE_DURCH:
+ // setting a sensible default?
+ // limit MS min(10, aPageSize)
+ m_xLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
+
+ if (m_xLineDistAtMetricBox->get_text().isEmpty())
+ m_xLineDistAtMetricBox->set_value(m_xLineDistAtMetricBox->normalize(1), FieldUnit::NONE);
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtMetricBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+
+ case LLINESPACE_MIN:
+ m_xLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
+
+ if (m_xLineDistAtMetricBox->get_text().isEmpty())
+ m_xLineDistAtMetricBox->set_value(m_xLineDistAtMetricBox->normalize(10), FieldUnit::TWIP);
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtMetricBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+
+ case LLINESPACE_PROP:
+
+ if (m_xLineDistAtPercentBox->get_text().isEmpty())
+ m_xLineDistAtPercentBox->set_value(m_xLineDistAtPercentBox->normalize(100), FieldUnit::TWIP);
+ m_xLineDistAtMetricBox->hide();
+ m_xLineDistAtPercentBox->show();
+ m_xLineDistAtPercentBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+ case LLINESPACE_FIX:
+ {
+ auto nTemp = m_xLineDistAtMetricBox->get_value(FieldUnit::NONE);
+ m_xLineDistAtMetricBox->set_min(m_xLineDistAtMetricBox->normalize(nMinFixDist), FieldUnit::TWIP);
+
+ // if the value has been changed at SetMin,
+ // it is time for the default
+ if (m_xLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp)
+ SetMetricValue( *m_xLineDistAtMetricBox, FIX_DIST_DEF, MapUnit::MapTwip ); // fix is only in Writer
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtMetricBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ }
+ break;
+ }
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, ModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ UpdateExample_Impl();
+}
+
+void SvxStdParagraphTabPage::Init_Impl()
+{
+ m_xLineDist->connect_popup_toggled(LINK(this, SvxStdParagraphTabPage, LineDistPopupHdl_Impl));
+ m_xLineDist->connect_changed(LINK(this, SvxStdParagraphTabPage, LineDistHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink2 = LINK(this, SvxStdParagraphTabPage, ELRLoseFocusHdl);
+ m_xFLineIndent->connect_value_changed(aLink2);
+ m_xLeftIndent->connect_value_changed(aLink2);
+ m_xRightIndent->connect_value_changed(aLink2);
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK(this, SvxStdParagraphTabPage, ModifyHdl_Impl);
+ m_xTopDist->connect_value_changed(aLink);
+ m_xBottomDist->connect_value_changed(aLink);
+
+ m_xAutoCB->connect_toggled(LINK(this, SvxStdParagraphTabPage, AutoHdl_Impl));
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) ) );
+
+ m_xTopDist->set_max( m_xTopDist->normalize( MAX_DURCH ), eUnit );
+ m_xBottomDist->set_max( m_xBottomDist->normalize( MAX_DURCH ), eUnit );
+ m_xLineDistAtMetricBox->set_max( m_xLineDistAtMetricBox->normalize( MAX_DURCH ), eUnit );
+}
+
+void SvxStdParagraphTabPage::UpdateExample_Impl()
+{
+ m_aExampleWin.SetFirstLineOffset( static_cast<short>(m_xFLineIndent->denormalize( m_xFLineIndent->get_value( FieldUnit::TWIP ) )) );
+ m_aExampleWin.SetLeftMargin( static_cast<tools::Long>(m_xLeftIndent->denormalize( m_xLeftIndent->get_value( FieldUnit::TWIP ) ) ) );
+ m_aExampleWin.SetRightMargin( static_cast<tools::Long>(m_xRightIndent->denormalize( m_xRightIndent->get_value( FieldUnit::TWIP ) ) ) );
+ m_aExampleWin.SetUpper( static_cast<sal_uInt16>(m_xTopDist->denormalize( m_xTopDist->get_value( FieldUnit::TWIP ) )) );
+ m_aExampleWin.SetLower( static_cast<sal_uInt16>(m_xBottomDist->denormalize( m_xBottomDist->get_value( FieldUnit::TWIP ) )) );
+
+ int nPos = m_xLineDist->get_active();
+
+ switch ( nPos )
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ case LLINESPACE_PROP:
+ case LLINESPACE_MIN:
+ case LLINESPACE_DURCH:
+ case LLINESPACE_FIX:
+ m_aExampleWin.SetLineSpace( static_cast<SvxPrevLineSpace>(nPos) );
+ break;
+ }
+ m_aExampleWin.Invalidate();
+}
+
+void SvxStdParagraphTabPage::EnableRegisterMode()
+{
+ m_xRegisterCB->show();
+}
+
+void SvxStdParagraphTabPage::EnableContextualMode()
+{
+ m_xContextualCB->show();
+}
+
+IMPL_LINK(SvxStdParagraphTabPage, AutoHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = !rBox.get_active();
+ m_xFLineLabel->set_sensitive(bEnable);
+ m_xFLineIndent->set_sensitive(bEnable);
+}
+
+void SvxStdParagraphTabPage::EnableAutoFirstLine()
+{
+ m_xAutoCB->show();
+}
+
+void SvxStdParagraphTabPage::EnableAbsLineDist(tools::Long nMinTwip)
+{
+ m_xLineDist->append_text(sAbsDist);
+ nMinFixDist = nMinTwip;
+}
+
+void SvxStdParagraphTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+
+/* different bit represent call to different method of SvxStdParagraphTabPage
+ 0x0001 --->EnableRelativeMode()
+ 0x0002 --->EnableRegisterMode()
+ 0x0004 --->EnableAutoFirstLine()
+ 0x0008 --->EnableNegativeMode()
+ 0x0010 --->EnableContextualMode()
+ */
+ const SfxUInt16Item* pPageWidthItem = aSet.GetItem<SfxUInt16Item>(SID_SVXSTDPARAGRAPHTABPAGE_PAGEWIDTH, false);
+ const SfxUInt32Item* pFlagSetItem = aSet.GetItem<SfxUInt32Item>(SID_SVXSTDPARAGRAPHTABPAGE_FLAGSET, false);
+ const SfxUInt32Item* pLineDistItem = aSet.GetItem<SfxUInt32Item>(SID_SVXSTDPARAGRAPHTABPAGE_ABSLINEDIST, false);
+
+ if (pPageWidthItem)
+ nWidth = pPageWidthItem->GetValue();
+
+ if (pFlagSetItem )
+ {
+ if (( 0x0001 & pFlagSetItem->GetValue())== 0x0001 )
+ EnableRelativeMode();
+
+ if (( 0x0002 & pFlagSetItem->GetValue())== 0x0002 )
+ EnableRegisterMode();
+
+ if ( ( 0x0004 & pFlagSetItem->GetValue())== 0x0004 )
+ EnableAutoFirstLine();
+ }
+
+ if(pLineDistItem)
+ EnableAbsLineDist(pLineDistItem->GetValue());
+
+ if (pFlagSetItem)
+ {
+ if (( 0x0008 & pFlagSetItem->GetValue()) == 0x0008 )
+ EnableNegativeMode();
+
+ if (( 0x0010 & pFlagSetItem->GetValue()) == 0x0010 )
+ EnableContextualMode();
+ }
+}
+
+#define LASTLINEPOS_DEFAULT 0
+#define LASTLINEPOS_LEFT 1
+
+#define LASTLINECOUNT_OLD 3
+#define LASTLINECOUNT_NEW 4
+
+SvxParaAlignTabPage::SvxParaAlignTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/paragalignpage.ui", "ParaAlignPage", &rSet)
+ , m_xLeft(m_xBuilder->weld_radio_button("radioBTN_LEFTALIGN"))
+ , m_xRight(m_xBuilder->weld_radio_button("radioBTN_RIGHTALIGN"))
+ , m_xCenter(m_xBuilder->weld_radio_button("radioBTN_CENTERALIGN"))
+ , m_xJustify(m_xBuilder->weld_radio_button("radioBTN_JUSTIFYALIGN"))
+ , m_xLeftBottom(m_xBuilder->weld_label("labelST_LEFTALIGN_ASIAN"))
+ , m_xRightTop(m_xBuilder->weld_label("labelST_RIGHTALIGN_ASIAN"))
+ , m_xLastLineFT(m_xBuilder->weld_label("labelLB_LASTLINE"))
+ , m_xLastLineLB(m_xBuilder->weld_combo_box("comboLB_LASTLINE"))
+ , m_xExpandCB(m_xBuilder->weld_check_button("checkCB_EXPAND"))
+ , m_xSnapToGridCB(m_xBuilder->weld_check_button("checkCB_SNAP"))
+ , m_xExampleWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWin))
+ , m_xVertAlignFL(m_xBuilder->weld_widget("frameFL_VERTALIGN"))
+ , m_xVertAlignLB(m_xBuilder->weld_combo_box("comboLB_VERTALIGN"))
+ , m_xPropertiesFL(m_xBuilder->weld_widget("framePROPERTIES"))
+ , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboLB_TEXTDIRECTION")))
+{
+ SetExchangeSupport();
+
+ sal_uInt16 nLastLinePos = LASTLINEPOS_DEFAULT;
+
+ if ( SvtCJKOptions::IsAsianTypographyEnabled() )
+ {
+ m_xLeft->set_label(m_xLeftBottom->get_label());
+ m_xRight->set_label(m_xRightTop->get_label());
+
+ OUString sLeft(m_xLeft->get_label());
+ sLeft = MnemonicGenerator::EraseAllMnemonicChars( sLeft );
+
+ if (m_xLastLineLB->get_count() == LASTLINECOUNT_OLD)
+ {
+ m_xLastLineLB->remove(0);
+ m_xLastLineLB->insert_text(0, sLeft);
+ }
+ else
+ nLastLinePos = LASTLINEPOS_LEFT;
+ }
+
+ // remove "Default" or "Left" entry, depends on CJKOptions
+ if (m_xLastLineLB->get_count() == LASTLINECOUNT_NEW)
+ m_xLastLineLB->remove(nLastLinePos);
+
+ Link<weld::Toggleable&, void> aLink = LINK( this, SvxParaAlignTabPage, AlignHdl_Impl );
+ m_xLeft->connect_toggled(aLink);
+ m_xRight->connect_toggled(aLink);
+ m_xCenter->connect_toggled(aLink);
+ m_xJustify->connect_toggled(aLink);
+ m_xLastLineLB->connect_changed(LINK(this, SvxParaAlignTabPage, LastLineHdl_Impl));
+ m_xTextDirectionLB->connect_changed(LINK(this, SvxParaAlignTabPage, TextDirectionHdl_Impl));
+
+ m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+}
+
+SvxParaAlignTabPage::~SvxParaAlignTabPage()
+{
+}
+
+DeactivateRC SvxParaAlignTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxParaAlignTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxParaAlignTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxParaAlignTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ bool bModified = false;
+
+ bool bAdj = false;
+ SvxAdjust eAdjust = SvxAdjust::Left;
+
+ if (m_xLeft->get_active())
+ {
+ eAdjust = SvxAdjust::Left;
+ bAdj = m_xLeft->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xRight->get_active())
+ {
+ eAdjust = SvxAdjust::Right;
+ bAdj = m_xRight->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xCenter->get_active())
+ {
+ eAdjust = SvxAdjust::Center;
+ bAdj = m_xCenter->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xJustify->get_active())
+ {
+ eAdjust = SvxAdjust::Block;
+ bAdj = m_xJustify->get_saved_state() == TRISTATE_FALSE ||
+ m_xExpandCB->get_state_changed_from_saved() ||
+ m_xLastLineLB->get_value_changed_from_saved();
+ }
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+
+ if (bAdj)
+ {
+ SvxAdjust eOneWord = m_xExpandCB->get_active() ? SvxAdjust::Block : SvxAdjust::Left;
+
+ int nLBPos = m_xLastLineLB->get_active();
+ SvxAdjust eLastBlock = SvxAdjust::Left;
+ if ( 1 == nLBPos )
+ eLastBlock = SvxAdjust::Center;
+ else if ( 2 == nLBPos )
+ eLastBlock = SvxAdjust::Block;
+
+ SvxAdjustItem aAdj( static_cast<const SvxAdjustItem&>(GetItemSet().Get( _nWhich )) );
+ aAdj.SetAdjust( eAdjust );
+ aAdj.SetOneWord( eOneWord );
+ aAdj.SetLastBlock( eLastBlock );
+ rOutSet->Put( aAdj );
+ bModified = true;
+ }
+
+ if (m_xSnapToGridCB->get_state_changed_from_saved())
+ {
+ rOutSet->Put(SvxParaGridItem(m_xSnapToGridCB->get_active(), GetWhich( SID_ATTR_PARA_SNAPTOGRID )));
+ bModified = true;
+ }
+
+ if (m_xVertAlignLB->get_value_changed_from_saved())
+ {
+ rOutSet->Put(SvxParaVertAlignItem(static_cast<SvxParaVertAlignItem::Align>(m_xVertAlignLB->get_active()), GetWhich( SID_PARA_VERTALIGN )));
+ bModified = true;
+ }
+
+ if (m_xTextDirectionLB->get_visible())
+ {
+ if (m_xTextDirectionLB->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+ rOutSet->Put( SvxFrameDirectionItem( eDir, GetWhich( SID_ATTR_FRAMEDIRECTION ) ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+void SvxParaAlignTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ Reset( &rSet );
+}
+
+void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ sal_Int32 nLBSelect = 0;
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxAdjustItem& rAdj = static_cast<const SvxAdjustItem&>(rSet->Get( _nWhich ));
+
+ switch ( rAdj.GetAdjust() /*!!! ask VB rAdj.GetLastBlock()*/ )
+ {
+ case SvxAdjust::Left: m_xLeft->set_active(true); break;
+
+ case SvxAdjust::Right: m_xRight->set_active(true); break;
+
+ case SvxAdjust::Center: m_xCenter->set_active(true); break;
+
+ case SvxAdjust::Block: m_xJustify->set_active(true); break;
+ default: ; //prevent warning
+ }
+ bool bEnable = m_xJustify->get_active();
+ m_xLastLineFT->set_sensitive(bEnable);
+ m_xLastLineLB->set_sensitive(bEnable);
+
+ switch(rAdj.GetLastBlock())
+ {
+ case SvxAdjust::Left: nLBSelect = 0; break;
+
+ case SvxAdjust::Center: nLBSelect = 1; break;
+
+ case SvxAdjust::Block: nLBSelect = 2; break;
+ default: ; //prevent warning
+ }
+ m_xExpandCB->set_sensitive(bEnable && nLBSelect == 2);
+ m_xExpandCB->set_active(SvxAdjust::Block == rAdj.GetOneWord());
+ }
+ else
+ {
+ m_xLeft->set_active(false);
+ m_xRight->set_active(false);
+ m_xCenter->set_active(false);
+ m_xJustify->set_active(false);
+ }
+ m_xLastLineLB->set_active(nLBSelect);
+
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl(*rSet);
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_xLastLineLB->hide();
+ m_xLastLineFT->hide();
+ m_xExpandCB->hide();
+ if(!(nHtmlMode & HTMLMODE_FULL_STYLES) )
+ m_xJustify->set_sensitive(false);
+ m_xSnapToGridCB->hide();
+ }
+ _nWhich = GetWhich(SID_ATTR_PARA_SNAPTOGRID);
+ eItemState = rSet->GetItemState( _nWhich );
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxParaGridItem& rSnap = static_cast<const SvxParaGridItem&>(rSet->Get( _nWhich ));
+ m_xSnapToGridCB->set_active(rSnap.GetValue());
+ }
+
+ _nWhich = GetWhich( SID_PARA_VERTALIGN );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ m_xVertAlignFL->show();
+
+ const SvxParaVertAlignItem& rAlign = static_cast<const SvxParaVertAlignItem&>(rSet->Get( _nWhich ));
+
+ m_xVertAlignLB->set_active(static_cast<sal_Int32>(rAlign.GetValue()));
+ }
+
+ _nWhich = GetWhich( SID_ATTR_FRAMEDIRECTION );
+ //text direction
+ if( SfxItemState::DEFAULT <= rSet->GetItemState( _nWhich ) )
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>( rSet->Get( _nWhich ) );
+ m_xTextDirectionLB->set_active_id(rFrameDirItem.GetValue());
+ m_xTextDirectionLB->save_value();
+ }
+
+ m_xSnapToGridCB->save_state();
+ m_xVertAlignLB->save_value();
+ m_xLeft->save_state();
+ m_xRight->save_state();
+ m_xCenter->save_state();
+ m_xJustify->save_state();
+ m_xLastLineLB->save_value();
+ m_xExpandCB->save_state();
+
+ UpdateExample_Impl();
+}
+
+void SvxParaAlignTabPage::ChangesApplied()
+{
+ m_xTextDirectionLB->save_value();
+ m_xSnapToGridCB->save_state();
+ m_xVertAlignLB->save_value();
+ m_xLeft->save_state();
+ m_xRight->save_state();
+ m_xCenter->save_state();
+ m_xJustify->save_state();
+ m_xLastLineLB->save_value();
+ m_xExpandCB->save_state();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, AlignHdl_Impl, weld::Toggleable&, void)
+{
+ bool bJustify = m_xJustify->get_active();
+ m_xLastLineFT->set_sensitive(bJustify);
+ m_xLastLineLB->set_sensitive(bJustify);
+ bool bLastLineIsBlock = m_xLastLineLB->get_active() == 2;
+ m_xExpandCB->set_sensitive(bJustify && bLastLineIsBlock);
+ //set last line listbox to entry position 0 if not enabled
+ if (!m_xLastLineLB->get_sensitive())
+ m_xLastLineLB->set_active(0);
+ //uncheck 'Expand ... word' when check box is not enabled
+ if (!m_xExpandCB->get_sensitive())
+ m_xExpandCB->set_active(false);
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, LastLineHdl_Impl, weld::ComboBox&, void)
+{
+ //fdo#41350 only enable 'Expand last word' if last line is also justified
+ bool bLastLineIsBlock = m_xLastLineLB->get_active() == 2;
+ m_xExpandCB->set_sensitive(bLastLineIsBlock);
+ //uncheck 'Expand ... word' when check box is not enabled
+ if (!m_xExpandCB->get_sensitive())
+ m_xExpandCB->set_active(false);
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, TextDirectionHdl_Impl, weld::ComboBox&, void)
+{
+ UpdateExample_Impl();
+}
+
+void SvxParaAlignTabPage::UpdateExample_Impl()
+{
+ if (m_xLeft->get_active())
+ {
+ m_aExampleWin.EnableRTL(false);
+ m_aExampleWin.SetAdjust(SvxAdjust::Left);
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ }
+ else if (m_xRight->get_active())
+ {
+ m_aExampleWin.EnableRTL(true);
+ m_aExampleWin.SetAdjust(SvxAdjust::Left);
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ }
+ else
+ {
+ SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+ switch ( eDir )
+ {
+ case SvxFrameDirection::Environment :
+ if ( !m_xRight->get_active() )
+ m_aExampleWin.EnableRTL( AllSettings::GetLayoutRTL() );
+ break;
+ case SvxFrameDirection::Horizontal_RL_TB :
+ if ( !m_xLeft->get_active() )
+ m_aExampleWin.EnableRTL( true );
+ break;
+ case SvxFrameDirection::Horizontal_LR_TB :
+ if ( !m_xRight->get_active() )
+ m_aExampleWin.EnableRTL( false );
+ break;
+ default: ; //prevent warning
+ }
+ if (m_xCenter->get_active())
+ m_aExampleWin.SetAdjust( SvxAdjust::Center );
+ else if (m_xJustify->get_active())
+ {
+ m_aExampleWin.SetAdjust( SvxAdjust::Block );
+ int nLBPos = m_xLastLineLB->get_active();
+ if (nLBPos == 0)
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ else if (nLBPos == 1)
+ m_aExampleWin.SetLastLine(SvxAdjust::Center);
+ else if (nLBPos == 2)
+ m_aExampleWin.SetLastLine(SvxAdjust::Block);
+ }
+ }
+
+ m_aExampleWin.Invalidate();
+}
+
+void SvxParaAlignTabPage::EnableJustifyExt()
+{
+ m_xLastLineFT->show();
+ m_xLastLineLB->show();
+ m_xExpandCB->show();
+ if (SvtCJKOptions::IsAsianTypographyEnabled())
+ m_xSnapToGridCB->show();
+
+}
+
+void SvxParaAlignTabPage::PageCreated (const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pBoolItem = aSet.GetItem<SfxBoolItem>(SID_SVXPARAALIGNTABPAGE_ENABLEJUSTIFYEXT, false);
+ if (pBoolItem && pBoolItem->GetValue())
+ EnableJustifyExt();
+}
+
+std::unique_ptr<SfxTabPage> SvxExtParagraphTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxExtParagraphTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ bool bModified = false;
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
+ const TriState eHyphenState = m_xHyphenBox->get_state();
+ const SfxPoolItem* pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_HYPHENZONE );
+
+ if ( m_xHyphenBox->get_state_changed_from_saved() ||
+ m_xHyphenNoCapsBox->get_state_changed_from_saved() ||
+ m_xHyphenNoLastWordBox->get_state_changed_from_saved() ||
+ m_xExtHyphenBeforeBox->get_value_changed_from_saved() ||
+ m_xExtHyphenAfterBox->get_value_changed_from_saved() ||
+ m_xMaxHyphenEdit->get_value_changed_from_saved() ||
+ m_xMinWordLength->get_value_changed_from_saved() ||
+ m_xHyphenZone->get_value_changed_from_saved() )
+ {
+ SvxHyphenZoneItem aHyphen(
+ static_cast<const SvxHyphenZoneItem&>(GetItemSet().Get( _nWhich )) );
+ aHyphen.SetHyphen( eHyphenState == TRISTATE_TRUE );
+ aHyphen.SetNoCapsHyphenation(m_xHyphenNoCapsBox->get_state() == TRISTATE_TRUE);
+ aHyphen.SetNoLastWordHyphenation(m_xHyphenNoLastWordBox->get_state() == TRISTATE_TRUE);
+
+ if ( eHyphenState == TRISTATE_TRUE )
+ {
+ aHyphen.GetMinLead() = static_cast<sal_uInt8>(m_xExtHyphenBeforeBox->get_value());
+ aHyphen.GetMinTrail() = static_cast<sal_uInt8>(m_xExtHyphenAfterBox->get_value());
+ aHyphen.GetMinWordLength() = static_cast<sal_uInt8>(m_xMinWordLength->get_value());
+ }
+ aHyphen.GetMaxHyphens() = static_cast<sal_uInt8>(m_xMaxHyphenEdit->get_value());
+
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+ aHyphen.GetTextHyphenZone() = static_cast<sal_uInt16>(m_xHyphenZone->GetCoreValue(eUnit));
+
+ if ( !pOld ||
+ *static_cast<const SvxHyphenZoneItem*>(pOld) != aHyphen ||
+ m_xHyphenBox->get_state_changed_from_saved())
+ {
+ rOutSet->Put( aHyphen );
+ bModified = true;
+ }
+ }
+
+ if (m_xPageNumBox->get_sensitive()
+ && (m_xPageNumBox->get_state_changed_from_saved() || m_xPagenumEdit->get_value_changed_from_saved()))
+ {
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_PAGENUM );
+
+ if (TRISTATE_TRUE == m_xPageNumBox->get_state()
+ && (!pOld || IsInvalidItem(pOld)
+ || static_cast<const SfxUInt16Item*>(pOld)->GetValue() != m_xPagenumEdit->get_value()))
+ {
+ SfxUInt16Item aPageNum(SID_ATTR_PARA_PAGENUM,
+ static_cast<sal_uInt16>(m_xPagenumEdit->get_value()));
+ rOutSet->Put( aPageNum );
+ bModified = true;
+ }
+ else if (TRISTATE_FALSE == m_xPageNumBox->get_state()
+ && (pOld || IsInvalidItem(pOld)))
+ {
+ // need to tell sw to remove the item
+ rOutSet->DisableItem(SID_ATTR_PARA_PAGENUM);
+ bModified = true;
+ }
+ }
+
+ // pagebreak
+
+ TriState eState = m_xApplyCollBtn->get_state();
+ bool bIsPageModel = false;
+
+ OUString sPage;
+ if ( m_xApplyCollBtn->get_state_changed_from_saved() ||
+ ( TRISTATE_TRUE == eState &&
+ m_xApplyCollBox->get_value_changed_from_saved() ) )
+ {
+ if ( eState == TRISTATE_TRUE )
+ {
+ sPage = m_xApplyCollBox->get_active_text();
+ bIsPageModel = !sPage.isEmpty();
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_MODEL );
+
+ if ( !pOld || static_cast<const SvxPageModelItem*>(pOld)->GetValue() != sPage )
+ {
+ rOutSet->Put( SvxPageModelItem( sPage, false, SID_ATTR_PARA_MODEL ) );
+ bModified = true;
+ }
+ else
+ bIsPageModel = false;
+ }
+ else if(TRISTATE_TRUE == eState && m_xApplyCollBtn->get_sensitive())
+ bIsPageModel = true;
+ else
+ rOutSet->Put( SvxPageModelItem( sPage, false, SID_ATTR_PARA_MODEL ) );
+
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGEBREAK );
+
+ if ( bIsPageModel )
+ // if PageModel is turned on, always turn off PageBreak
+ rOutSet->Put( SvxFormatBreakItem( SvxBreak::NONE, _nWhich ) );
+ else
+ {
+ eState = m_xPageBreakBox->get_state();
+ SfxItemState eModelState = GetItemSet().GetItemState(SID_ATTR_PARA_MODEL, false);
+
+ if ( (eModelState == SfxItemState::SET && TRISTATE_TRUE == m_xPageBreakBox->get_state()) ||
+ m_xPageBreakBox->get_state_changed_from_saved() ||
+ m_xBreakTypeLB->get_value_changed_from_saved() ||
+ m_xBreakPositionLB->get_value_changed_from_saved() )
+ {
+ const SvxFormatBreakItem rOldBreak(
+ static_cast<const SvxFormatBreakItem&>(GetItemSet().Get( _nWhich )));
+ SvxFormatBreakItem aBreak(rOldBreak.GetBreak(), rOldBreak.Which());
+
+ switch ( eState )
+ {
+ case TRISTATE_TRUE:
+ {
+ bool bBefore = m_xBreakPositionLB->get_active() == 0;
+
+ if (m_xBreakTypeLB->get_active() == 0)
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::PageBefore );
+ else
+ aBreak.SetValue( SvxBreak::PageAfter );
+ }
+ else
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::ColumnBefore );
+ else
+ aBreak.SetValue( SvxBreak::ColumnAfter );
+ }
+ break;
+ }
+
+ case TRISTATE_FALSE:
+ aBreak.SetValue( SvxBreak::NONE );
+ break;
+ default: ; //prevent warning
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_PAGEBREAK );
+
+ if ( eState != m_xPageBreakBox->get_saved_state() ||
+ !pOld || !( *static_cast<const SvxFormatBreakItem*>(pOld) == aBreak ) )
+ {
+ bModified = true;
+ rOutSet->Put( aBreak );
+ }
+ }
+ }
+
+ // paragraph split
+ _nWhich = GetWhich( SID_ATTR_PARA_SPLIT );
+ eState = m_xKeepTogetherBox->get_state();
+
+ if (m_xKeepTogetherBox->get_state_changed_from_saved())
+ {
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_SPLIT );
+
+ if ( !pOld || static_cast<const SvxFormatSplitItem*>(pOld)->GetValue() !=
+ ( eState == TRISTATE_FALSE ) )
+ {
+ rOutSet->Put( SvxFormatSplitItem( eState == TRISTATE_FALSE, _nWhich ) );
+ bModified = true;
+ }
+ }
+
+ // keep paragraphs
+ _nWhich = GetWhich( SID_ATTR_PARA_KEEP );
+ eState = m_xKeepParaBox->get_state();
+
+ if (m_xKeepParaBox->get_state_changed_from_saved())
+ {
+ // if the status has changed, putting is necessary
+ rOutSet->Put( SvxFormatKeepItem( eState == TRISTATE_TRUE, _nWhich ) );
+ bModified = true;
+ }
+
+ // widows and orphans
+ _nWhich = GetWhich( SID_ATTR_PARA_WIDOWS );
+ eState = m_xWidowBox->get_state();
+
+ if ( m_xWidowBox->get_state_changed_from_saved() ||
+ m_xWidowRowNo->get_value_changed_from_saved() )
+ {
+ SvxWidowsItem rItem( eState == TRISTATE_TRUE ?
+ static_cast<sal_uInt8>(m_xWidowRowNo->get_value()) : 0, _nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_WIDOWS );
+
+ if ( m_xWidowBox->get_state_changed_from_saved() || !pOld || !( *static_cast<const SvxWidowsItem*>(pOld) == rItem ) )
+ {
+ rOutSet->Put( rItem );
+ bModified = true;
+ }
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_ORPHANS );
+ eState = m_xOrphanBox->get_state();
+
+ if ( m_xOrphanBox->get_state_changed_from_saved() ||
+ m_xOrphanRowNo->get_value_changed_from_saved() )
+ {
+ SvxOrphansItem rItem( eState == TRISTATE_TRUE ?
+ static_cast<sal_uInt8>(m_xOrphanRowNo->get_value()) : 0, _nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_ORPHANS );
+
+ if ( m_xOrphanBox->get_state_changed_from_saved() ||
+ !pOld ||
+ !( *static_cast<const SvxOrphansItem*>(pOld) == rItem ) )
+ {
+ rOutSet->Put( rItem );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
+
+ bool bApplyCharUnit = GetApplyCharUnit( *rSet );
+
+ if( SvtCJKOptions::IsAsianTypographyEnabled() && bApplyCharUnit )
+ eFUnit = FieldUnit::CHAR;
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ bool bItemAvailable = eItemState >= SfxItemState::DEFAULT;
+ bool bIsHyphen = false;
+ if( !bHtmlMode && bItemAvailable )
+ {
+ const SvxHyphenZoneItem& rHyphen =
+ static_cast<const SvxHyphenZoneItem&>(rSet->Get( _nWhich ));
+ aHyphenState.bTriStateEnabled = false;
+
+ bIsHyphen = rHyphen.IsHyphen();
+ m_xHyphenBox->set_state(bIsHyphen ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xHyphenNoCapsBox->set_state(rHyphen.IsNoCapsHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xHyphenNoLastWordBox->set_state(rHyphen.IsNoLastWordHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ m_xExtHyphenBeforeBox->set_value(rHyphen.GetMinLead());
+ m_xExtHyphenAfterBox->set_value(rHyphen.GetMinTrail());
+ m_xMaxHyphenEdit->set_value(rHyphen.GetMaxHyphens());
+ m_xMinWordLength->set_value(rHyphen.GetMinWordLength());
+ m_xHyphenZone->SetFieldUnit(eFUnit);
+ m_xHyphenZone->SetMetricValue(rHyphen.GetTextHyphenZone(), MapUnit::MapTwip);
+ }
+ else
+ {
+ m_xHyphenBox->set_state(TRISTATE_INDET);
+ m_xHyphenNoCapsBox->set_state(TRISTATE_INDET);
+ m_xHyphenNoLastWordBox->set_state(TRISTATE_INDET);
+ }
+ bool bEnable = bItemAvailable && bIsHyphen;
+ m_xHyphenNoCapsBox->set_sensitive(bEnable);
+ m_xHyphenNoLastWordBox->set_sensitive(bEnable);
+ m_xExtHyphenBeforeBox->set_sensitive(bEnable);
+ m_xExtHyphenAfterBox->set_sensitive(bEnable);
+ m_xBeforeText->set_sensitive(bEnable);
+ m_xAfterText->set_sensitive(bEnable);
+ m_xMaxHyphenLabel->set_sensitive(bEnable);
+ m_xMaxHyphenEdit->set_sensitive(bEnable);
+ m_xMinWordLabel->set_sensitive(bEnable);
+ m_xMinWordLength->set_sensitive(bEnable);
+ m_xHyphenZoneLabel->set_sensitive(bEnable);
+ m_xHyphenZone->set_sensitive(bEnable);
+
+ switch (rSet->GetItemState(SID_ATTR_PARA_PAGENUM))
+ {
+ case SfxItemState::SET:
+ {
+ aPageNumState.bTriStateEnabled = false;
+ m_xPageNumBox->set_state(TRISTATE_TRUE);
+ SfxUInt16Item const*const pItem(rSet->GetItem<SfxUInt16Item>(SID_ATTR_PARA_PAGENUM));
+ const sal_uInt16 nPageNum(pItem->GetValue());
+ m_xPagenumEdit->set_value(nPageNum);
+ break;
+ }
+ case SfxItemState::DONTCARE:
+ {
+ aPageNumState.bTriStateEnabled = true;
+ m_xPageNumBox->set_state(TRISTATE_INDET);
+ break;
+ }
+ case SfxItemState::UNKNOWN:
+ case SfxItemState::DEFAULT:
+ case SfxItemState::DISABLED:
+ {
+ aPageNumState.bTriStateEnabled = false;
+ m_xPageNumBox->set_state(TRISTATE_FALSE);
+ break;
+ }
+ default:
+ assert(false); // unexpected
+ break;
+ }
+
+ if ( bPageBreak )
+ {
+ // first handle PageModel
+ bool bIsPageModel = false;
+ eItemState = rSet->GetItemState( SID_ATTR_PARA_MODEL );
+
+ if ( eItemState >= SfxItemState::SET )
+ {
+ aApplyCollState.bTriStateEnabled = false;
+
+ const SvxPageModelItem& rModel = rSet->Get( SID_ATTR_PARA_MODEL );
+ const OUString& aStr( rModel.GetValue() );
+
+ if (!aStr.isEmpty() && m_xApplyCollBox->find_text(aStr) != -1)
+ {
+ m_xApplyCollBox->set_active_text(aStr);
+ m_xApplyCollBtn->set_state(TRISTATE_TRUE);
+ bIsPageModel = true;
+
+ m_xPageBreakBox->set_sensitive(true);
+ aPageBreakState.bTriStateEnabled = false;
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xPageBreakBox->set_state(TRISTATE_TRUE);
+
+ //select page break
+ m_xBreakTypeLB->set_active(0);
+ //select break before
+ m_xBreakPositionLB->set_active(0);
+ }
+ else
+ {
+ m_xApplyCollBox->set_active(-1);
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ }
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ {
+ aApplyCollState.bTriStateEnabled = true;
+ m_xApplyCollBtn->set_state(TRISTATE_INDET);
+ m_xApplyCollBox->set_active(-1);
+ }
+ else
+ {
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ }
+
+ if ( !bIsPageModel )
+ {
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGEBREAK );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFormatBreakItem& rPageBreak =
+ static_cast<const SvxFormatBreakItem&>(rSet->Get( _nWhich ));
+
+ SvxBreak eBreak = rPageBreak.GetBreak();
+
+ // PageBreak not via CTRL-RETURN,
+ // then CheckBox can be freed
+ m_xPageBreakBox->set_sensitive(true);
+ aPageBreakState.bTriStateEnabled = false;
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+
+ m_xPageBreakBox->set_state(TRISTATE_TRUE);
+
+ bool _bEnable = eBreak != SvxBreak::NONE &&
+ eBreak != SvxBreak::ColumnBefore &&
+ eBreak != SvxBreak::ColumnAfter;
+ m_xApplyCollBtn->set_sensitive(_bEnable);
+ if (!_bEnable)
+ {
+ m_xApplyCollBox->set_sensitive(_bEnable);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(_bEnable);
+ }
+
+ if ( eBreak == SvxBreak::NONE )
+ m_xPageBreakBox->set_state(TRISTATE_FALSE);
+
+ sal_Int32 nType = 0; // selection position in break type ListBox : Page
+ sal_Int32 nPosition = 0; // selection position in break position ListBox : Before
+ switch ( eBreak )
+ {
+ case SvxBreak::PageBefore:
+ break;
+ case SvxBreak::PageAfter:
+ nPosition = 1;
+ break;
+ case SvxBreak::ColumnBefore:
+ nType = 1;
+ break;
+ case SvxBreak::ColumnAfter:
+ nType = 1;
+ nPosition = 1;
+ break;
+ default: ;//prevent warning
+ }
+ m_xBreakTypeLB->set_active(nType);
+ m_xBreakPositionLB->set_active(nPosition);
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xPageBreakBox->set_state(TRISTATE_INDET);
+ else
+ {
+ m_xPageBreakBox->set_sensitive(false);
+ m_xBreakTypeFT->set_sensitive(false);
+ m_xBreakTypeLB->set_sensitive(false);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ }
+ }
+
+ PageBreakPosHdl_Impl(*m_xBreakPositionLB);
+ PageBreakHdl();
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_KEEP );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ aKeepParaState.bTriStateEnabled = false;
+ const SvxFormatKeepItem& rKeep =
+ static_cast<const SvxFormatKeepItem&>(rSet->Get( _nWhich ));
+
+ if ( rKeep.GetValue() )
+ m_xKeepParaBox->set_state(TRISTATE_TRUE);
+ else
+ m_xKeepParaBox->set_state(TRISTATE_FALSE);
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xKeepParaBox->set_state(TRISTATE_INDET);
+ else
+ m_xKeepParaBox->set_sensitive(false);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_SPLIT );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFormatSplitItem& rSplit =
+ static_cast<const SvxFormatSplitItem&>(rSet->Get( _nWhich ));
+ aKeepTogetherState.bTriStateEnabled = false;
+
+ if ( !rSplit.GetValue() )
+ m_xKeepTogetherBox->set_state(TRISTATE_TRUE);
+ else
+ {
+ m_xKeepTogetherBox->set_state(TRISTATE_FALSE);
+ // default widows and orphans to enabled
+ m_xWidowBox->set_sensitive(true);
+ m_xOrphanBox->set_sensitive(true);
+ }
+
+ // widows and orphans
+ _nWhich = GetWhich( SID_ATTR_PARA_WIDOWS );
+ SfxItemState eTmpState = rSet->GetItemState( _nWhich );
+
+ if ( eTmpState >= SfxItemState::DEFAULT )
+ {
+ const SvxWidowsItem& rWidow =
+ static_cast<const SvxWidowsItem&>(rSet->Get( _nWhich ));
+ aWidowState.bTriStateEnabled = false;
+ const sal_uInt16 nLines = rWidow.GetValue();
+
+ bool _bEnable = nLines > 0;
+ m_xWidowRowNo->set_value(m_xWidowRowNo->normalize(nLines));
+ m_xWidowBox->set_state(_bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xWidowRowNo->set_sensitive(_bEnable);
+ }
+ else if ( SfxItemState::DONTCARE == eTmpState )
+ m_xWidowBox->set_state( TRISTATE_INDET );
+ else
+ m_xWidowBox->set_sensitive(false);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_ORPHANS );
+ eTmpState = rSet->GetItemState( _nWhich );
+
+ if ( eTmpState >= SfxItemState::DEFAULT )
+ {
+ const SvxOrphansItem& rOrphan =
+ static_cast<const SvxOrphansItem&>(rSet->Get( _nWhich ));
+ const sal_uInt16 nLines = rOrphan.GetValue();
+ aOrphanState.bTriStateEnabled = false;
+
+ bool _bEnable = nLines > 0;
+ m_xOrphanBox->set_state(_bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xOrphanRowNo->set_value(m_xOrphanRowNo->normalize(nLines));
+ m_xOrphanRowNo->set_sensitive(_bEnable);
+ m_xOrphanRowLabel->set_sensitive(_bEnable);
+
+ }
+ else if ( SfxItemState::DONTCARE == eTmpState )
+ m_xOrphanBox->set_state(TRISTATE_INDET);
+ else
+ m_xOrphanBox->set_sensitive(false);
+ aOrphanState.eState = m_xOrphanBox->get_state();
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xKeepTogetherBox->set_state(TRISTATE_INDET);
+ else
+ m_xKeepTogetherBox->set_sensitive(false);
+
+ // so that everything is enabled correctly
+ KeepTogetherHdl();
+ WidowHdl();
+ OrphanHdl();
+ ChangesApplied();
+}
+void SvxExtParagraphTabPage::ChangesApplied()
+{
+ m_xHyphenBox->save_state();
+ m_xHyphenNoCapsBox->save_state();
+ m_xHyphenNoLastWordBox->save_state();
+ m_xExtHyphenBeforeBox->set_value(m_xExtHyphenBeforeBox->get_value());
+ m_xExtHyphenAfterBox->set_value(m_xExtHyphenAfterBox->get_value());
+ m_xMaxHyphenEdit->set_value(m_xMaxHyphenEdit->get_value());
+ m_xMinWordLength->set_value(m_xMinWordLength->get_value());
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit =
+ MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_PARA_HYPHENZONE ) ) );
+ m_xHyphenZone->set_value(m_xHyphenZone->get_value(eUnit), eUnit);
+ m_xPageBreakBox->save_state();
+ m_xBreakPositionLB->save_value();
+ m_xBreakTypeLB->save_value();
+ m_xApplyCollBtn->save_state();
+ m_xApplyCollBox->save_value();
+ m_xPageNumBox->save_state();
+ m_xPagenumEdit->save_value();
+ m_xKeepTogetherBox->save_state();
+ m_xKeepParaBox->save_state();
+ m_xWidowBox->save_state();
+ m_xOrphanBox->save_state();
+ m_xOrphanRowNo->save_value();
+ m_xWidowRowNo->save_value();
+}
+
+DeactivateRC SvxExtParagraphTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxExtParagraphTabPage::DisablePageBreak()
+{
+ bPageBreak = false;
+ m_xPageBreakBox->set_sensitive(false);
+ m_xBreakTypeLB->remove(0);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+}
+
+SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/textflowpage.ui", "TextFlowPage", &rAttr)
+ , bPageBreak(true)
+ , bHtmlMode(false)
+ , nStdPos(0)
+ // Hyphenation
+ , m_xHyphenBox(m_xBuilder->weld_check_button("checkAuto"))
+ , m_xHyphenNoCapsBox(m_xBuilder->weld_check_button("checkNoCaps"))
+ , m_xHyphenNoLastWordBox(m_xBuilder->weld_check_button("checkNoLastWord"))
+ , m_xBeforeText(m_xBuilder->weld_label("labelLineBegin"))
+ , m_xExtHyphenBeforeBox(m_xBuilder->weld_spin_button("spinLineEnd"))
+ , m_xAfterText(m_xBuilder->weld_label("labelLineEnd"))
+ , m_xExtHyphenAfterBox(m_xBuilder->weld_spin_button("spinLineBegin"))
+ , m_xMaxHyphenLabel(m_xBuilder->weld_label("labelMaxNum"))
+ , m_xMaxHyphenEdit(m_xBuilder->weld_spin_button("spinMaxNum"))
+ , m_xMinWordLabel(m_xBuilder->weld_label("labelMinLen"))
+ , m_xMinWordLength(m_xBuilder->weld_spin_button("spinMinLen"))
+ , m_xHyphenZoneLabel(m_xBuilder->weld_label("labelHyphenZone"))
+ , m_xHyphenZone(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinHyphenZone", FieldUnit::CM)))
+ //Page break
+ , m_xPageBreakBox(m_xBuilder->weld_check_button("checkInsert"))
+ , m_xBreakTypeFT(m_xBuilder->weld_label("labelType"))
+ , m_xBreakTypeLB(m_xBuilder->weld_combo_box("comboBreakType"))
+ , m_xBreakPositionFT(m_xBuilder->weld_label("labelPosition"))
+ , m_xBreakPositionLB(m_xBuilder->weld_combo_box("comboBreakPosition"))
+ , m_xApplyCollBtn(m_xBuilder->weld_check_button("checkPageStyle"))
+ , m_xApplyCollBox(m_xBuilder->weld_combo_box("comboPageStyle"))
+ , m_xPageNumBox(m_xBuilder->weld_check_button("labelPageNum"))
+ , m_xPagenumEdit(m_xBuilder->weld_spin_button("spinPageNumber"))
+ // Options
+ , m_xKeepTogetherBox(m_xBuilder->weld_check_button("checkSplitPara"))
+ , m_xKeepParaBox(m_xBuilder->weld_check_button("checkKeepPara"))
+ , m_xOrphanBox(m_xBuilder->weld_check_button("checkOrphan"))
+ , m_xOrphanRowNo(m_xBuilder->weld_spin_button("spinOrphan"))
+ , m_xOrphanRowLabel(m_xBuilder->weld_label("labelOrphan"))
+ , m_xWidowBox(m_xBuilder->weld_check_button("checkWidow"))
+ , m_xWidowRowNo(m_xBuilder->weld_spin_button("spinWidow"))
+ , m_xWidowRowLabel(m_xBuilder->weld_label("labelWidow"))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ m_xHyphenBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, HyphenClickHdl_Impl));
+ m_xPageBreakBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, PageBreakHdl_Impl));
+ m_xKeepTogetherBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, KeepTogetherHdl_Impl));
+ m_xWidowBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, WidowHdl_Impl));
+ m_xOrphanBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, OrphanHdl_Impl));
+ m_xApplyCollBtn->connect_toggled(LINK(this, SvxExtParagraphTabPage, ApplyCollClickHdl_Impl));
+ m_xBreakTypeLB->connect_changed(LINK(this, SvxExtParagraphTabPage, PageBreakTypeHdl_Impl));
+ m_xBreakPositionLB->connect_changed(LINK(this, SvxExtParagraphTabPage, PageBreakPosHdl_Impl));
+ m_xPageNumBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, PageNumBoxClickHdl_Impl));
+ m_xKeepParaBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, KeepParaBoxClickHdl_Impl));
+
+ if (SfxObjectShell* pSh = SfxObjectShell::Current())
+ {
+ SfxStyleSheetBasePool* pPool = pSh->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyle = pPool->First(SfxStyleFamily::Page);
+ OUString aStdName;
+
+ // tdf139131 - sort page styles
+ m_xApplyCollBox->make_sorted();
+ while( pStyle )
+ {
+ if ( aStdName.isEmpty() )
+ // first style == standard style
+ aStdName = pStyle->GetName();
+ m_xApplyCollBox->append_text(pStyle->GetName());
+ pStyle = pPool->Next();
+ }
+ nStdPos = m_xApplyCollBox->find_text(aStdName);
+ }
+
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl( rAttr );
+ if ( !(nHtmlMode & HTMLMODE_ON) )
+ return;
+
+ bHtmlMode = true;
+ m_xHyphenBox->set_sensitive(false);
+ m_xHyphenNoCapsBox->set_sensitive(false);
+ m_xHyphenNoLastWordBox->set_sensitive(false);
+ m_xBeforeText->set_sensitive(false);
+ m_xExtHyphenBeforeBox->set_sensitive(false);
+ m_xAfterText->set_sensitive(false);
+ m_xExtHyphenAfterBox->set_sensitive(false);
+ m_xMaxHyphenLabel->set_sensitive(false);
+ m_xMaxHyphenEdit->set_sensitive(false);
+ m_xMinWordLabel->set_sensitive(false);
+ m_xMinWordLength->set_sensitive(false);
+ m_xHyphenZoneLabel->set_sensitive(false);
+ m_xHyphenZone->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ // no column break in HTML
+ m_xBreakTypeLB->remove(1);
+}
+
+SvxExtParagraphTabPage::~SvxExtParagraphTabPage()
+{
+}
+
+void SvxExtParagraphTabPage::PageBreakHdl()
+{
+ switch (m_xPageBreakBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+
+ if (0 == m_xBreakTypeLB->get_active() && 0 == m_xBreakPositionLB->get_active())
+ {
+ m_xApplyCollBtn->set_sensitive(true);
+
+ bool bEnable = TRISTATE_TRUE == m_xApplyCollBtn->get_state() &&
+ m_xApplyCollBox->get_count();
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if(!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+ }
+ break;
+
+ case TRISTATE_FALSE:
+ case TRISTATE_INDET:
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ m_xBreakTypeFT->set_sensitive(false);
+ m_xBreakTypeLB->set_sensitive(false);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aPageBreakState.ButtonToggled(rToggle);
+ PageBreakHdl();
+}
+
+void SvxExtParagraphTabPage::KeepTogetherHdl()
+{
+ bool bEnable = m_xKeepTogetherBox->get_state() == TRISTATE_FALSE;
+ m_xWidowBox->set_sensitive(bEnable);
+ m_xOrphanBox->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, KeepTogetherHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aKeepTogetherState.ButtonToggled(rToggle);
+ KeepTogetherHdl();
+}
+
+void SvxExtParagraphTabPage::WidowHdl()
+{
+ switch (m_xWidowBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xWidowRowNo->set_sensitive(true);
+ m_xWidowRowLabel->set_sensitive(true);
+ m_xKeepTogetherBox->set_sensitive(false);
+ break;
+ case TRISTATE_FALSE:
+ if (m_xOrphanBox->get_state() == TRISTATE_FALSE)
+ m_xKeepTogetherBox->set_sensitive(true);
+ [[fallthrough]];
+ case TRISTATE_INDET:
+ m_xWidowRowNo->set_sensitive(false);
+ m_xWidowRowLabel->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, WidowHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aWidowState.ButtonToggled(rToggle);
+ WidowHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, OrphanHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aOrphanState.ButtonToggled(rToggle);
+ OrphanHdl();
+}
+
+void SvxExtParagraphTabPage::OrphanHdl()
+{
+ switch (m_xOrphanBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xOrphanRowNo->set_sensitive(true);
+ m_xOrphanRowLabel->set_sensitive(true);
+ m_xKeepTogetherBox->set_sensitive(false);
+ break;
+
+ case TRISTATE_FALSE:
+ if (m_xWidowBox->get_state() == TRISTATE_FALSE)
+ m_xKeepTogetherBox->set_sensitive(true);
+ [[fallthrough]];
+ case TRISTATE_INDET:
+ m_xOrphanRowNo->set_sensitive(false);
+ m_xOrphanRowLabel->set_sensitive(false);
+ break;
+ }
+}
+
+void SvxExtParagraphTabPage::HyphenClickHdl()
+{
+ bool bEnable = m_xHyphenBox->get_state() == TRISTATE_TRUE;
+ m_xHyphenNoCapsBox->set_sensitive(bEnable);
+ m_xHyphenNoLastWordBox->set_sensitive(bEnable);
+ m_xBeforeText->set_sensitive(bEnable);
+ m_xExtHyphenBeforeBox->set_sensitive(bEnable);
+ m_xAfterText->set_sensitive(bEnable);
+ m_xExtHyphenAfterBox->set_sensitive(bEnable);
+ m_xMaxHyphenLabel->set_sensitive(bEnable);
+ m_xMaxHyphenEdit->set_sensitive(bEnable);
+ m_xMinWordLabel->set_sensitive(bEnable);
+ m_xMinWordLength->set_sensitive(bEnable);
+ m_xHyphenZoneLabel->set_sensitive(bEnable);
+ m_xHyphenZone->set_sensitive(bEnable);
+ m_xHyphenBox->set_state(bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, HyphenClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aHyphenState.ButtonToggled(rToggle);
+ HyphenClickHdl();
+}
+
+void SvxExtParagraphTabPage::ApplyCollClickHdl()
+{
+ bool bEnable = false;
+ if (m_xApplyCollBtn->get_state() == TRISTATE_TRUE && m_xApplyCollBox->get_count())
+ {
+ bEnable = true;
+ m_xApplyCollBox->set_active(nStdPos);
+ }
+ else
+ {
+ m_xApplyCollBox->set_active(-1);
+ }
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if (!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, ApplyCollClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aApplyCollState.ButtonToggled(rToggle);
+ ApplyCollClickHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakPosHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (0 == rListBox.get_active())
+ {
+ m_xApplyCollBtn->set_sensitive(true);
+
+ bool bEnable = m_xApplyCollBtn->get_state() == TRISTATE_TRUE && m_xApplyCollBox->get_count();
+
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if (!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+ }
+ else if (1 == rListBox.get_active())
+ {
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakTypeHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ //column break or break after
+ int nBreakPos = m_xBreakPositionLB->get_active();
+ if (rListBox.get_active() == 1 || 1 == nBreakPos)
+ {
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ }
+ else
+ PageBreakPosHdl_Impl(*m_xBreakPositionLB);
+}
+
+void SvxExtParagraphTabPage::PageNumBoxClickHdl()
+{
+ m_xPagenumEdit->set_sensitive(m_xPageNumBox->get_state() == TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageNumBoxClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aPageNumState.ButtonToggled(rToggle);
+ PageNumBoxClickHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, KeepParaBoxClickHdl_Impl, weld::Toggleable&, rToggle, void)
+{
+ aKeepParaState.ButtonToggled(rToggle);
+}
+
+void SvxExtParagraphTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pDisablePageBreakItem = aSet.GetItem<SfxBoolItem>(SID_DISABLE_SVXEXTPARAGRAPHTABPAGE_PAGEBREAK, false);
+
+ if (pDisablePageBreakItem)
+ if ( pDisablePageBreakItem->GetValue())
+ DisablePageBreak();
+}
+
+SvxAsianTabPage::SvxAsianTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/asiantypography.ui", "AsianTypography", &rSet)
+ , m_xForbiddenRulesCB(m_xBuilder->weld_check_button("checkForbidList"))
+ , m_xHangingPunctCB(m_xBuilder->weld_check_button("checkHangPunct"))
+ , m_xScriptSpaceCB(m_xBuilder->weld_check_button("checkApplySpacing"))
+{
+}
+
+SvxAsianTabPage::~SvxAsianTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAsianTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxAsianTabPage>(pPage, pController, *rSet);
+}
+
+WhichRangesContainer SvxAsianTabPage::GetRanges()
+{
+ return WhichRangesContainer(svl::Items<SID_ATTR_PARA_SCRIPTSPACE, SID_ATTR_PARA_FORBIDDEN_RULES>);
+}
+
+bool SvxAsianTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bRet = false;
+ SfxItemPool* pPool = rSet->GetPool();
+ if (m_xScriptSpaceCB->get_sensitive() && m_xScriptSpaceCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_SCRIPTSPACE)).Clone()));
+ pNewItem->SetValue(m_xScriptSpaceCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ if (m_xHangingPunctCB->get_sensitive() && m_xHangingPunctCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_HANGPUNCTUATION)).Clone()));
+ pNewItem->SetValue(m_xHangingPunctCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ if (m_xForbiddenRulesCB->get_sensitive() && m_xForbiddenRulesCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_FORBIDDEN_RULES)).Clone()));
+ pNewItem->SetValue(m_xForbiddenRulesCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ return bRet;
+}
+
+static void lcl_SetBox(const SfxItemSet& rSet, sal_uInt16 nSlotId, weld::CheckButton& rBox)
+{
+ sal_uInt16 _nWhich = rSet.GetPool()->GetWhich(nSlotId);
+ SfxItemState eState = rSet.GetItemState(_nWhich);
+ if( eState == SfxItemState::UNKNOWN || eState == SfxItemState::DISABLED )
+ rBox.set_sensitive(false);
+ else if(eState >= SfxItemState::DEFAULT)
+ rBox.set_active(static_cast<const SfxBoolItem&>(rSet.Get(_nWhich)).GetValue());
+ else
+ rBox.set_state(TRISTATE_INDET);
+ rBox.save_state();
+}
+
+void SvxAsianTabPage::Reset( const SfxItemSet* rSet )
+{
+ lcl_SetBox(*rSet, SID_ATTR_PARA_FORBIDDEN_RULES, *m_xForbiddenRulesCB );
+ lcl_SetBox(*rSet, SID_ATTR_PARA_HANGPUNCTUATION, *m_xHangingPunctCB );
+
+ //character distance not yet available
+ lcl_SetBox(*rSet, SID_ATTR_PARA_SCRIPTSPACE, *m_xScriptSpaceCB );
+}
+
+void SvxAsianTabPage::ChangesApplied()
+{
+ m_xForbiddenRulesCB->save_state();
+ m_xHangingPunctCB->save_state();
+ m_xScriptSpaceCB->save_state();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/swpossizetabpage.cxx b/cui/source/tabpages/swpossizetabpage.cxx
new file mode 100644
index 000000000..e8a1e4eb9
--- /dev/null
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -0,0 +1,1878 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <cstddef>
+#include <swpossizetabpage.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/anchorid.hxx>
+#include <svl/intitem.hxx>
+#include <svx/swframevalidation.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/swframeposstrings.hxx>
+#include <svx/rectenum.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star::text;
+
+namespace {
+
+enum class LB;
+
+}
+
+struct FrmMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ short nAlign;
+ LB nLBRelations;
+};
+
+namespace {
+
+struct RelationMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ LB nLBRelation;
+ short nRelation;
+};
+struct StringIdPair_Impl
+{
+ SvxSwFramePosString::StringId eHori;
+ SvxSwFramePosString::StringId eVert;
+};
+
+enum class LB {
+ NONE = 0x000000,
+ Frame = 0x000001, // paragraph text area
+ PrintArea = 0x000002, // paragraph text area + indents
+ VertFrame = 0x000004, // vertical paragraph text area
+ VertPrintArea = 0x000008, // vertical paragraph text area + indents
+ RelFrameLeft = 0x000010, // left paragraph margin
+ RelFrameRight = 0x000020, // right paragraph margin
+
+ RelPageLeft = 0x000040, // left page margin
+ RelPageRight = 0x000080, // right page margin
+ RelPageFrame = 0x000100, // complete page
+ RelPagePrintArea = 0x000200, // text area of page
+
+ FlyRelPageLeft = 0x000400, // left frame margin
+ FlyRelPageRight = 0x000800, // right frame margin
+ FlyRelPageFrame = 0x001000, // complete frame
+ FlyRelPagePrintArea = 0x002000, // frame interior
+
+ RelBase = 0x004000, // as char, relative to baseline
+ RelChar = 0x008000, // as char, relative to character
+ RelRow = 0x010000, // as char, relative to line
+
+// #i22305#
+ FlyVertFrame = 0x020000, // vertical entire frame
+ FlyVertPrintArea = 0x040000, // vertical frame text area
+
+// #i22341#
+ VertLine = 0x080000, // vertical text line
+
+ RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
+ RelPagePrintAreaTop = 0x200000,
+
+ LAST = 0x400000
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
+}
+
+RelationMap const aRelationMap[] =
+{
+ {SvxSwFramePosString::FRAME, SvxSwFramePosString::FRAME, LB::Frame, RelOrientation::FRAME},
+ {SvxSwFramePosString::PRTAREA, SvxSwFramePosString::PRTAREA, LB::PrintArea, RelOrientation::PRINT_AREA},
+ {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::MIR_REL_PG_LEFT, LB::RelPageLeft, RelOrientation::PAGE_LEFT},
+ {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::MIR_REL_PG_RIGHT, LB::RelPageRight, RelOrientation::PAGE_RIGHT},
+ {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::MIR_REL_FRM_LEFT, LB::RelFrameLeft, RelOrientation::FRAME_LEFT},
+ {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::MIR_REL_FRM_RIGHT, LB::RelFrameRight, RelOrientation::FRAME_RIGHT},
+ {SvxSwFramePosString::REL_PG_FRAME, SvxSwFramePosString::REL_PG_FRAME, LB::RelPageFrame, RelOrientation::PAGE_FRAME},
+ {SvxSwFramePosString::REL_PG_PRTAREA,SvxSwFramePosString::REL_PG_PRTAREA, LB::RelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
+ {SvxSwFramePosString::REL_PG_PRTAREA_TOP,SvxSwFramePosString::REL_PG_PRTAREA_TOP, LB::RelPagePrintAreaTop, RelOrientation::PAGE_PRINT_AREA_TOP},
+ {SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM, LB::RelPagePrintAreaBottom, RelOrientation::PAGE_PRINT_AREA_BOTTOM},
+ {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::CHAR},
+
+ {SvxSwFramePosString::FLY_REL_PG_LEFT, SvxSwFramePosString::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, RelOrientation::PAGE_LEFT},
+ {SvxSwFramePosString::FLY_REL_PG_RIGHT, SvxSwFramePosString::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, RelOrientation::PAGE_RIGHT},
+ {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, RelOrientation::PAGE_FRAME},
+ {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
+
+ {SvxSwFramePosString::REL_BORDER, SvxSwFramePosString::REL_BORDER, LB::VertFrame, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_PRTAREA, SvxSwFramePosString::REL_PRTAREA, LB::VertPrintArea, RelOrientation::PRINT_AREA},
+
+ // #i22305#
+ {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyVertFrame, RelOrientation::FRAME},
+ {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, RelOrientation::PRINT_AREA},
+
+ // #i22341#
+ {SvxSwFramePosString::REL_LINE, SvxSwFramePosString::REL_LINE, LB::VertLine, RelOrientation::TEXT_LINE}
+};
+
+RelationMap const aAsCharRelationMap[] =
+{
+ {SvxSwFramePosString::REL_BASE, SvxSwFramePosString::REL_BASE, LB::RelBase, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_ROW, SvxSwFramePosString::REL_ROW, LB::RelRow, RelOrientation::FRAME}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at page
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
+ LB::RelPageRight;
+
+FrmMap const aHPageMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PAGE_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PAGE_REL},
+ {SvxSwFramePosString::CENTER_HORI,SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PAGE_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PAGE_REL}
+};
+
+FrmMap const aHPageHtmlMap[] =
+{
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+#define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
+
+FrmMap const aVPageMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PAGE_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PAGE_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PAGE_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PAGE_REL}
+};
+
+FrmMap const aVPageHtmlMap[] =
+{
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::RelPageFrame}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at frame
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
+ LB::FlyRelPageLeft|LB::FlyRelPageRight;
+
+FrmMap const aHFrameMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_FRAME_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_FRAME_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_FRAME_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_FRAME_REL}
+};
+
+FrmMap const aHFlyHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::FlyRelPageFrame},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::FlyRelPageFrame}
+};
+
+// #i18732# - own vertical alignment map for to frame anchored objects
+// #i22305#
+#define VERT_FRAME_REL (LB::FlyVertFrame|LB::FlyVertPrintArea)
+
+FrmMap const aVFrameMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_FRAME_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_FRAME_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_FRAME_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_FRAME_REL}
+};
+
+FrmMap const aVFlyHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::FlyVertFrame},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::FlyVertFrame}
+};
+
+FrmMap const aVMultiSelectionMap[] =
+{
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::NONE}
+};
+FrmMap const aHMultiSelectionMap[] =
+{
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::FROMLEFT, HoriOrientation::NONE, LB::NONE}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at paragraph
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
+ LB::RelFrameRight;
+
+FrmMap const aHParaMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PARA_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PARA_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PARA_REL}
+};
+
+#define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
+
+FrmMap const aHParaHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+FrmMap const aHParaHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+
+constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
+ LB::RelPageFrame|LB::RelPagePrintArea| LB::RelPagePrintAreaTop |LB::RelPagePrintAreaBottom;
+
+FrmMap const aVParaMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PARA_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PARA_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PARA_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PARA_REL}
+};
+
+FrmMap const aVParaHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::VertPrintArea}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at character
+ --------------------------------------------------------------------*/
+
+constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
+ LB::RelFrameRight|LB::RelChar;
+
+static FrmMap aHCharMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_CHAR_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_CHAR_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_CHAR_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_CHAR_REL}
+};
+
+#define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
+
+static FrmMap aHCharHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_CHAR_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_CHAR_REL}
+};
+
+static FrmMap aHCharHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, LB::PrintArea},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+// #i18732# - allow vertical alignment at page areas
+// #i22341# - handle <LB::RelChar> on its own
+constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPagePrintAreaBottom;
+
+static FrmMap aVCharMap[] =
+{
+ // #i22341#
+ // introduce mappings for new vertical alignment at top of line <LB::VertLine>
+ // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
+ // Note: because of these adjustments the map becomes ambiguous in its values
+ // <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
+ // in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
+ // and <SwFrmPage::FillPosLB(..)>
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_CHAR_REL},
+ {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelChar|LB::VertLine},
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::VertLine},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::VertLine},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::VertLine}
+};
+
+
+FrmMap const aVCharHtmlMap[] =
+{
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+
+FrmMap const aVCharHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelChar},
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+/*--------------------------------------------------------------------
+ anchored as character
+ --------------------------------------------------------------------*/
+
+FrmMap const aVAsCharMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, LB::RelBase},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CHAR_CENTER, LB::RelChar},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow},
+
+ {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelBase}
+};
+
+FrmMap const aVAsCharHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow}
+};
+
+static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
+{
+ if( !pMap )
+ return 0;
+
+ if( pMap == aVParaHtmlMap )
+ return std::size(aVParaHtmlMap);
+ if( pMap == aVAsCharHtmlMap )
+ return std::size( aVAsCharHtmlMap );
+ if( pMap == aHParaHtmlMap )
+ return std::size( aHParaHtmlMap );
+ if( pMap == aHParaHtmlAbsMap )
+ return std::size( aHParaHtmlAbsMap );
+ if( pMap == aVPageMap )
+ return std::size( aVPageMap );
+ if( pMap == aVPageHtmlMap )
+ return std::size( aVPageHtmlMap );
+ if( pMap == aVAsCharMap )
+ return std::size( aVAsCharMap );
+ if( pMap == aVParaMap )
+ return std::size( aVParaMap );
+ if( pMap == aHParaMap )
+ return std::size( aHParaMap );
+ if( pMap == aHFrameMap )
+ return std::size( aHFrameMap );
+ if( pMap == aVFrameMap )
+ return std::size( aVFrameMap );
+ if( pMap == aHCharMap )
+ return std::size( aHCharMap );
+ if( pMap == aHCharHtmlMap )
+ return std::size( aHCharHtmlMap );
+ if( pMap == aHCharHtmlAbsMap )
+ return std::size( aHCharHtmlAbsMap );
+ if( pMap == aVCharMap )
+ return std::size( aVCharMap );
+ if( pMap == aVCharHtmlMap )
+ return std::size( aVCharHtmlMap );
+ if( pMap == aVCharHtmlAbsMap )
+ return std::size( aVCharHtmlAbsMap );
+ if( pMap == aHPageHtmlMap )
+ return std::size( aHPageHtmlMap );
+ if( pMap == aHFlyHtmlMap )
+ return std::size( aHFlyHtmlMap );
+ if( pMap == aVFlyHtmlMap )
+ return std::size( aVFlyHtmlMap );
+ if( pMap == aVMultiSelectionMap )
+ return std::size( aVMultiSelectionMap );
+ if( pMap == aHMultiSelectionMap )
+ return std::size( aHMultiSelectionMap );
+ return std::size(aHPageMap);
+}
+
+static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
+ SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
+{
+ //special handling of STR_FROMLEFT
+ if(SvxSwFramePosString::FROMLEFT == eStringId)
+ {
+ eStringId = bVertical ?
+ bRTL ? SvxSwFramePosString::FROMBOTTOM : SvxSwFramePosString::FROMTOP :
+ bRTL ? SvxSwFramePosString::FROMRIGHT : SvxSwFramePosString::FROMLEFT;
+ return eStringId;
+ }
+ if(bVertical)
+ {
+ //exchange horizontal strings with vertical strings and vice versa
+ static const StringIdPair_Impl aHoriIds[] =
+ {
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::TOP},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::BOTTOM},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_VERT},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT},
+ {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::REL_PG_TOP},
+ {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::REL_PG_BOTTOM} ,
+ {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::REL_FRM_TOP},
+ {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::REL_FRM_BOTTOM}
+ };
+ static const StringIdPair_Impl aVertIds[] =
+ {
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::RIGHT},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::LEFT },
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_HORI},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT },
+ {SvxSwFramePosString::REL_PG_TOP, SvxSwFramePosString::REL_PG_LEFT },
+ {SvxSwFramePosString::REL_PG_BOTTOM, SvxSwFramePosString::REL_PG_RIGHT } ,
+ {SvxSwFramePosString::REL_FRM_TOP, SvxSwFramePosString::REL_FRM_LEFT },
+ {SvxSwFramePosString::REL_FRM_BOTTOM, SvxSwFramePosString::REL_FRM_RIGHT }
+ };
+ for(const auto &a : aHoriIds)
+ {
+ if(a.eHori == eStringId)
+ {
+ eStringId = a.eVert;
+ return eStringId;
+ }
+ }
+ for(const auto &a : aVertIds)
+ {
+ if(a.eHori == eStringId)
+ {
+ eStringId = a.eVert;
+ break;
+ }
+ }
+ }
+ return eStringId;
+}
+// #i22341# - helper method in order to determine all possible
+// listbox relations in a relation map for a given relation
+static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
+{
+ LB nLBRelations = LB::NONE;
+
+ for (RelationMap const & nRelMapPos : aRelationMap)
+ {
+ if ( nRelMapPos.nRelation == _nRel )
+ {
+ nLBRelations |= nRelMapPos.nLBRelation;
+ }
+ }
+
+ return nLBRelations;
+}
+
+// #i22341# - helper method on order to determine all possible
+// listbox relations in a relation map for a given string ID
+static LB lcl_GetLBRelationsForStrID(const FrmMap* _pMap,
+ const SvxSwFramePosString::StringId _eStrId,
+ const bool _bUseMirrorStr )
+{
+ LB nLBRelations = LB::NONE;
+
+ std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
+ for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
+ {
+ if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
+ ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
+ {
+ nLBRelations |= _pMap[nRelMapPos].nLBRelations;
+ }
+ }
+
+ return nLBRelations;
+}
+
+SvxSwPosSizeTabPage::SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
+ , m_pVMap(nullptr)
+ , m_pHMap(nullptr)
+ , m_pSdrView(nullptr)
+ , m_nOldH(HoriOrientation::CENTER)
+ , m_nOldHRel(RelOrientation::FRAME)
+ , m_nOldV(VertOrientation::TOP)
+ , m_nOldVRel(RelOrientation::PRINT_AREA)
+ , m_fWidthHeightRatio(1.0)
+ , m_bHtmlMode(false)
+ , m_bIsVerticalFrame(false)
+ , m_bPositioningDisabled(false)
+ , m_bIsMultiSelection(false)
+ , m_bIsInRightToLeft(false)
+ , m_nProtectSizeState(TRISTATE_FALSE)
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
+ , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
+ , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
+ , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
+ , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
+ , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
+ , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
+ , m_xSizeCB(m_xBuilder->weld_check_button("size"))
+ , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
+ , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
+ , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
+ , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
+ , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
+ , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
+ , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
+ , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
+ , m_xVertFT(m_xBuilder->weld_label("vertposft"))
+ , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
+ , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
+ , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
+ , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
+ , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
+ , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+{
+ setOptimalFrmWidth();
+ setOptimalRelWidth();
+
+ FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
+ SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
+ SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
+ SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
+
+ SetExchangeSupport();
+
+ Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
+ m_xWidthMF->connect_focus_out(aLk3);
+ m_xHeightMF->connect_focus_out(aLk3);
+ m_xHoriByMF->connect_focus_out(aLk3);
+ m_xVertByMF->connect_focus_out(aLk3);
+ m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxSwPosSizeTabPage, ModifyHdl);
+ m_xWidthMF->connect_value_changed( aLk );
+ m_xHeightMF->connect_value_changed( aLk );
+ m_xHoriByMF->connect_value_changed( aLk );
+ m_xVertByMF->connect_value_changed( aLk );
+
+ Link<weld::Toggleable&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
+ m_xToPageRB->connect_toggled( aLk2 );
+ m_xToParaRB->connect_toggled( aLk2 );
+ m_xToCharRB->connect_toggled( aLk2 );
+ m_xAsCharRB->connect_toggled( aLk2 );
+ m_xToFrameRB->connect_toggled( aLk2 );
+
+ m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
+ m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
+
+ m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
+ m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
+
+ m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
+ m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
+}
+
+SvxSwPosSizeTabPage::~SvxSwPosSizeTabPage()
+{
+ m_xWidthMF.reset();
+ m_xHeightMF.reset();
+ m_xHoriByMF.reset();
+ m_xVertByMF.reset();
+}
+
+namespace
+{
+ struct FrmMaps
+ {
+ FrmMap const *pMap;
+ size_t nCount;
+ };
+}
+
+void SvxSwPosSizeTabPage::setOptimalFrmWidth()
+{
+ static const FrmMaps aMaps[] = {
+ { aHPageMap, std::size(aHPageMap) },
+ { aHPageHtmlMap, std::size(aHPageHtmlMap) },
+ { aVPageMap, std::size(aVPageMap) },
+ { aVPageHtmlMap, std::size(aVPageHtmlMap) },
+ { aHFrameMap, std::size(aHFrameMap) },
+ { aHFlyHtmlMap, std::size(aHFlyHtmlMap) },
+ { aVFrameMap, std::size(aVFrameMap) },
+ { aVFlyHtmlMap, std::size(aVFlyHtmlMap) },
+ { aHParaMap, std::size(aHParaMap) },
+ { aHParaHtmlMap, std::size(aHParaHtmlMap) },
+ { aHParaHtmlAbsMap, std::size(aHParaHtmlAbsMap) },
+ { aVParaMap, std::size(aVParaMap) },
+ { aVParaHtmlMap, std::size(aVParaHtmlMap) },
+ { aHCharMap, std::size(aHCharMap) },
+ { aHCharHtmlMap, std::size(aHCharHtmlMap) },
+ { aHCharHtmlAbsMap, std::size(aHCharHtmlAbsMap) },
+ { aVCharMap, std::size(aVCharMap) },
+ { aVCharHtmlMap, std::size(aVCharHtmlMap) },
+ { aVCharHtmlAbsMap, std::size(aVCharHtmlAbsMap) },
+ { aVAsCharMap, std::size(aVAsCharMap) },
+ { aVAsCharHtmlMap, std::size(aVAsCharHtmlMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aFrames;
+ for (const FrmMaps& aMap : aMaps)
+ {
+ for (size_t j = 0; j < aMap.nCount; ++j)
+ {
+ aFrames.push_back(aMap.pMap[j].eStrId);
+ aFrames.push_back(aMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aFrames.begin(), aFrames.end());
+ aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
+
+ for (auto const& frame : aFrames)
+ {
+ m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
+ }
+
+ Size aBiggest(m_xHoriLB->get_preferred_size());
+ m_xHoriLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriLB->clear();
+}
+
+namespace
+{
+ struct RelationMaps
+ {
+ RelationMap const *pMap;
+ size_t nCount;
+ };
+}
+
+void SvxSwPosSizeTabPage::setOptimalRelWidth()
+{
+ static const RelationMaps aMaps[] = {
+ { aRelationMap, std::size(aRelationMap) },
+ { aAsCharRelationMap, std::size(aAsCharRelationMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aRels;
+ for (const RelationMaps& aMap : aMaps)
+ {
+ for (size_t j = 0; j < aMap.nCount; ++j)
+ {
+ aRels.push_back(aMap.pMap[j].eStrId);
+ aRels.push_back(aMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aRels.begin(), aRels.end());
+ aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
+
+ for (auto const& elem : aRels)
+ {
+ m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
+ }
+
+ Size aBiggest(m_xHoriLB->get_preferred_size());
+ m_xHoriLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriLB->clear();
+}
+
+std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
+}
+
+WhichRangesContainer SvxSwPosSizeTabPage::GetRanges()
+{
+ static const WhichRangesContainer ranges(svl::Items<
+ SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
+ SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
+ SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
+ SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
+ >);
+ return ranges;
+}
+
+bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
+{
+ bool bAnchorChanged = false;
+ RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
+ bool bModified = false;
+ if(bAnchorChanged)
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
+ bModified = true;
+ }
+ if (m_xPositionCB->get_state_changed_from_saved())
+ {
+ if (m_xPositionCB->get_inconsistent())
+ rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
+ else
+ rSet->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xPositionCB->get_state() == TRISTATE_TRUE ) );
+ bModified = true;
+ }
+
+ if (m_xSizeCB->get_state_changed_from_saved())
+ {
+ if (m_xSizeCB->get_inconsistent())
+ rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ else
+ rSet->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xSizeCB->get_state() == TRISTATE_TRUE ) );
+ bModified = true;
+ }
+
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ if(!m_bPositioningDisabled)
+ {
+ //on multiple selections the positioning is set via SdrView
+ if (m_bIsMultiSelection)
+ {
+ if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
+ {
+ auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+
+ // old rectangle with CoreUnit
+ m_aRect = m_pSdrView->GetAllMarkedRect();
+ m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
+
+ nHoriByPos += m_aAnchorPos.X();
+ nVertByPos += m_aAnchorPos.Y();
+
+ rSet->Put( SfxInt32Item( SID_ATTR_TRANSFORM_POS_X, nHoriByPos ) );
+ rSet->Put( SfxInt32Item( SID_ATTR_TRANSFORM_POS_Y, nVertByPos ) );
+
+ bModified = true;
+ }
+ }
+ else
+ {
+ if ( m_pHMap )
+ {
+ const SfxInt16Item& rHoriOrient =
+ rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT );
+ const SfxInt16Item& rHoriRelation =
+ rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION);
+ const SfxInt32Item& rHoriPosition =
+ rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION);
+
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
+ short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ short nRel = GetRelation(*m_xHoriToLB);
+ const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ if (
+ nAlign != rHoriOrient.GetValue() ||
+ nRel != rHoriRelation.GetValue() ||
+ (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
+ )
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
+ if(m_xHoriByMF->get_sensitive())
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
+ bModified = true;
+ }
+ }
+ if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
+ bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
+
+ if ( m_pVMap )
+ {
+ const SfxInt16Item& rVertOrient =
+ rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT);
+ const SfxInt16Item& rVertRelation =
+ rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION);
+ const SfxInt32Item& rVertPosition =
+ rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION);
+
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ short nRel = GetRelation(*m_xVertToLB);
+ // #i34055# - convert vertical position for
+ // as-character anchored objects
+ auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+ if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
+ {
+ nVertByPos *= -1;
+ }
+ if ( nAlign != rVertOrient.GetValue() ||
+ nRel != rVertRelation.GetValue() ||
+ ( m_xVertByMF->get_sensitive() &&
+ nVertByPos != rVertPosition.GetValue() ) )
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
+ if(m_xVertByMF->get_sensitive())
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
+ bModified = true;
+ }
+ }
+
+ // #i18732#
+ if (m_xFollowCB->get_state_changed_from_saved())
+ {
+ //Writer internal type - based on SfxBoolItem
+ const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
+ if(pItem)
+ {
+ std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
+ pFollow->SetValue(m_xFollowCB->get_active());
+ bModified |= nullptr != rSet->Put(std::move(pFollow));
+ }
+ }
+ }
+ }
+ if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
+ {
+ sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
+ rSet->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, nWidth ) );
+ rSet->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, nHeight ) );
+ //this item is required by SdrEditView::SetGeoAttrToMarked()
+ rSet->Put( SfxUInt16Item( SID_ATTR_TRANSFORM_SIZE_POINT, sal_uInt16(RectPoint::LT) ) );
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
+{
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
+ bool bInvalidateAnchor = false;
+ RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
+ if(pItem)
+ {
+ nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
+ switch(nAnchorType)
+ {
+ case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
+ case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
+ case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
+ case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
+ case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
+ default : bInvalidateAnchor = true;
+ }
+ m_xToPageRB->save_state();
+ m_xToParaRB->save_state();
+ m_xToCharRB->save_state();
+ m_xAsCharRB->save_state();
+ m_xToFrameRB->save_state();
+ }
+ if (bInvalidateAnchor)
+ {
+ m_xToPageRB->set_sensitive( false );
+ m_xToParaRB->set_sensitive( false );
+ m_xToCharRB->set_sensitive( false );
+ m_xAsCharRB->set_sensitive( false );
+ m_xToFrameRB->set_sensitive( false );
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
+ if (pItem)
+ {
+ bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xPositionCB->set_active(bProtected);
+ m_xSizeCB->set_sensitive(!bProtected);
+ }
+ else
+ {
+ m_xPositionCB->set_inconsistent(true);
+ }
+
+ m_xPositionCB->save_state();
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
+
+ if (pItem)
+ {
+ m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ }
+ else
+ m_xSizeCB->set_inconsistent(true);
+ m_xSizeCB->save_state();
+
+ pItem = GetItem( *rSet, SID_HTML_MODE );
+ if(pItem)
+ {
+ m_bHtmlMode =
+ (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
+ != 0;
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
+ if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
+ {
+ OUString sHLabel = m_xHoriFT->get_label();
+ m_xHoriFT->set_label(m_xVertFT->get_label());
+ m_xVertFT->set_label(sHLabel);
+ m_bIsVerticalFrame = true;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
+ if(pItem)
+ m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
+ pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
+ if(pItem)
+ {
+ const bool bFollowTextFlow =
+ static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xFollowCB->set_active(bFollowTextFlow);
+ }
+ m_xFollowCB->save_state();
+
+ if(m_bHtmlMode)
+ {
+ m_xHoriMirrorCB->hide();
+ m_xKeepRatioCB->set_sensitive(false);
+ // #i18732# - hide checkbox in HTML mode
+ m_xFollowCB->hide();
+ }
+ else
+ {
+ // #i18732# correct enable/disable of check box 'Mirror on..'
+ m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
+
+ // #i18732# - enable/disable check box 'Follow text flow'.
+ m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
+ m_xToCharRB->get_active());
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
+ sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
+
+ m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
+ sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
+ m_xHeightMF->save_value();
+ m_fWidthHeightRatio = double(nWidth) / double(nHeight);
+
+ if(m_bPositioningDisabled)
+ return;
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
+ if(pItem)
+ {
+ short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ m_nOldH = nHoriOrientation;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
+ if(pItem)
+ {
+ short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ m_nOldV = nVertOrientation;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
+ if(pItem)
+ {
+ m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
+ if(pItem)
+ {
+ m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
+ if(pItem)
+ m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ m_xHoriMirrorCB->save_state();
+
+ sal_Int32 nHoriPos = 0;
+ sal_Int32 nVertPos = 0;
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
+ if(pItem)
+ nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
+ if(pItem)
+ nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+
+ InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
+
+ m_xVertByMF->save_value();
+ m_xHoriByMF->save_value();
+ // #i18732#
+ m_xFollowCB->save_state();
+
+ RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
+}
+
+DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ {
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xPositionCB->get_active()));
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xSizeCB->get_active()));
+ FillItemSet( _pSet );
+ }
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
+{
+ if (nAnchorEnable & SvxAnchorIds::Fly)
+ m_xToFrameRB->show();
+ if (!(nAnchorEnable & SvxAnchorIds::Page))
+ m_xToPageRB->set_sensitive(false);
+}
+
+RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
+{
+ RndStdIds nRet = RndStdIds::UNKNOWN;
+ weld::RadioButton* pCheckedButton = nullptr;
+ if(m_xToParaRB->get_sensitive())
+ {
+ if(m_xToPageRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PAGE;
+ pCheckedButton = m_xToPageRB.get();
+ }
+ else if(m_xToParaRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PARA;
+ pCheckedButton = m_xToParaRB.get();
+ }
+ else if(m_xToCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_CHAR;
+ pCheckedButton = m_xToCharRB.get();
+ }
+ else if(m_xAsCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AS_CHAR;
+ pCheckedButton = m_xAsCharRB.get();
+ }
+ else if(m_xToFrameRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_FLY;
+ pCheckedButton = m_xToFrameRB.get();
+ }
+ }
+ if(pbHasChanged)
+ {
+ if(pCheckedButton)
+ *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
+ else
+ *pbHasChanged = false;
+ }
+ return nRet;
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::Toggleable&, void)
+{
+ RangeModifyHdl(m_xWidthMF->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
+{
+ if (m_bPositioningDisabled)
+ return;
+ SvxSwFrameValidation aVal;
+
+ aVal.nAnchorType = GetAnchorType();
+ aVal.bAutoHeight = false;
+ aVal.bMirror = m_xHoriMirrorCB->get_active();
+ // #i18732#
+ aVal.bFollowTextFlow = m_xFollowCB->get_active();
+
+ if ( m_pHMap )
+ {
+ // horizontal alignment
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
+ sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
+
+ aVal.nHoriOrient = static_cast<short>(nAlign);
+ aVal.nHRelOrient = static_cast<short>(nRel);
+ }
+ else
+ aVal.nHoriOrient = HoriOrientation::NONE;
+
+ if ( m_pVMap )
+ {
+ // vertical alignment
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ sal_uInt16 nRel = GetRelation(*m_xVertToLB);
+
+ aVal.nVertOrient = static_cast<short>(nAlign);
+ aVal.nVRelOrient = static_cast<short>(nRel);
+ }
+ else
+ aVal.nVertOrient = VertOrientation::NONE;
+
+ const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+
+ aVal.nHPos = nAtHorzPosVal;
+ aVal.nVPos = nAtVertPosVal;
+
+ sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
+ aVal.nWidth = nWidth;
+ aVal.nHeight = nHeight;
+
+ m_aValidateLink.Call(aVal);
+
+ // minimum width also for style
+ m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
+ m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
+
+ sal_Int32 nMaxWidth(aVal.nMaxWidth);
+ sal_Int32 nMaxHeight(aVal.nMaxHeight);
+
+ sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
+ m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
+
+ nTmp = m_xWidthMF->normalize(nMaxWidth);
+ m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
+
+ m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
+ m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
+ if ( aVal.nHPos != nAtHorzPosVal )
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
+
+ m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
+ m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
+ if ( aVal.nVPos != nAtVertPosVal )
+ m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::Toggleable&, void)
+{
+ m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
+
+ // #i18732# - enable check box 'Follow text flow' for anchor
+ // type to-paragraph' and to-character
+ m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
+
+ RndStdIds nId = GetAnchorType();
+
+ InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
+ RangeModifyHdl(m_xWidthMF->get_widget());
+
+ if(m_bHtmlMode)
+ {
+ PosHdl(*m_xHoriLB);
+ PosHdl(*m_xVertLB);
+ }
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::Toggleable&, void)
+{
+ RndStdIds nId = GetAnchorType();
+ InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
+}
+
+IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
+{
+ bool bHori = &rLB == m_xHoriToLB.get();
+
+ UpdateExample();
+
+ if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
+ {
+ if(bHori)
+ {
+ sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
+ if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(1);
+ }
+ else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ }
+ }
+ }
+ RangeModifyHdl(m_xWidthMF->get_widget());
+}
+
+IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
+{
+ bool bHori = &rLB == m_xHoriLB.get();
+ weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
+ weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
+ FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
+
+
+ sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
+ sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
+
+ if (bHori)
+ {
+ bool bEnable = HoriOrientation::NONE == nAlign;
+ m_xHoriByMF->set_sensitive( bEnable );
+ m_xHoriByFT->set_sensitive( bEnable );
+ }
+ else
+ {
+ bool bEnable = VertOrientation::NONE == nAlign;
+ m_xVertByMF->set_sensitive( bEnable );
+ m_xVertByFT->set_sensitive( bEnable );
+ }
+
+ RangeModifyHdl(m_xWidthMF->get_widget());
+
+ short nRel = 0;
+ if (rLB.get_active() != -1)
+ {
+ if (pRelLB->get_active() != -1)
+ nRel = weld::fromId<RelationMap*>(pRelLB->get_active_id())->nRelation;
+
+ FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
+ }
+ else
+ pRelLB->clear();
+
+ UpdateExample();
+
+ // special treatment for HTML-Mode with horz-vert-dependencies
+ if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
+ return;
+
+ bool bSet = false;
+ if(bHori)
+ {
+ // on the right only below is allowed - from the left only at the top
+ // from the left at the character -> below
+ if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
+ 0 == m_xVertLB->get_active())
+ {
+ if(RelOrientation::FRAME == nRel)
+ m_xVertLB->set_active(1);
+ else
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ if(bSet)
+ PosHdl(*m_xVertLB);
+ }
+ else
+ {
+ if(VertOrientation::TOP == nAlign)
+ {
+ if(1 == m_xHoriLB->get_active())
+ {
+ m_xHoriLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriToLB->set_active(1);
+ }
+ else if(VertOrientation::CHAR_BOTTOM == nAlign)
+ {
+ if(2 == m_xHoriLB->get_active())
+ {
+ m_xHoriLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriToLB->set_active(0) ;
+ }
+ if(bSet)
+ PosHdl(*m_xHoriLB);
+ }
+}
+
+IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
+{
+ auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
+ auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
+ if (m_xKeepRatioCB->get_active())
+ {
+ if ( &rEdit == m_xWidthMF.get() )
+ {
+ nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
+ m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
+ }
+ else if(&rEdit == m_xHeightMF.get())
+ {
+ nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
+ m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ }
+ }
+ m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
+ UpdateExample();
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::Toggleable&, void)
+{
+ if (m_xSizeCB->get_sensitive())
+ {
+ m_nProtectSizeState = m_xSizeCB->get_state();
+ }
+
+ m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
+ m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
+}
+
+short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
+{
+ short nRel = 0;
+ int nPos = rRelationLB.get_active();
+ if (nPos != -1)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rRelationLB.get_id(nPos));
+ nRel = pEntry->nRelation;
+ }
+
+ return nRel;
+}
+
+short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
+{
+ short nAlign = 0;
+
+ // #i22341# - special handling also for map <aVCharMap>,
+ // because it contains ambiguous items for alignment
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
+ pMap == aVCharMap )
+ {
+ if (rRelationLB.get_active() != -1)
+ {
+ LB nRel = weld::fromId<RelationMap*>(rRelationLB.get_active_id())->nLBRelation;
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+ SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (std::size_t i = 0; i < nMapCount; i++)
+ {
+ if (pMap[i].eStrId == eStrId)
+ {
+ LB nLBRelations = pMap[i].nLBRelations;
+ if (nLBRelations & nRel)
+ {
+ nAlign = pMap[i].nAlign;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (pMap)
+ nAlign = pMap[nMapPos].nAlign;
+
+ return nAlign;
+}
+
+sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
+{
+ sal_uInt16 nMapPos = 0;
+ int nLBSelPos = rAlignLB.get_active();
+
+ if (nLBSelPos != -1)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+ OUString sSelEntry(rAlignLB.get_active_text());
+
+ for (std::size_t i = 0; i < nMapCount; i++)
+ {
+ SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
+
+ OUString sEntry = SvxSwFramePosString::GetString(eResId);
+
+ if (sEntry == sSelEntry)
+ {
+ nMapPos = sal::static_int_cast< sal_uInt16 >(i);
+ break;
+ }
+ }
+ }
+ else
+ nMapPos = nLBSelPos;
+ }
+
+ return nMapPos;
+}
+
+void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
+ sal_uInt16 nH,
+ sal_uInt16 nHRel,
+ sal_uInt16 nV,
+ sal_uInt16 nVRel,
+ tools::Long nX,
+ tools::Long nY)
+{
+ int nPos = m_xVertLB->get_active();
+ if (nPos != -1 && m_pVMap)
+ {
+ m_nOldV = m_pVMap[nPos].nAlign;
+ nPos = m_xVertToLB->get_active();
+ if (nPos != -1)
+ m_nOldVRel = weld::fromId<RelationMap*>(m_xVertToLB->get_id(nPos))->nRelation;
+ }
+
+ nPos = m_xHoriLB->get_active();
+ if (nPos != -1 && m_pHMap)
+ {
+ m_nOldH = m_pHMap[nPos].nAlign;
+
+ nPos = m_xHoriToLB->get_active();
+ if (nPos != -1)
+ m_nOldHRel = weld::fromId<RelationMap*>(m_xHoriToLB->get_id(nPos))->nRelation;
+ }
+
+ bool bEnable = true;
+ if( m_bIsMultiSelection )
+ {
+ m_pVMap = aVMultiSelectionMap;
+ m_pHMap = aHMultiSelectionMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_PAGE)
+ {
+ m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
+ m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_FLY)
+ {
+ // #i18732# - own vertical alignment map for to frame
+ // anchored objects.
+ m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
+ m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_PARA)
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVParaHtmlMap;
+ m_pHMap = aHParaHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVParaMap;
+ m_pHMap = aHParaMap;
+ }
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_CHAR)
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVCharHtmlAbsMap;
+ m_pHMap = aHCharHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVCharMap;
+ m_pHMap = aHCharMap;
+ }
+ }
+ else if (nAnchor == RndStdIds::FLY_AS_CHAR)
+ {
+ m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
+ m_pHMap = nullptr;
+ bEnable = false;
+ }
+ m_xHoriLB->set_sensitive(bEnable);
+ m_xHoriFT->set_sensitive(bEnable);
+
+ // select current Pos
+ // horizontal
+ if ( nH == USHRT_MAX )
+ {
+ nH = m_nOldH;
+ nHRel = m_nOldHRel;
+ }
+ // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
+ sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
+ FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
+
+ // vertical
+ if ( nV == USHRT_MAX )
+ {
+ nV = m_nOldV;
+ nVRel = m_nOldVRel;
+ }
+ // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
+ nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
+ FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
+
+ // Edits init
+ bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
+ if (!bEnable)
+ {
+ m_xHoriByMF->set_value(0, FieldUnit::TWIP);
+ }
+ else if(m_bIsMultiSelection)
+ {
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
+ }
+ else
+ {
+ if (nX != LONG_MAX)
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
+ }
+ m_xHoriByFT->set_sensitive(bEnable);
+ m_xHoriByMF->set_sensitive(bEnable);
+
+ bEnable = nV == VertOrientation::NONE;
+ if ( !bEnable )
+ {
+ m_xVertByMF->set_value( 0, FieldUnit::TWIP );
+ }
+ else if(m_bIsMultiSelection)
+ {
+ m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
+ }
+ else
+ {
+ if (nAnchor == RndStdIds::FLY_AS_CHAR)
+ {
+ if ( nY == LONG_MAX )
+ nY = 0;
+ else
+ nY *= -1;
+ }
+ if ( nY != LONG_MAX )
+ m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
+ }
+ m_xVertByFT->set_sensitive( bEnable );
+ m_xVertByMF->set_sensitive( bEnable );
+ UpdateExample();
+}
+
+void SvxSwPosSizeTabPage::UpdateExample()
+{
+ int nPos = m_xHoriLB->get_active();
+ if (m_pHMap && nPos != -1)
+ {
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
+ short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ short nRel = GetRelation(*m_xHoriToLB);
+
+ m_aExampleWN.SetHAlign(nAlign);
+ m_aExampleWN.SetHoriRel(nRel);
+ }
+
+ nPos = m_xVertLB->get_active();
+ if (m_pVMap && nPos != -1)
+ {
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ sal_uInt16 nRel = GetRelation(*m_xVertToLB);
+
+ m_aExampleWN.SetVAlign(nAlign);
+ m_aExampleWN.SetVertRel(nRel);
+ }
+
+ // Size
+ auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+ m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
+
+ m_aExampleWN.SetAnchor( GetAnchorType() );
+ m_aExampleWN.Invalidate();
+}
+
+void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
+ sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
+{
+ OUString sSelEntry;
+ LB nLBRelations = LB::NONE;
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+
+ rLB.clear();
+
+ if (nMapPos < nMapCount)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ OUString sOldEntry(rLB.get_active_text());
+ SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
+ {
+ if (pMap[_nMapPos].eStrId == eStrId)
+ {
+ nLBRelations = pMap[_nMapPos].nLBRelations;
+ for (size_t nRelPos = 0; nRelPos < std::size(aAsCharRelationMap); nRelPos++)
+ {
+ if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
+ {
+ SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
+
+ sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ rLB.append(weld::toId(&aAsCharRelationMap[nRelPos]), sEntry);
+ if (pMap[_nMapPos].nAlign == nAlign)
+ sSelEntry = sEntry;
+ break;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ rLB.set_active_text(sSelEntry);
+ else
+ {
+ rLB.set_active_text(sOldEntry);
+ if (rLB.get_active() == -1)
+ {
+ for (int i = 0; i < rLB.get_count(); i++)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rLB.get_id(i));
+ if (pEntry->nLBRelation == LB::RelChar) // Default
+ {
+ rLB.set_active(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // #i22341# - special handling for map <aVCharMap>,
+ // because its ambiguous in its <eStrId>/<eMirrorStrId>.
+ if ( pMap == aVCharMap )
+ {
+ nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
+ ( m_xHoriMirrorCB->get_active()
+ ? pMap[nMapPos].eMirrorStrId
+ : pMap[nMapPos].eStrId ),
+ m_xHoriMirrorCB->get_active() );
+ }
+ else
+ {
+ nLBRelations = pMap[nMapPos].nLBRelations;
+ }
+
+ for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
+ {
+ if (nLBRelations & static_cast<LB>(nBit))
+ {
+ for (size_t nRelPos = 0; nRelPos < std::size(aRelationMap); nRelPos++)
+ {
+ if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
+ {
+ SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
+ sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ rLB.append(weld::toId(&aRelationMap[nRelPos]), sEntry);
+ if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
+ sSelEntry = sEntry;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ rLB.set_active_text(sSelEntry);
+ else
+ {
+ // Probably anchor change. So look for a similar relation.
+ switch (nRel)
+ {
+ case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
+ case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
+ case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
+ case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
+ case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
+ case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
+ case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
+ case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
+
+ default:
+ if (rLB.get_count())
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rLB.get_id(rLB.get_count() - 1));
+ nRel = pEntry->nRelation;
+ }
+ break;
+ }
+
+ for (int i = 0; i < rLB.get_count(); ++i)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(rLB.get_id(i));
+ if (pEntry->nRelation == nRel)
+ {
+ rLB.set_active(i);
+ break;
+ }
+ }
+
+ if (rLB.get_active() == -1)
+ rLB.set_active(0);
+ }
+ }
+ }
+
+ rLB.set_sensitive(rLB.get_count() != 0);
+ rFT.set_sensitive(rLB.get_count() != 0);
+
+ RelHdl(rLB);
+}
+
+sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
+ sal_uInt16 _nAlign,
+ const sal_uInt16 _nRel,
+ weld::ComboBox& _rLB)
+{
+ OUString sSelEntry, sOldEntry;
+ sOldEntry = _rLB.get_active_text();
+
+ _rLB.clear();
+
+ // #i22341# - determine all possible listbox relations for
+ // given relation for map <aVCharMap>
+ const LB nLBRelations = (_pMap != aVCharMap)
+ ? LB::NONE
+ : ::lcl_GetLBRelationsForRelations( _nRel );
+
+ // fill listbox
+ std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
+ for (std::size_t i = 0; _pMap && i < nCount; ++i)
+ {
+ SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
+ eStrId = lcl_ChangeResIdToVerticalOrRTL(eStrId, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry(SvxSwFramePosString::GetString(eStrId));
+ if (_rLB.find_text(sEntry) == -1)
+ {
+ // don't insert duplicate entries at character wrapped borders
+ _rLB.append_text(sEntry);
+ }
+ // #i22341# - add condition to handle map <aVCharMap>
+ // that is ambiguous in the alignment.
+ if ( _pMap[i].nAlign == _nAlign &&
+ ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
+ {
+ sSelEntry = sEntry;
+ }
+ }
+
+ _rLB.set_active_text(sSelEntry);
+ if (_rLB.get_active() == -1)
+ _rLB.set_active_text(sOldEntry);
+
+ if (_rLB.get_active() == -1)
+ _rLB.set_active(0);
+
+ PosHdl(_rLB);
+
+ return GetMapPos(_pMap, _rLB);
+}
+
+void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
+{
+ m_pSdrView = pSdrView;
+ if(!m_pSdrView)
+ {
+ OSL_FAIL("No SdrView* set");
+ return;
+ }
+
+ // setting of the rectangle and the working area
+ m_aRect = m_pSdrView->GetAllMarkedRect();
+ m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
+
+ // get WorkArea
+ m_aWorkArea = m_pSdrView->GetWorkArea();
+
+ // consider anchor position (for Writer)
+ const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() > 0 )
+ {
+ const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ m_aAnchorPos = pObj->GetAnchorPos();
+
+ if( m_aAnchorPos != Point(0,0) ) // -> Writer
+ {
+ for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
+ {
+ pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
+ if( m_aAnchorPos != pObj->GetAnchorPos() )
+ {
+ // different anchor positions -> disable positioning
+ m_xPosFrame->set_sensitive(false);
+ m_bPositioningDisabled = true;
+ return;
+ }
+ }
+ }
+ Point aPt = m_aAnchorPos * -1;
+ Point aPt2 = aPt;
+
+ aPt += m_aWorkArea.TopLeft();
+ m_aWorkArea.SetPos( aPt );
+
+ aPt2 += m_aRect.TopLeft();
+ m_aRect.SetPos( aPt2 );
+ }
+
+ // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
+ if( rMarkList.GetMarkCount() != 1 )
+ m_bIsMultiSelection = true;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
+ if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
+ ( eKind==SdrObjKind::Text || eKind==SdrObjKind::TitleText || eKind==SdrObjKind::OutlineText) &&
+ pObj->HasText() )
+ {
+ OSL_FAIL("AutoWidth/AutoHeight should be enabled");
+ }
+ }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx
new file mode 100644
index 000000000..d03199c7b
--- /dev/null
+++ b/cui/source/tabpages/tabarea.cxx
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/objsh.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svx/svxids.hrc>
+
+#include <svx/xtable.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/drawitem.hxx>
+#include <cuitabarea.hxx>
+
+SvxAreaTabDialog::SvxAreaTabDialog
+(
+ weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow,
+ bool bSlideBackground
+)
+ : SfxTabDialogController(pParent, "cui/ui/areadialog.ui", "AreaDialog", pAttr)
+ , mpDrawModel ( pModel ),
+ mpColorList ( pModel->GetColorList() ),
+ mpNewColorList ( pModel->GetColorList() ),
+ mpGradientList ( pModel->GetGradientList() ),
+ mpNewGradientList ( pModel->GetGradientList() ),
+ mpHatchingList ( pModel->GetHatchList() ),
+ mpNewHatchingList ( pModel->GetHatchList() ),
+ mpBitmapList ( pModel->GetBitmapList() ),
+ mpNewBitmapList ( pModel->GetBitmapList() ),
+ mpPatternList ( pModel->GetPatternList() ),
+ mpNewPatternList ( pModel->GetPatternList() ),
+
+ mnColorListState ( ChangeType::NONE ),
+ mnBitmapListState ( ChangeType::NONE ),
+ mnPatternListState ( ChangeType::NONE ),
+ mnGradientListState ( ChangeType::NONE ),
+ mnHatchingListState ( ChangeType::NONE )
+{
+ if (bSlideBackground)
+ AddTabPage("RID_SVXPAGE_AREA", SvxAreaTabPage::CreateWithSlideBackground, nullptr);
+ else
+ AddTabPage("RID_SVXPAGE_AREA", SvxAreaTabPage::Create, nullptr);
+
+ if (bShadow)
+ {
+ AddTabPage("RID_SVXPAGE_SHADOW", SvxShadowTabPage::Create, nullptr);
+ }
+ else
+ {
+ RemoveTabPage( "RID_SVXPAGE_SHADOW" );
+ }
+
+ AddTabPage( "RID_SVXPAGE_TRANSPARENCE", SvxTransparenceTabPage::Create, nullptr);
+
+ weld::Button& rBtnCancel = GetCancelButton();
+ rBtnCancel.connect_clicked(LINK(this, SvxAreaTabDialog, CancelHdlImpl));
+}
+
+void SvxAreaTabDialog::SavePalettes()
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if( mpNewColorList != mpDrawModel->GetColorList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewColorList.get()) );
+ SvxColorListItem aColorListItem( mpNewColorList, SID_COLOR_TABLE );
+ if ( pShell )
+ pShell->PutItem( aColorListItem );
+ else
+ mpDrawModel->GetItemPool().Put(aColorListItem,SID_COLOR_TABLE);
+ mpColorList = mpDrawModel->GetColorList();
+ }
+ if( mpNewGradientList != mpDrawModel->GetGradientList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewGradientList.get()) );
+ SvxGradientListItem aItem( mpNewGradientList, SID_GRADIENT_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_GRADIENT_LIST);
+ mpGradientList = mpDrawModel->GetGradientList();
+ }
+ if( mpNewHatchingList != mpDrawModel->GetHatchList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewHatchingList.get()) );
+ SvxHatchListItem aItem( mpNewHatchingList, SID_HATCH_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_HATCH_LIST);
+ mpHatchingList = mpDrawModel->GetHatchList();
+ }
+ if( mpNewBitmapList != mpDrawModel->GetBitmapList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewBitmapList.get()) );
+ SvxBitmapListItem aItem( mpNewBitmapList, SID_BITMAP_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_BITMAP_LIST);
+ mpBitmapList = mpDrawModel->GetBitmapList();
+ }
+ if( mpNewPatternList != mpDrawModel->GetPatternList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewPatternList.get()) );
+ SvxPatternListItem aItem( mpNewPatternList, SID_PATTERN_LIST );
+ if( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_PATTERN_LIST);
+ mpPatternList = mpDrawModel->GetPatternList();
+ }
+
+ // save the tables when they have been changed
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aPath;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aPath = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ if( mnHatchingListState & ChangeType::MODIFIED )
+ {
+ mpHatchingList->SetPath( aPath );
+ mpHatchingList->Save();
+
+ SvxHatchListItem aItem( mpHatchingList, SID_HATCH_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+
+ if( mnBitmapListState & ChangeType::MODIFIED )
+ {
+ mpBitmapList->SetPath( aPath );
+ mpBitmapList->Save();
+
+ SvxBitmapListItem aItem( mpBitmapList, SID_BITMAP_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+ }
+
+ if( mnPatternListState & ChangeType::MODIFIED )
+ {
+ mpPatternList->SetPath( aPath );
+ mpPatternList->Save();
+
+ SvxPatternListItem aItem( mpPatternList, SID_PATTERN_LIST );
+ // ToolBoxControls are informed:
+ if( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+
+ if( mnGradientListState & ChangeType::MODIFIED )
+ {
+ mpGradientList->SetPath( aPath );
+ mpGradientList->Save();
+
+ SvxGradientListItem aItem( mpGradientList, SID_GRADIENT_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+ }
+
+ if (mnColorListState & ChangeType::MODIFIED && mpColorList.is())
+ {
+ SvxColorListItem aItem( mpColorList, SID_COLOR_TABLE );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+ }
+}
+
+short SvxAreaTabDialog::Ok()
+{
+ SavePalettes();
+ // RET_OK is returned, if at least one
+ // TabPage returns sal_True in FillItemSet().
+ // This happens by default at the moment.
+ return SfxTabDialogController::Ok();
+}
+
+IMPL_LINK_NOARG(SvxAreaTabDialog, CancelHdlImpl, weld::Button&, void)
+{
+ SavePalettes();
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SvxAreaTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_AREA")
+ {
+ static_cast<SvxAreaTabPage&>(rPage).SetColorList( mpColorList );
+ static_cast<SvxAreaTabPage&>(rPage).SetGradientList( mpGradientList );
+ static_cast<SvxAreaTabPage&>(rPage).SetHatchingList( mpHatchingList );
+ static_cast<SvxAreaTabPage&>(rPage).SetBitmapList( mpBitmapList );
+ static_cast<SvxAreaTabPage&>(rPage).SetPatternList( mpPatternList );
+ static_cast<SvxAreaTabPage&>(rPage).SetGrdChgd( &mnGradientListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetHtchChgd( &mnHatchingListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetBmpChgd( &mnBitmapListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetPtrnChgd( &mnPatternListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_SHADOW")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( mpColorList );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_TRANSPARENCE")
+ {
+ static_cast<SvxTransparenceTabPage&>(rPage).SetPageType( PageType::Area );
+ static_cast<SvxTransparenceTabPage&>(rPage).SetDlgType( 0 );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabline.cxx b/cui/source/tabpages/tabline.cxx
new file mode 100644
index 000000000..1cf548850
--- /dev/null
+++ b/cui/source/tabpages/tabline.cxx
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/pathoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <cuitabarea.hxx>
+#include <cuitabline.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+
+SvxLineTabDialog::SvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel, const SdrObject* pSdrObj, bool bHasObj)
+ : SfxTabDialogController(pParent, "cui/ui/linedialog.ui", "LineDialog", pAttr)
+ , pDrawModel(pModel)
+ , pObj(pSdrObj)
+ , pColorList(pModel->GetColorList())
+ , mpNewColorList(pModel->GetColorList())
+ , pDashList(pModel->GetDashList())
+ , pNewDashList(pModel->GetDashList())
+ , pLineEndList(pModel->GetLineEndList())
+ , pNewLineEndList(pModel->GetLineEndList())
+ , bObjSelected(bHasObj)
+ , nLineEndListState(ChangeType::NONE)
+ , nDashListState(ChangeType::NONE)
+ , mnColorListState(ChangeType::NONE)
+ , nPageType(PageType::Area) // We use it here primarily to get the right attributes with FillItemSet
+ , nPosDashLb(0)
+ , nPosLineEndLb(0)
+{
+ bool bLineOnly = false;
+ if( pObj && pObj->GetObjInventor() == SdrInventor::Default )
+ {
+ switch( pObj->GetObjIdentifier() )
+ {
+ case SdrObjKind::Line:
+ case SdrObjKind::PolyLine:
+ case SdrObjKind::PathLine:
+ case SdrObjKind::FreehandLine:
+ case SdrObjKind::Measure:
+ case SdrObjKind::Edge:
+ bLineOnly = true;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ AddTabPage("RID_SVXPAGE_LINE", SvxLineTabPage::Create, nullptr);
+ if( bLineOnly )
+ AddTabPage("RID_SVXPAGE_SHADOW", SvxShadowTabPage::Create, nullptr);
+ else
+ RemoveTabPage( "RID_SVXPAGE_SHADOW" );
+
+ AddTabPage("RID_SVXPAGE_LINE_DEF", SvxLineDefTabPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_LINEEND_DEF", SvxLineEndDefTabPage::Create, nullptr);
+
+ weld::Button& rBtnCancel = GetCancelButton();
+ rBtnCancel.connect_clicked(LINK(this, SvxLineTabDialog, CancelHdlImpl));
+}
+
+void SvxLineTabDialog::SavePalettes()
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if( mpNewColorList != pDrawModel->GetColorList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewColorList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxColorListItem( mpNewColorList, SID_COLOR_TABLE ) );
+ pColorList = pDrawModel->GetColorList();
+ }
+ if( pNewDashList != pDrawModel->GetDashList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(pNewDashList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxDashListItem( pNewDashList, SID_DASH_LIST ) );
+ pDashList = pDrawModel->GetDashList();
+ }
+ if( pNewLineEndList != pDrawModel->GetLineEndList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(pNewLineEndList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxLineEndListItem( pNewLineEndList, SID_LINEEND_LIST ) );
+ pLineEndList = pDrawModel->GetLineEndList();
+ }
+
+ // Save the tables when they have been changed
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aPath;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aPath = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ if( nDashListState & ChangeType::MODIFIED )
+ {
+ pDashList->SetPath( aPath );
+ pDashList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxDashListItem( pDashList, SID_DASH_LIST ) );
+ }
+
+ if( nLineEndListState & ChangeType::MODIFIED )
+ {
+ pLineEndList->SetPath( aPath );
+ pLineEndList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxLineEndListItem( pLineEndList, SID_LINEEND_LIST ) );
+ }
+
+ if( mnColorListState & ChangeType::MODIFIED )
+ {
+ pColorList->SetPath( aPath );
+ pColorList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxColorListItem( pColorList, SID_COLOR_TABLE ) );
+ }
+}
+
+short SvxLineTabDialog::Ok()
+{
+ SavePalettes();
+
+ // We return RET_OK if at least one TabPage in FillItemSet() returns sal_True.
+ // We do this by default at the moment.
+ return SfxTabDialogController::Ok();
+}
+
+IMPL_LINK_NOARG(SvxLineTabDialog, CancelHdlImpl, weld::Button&, void)
+{
+ SavePalettes();
+
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SvxLineTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_LINE")
+ {
+ static_cast<SvxLineTabPage&>(rPage).SetDashList( pDashList );
+ static_cast<SvxLineTabPage&>(rPage).SetLineEndList( pLineEndList );
+ static_cast<SvxLineTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineTabPage&>(rPage).SetPageType( nPageType );
+ static_cast<SvxLineTabPage&>(rPage).SetPosDashLb( &nPosDashLb );
+ static_cast<SvxLineTabPage&>(rPage).SetPosLineEndLb( &nPosLineEndLb );
+ static_cast<SvxLineTabPage&>(rPage).SetDashChgd( &nDashListState );
+ static_cast<SvxLineTabPage&>(rPage).SetLineEndChgd( &nLineEndListState );
+ static_cast<SvxLineTabPage&>(rPage).SetObjSelected( bObjSelected );
+ static_cast<SvxLineTabPage&>(rPage).Construct();
+ static_cast<SvxLineTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_LINE_DEF")
+ {
+ static_cast<SvxLineDefTabPage&>(rPage).SetDashList( pDashList );
+ static_cast<SvxLineDefTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineDefTabPage&>(rPage).SetPageType( &nPageType );
+ static_cast<SvxLineDefTabPage&>(rPage).SetPosDashLb( &nPosDashLb );
+ static_cast<SvxLineDefTabPage&>(rPage).SetDashChgd( &nDashListState );
+ static_cast<SvxLineDefTabPage&>(rPage).Construct();
+ }
+ else if (rId == "RID_SVXPAGE_LINEEND_DEF")
+ {
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetLineEndList( pLineEndList );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPolyObj( pObj );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPageType( &nPageType );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPosLineEndLb( &nPosLineEndLb );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetLineEndChgd( &nLineEndListState );
+ static_cast<SvxLineEndDefTabPage&>(rPage).Construct();
+ }
+ else if (rId == "RID_SVXPAGE_SHADOW")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( pColorList );
+ static_cast<SvxShadowTabPage&>(rPage).SetPageType( nPageType );
+ static_cast<SvxShadowTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabstpge.cxx b/cui/source/tabpages/tabstpge.cxx
new file mode 100644
index 000000000..b3a1745c2
--- /dev/null
+++ b/cui/source/tabpages/tabstpge.cxx
@@ -0,0 +1,663 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svtools/ruler.hxx>
+#include <svtools/unitconv.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/lrspitem.hxx>
+#include <tabstpge.hxx>
+#include <svx/dlgutil.hxx>
+#include <svl/cjkoptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <svl/intitem.hxx>
+
+constexpr FieldUnit eDefUnit = FieldUnit::MM_100TH;
+
+const WhichRangesContainer SvxTabulatorTabPage::pRanges(
+ svl::Items<SID_ATTR_TABSTOP, SID_ATTR_TABSTOP_OFFSET>);
+
+static void FillUpWithDefTabs_Impl( tools::Long nDefDist, SvxTabStopItem& rTabs )
+{
+ if( rTabs.Count() )
+ return;
+ {
+ SvxTabStop aSwTabStop( nDefDist, SvxTabAdjust::Default );
+ rTabs.Insert( aSwTabStop );
+ }
+}
+
+void TabWin_Impl::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ // Paint tabulators
+ Point aPoint;
+ Size aSize(GetOutputSizePixel());
+ aPoint.setX( aSize.Width() / 2 );
+ aPoint.setY( aSize.Height() / 2 );
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
+ rRenderContext.SetFillColor(rStyleSettings.GetDialogColor());
+ rRenderContext.DrawRect(tools::Rectangle(Point(0,0), rRenderContext.GetOutputSize()));
+ Ruler::DrawTab(rRenderContext, rStyleSettings.GetDialogTextColor(), aPoint, nTabStyle);
+}
+
+SvxTabulatorTabPage::SvxTabulatorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/paratabspage.ui", "ParagraphTabsPage", &rAttr)
+ , aCurrentTab(0)
+ , aNewTabs(std::make_unique<SvxTabStopItem>(0, 0, SvxTabAdjust::Left, GetWhich(SID_ATTR_TABSTOP)))
+ , nDefDist(0)
+ , m_xTabSpin(m_xBuilder->weld_metric_spin_button("SP_TABPOS", FieldUnit::CM))
+ , m_xTabBox(m_xBuilder->weld_entry_tree_view("tabgrid", "ED_TABPOS", "LB_TABPOS"))
+ , m_xCenterTab(m_xBuilder->weld_radio_button("radiobuttonBTN_TABTYPE_CENTER"))
+ , m_xDezTab(m_xBuilder->weld_radio_button("radiobuttonBTN_TABTYPE_DECIMAL"))
+ , m_xDezChar(m_xBuilder->weld_entry("entryED_TABTYPE_DECCHAR"))
+ , m_xDezCharLabel(m_xBuilder->weld_label("labelFT_TABTYPE_DECCHAR"))
+ // lower radio buttons
+ , m_xNoFillChar(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_NO"))
+ , m_xFillPoints(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_POINTS"))
+ , m_xFillDashLine(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_DASHLINE"))
+ , m_xFillSolidLine(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_UNDERSCORE"))
+ , m_xFillSpecial(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_OTHER"))
+ , m_xFillChar(m_xBuilder->weld_entry("entryED_FILLCHAR_OTHER"))
+ // button bar
+ , m_xNewBtn(m_xBuilder->weld_button("buttonBTN_NEW"))
+ , m_xDelAllBtn(m_xBuilder->weld_button("buttonBTN_DELALL"))
+ , m_xDelBtn(m_xBuilder->weld_button("buttonBTN_DEL"))
+ , m_xTypeFrame(m_xBuilder->weld_container("frameFL_TABTYPE"))
+ , m_xFillFrame(m_xBuilder->weld_container("frameFL_FILLCHAR"))
+ // the tab images
+ , m_xLeftWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABLEFT", m_aLeftWin))
+ , m_xRightWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABRIGHT", m_aRightWin))
+ , m_xCenterWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABCENTER", m_aCenterWin))
+ , m_xDezWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABDECIMAL", m_aDezWin))
+{
+ m_aLeftWin.SetTabStyle(sal_uInt16(RULER_TAB_LEFT|WB_HORZ));
+ m_aRightWin.SetTabStyle(sal_uInt16(RULER_TAB_RIGHT|WB_HORZ));
+ m_aCenterWin.SetTabStyle(sal_uInt16(RULER_TAB_CENTER|WB_HORZ));
+ m_aDezWin.SetTabStyle(sal_uInt16(RULER_TAB_DECIMAL|WB_HORZ));
+ //upper radiobuttons
+ m_xLeftTab = m_xBuilder->weld_radio_button(SvtCJKOptions::IsAsianTypographyEnabled() ? "radiobuttonST_LEFTTAB_ASIAN" : "radiobuttonBTN_TABTYPE_LEFT");
+ m_xRightTab = m_xBuilder->weld_radio_button(SvtCJKOptions::IsAsianTypographyEnabled() ? "radiobuttonST_RIGHTTAB_ASIAN" : "radiobuttonBTN_TABTYPE_RIGHT");
+ m_xLeftTab->show();
+ m_xRightTab->show();
+
+ // This page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // Set metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rAttr );
+ SetFieldUnit(*m_xTabSpin, eFUnit);
+
+ // Initialize buttons
+ m_xNewBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, NewHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, DelHdl_Impl));
+ m_xDelAllBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, DelAllHdl_Impl));
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, SvxTabulatorTabPage, TabTypeCheckHdl_Impl);
+ m_xLeftTab->connect_toggled(aLink);
+ m_xRightTab->connect_toggled(aLink);
+ m_xDezTab->connect_toggled(aLink);
+ m_xCenterTab->connect_toggled(aLink);
+
+ m_xDezChar->connect_focus_out(LINK(this, SvxTabulatorTabPage, GetDezCharHdl_Impl));
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+
+ aLink = LINK(this, SvxTabulatorTabPage, FillTypeCheckHdl_Impl);
+ m_xNoFillChar->connect_toggled(aLink);
+ m_xFillPoints->connect_toggled(aLink);
+ m_xFillDashLine->connect_toggled(aLink);
+ m_xFillSolidLine->connect_toggled(aLink);
+ m_xFillSpecial->connect_toggled(aLink);
+ m_xFillChar->connect_focus_out(LINK(this, SvxTabulatorTabPage, GetFillCharHdl_Impl));
+ m_xFillChar->set_sensitive(false);
+
+ m_xTabBox->connect_row_activated(LINK(this, SvxTabulatorTabPage, SelectHdl_Impl));
+ m_xTabBox->connect_changed(LINK(this, SvxTabulatorTabPage, ModifyHdl_Impl));
+ m_xTabBox->connect_focus_out(LINK(this, SvxTabulatorTabPage, ReformatHdl_Impl));
+
+ // Get the default decimal char from the system
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aCurrentTab.GetDecimal() = rLocaleWrapper.getNumDecimalSep()[0];
+}
+
+SvxTabulatorTabPage::~SvxTabulatorTabPage()
+{
+ m_xDezWin.reset();
+ m_xCenterWin.reset();
+ m_xRightWin.reset();
+ m_xLeftWin.reset();
+ m_xFillChar.reset();
+ m_xDezChar.reset();
+ m_xTabBox.reset();
+}
+
+bool SvxTabulatorTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ bool bModified = false;
+
+ // Put the controls' values in here
+ if (m_xNewBtn->get_sensitive())
+ NewHdl_Impl(nullptr);
+
+ // Call the LoseFocus-Handler first
+ GetDezCharHdl_Impl(*m_xDezChar);
+ GetFillCharHdl_Impl(*m_xFillChar);
+
+ FillUpWithDefTabs_Impl(nDefDist, *aNewTabs);
+ SfxItemPool* pPool = rSet->GetPool();
+ MapUnit eUnit = pPool->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+ const SfxPoolItem* pOld = GetOldItem(*rSet, SID_ATTR_TABSTOP);
+
+ if (MapUnit::Map100thMM != eUnit)
+ {
+ // If the ItemSet contains a LRSpaceItem with negative first line indent,
+ // the TabStopItem needs to have a DefTab at position 0.
+ const SfxPoolItem* pLRSpace;
+ // If not in the new set, then maybe in the old one
+ if (SfxItemState::SET != rSet->GetItemState(GetWhich(SID_ATTR_LRSPACE), true, &pLRSpace))
+ pLRSpace = GetOldItem(*rSet, SID_ATTR_LRSPACE);
+
+ if (pLRSpace && static_cast<const SvxLRSpaceItem*>(pLRSpace)->GetTextFirstLineOffset() < 0)
+ {
+ SvxTabStop aNull(0, SvxTabAdjust::Default);
+ aNewTabs->Insert(aNull);
+ }
+
+ std::unique_ptr<SvxTabStopItem> aTmp(aNewTabs->Clone());
+ aTmp->Remove(0, aTmp->Count());
+
+ for (sal_uInt16 i = 0; i < aNewTabs->Count(); ++i)
+ {
+ SvxTabStop aTmpStop = (*aNewTabs)[i];
+ aTmpStop.GetTabPos() = OutputDevice::LogicToLogic(aTmpStop.GetTabPos(), MapUnit::Map100thMM, eUnit);
+ aTmp->Insert(aTmpStop);
+ }
+
+ if (!pOld || *static_cast<const SvxTabStopItem*>(pOld) != *aTmp)
+ {
+ rSet->Put(std::move(aTmp));
+ bModified = true;
+ }
+ }
+ else if (!pOld || *static_cast<const SvxTabStopItem*>(pOld) != *aNewTabs)
+ {
+ rSet->Put(*aNewTabs);
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+std::unique_ptr<SfxTabPage> SvxTabulatorTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxTabulatorTabPage>(pPage, pController, *rSet);
+}
+
+void SvxTabulatorTabPage::Reset(const SfxItemSet* rSet)
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ MapUnit eUnit = pPool->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+
+ // Current tabs
+ const SfxPoolItem* pItem = GetItem(*rSet, SID_ATTR_TABSTOP);
+
+ if (pItem)
+ {
+ if (MapUnit::Map100thMM != eUnit)
+ {
+ std::unique_ptr<SvxTabStopItem> aTmp(static_cast<SvxTabStopItem*>(pItem->Clone()));
+ aNewTabs->Remove(0, aNewTabs->Count());
+
+ for (sal_uInt16 i = 0; i < aTmp->Count(); ++i)
+ {
+ SvxTabStop aTmpStop = (*aTmp)[i];
+ aTmpStop.GetTabPos() = OutputDevice::LogicToLogic(aTmpStop.GetTabPos(), eUnit, MapUnit::Map100thMM);
+ aNewTabs->Insert(aTmpStop);
+ }
+ }
+ else
+ {
+ aNewTabs.reset(static_cast<SvxTabStopItem*>(pItem->Clone()));
+ }
+ }
+ else
+ {
+ aNewTabs->Remove(0, aNewTabs->Count());
+ }
+
+ // Default tab distance
+ nDefDist = SVX_TAB_DEFDIST;
+ pItem = GetItem(*rSet, SID_ATTR_TABSTOP_DEFAULTS);
+
+ if (pItem)
+ nDefDist = OutputDevice::LogicToLogic(tools::Long(static_cast<const SfxUInt16Item*>(pItem)->GetValue()), eUnit, MapUnit::Map100thMM);
+
+ // Tab pos currently selected
+ sal_uInt16 nTabPos = 0;
+ pItem = GetItem(*rSet, SID_ATTR_TABSTOP_POS);
+
+ if (pItem)
+ nTabPos = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+
+ InitTabPos_Impl(nTabPos);
+}
+
+void SvxTabulatorTabPage::DisableControls(const TabulatorDisableFlags nFlag)
+{
+ if (TabulatorDisableFlags::TypeLeft & nFlag)
+ {
+ m_xLeftTab->set_sensitive(false);
+ m_xLeftWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeRight & nFlag)
+ {
+ m_xRightTab->set_sensitive(false);
+ m_xRightWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeCenter & nFlag)
+ {
+ m_xCenterTab->set_sensitive(false);
+ m_xCenterWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeDecimal & nFlag)
+ {
+ m_xDezTab->set_sensitive(false);
+ m_xDezWin->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+ m_xDezChar->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeMask & nFlag)
+ m_xTypeFrame->set_sensitive(false);
+ if (TabulatorDisableFlags::FillNone & nFlag)
+ m_xNoFillChar->set_sensitive(false);
+ if (TabulatorDisableFlags::FillPoint & nFlag)
+ m_xFillPoints->set_sensitive(false);
+ if (TabulatorDisableFlags::FillDashLine & nFlag)
+ m_xFillDashLine->set_sensitive(false);
+ if (TabulatorDisableFlags::FillSolidLine & nFlag)
+ m_xFillSolidLine->set_sensitive(false);
+ if (TabulatorDisableFlags::FillSpecial & nFlag)
+ {
+ m_xFillSpecial->set_sensitive(false);
+ m_xFillChar->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::FillMask & nFlag)
+ m_xFillFrame->set_sensitive(false);
+}
+
+DeactivateRC SvxTabulatorTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxTabulatorTabPage::InitTabPos_Impl( sal_uInt16 nTabPos )
+{
+ m_xTabBox->clear();
+
+ tools::Long nOffset = 0;
+ if (const SfxInt32Item* pOffSetItem = GetItemSet().GetItemIfSet(SID_ATTR_TABSTOP_OFFSET))
+ {
+ nOffset = pOffSetItem->GetValue();
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+ nOffset = OutputDevice::LogicToLogic(nOffset, eUnit, MapUnit::Map100thMM);
+ }
+
+ // Correct current TabPos and default tabs
+ for ( sal_uInt16 i = 0; i < aNewTabs->Count(); i++ )
+ {
+ if ( (*aNewTabs)[i].GetAdjustment() != SvxTabAdjust::Default )
+ {
+ m_xTabSpin->set_value(m_xTabSpin->normalize((*aNewTabs)[i].GetTabPos() + nOffset ), eDefUnit);
+ m_xTabBox->append_text(m_xTabSpin->get_text());
+ }
+ else
+ {
+ aNewTabs->Remove( i-- );
+ }
+ }
+
+ // Select current tabulator
+ const sal_uInt16 nSize = aNewTabs->Count();
+
+ if ( nTabPos >= nSize )
+ nTabPos = 0;
+
+ // Switch off all RadioButtons for a start
+ m_xLeftTab->set_active(true);
+ m_xNoFillChar->set_active(true);
+
+ if (m_xTabBox->get_count() > 0)
+ {
+ m_xTabBox->set_active(nTabPos);
+ aCurrentTab = (*aNewTabs)[nTabPos];
+
+ SetFillAndTabType_Impl();
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ }
+ else
+ { // If no entry, 0 is the default value
+ m_xTabSpin->set_value(0, eDefUnit);
+ m_xTabBox->set_entry_text(m_xTabSpin->get_text());
+
+ m_xNewBtn->set_sensitive(true);
+ m_xDelBtn->set_sensitive(false);
+ }
+}
+
+void SvxTabulatorTabPage::SetFillAndTabType_Impl()
+{
+ weld::RadioButton* pTypeBtn = nullptr;
+ weld::RadioButton* pFillBtn = nullptr;
+
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+
+ if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Left )
+ pTypeBtn = m_xLeftTab.get();
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Right )
+ pTypeBtn = m_xRightTab.get();
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Decimal )
+ {
+ pTypeBtn = m_xDezTab.get();
+ m_xDezChar->set_sensitive(true);
+ m_xDezCharLabel->set_sensitive(true);
+ m_xDezChar->set_text(OUString(aCurrentTab.GetDecimal()));
+ }
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Center )
+ pTypeBtn = m_xCenterTab.get();
+
+ if (pTypeBtn)
+ pTypeBtn->set_active(true);
+
+ m_xFillChar->set_sensitive(false);
+ m_xFillChar->set_text("");
+
+ if ( aCurrentTab.GetFill() == ' ' )
+ pFillBtn = m_xNoFillChar.get();
+ else if ( aCurrentTab.GetFill() == '-' )
+ pFillBtn = m_xFillDashLine.get();
+ else if ( aCurrentTab.GetFill() == '_' )
+ pFillBtn = m_xFillSolidLine.get();
+ else if ( aCurrentTab.GetFill() == '.' )
+ pFillBtn = m_xFillPoints.get();
+ else
+ {
+ pFillBtn = m_xFillSpecial.get();
+ m_xFillChar->set_sensitive(true);
+ m_xFillChar->set_text(OUString(aCurrentTab.GetFill()));
+ }
+ pFillBtn->set_active(true);
+}
+
+IMPL_LINK(SvxTabulatorTabPage, NewHdl_Impl, weld::Button&, rBtn, void)
+{
+ NewHdl_Impl(&rBtn);
+}
+
+void SvxTabulatorTabPage::NewHdl_Impl(const weld::Button* pBtn)
+{
+ // Add a new one and select it
+ // Get the value from the display
+ ReformatHdl_Impl(*m_xTabBox);
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ auto nVal = m_xTabSpin->denormalize(m_xTabSpin->get_value(eDefUnit));
+
+ // If the pBtn == 0 && the value == 0 then do not create a tab, because we create via OK
+ if (nVal == 0 && pBtn == nullptr)
+ return;
+
+ tools::Long nOffset = 0;
+
+ if ( const SfxInt32Item* pOffsetItem = GetItemSet().GetItemIfSet( SID_ATTR_TABSTOP_OFFSET ) )
+ {
+ nOffset = pOffsetItem->GetValue();
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( GetWhich( SID_ATTR_TABSTOP ) );
+ nOffset = OutputDevice::LogicToLogic( nOffset, eUnit, MapUnit::Map100thMM );
+ }
+ const tools::Long nReal = nVal - nOffset;
+ sal_Int32 nSize = m_xTabBox->get_count();
+
+ sal_Int32 i;
+ for( i = 0; i < nSize; i++ )
+ {
+ if ( nReal < (*aNewTabs)[i].GetTabPos() )
+ break;
+ }
+
+ // Make ListBox entry
+ m_xTabSpin->set_value(m_xTabSpin->normalize(nVal), eDefUnit);
+ m_xTabBox->insert_text(i, m_xTabSpin->get_text());
+
+ aCurrentTab.GetTabPos() = nReal;
+ SvxTabAdjust eAdj = SvxTabAdjust::Left;
+
+ if (m_xRightTab->get_active())
+ eAdj = SvxTabAdjust::Right;
+ else if (m_xCenterTab->get_active())
+ eAdj = SvxTabAdjust::Center;
+ else if (m_xDezTab->get_active())
+ eAdj = SvxTabAdjust::Decimal;
+
+ aCurrentTab.GetAdjustment() = eAdj;
+ aNewTabs->Insert( aCurrentTab );
+
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ m_xTabBox->grab_focus();
+
+ // Set the selection into the position Edit
+ m_xTabBox->select_entry_region(0, -1);
+}
+
+int SvxTabulatorTabPage::FindCurrentTab()
+{
+ return m_xTabBox->find_text(FormatTab());
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = FindCurrentTab();
+ if (nPos == -1)
+ return;
+
+ if (m_xTabBox->get_count() == 1)
+ {
+ DelAllHdl_Impl(*m_xDelAllBtn);
+ return;
+ }
+
+ // Delete Tab
+ m_xTabBox->remove(nPos);
+ aNewTabs->Remove( nPos );
+
+ // Reset aCurrentTab
+ const sal_uInt16 nSize = aNewTabs->Count();
+
+ if ( nSize > 0 )
+ {
+ // Correct Pos
+ nPos = ( ( nSize - 1 ) >= nPos) ? nPos : nPos - 1;
+ m_xTabBox->set_active(nPos);
+ aCurrentTab = (*aNewTabs)[nPos];
+ }
+
+ // If no Tabs Enable Disable Controls
+ if (m_xTabBox->get_count() == 0)
+ {
+ m_xDelBtn->set_sensitive(false);
+ m_xNewBtn->set_sensitive(true);
+ m_xTabBox->grab_focus();
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, DelAllHdl_Impl, weld::Button&, void)
+{
+ if ( aNewTabs->Count() )
+ {
+ aNewTabs = std::make_unique<SvxTabStopItem>(GetWhich(SID_ATTR_TABSTOP));
+ InitTabPos_Impl();
+ }
+}
+
+IMPL_LINK(SvxTabulatorTabPage, TabTypeCheckHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ SvxTabAdjust eAdj;
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+ m_xDezChar->set_text("");
+
+ if (&rBox == m_xLeftTab.get())
+ eAdj = SvxTabAdjust::Left;
+ else if (&rBox == m_xRightTab.get())
+ eAdj = SvxTabAdjust::Right;
+ else if (&rBox == m_xCenterTab.get())
+ eAdj = SvxTabAdjust::Center;
+ else
+ {
+ eAdj = SvxTabAdjust::Decimal;
+ m_xDezChar->set_sensitive(true);
+ m_xDezCharLabel->set_sensitive(true);
+ m_xDezChar->set_text(OUString(aCurrentTab.GetDecimal()));
+ }
+
+ aCurrentTab.GetAdjustment() = eAdj;
+ int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK(SvxTabulatorTabPage, FillTypeCheckHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ sal_uInt8 cFill = ' ';
+ m_xFillChar->set_text( "" );
+ m_xFillChar->set_sensitive(false);
+
+ if (&rBox == m_xFillSpecial.get())
+ m_xFillChar->set_sensitive(true);
+ else if (&rBox == m_xNoFillChar.get())
+ cFill = ' ';
+ else if (&rBox == m_xFillSolidLine.get())
+ cFill = '_';
+ else if (&rBox == m_xFillPoints.get())
+ cFill = '.';
+ else if (&rBox == m_xFillDashLine.get())
+ cFill = '-';
+
+ aCurrentTab.GetFill() = cFill;
+ int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, GetFillCharHdl_Impl, weld::Widget&, void)
+{
+ OUString aChar(m_xFillChar->get_text());
+ if ( !aChar.isEmpty() )
+ aCurrentTab.GetFill() = aChar[0];
+
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, GetDezCharHdl_Impl, weld::Widget&, void)
+{
+ OUString aChar(m_xDezChar->get_text());
+ if ( !aChar.isEmpty() && ( aChar[0] >= ' '))
+ aCurrentTab.GetDecimal() = aChar[0];
+
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, SelectHdl_Impl, weld::TreeView&, bool)
+{
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aCurrentTab = (*aNewTabs)[nPos];
+ m_xNewBtn->set_sensitive(false);
+ SetFillAndTabType_Impl();
+ }
+ return true;
+}
+
+OUString SvxTabulatorTabPage::FormatTab()
+{
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ m_xTabSpin->reformat();
+ return m_xTabSpin->get_text();
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, ReformatHdl_Impl, weld::Widget&, void)
+{
+ m_xTabBox->set_entry_text(FormatTab());
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, ModifyHdl_Impl, weld::ComboBox&, void)
+{
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aCurrentTab = (*aNewTabs)[nPos];
+ SetFillAndTabType_Impl();
+
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ aCurrentTab.GetTabPos() = m_xTabSpin->denormalize(m_xTabSpin->get_value(eDefUnit));
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ return;
+ }
+ m_xNewBtn->set_sensitive(true);
+ m_xDelBtn->set_sensitive(false);
+}
+
+void SvxTabulatorTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pControlItem = aSet.GetItem<SfxUInt16Item>(SID_SVXTABULATORTABPAGE_DISABLEFLAGS, false);
+ if (pControlItem)
+ DisableControls(static_cast<TabulatorDisableFlags>(pControlItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/textanim.cxx b/cui/source/tabpages/textanim.cxx
new file mode 100644
index 000000000..e086969bb
--- /dev/null
+++ b/cui/source/tabpages/textanim.cxx
@@ -0,0 +1,534 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <textanim.hxx>
+#include <textattr.hxx>
+#include <TextColumnsPage.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdtaaitm.hxx>
+#include <svx/sdtacitm.hxx>
+#include <svx/sdtaiitm.hxx>
+#include <svx/sdtayitm.hxx>
+#include <svtools/unitconv.hxx>
+
+const WhichRangesContainer SvxTextAnimationPage::pRanges(
+ svl::Items<SDRATTR_TEXT_ANIKIND, SDRATTR_TEXT_ANIAMOUNT>);
+
+/*************************************************************************
+|*
+|* constructor of the tab dialog: adds pages to the dialog
+|*
+\************************************************************************/
+
+SvxTextTabDialog::SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrView* pSdrView)
+ : SfxTabDialogController(pParent, "cui/ui/textdialog.ui", "TextDialog", pAttr)
+ , pView(pSdrView)
+{
+ AddTabPage("RID_SVXPAGE_TEXTATTR", SvxTextAttrPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_TEXTANIMATION", SvxTextAnimationPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_TEXTCOLUMNS", SvxTextColumnsPage::Create, nullptr);
+}
+
+/*************************************************************************
+|*
+|* PageCreated()
+|*
+\************************************************************************/
+
+void SvxTextTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId != "RID_SVXPAGE_TEXTATTR")
+ return;
+
+ SdrObjKind eKind = SdrObjKind::NONE;
+ if (pView)
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ bool bHasMarked = rMarkList.GetMarkCount() > 0;
+ if (bHasMarked)
+ {
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ eKind = pObj->GetObjIdentifier();
+ }
+ }
+ }
+ static_cast<SvxTextAttrPage&>(rPage).SetObjKind(eKind);
+ static_cast<SvxTextAttrPage&>(rPage).Construct();
+}
+
+/*************************************************************************
+|*
+|* Page
+|*
+\************************************************************************/
+SvxTextAnimationPage::SvxTextAnimationPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/textanimtabpage.ui", "TextAnimation", &rInAttrs)
+ , eAniKind(SdrTextAniKind::NONE)
+ , m_aUpState(TRISTATE_INDET)
+ , m_aLeftState(TRISTATE_INDET)
+ , m_aRightState(TRISTATE_INDET)
+ , m_aDownState(TRISTATE_INDET)
+ , m_xLbEffect(m_xBuilder->weld_combo_box("LB_EFFECT"))
+ , m_xBoxDirection(m_xBuilder->weld_widget("boxDIRECTION"))
+ , m_xBtnUp(m_xBuilder->weld_toggle_button("BTN_UP"))
+ , m_xBtnLeft(m_xBuilder->weld_toggle_button("BTN_LEFT"))
+ , m_xBtnRight(m_xBuilder->weld_toggle_button("BTN_RIGHT"))
+ , m_xBtnDown(m_xBuilder->weld_toggle_button("BTN_DOWN"))
+ , m_xFlProperties(m_xBuilder->weld_frame("FL_PROPERTIES"))
+ , m_xTsbStartInside(m_xBuilder->weld_check_button("TSB_START_INSIDE"))
+ , m_xTsbStopInside(m_xBuilder->weld_check_button("TSB_STOP_INSIDE"))
+ , m_xBoxCount(m_xBuilder->weld_widget("boxCOUNT"))
+ , m_xTsbEndless(m_xBuilder->weld_check_button("TSB_ENDLESS"))
+ , m_xNumFldCount(m_xBuilder->weld_spin_button("NUM_FLD_COUNT"))
+ , m_xTsbPixel(m_xBuilder->weld_check_button("TSB_PIXEL"))
+ , m_xMtrFldAmount(m_xBuilder->weld_metric_spin_button("MTR_FLD_AMOUNT", FieldUnit::PIXEL))
+ , m_xTsbAuto(m_xBuilder->weld_check_button("TSB_AUTO"))
+ , m_xMtrFldDelay(m_xBuilder->weld_metric_spin_button("MTR_FLD_DELAY", FieldUnit::MILLISECOND))
+{
+ eFUnit = GetModuleFieldUnit( rInAttrs );
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ m_xLbEffect->connect_changed( LINK( this, SvxTextAnimationPage, SelectEffectHdl_Impl ) );
+ m_xTsbEndless->connect_toggled( LINK( this, SvxTextAnimationPage, ClickEndlessHdl_Impl ) );
+ m_xTsbAuto->connect_toggled( LINK( this, SvxTextAnimationPage, ClickAutoHdl_Impl ) );
+ m_xTsbPixel->connect_toggled( LINK( this, SvxTextAnimationPage, ClickPixelHdl_Impl ) );
+
+ Link<weld::Button&,void> aLink( LINK( this, SvxTextAnimationPage, ClickDirectionHdl_Impl ) );
+ m_xBtnUp->connect_clicked( aLink );
+ m_xBtnLeft->connect_clicked( aLink );
+ m_xBtnRight->connect_clicked( aLink );
+ m_xBtnDown->connect_clicked( aLink );
+}
+
+SvxTextAnimationPage::~SvxTextAnimationPage()
+{
+}
+
+/*************************************************************************
+|*
+|* reads the passed item set
+|*
+\************************************************************************/
+
+void SvxTextAnimationPage::Reset( const SfxItemSet* rAttrs )
+{
+ const SfxItemPool* pPool = rAttrs->GetPool();
+
+ // animation type
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIKIND );
+
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIKIND );
+
+ eAniKind = static_cast<const SdrTextAniKindItem*>(pItem)->GetValue();
+ m_xLbEffect->set_active(sal::static_int_cast<sal_Int32>(eAniKind));
+ m_xLbEffect->save_value();
+
+ // animation direction
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDIRECTION );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDIRECTION );
+
+ SelectDirection(static_cast<const SdrTextAniDirectionItem*>(pItem)->GetValue());
+ m_aUpState = m_xBtnUp->get_state();
+ m_aLeftState = m_xBtnLeft->get_state();
+ m_aRightState = m_xBtnRight->get_state();
+ m_aDownState = m_xBtnDown->get_state();
+
+ // Start inside
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTARTINSIDE );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTARTINSIDE );
+
+ if (static_cast<const SdrTextAniStartInsideItem*>(pItem)->GetValue())
+ m_xTsbStartInside->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbStartInside->set_state(TRISTATE_FALSE);
+ m_xTsbStartInside->save_state();
+
+ // Stop inside
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTOPINSIDE );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTOPINSIDE );
+
+ if (static_cast<const SdrTextAniStopInsideItem*>(pItem)->GetValue())
+ m_xTsbStopInside->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbStopInside->set_state(TRISTATE_FALSE);
+ m_xTsbStopInside->save_state();
+
+ // quantity
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANICOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANICOUNT );
+
+ tools::Long nValue = static_cast<tools::Long>(static_cast<const SdrTextAniCountItem*>(pItem)->GetValue());
+ m_xNumFldCount->set_value(nValue);
+ if (nValue == 0)
+ {
+ if (eAniKind == SdrTextAniKind::Slide)
+ {
+ m_xTsbEndless->set_state(TRISTATE_FALSE);
+ m_xTsbEndless->set_sensitive(false);
+ }
+ else
+ {
+ m_xTsbEndless->set_state(TRISTATE_TRUE);
+ m_xNumFldCount->set_text("");
+ }
+ }
+ else
+ m_xTsbEndless->set_state(TRISTATE_FALSE);
+ m_xTsbEndless->save_state();
+ m_xNumFldCount->save_value();
+
+ // delay
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDELAY );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDELAY );
+
+ nValue = static_cast<tools::Long>(static_cast<const SdrTextAniDelayItem*>(pItem)->GetValue());
+ m_xMtrFldDelay->set_value(nValue, FieldUnit::NONE);
+ if (nValue == 0)
+ {
+ m_xTsbAuto->set_state(TRISTATE_TRUE);
+ m_xMtrFldDelay->set_text("");
+ }
+ else
+ m_xTsbAuto->set_state(TRISTATE_FALSE);
+ m_xTsbAuto->save_state();
+ m_xMtrFldDelay->save_value();
+
+ // step size
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIAMOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIAMOUNT );
+
+ nValue = static_cast<tools::Long>(static_cast<const SdrTextAniAmountItem*>(pItem)->GetValue());
+ if (nValue <= 0)
+ {
+ m_xTsbPixel->set_state(TRISTATE_TRUE);
+ nValue = -nValue;
+ if (nValue == 0)
+ nValue++;
+ m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
+ m_xMtrFldAmount->set_digits(0);
+
+ m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xTsbPixel->set_state(TRISTATE_FALSE);
+ m_xMtrFldAmount->set_unit(eFUnit);
+ m_xMtrFldAmount->set_digits(2);
+
+ m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
+
+ SetMetricValue(*m_xMtrFldAmount, nValue, eUnit);
+ }
+ m_xTsbPixel->save_state();
+ m_xMtrFldAmount->save_value();
+
+ SelectEffectHdl_Impl(*m_xLbEffect);
+ ClickEndlessHdl_Impl(*m_xTsbEndless);
+ ClickAutoHdl_Impl(*m_xTsbAuto);
+}
+
+/*************************************************************************
+|*
+|* fills the passed item set with dialog box attributes
+|*
+\************************************************************************/
+
+bool SvxTextAnimationPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ TriState eState;
+
+ // animation type
+ int nPos = m_xLbEffect->get_active();
+ if( nPos != -1 &&
+ m_xLbEffect->get_value_changed_from_saved() )
+ {
+ rAttrs->Put( SdrTextAniKindItem( static_cast<SdrTextAniKind>(nPos) ) );
+ bModified = true;
+ }
+
+ // animation direction
+ if (m_aUpState != m_xBtnUp->get_state() ||
+ m_aLeftState != m_xBtnLeft->get_state() ||
+ m_aRightState != m_xBtnRight->get_state() ||
+ m_aDownState != m_xBtnDown->get_state())
+ {
+ SdrTextAniDirection eValue = static_cast<SdrTextAniDirection>(GetSelectedDirection());
+ rAttrs->Put( SdrTextAniDirectionItem( eValue ) );
+ bModified = true;
+ }
+
+ // Start inside
+ eState = m_xTsbStartInside->get_state();
+ if (m_xTsbStartInside->get_state_changed_from_saved())
+ {
+ rAttrs->Put( SdrTextAniStartInsideItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ // Stop inside
+ eState = m_xTsbStopInside->get_state();
+ if (m_xTsbStopInside->get_state_changed_from_saved())
+ {
+ rAttrs->Put( SdrTextAniStopInsideItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ // quantity
+ eState = m_xTsbEndless->get_state();
+ if (m_xTsbEndless->get_state_changed_from_saved() ||
+ m_xNumFldCount->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE /*#89844#*/ && m_xTsbEndless->get_sensitive())
+ bModified = true;
+ else
+ {
+ if( m_xNumFldCount->get_value_changed_from_saved() )
+ {
+ nValue = m_xNumFldCount->get_value();
+ bModified = true;
+ }
+ }
+ if( bModified )
+ rAttrs->Put( SdrTextAniCountItem( static_cast<sal_uInt16>(nValue) ) );
+ }
+
+ // delay
+ eState = m_xTsbAuto->get_state();
+ if (m_xTsbAuto->get_state_changed_from_saved() ||
+ m_xMtrFldDelay->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE )
+ bModified = true;
+ else
+ {
+ if( m_xMtrFldDelay->get_value_changed_from_saved() )
+ {
+ nValue = m_xMtrFldDelay->get_value(FieldUnit::NONE);
+ bModified = true;
+ }
+ }
+ if( bModified )
+ rAttrs->Put( SdrTextAniDelayItem( static_cast<sal_uInt16>(nValue) ) );
+ }
+
+ // step size
+ eState = m_xTsbPixel->get_state();
+ if (m_xTsbPixel->get_state_changed_from_saved() ||
+ m_xMtrFldAmount->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE )
+ {
+ nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE);
+ nValue = -nValue;
+ }
+ else
+ {
+ nValue = GetCoreValue( *m_xMtrFldAmount, eUnit );
+ }
+ rAttrs->Put( SdrTextAniAmountItem( static_cast<sal_Int16>(nValue) ) );
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+/*************************************************************************
+|*
+|* creates the page
+|*
+\************************************************************************/
+
+std::unique_ptr<SfxTabPage> SvxTextAnimationPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextAnimationPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, SelectEffectHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xLbEffect->get_active();
+ if (nPos == -1)
+ return;
+
+ eAniKind = static_cast<SdrTextAniKind>(nPos);
+ switch( eAniKind )
+ {
+ case SdrTextAniKind::NONE:
+ {
+ m_xBoxDirection->set_sensitive(false);
+ m_xFlProperties->set_sensitive(false);
+ }
+ break;
+
+ case SdrTextAniKind::Blink:
+ case SdrTextAniKind::Scroll:
+ case SdrTextAniKind::Alternate:
+ case SdrTextAniKind::Slide:
+ {
+ m_xFlProperties->set_sensitive(true);
+ if( eAniKind == SdrTextAniKind::Slide )
+ {
+ m_xTsbStartInside->set_sensitive(false);
+ m_xTsbStopInside->set_sensitive(false);
+ m_xTsbEndless->set_sensitive(false);
+ m_xNumFldCount->set_sensitive(true);
+ m_xNumFldCount->set_value(m_xNumFldCount->get_value());
+ }
+ else
+ {
+ m_xTsbStartInside->set_sensitive(true);
+ m_xTsbStopInside->set_sensitive(true);
+ m_xTsbEndless->set_sensitive(true);
+ ClickEndlessHdl_Impl(*m_xTsbEndless);
+ }
+
+ m_xTsbAuto->set_sensitive(true);
+ ClickAutoHdl_Impl(*m_xTsbAuto);
+
+ if( eAniKind == SdrTextAniKind::Blink )
+ {
+ m_xBoxDirection->set_sensitive(false);
+ m_xBoxCount->set_sensitive(false);
+ }
+ else
+ {
+ m_xBoxDirection->set_sensitive(true);
+ m_xBoxCount->set_sensitive(true);
+ }
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickEndlessHdl_Impl, weld::Toggleable&, void)
+{
+ if( eAniKind == SdrTextAniKind::Slide )
+ return;
+
+ TriState eState = m_xTsbEndless->get_state();
+ if( eState != TRISTATE_FALSE )
+ {
+ m_xNumFldCount->set_sensitive(false);
+ m_xNumFldCount->set_text("");
+ }
+ else
+ {
+ m_xNumFldCount->set_sensitive(true);
+ m_xNumFldCount->set_value(m_xNumFldCount->get_value());
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickAutoHdl_Impl, weld::Toggleable&, void)
+{
+ TriState eState = m_xTsbAuto->get_state();
+ if( eState != TRISTATE_FALSE )
+ {
+ m_xMtrFldDelay->set_sensitive(false);
+ m_xMtrFldDelay->set_text("");
+ }
+ else
+ {
+ m_xMtrFldDelay->set_sensitive(true);
+ m_xMtrFldDelay->set_value(m_xMtrFldDelay->get_value(FieldUnit::NONE), FieldUnit::NONE); //to-do
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickPixelHdl_Impl, weld::Toggleable&, void)
+{
+ TriState eState = m_xTsbPixel->get_state();
+ if (eState == TRISTATE_TRUE)
+ {
+ int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) / 10;
+ m_xMtrFldAmount->set_sensitive(true);
+ m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
+ m_xMtrFldAmount->set_digits(0);
+
+ m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
+
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+ else if( eState == TRISTATE_FALSE )
+ {
+ int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) * 10;
+ m_xMtrFldAmount->set_sensitive(true);
+ m_xMtrFldAmount->set_unit(eFUnit);
+ m_xMtrFldAmount->set_digits(2);
+
+ m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
+
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK(SvxTextAnimationPage, ClickDirectionHdl_Impl, weld::Button&, rBtn, void)
+{
+ m_xBtnUp->set_active(&rBtn == m_xBtnUp.get());
+ m_xBtnLeft->set_active(&rBtn == m_xBtnLeft.get());
+ m_xBtnRight->set_active(&rBtn == m_xBtnRight.get());
+ m_xBtnDown->set_active(&rBtn == m_xBtnDown.get());
+}
+
+void SvxTextAnimationPage::SelectDirection( SdrTextAniDirection nValue )
+{
+ m_xBtnUp->set_active( nValue == SdrTextAniDirection::Up );
+ m_xBtnLeft->set_active( nValue == SdrTextAniDirection::Left );
+ m_xBtnRight->set_active( nValue == SdrTextAniDirection::Right );
+ m_xBtnDown->set_active( nValue == SdrTextAniDirection::Down );
+}
+
+sal_uInt16 SvxTextAnimationPage::GetSelectedDirection() const
+{
+ SdrTextAniDirection nValue = SdrTextAniDirection::Left;
+
+ if( m_xBtnUp->get_active() )
+ nValue = SdrTextAniDirection::Up;
+ else if( m_xBtnLeft->get_active() )
+ nValue = SdrTextAniDirection::Left;
+ else if( m_xBtnRight->get_active() )
+ nValue = SdrTextAniDirection::Right;
+ else if( m_xBtnDown->get_active() )
+ nValue = SdrTextAniDirection::Down;
+
+ return static_cast<sal_uInt16>(nValue);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/textattr.cxx b/cui/source/tabpages/textattr.cxx
new file mode 100644
index 000000000..f773be6b8
--- /dev/null
+++ b/cui/source/tabpages/textattr.cxx
@@ -0,0 +1,665 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svddef.hxx>
+#include <svx/sdasitm.hxx>
+#include <svx/sdtditm.hxx>
+#include <svx/sdtagitm.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/sdtfsitm.hxx>
+#include <svx/sdtcfitm.hxx>
+#include <svx/svxids.hrc>
+
+#include <textattr.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <svtools/unitconv.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star;
+
+const WhichRangesContainer SvxTextAttrPage::pRanges(
+ svl::Items<
+ SDRATTR_MISC_FIRST ,SDRATTR_TEXT_HORZADJUST,
+ SDRATTR_TEXT_WORDWRAP, SDRATTR_TEXT_WORDWRAP
+>);
+
+/*************************************************************************
+|*
+|* dialog (page) for copying objects
+|*
+\************************************************************************/
+SvxTextAttrPage::SvxTextAttrPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/textattrtabpage.ui", "TextAttributesPage", rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , m_eObjKind(SdrObjKind::NONE)
+ , bAutoGrowSizeEnabled(false)
+ , bContourEnabled(false)
+ , bAutoGrowWidthEnabled(false)
+ , bAutoGrowHeightEnabled(false)
+ , bWordWrapTextEnabled(false)
+ , bFitToSizeEnabled(false)
+ , m_aCtlPosition(this)
+ , m_xDrawingText(m_xBuilder->weld_widget("drawingtext"))
+ , m_xCustomShapeText(m_xBuilder->weld_widget("customshapetext"))
+ , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
+ , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
+ , m_xTsbFitToSize(m_xBuilder->weld_check_button("TSB_FIT_TO_SIZE"))
+ , m_xTsbContour(m_xBuilder->weld_check_button("TSB_CONTOUR"))
+ , m_xTsbWordWrapText(m_xBuilder->weld_check_button("TSB_WORDWRAP_TEXT"))
+ , m_xTsbAutoGrowSize(m_xBuilder->weld_check_button("TSB_AUTOGROW_SIZE"))
+ , m_xFlDistance(m_xBuilder->weld_frame("FL_DISTANCE"))
+ , m_xMtrFldLeft(m_xBuilder->weld_metric_spin_button("MTR_FLD_LEFT", FieldUnit::CM))
+ , m_xMtrFldRight(m_xBuilder->weld_metric_spin_button("MTR_FLD_RIGHT", FieldUnit::CM))
+ , m_xMtrFldTop(m_xBuilder->weld_metric_spin_button("MTR_FLD_TOP", FieldUnit::CM))
+ , m_xMtrFldBottom(m_xBuilder->weld_metric_spin_button("MTR_FLD_BOTTOM", FieldUnit::CM))
+ , m_xFlPosition(m_xBuilder->weld_frame("FL_POSITION"))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xTsbFullWidth(m_xBuilder->weld_check_button("TSB_FULL_WIDTH"))
+{
+ m_aCtlPosition.SetControlSettings(RectPoint::MM, 240);
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldLeft, eFUnit );
+ SetFieldUnit( *m_xMtrFldRight, eFUnit );
+ SetFieldUnit( *m_xMtrFldTop, eFUnit );
+ SetFieldUnit( *m_xMtrFldBottom, eFUnit );
+
+ Link<weld::Toggleable&,void> aLink( LINK( this, SvxTextAttrPage, ClickHdl_Impl ) );
+ m_xTsbAutoGrowWidth->connect_toggled( aLink );
+ m_xTsbAutoGrowHeight->connect_toggled( aLink );
+ m_xTsbAutoGrowSize->connect_toggled( aLink );
+ m_xTsbFitToSize->connect_toggled( aLink );
+ m_xTsbContour->connect_toggled( aLink );
+
+ m_xTsbFullWidth->connect_toggled(LINK( this, SvxTextAttrPage, ClickFullWidthHdl_Impl ) );
+}
+
+SvxTextAttrPage::~SvxTextAttrPage()
+{
+}
+
+/*************************************************************************
+|*
+|* reads the passed item set
+|*
+\************************************************************************/
+
+void SvxTextAttrPage::Reset( const SfxItemSet* rAttrs )
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ const SdrMetricItem* pItem = GetItem(*rAttrs, SDRATTR_TEXT_LEFTDIST);
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_LEFTDIST );
+
+ SetMetricValue(*m_xMtrFldLeft, pItem->GetValue(), eUnit);
+ m_xMtrFldLeft->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_RIGHTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_RIGHTDIST );
+
+ SetMetricValue(*m_xMtrFldRight, pItem->GetValue(), eUnit);
+ m_xMtrFldRight->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_UPPERDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_UPPERDIST );
+
+ SetMetricValue(*m_xMtrFldTop, pItem->GetValue(), eUnit);
+ m_xMtrFldTop->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_LOWERDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_LOWERDIST );
+
+ SetMetricValue(*m_xMtrFldBottom, pItem->GetValue(), eUnit);
+ m_xMtrFldBottom->save_value();
+
+ // adjust to height and autogrowsize
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_AUTOGROWHEIGHT ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbAutoGrowHeight->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWHEIGHT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+
+ m_xTsbAutoGrowSize->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWHEIGHT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbAutoGrowHeight->set_state( TRISTATE_INDET );
+ m_xTsbAutoGrowSize->set_state( TRISTATE_INDET );
+ }
+ m_xTsbAutoGrowHeight->save_state();
+ m_xTsbAutoGrowSize->save_state();
+
+ // adjust to width
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_AUTOGROWWIDTH ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbAutoGrowWidth->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWWIDTH ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbAutoGrowWidth->set_state( TRISTATE_INDET );
+ m_xTsbAutoGrowWidth->save_state();
+
+ // wordwrap text
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_WORDWRAP ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbWordWrapText->set_state( rAttrs->Get( SDRATTR_TEXT_WORDWRAP ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbWordWrapText->set_state( TRISTATE_INDET );
+ m_xTsbWordWrapText->save_state();
+
+
+ // #103516# Do the setup based on states of hor/ver adjust
+ // Setup center field and FullWidth
+ SfxItemState eVState = rAttrs->GetItemState( SDRATTR_TEXT_VERTADJUST );
+ SfxItemState eHState = rAttrs->GetItemState( SDRATTR_TEXT_HORZADJUST );
+
+ if(SfxItemState::DONTCARE != eVState && SfxItemState::DONTCARE != eHState)
+ {
+ // VertAdjust and HorAdjust are unequivocal, thus
+ SdrTextVertAdjust eTVA = rAttrs->Get(SDRATTR_TEXT_VERTADJUST).GetValue();
+ SdrTextHorzAdjust eTHA = rAttrs->Get(SDRATTR_TEXT_HORZADJUST).GetValue();
+ RectPoint eRP = RectPoint::LB;
+
+ if (m_xTsbFullWidth->get_state() == TRISTATE_INDET)
+ m_xTsbFullWidth->set_state(TRISTATE_FALSE);
+
+ // Translate item values into local anchor position.
+ switch (eTVA)
+ {
+ case SDRTEXTVERTADJUST_TOP:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LT; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MT; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RT; break;
+ }
+ break;
+ }
+ case SDRTEXTVERTADJUST_BLOCK:
+ case SDRTEXTVERTADJUST_CENTER:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LM; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MM; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RM; break;
+ }
+ break;
+ }
+ case SDRTEXTVERTADJUST_BOTTOM:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LB; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MB; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RB; break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ // See if we have to check the "full width" check button.
+ bool bLeftToRight(IsTextDirectionLeftToRight());
+
+ if((bLeftToRight && (SDRTEXTHORZADJUST_BLOCK == eTHA)) || (!bLeftToRight && (SDRTEXTVERTADJUST_BLOCK == eTVA)))
+ {
+ // Move anchor to valid position.
+ ClickFullWidthHdl_Impl(*m_xTsbFullWidth);
+ m_xTsbFullWidth->set_state(TRISTATE_TRUE);
+ }
+
+ m_aCtlPosition.SetActualRP( eRP );
+ }
+ else
+ {
+ // VertAdjust or HorAdjust is not unequivocal
+ m_aCtlPosition.Reset();
+
+ m_aCtlPosition.SetState(CTL_STATE::NOVERT);
+ m_aCtlPosition.DoCompletelyDisable(true);
+
+ m_xTsbFullWidth->set_state(TRISTATE_INDET);
+ m_xFlPosition->set_sensitive( false );
+ }
+
+ // adjust to border
+ if (rAttrs->GetItemState(SDRATTR_TEXT_FITTOSIZE) != SfxItemState::DONTCARE)
+ {
+ drawing::TextFitToSizeType const eFTS =
+ rAttrs->Get( SDRATTR_TEXT_FITTOSIZE ).GetValue();
+ if (eFTS == drawing::TextFitToSizeType_AUTOFIT || eFTS == drawing::TextFitToSizeType_NONE)
+ m_xTsbFitToSize->set_state( TRISTATE_FALSE );
+ else
+ m_xTsbFitToSize->set_state( TRISTATE_TRUE );
+ }
+ else
+ m_xTsbFitToSize->set_state( TRISTATE_INDET );
+ m_xTsbFitToSize->save_state();
+
+ if( rAttrs->GetItemState( SDRATTR_TEXT_CONTOURFRAME ) != SfxItemState::DONTCARE )
+ {
+ bool bContour = rAttrs->Get( SDRATTR_TEXT_CONTOURFRAME ).GetValue();
+ m_xTsbContour->set_state( bContour ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbContour->set_state( TRISTATE_INDET );
+ m_xTsbContour->save_state();
+
+ ClickHdl_Impl(*m_xTsbContour);
+}
+
+/*************************************************************************
+|*
+|* fills the passed item set with dialog box attributes
+|*
+\************************************************************************/
+
+bool SvxTextAttrPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ sal_Int32 nValue;
+ TriState eState;
+
+ if( m_xMtrFldLeft->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldLeft, eUnit );
+ rAttrs->Put( makeSdrTextLeftDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldRight->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldRight, eUnit );
+ rAttrs->Put( makeSdrTextRightDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldTop->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldTop, eUnit );
+ rAttrs->Put( makeSdrTextUpperDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldBottom->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldBottom, eUnit );
+ rAttrs->Put( makeSdrTextLowerDistItem( nValue ) );
+ }
+
+ eState = m_xTsbAutoGrowHeight->get_state();
+ if( m_xTsbAutoGrowHeight->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowHeightItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbAutoGrowWidth->get_state();
+ if( m_xTsbAutoGrowWidth->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowWidthItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbAutoGrowSize->get_state();
+ if( m_xTsbAutoGrowSize->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowHeightItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbWordWrapText->get_state();
+ if( m_xTsbWordWrapText->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextWordWrapItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbContour->get_state();
+ if( m_xTsbContour->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextContourFrameItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbFitToSize->get_state();
+ if( m_xTsbFitToSize->get_state_changed_from_saved() )
+ {
+ drawing::TextFitToSizeType eFTS;
+ switch( eState )
+ {
+ default: ; //prevent warning
+ OSL_FAIL( "svx::SvxTextAttrPage::FillItemSet(), unhandled state!" );
+ [[fallthrough]];
+ case TRISTATE_FALSE: eFTS = drawing::TextFitToSizeType_AUTOFIT; break;
+ case TRISTATE_TRUE: eFTS = drawing::TextFitToSizeType_PROPORTIONAL; break;
+ }
+ rAttrs->Put( SdrTextFitToSizeTypeItem( eFTS ) );
+ }
+
+ // centered
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ SdrTextVertAdjust eTVA;
+ SdrTextHorzAdjust eTHA;
+
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::LM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::LB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::MT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::MM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::MB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::RT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ case RectPoint::RM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ case RectPoint::RB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ }
+
+ // #103516# Do not change values if adjust controls were disabled.
+ bool bIsDisabled(m_aCtlPosition.IsCompletelyDisabled());
+
+ if(bIsDisabled)
+ return true;
+
+ if( m_xTsbFullWidth->get_state() == TRISTATE_TRUE )
+ {
+ if (IsTextDirectionLeftToRight())
+ eTHA = SDRTEXTHORZADJUST_BLOCK;
+ else
+ eTVA = SDRTEXTVERTADJUST_BLOCK;
+ }
+
+ if ( rOutAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST ) != SfxItemState::DONTCARE )
+ {
+ SdrTextVertAdjust eOldTVA = rOutAttrs.Get( SDRATTR_TEXT_VERTADJUST ).GetValue();
+ if( eOldTVA != eTVA )
+ rAttrs->Put( SdrTextVertAdjustItem( eTVA ) );
+ }
+ else
+ rAttrs->Put( SdrTextVertAdjustItem( eTVA ) );
+
+ if ( rOutAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST ) != SfxItemState::DONTCARE )
+ {
+ SdrTextHorzAdjust eOldTHA = rOutAttrs.Get( SDRATTR_TEXT_HORZADJUST ).GetValue();
+ if( eOldTHA != eTHA )
+ rAttrs->Put( SdrTextHorzAdjustItem( eTHA ) );
+ }
+ else
+ rAttrs->Put( SdrTextHorzAdjustItem( eTHA ) );
+
+ return true;
+}
+
+void SvxTextAttrPage::Construct()
+{
+ switch (m_eObjKind)
+ {
+ case SdrObjKind::NONE:
+ // indeterminate, show them all
+ bFitToSizeEnabled = bContourEnabled = bWordWrapTextEnabled =
+ bAutoGrowSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = true;
+ m_xCustomShapeText->show();
+ m_xDrawingText->show();
+ break;
+ case SdrObjKind::Text:
+ case SdrObjKind::TitleText:
+ case SdrObjKind::OutlineText:
+ case SdrObjKind::Caption:
+ // contour NOT possible for pure text objects
+ bContourEnabled = bWordWrapTextEnabled = bAutoGrowSizeEnabled = false;
+
+ // adjusting width and height is ONLY possible for pure text objects
+ bFitToSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = true;
+ m_xCustomShapeText->hide();
+ m_xDrawingText->show();
+ break;
+ case SdrObjKind::CustomShape:
+ bFitToSizeEnabled = bContourEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = false;
+ bWordWrapTextEnabled = bAutoGrowSizeEnabled = true;
+ m_xDrawingText->hide();
+ m_xCustomShapeText->show();
+ break;
+ default:
+ bFitToSizeEnabled = bContourEnabled = true;
+ bWordWrapTextEnabled = bAutoGrowSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = false;
+ m_xCustomShapeText->hide();
+ m_xDrawingText->show();
+ break;
+ }
+
+ m_xTsbAutoGrowHeight->set_visible( bAutoGrowHeightEnabled );
+ m_xTsbAutoGrowWidth->set_visible( bAutoGrowWidthEnabled );
+ m_xTsbFitToSize->set_visible( bFitToSizeEnabled );
+ m_xTsbContour->set_visible( bContourEnabled );
+ m_xTsbAutoGrowSize->set_visible( bAutoGrowSizeEnabled );
+ m_xTsbWordWrapText->set_visible( bWordWrapTextEnabled );
+}
+
+std::unique_ptr<SfxTabPage> SvxTextAttrPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextAttrPage>(pPage, pController, *rAttrs);
+}
+
+/** Check whether we have to uncheck the "Full width" check box.
+*/
+void SvxTextAttrPage::PointChanged(weld::DrawingArea*, RectPoint eRP)
+{
+ if (m_xTsbFullWidth->get_state() != TRISTATE_TRUE)
+ return;
+
+ // Depending on write direction and currently checked anchor we have
+ // to uncheck the "full width" button.
+ if (IsTextDirectionLeftToRight())
+ switch( eRP )
+ {
+ case RectPoint::LT:
+ case RectPoint::LM:
+ case RectPoint::LB:
+ case RectPoint::RT:
+ case RectPoint::RM:
+ case RectPoint::RB:
+ m_xTsbFullWidth->set_state( TRISTATE_FALSE );
+ break;
+ default: ;//prevent warning
+ }
+ else
+ switch (eRP)
+ {
+ case RectPoint::LT:
+ case RectPoint::MT:
+ case RectPoint::RT:
+ case RectPoint::LB:
+ case RectPoint::MB:
+ case RectPoint::RB:
+ m_xTsbFullWidth->set_state( TRISTATE_FALSE );
+ break;
+ default: ;//prevent warning
+ }
+}
+
+
+/*************************************************************************
+|*
+|* possibly changes the position of the position-control
+|*
+\************************************************************************/
+
+/** When switching the "full width" check button on the text anchor may have
+ to be moved to a valid and adjacent position. This position depends on
+ the current anchor position and the text writing direction.
+*/
+IMPL_LINK_NOARG(SvxTextAttrPage, ClickFullWidthHdl_Impl, weld::Toggleable&, void)
+{
+ if( m_xTsbFullWidth->get_state() != TRISTATE_TRUE )
+ return;
+
+ if (IsTextDirectionLeftToRight())
+ {
+ // Move text anchor to horizontal middle axis.
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::RT:
+ m_aCtlPosition.SetActualRP( RectPoint::MT );
+ break;
+
+ case RectPoint::LM:
+ case RectPoint::RM:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::LB:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::MB );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ else
+ {
+ // Move text anchor to vertical middle axis.
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::LB:
+ m_aCtlPosition.SetActualRP( RectPoint::LM );
+ break;
+
+ case RectPoint::MT:
+ case RectPoint::MB:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::RT:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::RM );
+ break;
+ default: ;//prevent warning
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* enables/disables "size at text" or "adjust to frame"
+|*
+\************************************************************************/
+
+IMPL_LINK(SvxTextAttrPage, ClickHdl_Impl, weld::Toggleable&, rButton, void)
+{
+ if (&rButton == m_xTsbAutoGrowSize.get())
+ {
+ m_xTsbAutoGrowHeight->set_state(m_xTsbAutoGrowSize->get_state());
+ if (m_xTsbAutoGrowSize->get_state() == TRISTATE_TRUE)
+ {
+ m_xTsbFitToSize->set_state(TRISTATE_FALSE);
+ m_xTsbContour->set_state(TRISTATE_FALSE);
+ }
+ }
+ else if (&rButton == m_xTsbAutoGrowHeight.get())
+ m_xTsbAutoGrowSize->set_state(m_xTsbAutoGrowHeight->get_state());
+
+ bool bAutoGrowWidth = m_xTsbAutoGrowWidth->get_state() == TRISTATE_TRUE;
+ bool bAutoGrowHeight = m_xTsbAutoGrowHeight->get_state() == TRISTATE_TRUE;
+ bool bFitToSize = m_xTsbFitToSize->get_state() == TRISTATE_TRUE;
+ bool bContour = m_xTsbContour->get_state() == TRISTATE_TRUE;
+
+ m_xTsbContour->set_sensitive( !bFitToSize &&
+ !( ( bAutoGrowWidth && bAutoGrowWidthEnabled ) || ( bAutoGrowHeight && bAutoGrowHeightEnabled ) ) &&
+ bContourEnabled );
+
+ m_xTsbAutoGrowWidth->set_sensitive( !bFitToSize &&
+ !( bContour && bContourEnabled ) &&
+ bAutoGrowWidthEnabled );
+
+ m_xTsbAutoGrowHeight->set_sensitive( !bFitToSize &&
+ !( bContour && bContourEnabled ) &&
+ bAutoGrowHeightEnabled );
+
+ m_xTsbFitToSize->set_sensitive( !( ( bAutoGrowWidth && bAutoGrowWidthEnabled ) || ( bAutoGrowHeight && bAutoGrowHeightEnabled ) ) &&
+ !( bContour && bContourEnabled ) &&
+ bFitToSizeEnabled );
+
+ // #101901# enable/disable metric fields and decorations dependent of contour
+ m_xFlDistance->set_sensitive(!bContour);
+
+ if( bContour && bContourEnabled )
+ {
+ m_xMtrFldLeft->set_value(0, FieldUnit::NONE);
+ m_xMtrFldRight->set_value(0, FieldUnit::NONE);
+ m_xMtrFldTop->set_value(0, FieldUnit::NONE);
+ m_xMtrFldBottom->set_value(0, FieldUnit::NONE);
+ }
+
+ // #103516# Do the setup based on states of hor/ver adjust
+ SfxItemState eVState = rOutAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST );
+ SfxItemState eHState = rOutAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST );
+ bool bHorAndVer(SfxItemState::DONTCARE == eVState || SfxItemState::DONTCARE == eHState);
+
+ // #83698# enable/disable text anchoring dependent of contour
+ m_xFlPosition->set_sensitive(!bContour && !bHorAndVer);
+}
+
+
+bool SvxTextAttrPage::IsTextDirectionLeftToRight() const
+{
+ // Determine the text writing direction with left to right as default.
+ bool bLeftToRightDirection = true;
+ SfxItemState eState = rOutAttrs.GetItemState(SDRATTR_TEXTDIRECTION);
+
+ if(SfxItemState::DONTCARE != eState)
+ {
+ const SvxWritingModeItem& rItem = rOutAttrs.Get(SDRATTR_TEXTDIRECTION);
+ if (rItem.GetValue() == css::text::WritingMode_TB_RL)
+ bLeftToRightDirection = false;
+ }
+ return bLeftToRightDirection;
+}
+
+void SvxTextAttrPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const CntUInt16Item* pObjTypeItem = aSet.GetItem<CntUInt16Item>(SID_SVXTEXTATTRPAGE_OBJKIND, false);
+
+ if (pObjTypeItem)
+ SetObjKind(static_cast<SdrObjKind>(pObjTypeItem->GetValue()));
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/themepage.cxx b/cui/source/tabpages/themepage.cxx
new file mode 100644
index 000000000..a7ea42801
--- /dev/null
+++ b/cui/source/tabpages/themepage.cxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <themepage.hxx>
+
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/util/Color.hpp>
+
+#include <comphelper/sequence.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <editeng/editids.hrc>
+#include <sal/log.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svx/colorbox.hxx>
+
+using namespace com::sun::star;
+
+const WhichRangesContainer
+ SvxThemePage::m_pRanges(svl::Items<SID_ATTR_CHAR_GRABBAG, SID_ATTR_CHAR_GRABBAG>);
+
+SvxThemePage::SvxThemePage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/themetabpage.ui", "ThemePage", &rInAttrs)
+ , m_xThemeName(m_xBuilder->weld_entry("themeName"))
+ , m_xColorSetName(m_xBuilder->weld_entry("colorSetName"))
+ , m_xDk1(new ColorListBox(m_xBuilder->weld_menu_button("btnDk1"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xLt1(new ColorListBox(m_xBuilder->weld_menu_button("btnLt1"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xDk2(new ColorListBox(m_xBuilder->weld_menu_button("btnDk2"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xLt2(new ColorListBox(m_xBuilder->weld_menu_button("btnLt2"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xAccent1(new ColorListBox(m_xBuilder->weld_menu_button("btnAccent1"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xAccent2(new ColorListBox(m_xBuilder->weld_menu_button("btnAccent2"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xAccent3(new ColorListBox(m_xBuilder->weld_menu_button("btnAccent3"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xAccent4(new ColorListBox(m_xBuilder->weld_menu_button("btnAccent4"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xAccent5(new ColorListBox(m_xBuilder->weld_menu_button("btnAccent5"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xAccent6(new ColorListBox(m_xBuilder->weld_menu_button("btnAccent6"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xHlink(new ColorListBox(m_xBuilder->weld_menu_button("btnHlink"),
+ [this] { return GetDialogController()->getDialog(); }))
+ , m_xFolHlink(new ColorListBox(m_xBuilder->weld_menu_button("btnFolHlink"),
+ [this] { return GetDialogController()->getDialog(); }))
+{
+}
+
+SvxThemePage::~SvxThemePage() = default;
+
+void SvxThemePage::Reset(const SfxItemSet* pAttrs)
+{
+ const SfxGrabBagItem* pGrabBagItem = pAttrs->GetItemIfSet(SID_ATTR_CHAR_GRABBAG);
+ if (!pGrabBagItem)
+ {
+ SAL_WARN("cui.tabpages", "SvxThemePage::Reset: no SfxGrabBagItem");
+ return;
+ }
+
+ auto itTheme = pGrabBagItem->GetGrabBag().find("Theme");
+ if (itTheme == pGrabBagItem->GetGrabBag().end())
+ {
+ // No theme was defined previously, allow specifying colors.
+ m_xDk1->set_sensitive(true);
+ m_xLt1->set_sensitive(true);
+ m_xDk2->set_sensitive(true);
+ m_xLt2->set_sensitive(true);
+ m_xAccent1->set_sensitive(true);
+ m_xAccent2->set_sensitive(true);
+ m_xAccent3->set_sensitive(true);
+ m_xAccent4->set_sensitive(true);
+ m_xAccent5->set_sensitive(true);
+ m_xAccent6->set_sensitive(true);
+ m_xHlink->set_sensitive(true);
+ m_xFolHlink->set_sensitive(true);
+ return;
+ }
+
+ comphelper::SequenceAsHashMap aMap(itTheme->second);
+ auto it = aMap.find("Name");
+ if (it != aMap.end())
+ {
+ OUString aName;
+ it->second >>= aName;
+ m_xThemeName->set_text(aName);
+ }
+
+ it = aMap.find("ColorSchemeName");
+ if (it != aMap.end())
+ {
+ OUString aName;
+ it->second >>= aName;
+ m_xColorSetName->set_text(aName);
+ }
+
+ it = aMap.find("ColorScheme");
+ if (it != aMap.end())
+ {
+ uno::Sequence<util::Color> aColors;
+ it->second >>= aColors;
+ m_xDk1->SelectEntry(Color(ColorTransparency, aColors[0]));
+ m_xLt1->SelectEntry(Color(ColorTransparency, aColors[1]));
+ m_xDk2->SelectEntry(Color(ColorTransparency, aColors[2]));
+ m_xLt2->SelectEntry(Color(ColorTransparency, aColors[3]));
+ m_xAccent1->SelectEntry(Color(ColorTransparency, aColors[4]));
+ m_xAccent2->SelectEntry(Color(ColorTransparency, aColors[5]));
+ m_xAccent3->SelectEntry(Color(ColorTransparency, aColors[6]));
+ m_xAccent4->SelectEntry(Color(ColorTransparency, aColors[7]));
+ m_xAccent5->SelectEntry(Color(ColorTransparency, aColors[8]));
+ m_xAccent6->SelectEntry(Color(ColorTransparency, aColors[9]));
+ m_xHlink->SelectEntry(Color(ColorTransparency, aColors[10]));
+ m_xFolHlink->SelectEntry(Color(ColorTransparency, aColors[11]));
+ }
+}
+
+bool SvxThemePage::FillItemSet(SfxItemSet* pAttrs)
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ if (!rOldSet.HasItem(SID_ATTR_CHAR_GRABBAG))
+ return true;
+
+ SfxGrabBagItem aGrabBagItem(rOldSet.Get(SID_ATTR_CHAR_GRABBAG));
+
+ comphelper::SequenceAsHashMap aMap;
+ auto it = aGrabBagItem.GetGrabBag().find("Theme");
+ if (it != aGrabBagItem.GetGrabBag().end())
+ {
+ aMap << it->second;
+ }
+
+ aMap["Name"] <<= m_xThemeName->get_text();
+ aMap["ColorSchemeName"] <<= m_xColorSetName->get_text();
+ std::vector<util::Color> aColorScheme = {
+ static_cast<sal_Int32>(m_xDk1->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xLt1->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xDk2->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xLt2->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xAccent1->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xAccent2->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xAccent3->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xAccent4->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xAccent5->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xAccent6->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xHlink->GetSelectEntryColor()),
+ static_cast<sal_Int32>(m_xFolHlink->GetSelectEntryColor()),
+ };
+ aMap["ColorScheme"] <<= comphelper::containerToSequence(aColorScheme);
+
+ beans::PropertyValues aTheme = aMap.getAsConstPropertyValueList();
+ aGrabBagItem.GetGrabBag()["Theme"] <<= aTheme;
+ pAttrs->Put(aGrabBagItem);
+
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxThemePage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxThemePage>(pPage, pController, *rAttrs);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/tabpages/tparea.cxx b/cui/source/tabpages/tparea.cxx
new file mode 100644
index 000000000..bbdb9733a
--- /dev/null
+++ b/cui/source/tabpages/tparea.cxx
@@ -0,0 +1,510 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xfilluseslidebackgrounditem.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <cuitabarea.hxx>
+#include <sfx2/tabdlg.hxx>
+
+using namespace com::sun::star;
+
+// static ----------------------------------------------------------------
+
+namespace {
+
+enum FillType
+{
+ TRANSPARENT,
+ SOLID,
+ GRADIENT,
+ HATCH,
+ BITMAP,
+ PATTERN,
+ USE_BACKGROUND_FILL
+};
+
+}
+
+const WhichRangesContainer SvxAreaTabPage::pAreaRanges(
+ svl::Items<
+ XATTR_GRADIENTSTEPCOUNT, XATTR_GRADIENTSTEPCOUNT,
+ SID_ATTR_FILL_STYLE, SID_ATTR_FILL_BITMAP>);
+
+namespace
+{
+
+void lclExtendSize(Size& rSize, const Size& rInputSize)
+{
+ if (rSize.Width() < rInputSize.Width())
+ rSize.setWidth( rInputSize.Width() );
+ if (rSize.Height() < rInputSize.Height())
+ rSize.setHeight( rInputSize.Height() );
+}
+
+} // end anonymous namespace
+
+/*************************************************************************
+|*
+|* Dialog to modify fill-attributes
+|*
+\************************************************************************/
+
+SvxAreaTabPage::SvxAreaTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs, bool bSlideBackground)
+ : SfxTabPage(pPage, pController, "cui/ui/areatabpage.ui", "AreaTabPage", &rInAttrs)
+ // local fixed not o be changed values for local pointers
+ , maFixed_ChangeType(ChangeType::NONE)
+ // init with pointers to fixed ChangeType
+ , m_pnColorListState(&maFixed_ChangeType)
+ , m_pnBitmapListState(&maFixed_ChangeType)
+ , m_pnPatternListState(&maFixed_ChangeType)
+ , m_pnGradientListState(&maFixed_ChangeType)
+ , m_pnHatchingListState(&maFixed_ChangeType)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xFillTab(m_xBuilder->weld_container("fillstylebox"))
+ , m_xBtnNone(m_xBuilder->weld_toggle_button("btnnone"))
+ , m_xBtnColor(m_xBuilder->weld_toggle_button("btncolor"))
+ , m_xBtnGradient(m_xBuilder->weld_toggle_button("btngradient"))
+ , m_xBtnHatch(m_xBuilder->weld_toggle_button("btnhatch"))
+ , m_xBtnBitmap(m_xBuilder->weld_toggle_button("btnbitmap"))
+ , m_xBtnPattern(m_xBuilder->weld_toggle_button("btnpattern"))
+ , m_xBtnUseBackground(m_xBuilder->weld_toggle_button("btnusebackground"))
+{
+ maBox.AddButton(m_xBtnNone.get());
+ maBox.AddButton(m_xBtnColor.get());
+ maBox.AddButton(m_xBtnGradient.get());
+ maBox.AddButton(m_xBtnHatch.get());
+ maBox.AddButton(m_xBtnBitmap.get());
+ maBox.AddButton(m_xBtnPattern.get());
+
+ Link<weld::Toggleable&, void> aLink = LINK(this, SvxAreaTabPage, SelectFillTypeHdl_Impl);
+ m_xBtnNone->connect_toggled(aLink);
+ m_xBtnColor->connect_toggled(aLink);
+ m_xBtnGradient->connect_toggled(aLink);
+ m_xBtnHatch->connect_toggled(aLink);
+ m_xBtnBitmap->connect_toggled(aLink);
+ m_xBtnPattern->connect_toggled(aLink);
+ if (bSlideBackground)
+ {
+ maBox.AddButton(m_xBtnUseBackground.get());
+ m_xBtnUseBackground->connect_toggled(aLink);
+ }
+ else
+ m_xBtnUseBackground->hide();
+
+ SetExchangeSupport();
+}
+
+void SvxAreaTabPage::SetOptimalSize(weld::DialogController* pController)
+{
+ m_xFillTab->set_size_request(-1, -1);
+
+ // Calculate optimal size of all pages...
+ m_xFillTabPage = SvxColorTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aSize(m_xFillTab->get_preferred_size());
+
+ if (m_xBtnGradient->get_visible())
+ {
+ m_xFillTabPage = SvxGradientTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aGradientSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aGradientSize);
+ }
+ if (m_xBtnBitmap->get_visible())
+ {
+ m_xFillTabPage = SvxBitmapTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aBitmapSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aBitmapSize);
+ }
+ if (m_xBtnHatch->get_visible())
+ {
+ m_xFillTabPage = SvxHatchTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aHatchSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aHatchSize);
+ }
+ if (m_xBtnPattern->get_visible())
+ {
+ m_xFillTabPage = SvxPatternTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aPatternSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aPatternSize);
+ }
+ m_xFillTabPage.reset();
+
+ aSize.extendBy(10, 10); // apply a bit of margin
+
+ m_xFillTab->set_size_request(aSize.Width(), aSize.Height());
+}
+
+SvxAreaTabPage::~SvxAreaTabPage()
+{
+ m_xFillTabPage.reset();
+}
+
+void SvxAreaTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ drawing::FillStyle eXFS = drawing::FillStyle_NONE;
+ if( rSet.GetItemState( XATTR_FILLSTYLE ) != SfxItemState::DONTCARE )
+ {
+ XFillStyleItem aFillStyleItem( rSet.Get( GetWhich( XATTR_FILLSTYLE ) ) );
+ eXFS = aFillStyleItem.GetValue();
+ m_rXFSet.Put( aFillStyleItem );
+ }
+
+ switch(eXFS)
+ {
+ default:
+ case drawing::FillStyle_NONE:
+ {
+ XFillUseSlideBackgroundItem aBckItem( rSet.Get(XATTR_FILLUSESLIDEBACKGROUND));
+ if (aBckItem.GetValue())
+ SelectFillType(*m_xBtnUseBackground);
+ else
+ SelectFillType(*m_xBtnNone);
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ m_rXFSet.Put( rSet.Get( GetWhich( XATTR_FILLCOLOR ) ) );
+ SelectFillType(*m_xBtnColor);
+ break;
+ }
+ case drawing::FillStyle_GRADIENT:
+ {
+ m_rXFSet.Put( rSet.Get( GetWhich( XATTR_FILLGRADIENT ) ) );
+ SelectFillType(*m_xBtnGradient);
+ break;
+ }
+ case drawing::FillStyle_HATCH:
+ {
+ m_rXFSet.Put( rSet.Get(XATTR_FILLHATCH) );
+ m_rXFSet.Put( rSet.Get(XATTR_FILLUSESLIDEBACKGROUND) );
+ m_rXFSet.Put( rSet.Get(XATTR_FILLCOLOR) );
+ SelectFillType(*m_xBtnHatch);
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ const bool bPattern = rSet.Get(GetWhich(XATTR_FILLBITMAP)).isPattern();
+ // pass full item set here, bitmap fill has many attributes (tiling, size, offset etc.)
+ m_rXFSet.Put( rSet );
+ if (!bPattern)
+ SelectFillType(*m_xBtnBitmap);
+ else
+ SelectFillType(*m_xBtnPattern);
+ break;
+ }
+ }
+}
+
+template< typename TTabPage >
+DeactivateRC SvxAreaTabPage::DeactivatePage_Impl( SfxItemSet* _pSet )
+{
+ return static_cast<TTabPage&>(*m_xFillTabPage).DeactivatePage(_pSet);
+}
+
+DeactivateRC SvxAreaTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ switch( eFillType )
+ {
+ case TRANSPARENT:
+ {
+ // Fill: None doesn't have its own tabpage and thus
+ // implementation of FillItemSet, so we supply it here
+ if ( m_bBtnClicked )
+ {
+ XFillStyleItem aStyleItem( drawing::FillStyle_NONE );
+ _pSet->Put( aStyleItem );
+ if (_pSet->HasItem(XATTR_FILLUSESLIDEBACKGROUND))
+ {
+ XFillUseSlideBackgroundItem aFillBgItem( false );
+ _pSet->Put( aFillBgItem );
+ }
+ }
+ break;
+ }
+ case SOLID:
+ return DeactivatePage_Impl<SvxColorTabPage>(_pSet);
+ case GRADIENT:
+ return DeactivatePage_Impl<SvxGradientTabPage>(_pSet);
+ case HATCH:
+ return DeactivatePage_Impl<SvxHatchTabPage>(_pSet);
+ case BITMAP:
+ return DeactivatePage_Impl<SvxBitmapTabPage&>(_pSet);
+ case PATTERN:
+ return DeactivatePage_Impl<SvxPatternTabPage>(_pSet);
+ case USE_BACKGROUND_FILL:
+ {
+ if ( m_bBtnClicked )
+ {
+ XFillStyleItem aStyleItem( drawing::FillStyle_NONE );
+ _pSet->Put( aStyleItem );
+ XFillUseSlideBackgroundItem aFillBgItem( true );
+ _pSet->Put( aFillBgItem );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return DeactivateRC::LeavePage;
+}
+
+template< typename TTabPage >
+bool SvxAreaTabPage::FillItemSet_Impl( SfxItemSet* rAttrs)
+{
+ return static_cast<TTabPage&>( *m_xFillTabPage ).FillItemSet( rAttrs );
+}
+
+bool SvxAreaTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ switch( eFillType )
+ {
+ case TRANSPARENT:
+ {
+ rAttrs->Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+ rAttrs->Put( XFillUseSlideBackgroundItem( false ) );
+ return true;
+ }
+ case SOLID:
+ {
+ return FillItemSet_Impl<SvxColorTabPage>( rAttrs );
+ }
+ case GRADIENT:
+ {
+ return FillItemSet_Impl<SvxGradientTabPage>( rAttrs );
+ }
+ case HATCH:
+ {
+ return FillItemSet_Impl<SvxHatchTabPage>( rAttrs );
+ }
+ case BITMAP:
+ {
+ return FillItemSet_Impl<SvxBitmapTabPage>( rAttrs );
+ }
+ case PATTERN:
+ {
+ return FillItemSet_Impl<SvxPatternTabPage>( rAttrs );
+ }
+ case USE_BACKGROUND_FILL:
+ {
+ rAttrs->Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+ rAttrs->Put( XFillUseSlideBackgroundItem( true ) );
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+template< typename TTabPage >
+void SvxAreaTabPage::Reset_Impl( const SfxItemSet* rAttrs )
+{
+ static_cast<TTabPage&>( *m_xFillTabPage ).Reset( rAttrs );
+}
+
+void SvxAreaTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ m_bBtnClicked = false;
+ auto eFillType = maBox.GetCurrentButtonPos();
+ switch(eFillType)
+ {
+ case SOLID:
+ {
+ Reset_Impl<SvxColorTabPage>( rAttrs );
+ break;
+ }
+ case GRADIENT:
+ {
+ Reset_Impl<SvxGradientTabPage>( rAttrs );
+ break;
+ }
+ case HATCH:
+ {
+ Reset_Impl<SvxHatchTabPage>( rAttrs );
+ break;
+ }
+ case BITMAP:
+ {
+ Reset_Impl<SvxBitmapTabPage>( rAttrs );
+ break;
+ }
+ case PATTERN:
+ {
+ Reset_Impl<SvxPatternTabPage>( rAttrs );
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxAreaTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxAreaTabPage>(pPage, pController, *rAttrs);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+std::unique_ptr<SfxTabPage> SvxAreaTabPage::CreateWithSlideBackground(
+ weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxAreaTabPage>(pPage, pController, *rAttrs, true);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+namespace {
+
+std::unique_ptr<SfxTabPage> lcl_CreateFillStyleTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+{
+ CreateTabPage fnCreate = nullptr;
+ switch(nId)
+ {
+ case TRANSPARENT: fnCreate = nullptr; break;
+ case SOLID: fnCreate = &SvxColorTabPage::Create; break;
+ case GRADIENT: fnCreate = &SvxGradientTabPage::Create; break;
+ case HATCH: fnCreate = &SvxHatchTabPage::Create; break;
+ case BITMAP: fnCreate = &SvxBitmapTabPage::Create; break;
+ case PATTERN: fnCreate = &SvxPatternTabPage::Create; break;
+ case USE_BACKGROUND_FILL: fnCreate = nullptr; break;
+ }
+ return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
+}
+
+}
+
+IMPL_LINK(SvxAreaTabPage, SelectFillTypeHdl_Impl, weld::Toggleable&, rButton, void)
+{
+ //tdf#124549 - If the button is already active do not toggle it back.
+ if(!rButton.get_active())
+ rButton.set_active(true);
+
+ SelectFillType(rButton);
+ m_bBtnClicked = true;
+}
+
+void SvxAreaTabPage::SelectFillType(weld::Toggleable& rButton, const SfxItemSet* _pSet)
+{
+ if (_pSet)
+ m_rXFSet.Set(*_pSet);
+
+ sal_Int32 nPos = maBox.GetButtonPos(&rButton);
+ if (nPos != -1 && (_pSet || nPos != maBox.GetCurrentButtonPos()))
+ {
+ maBox.SelectButton(&rButton);
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ m_xFillTabPage = lcl_CreateFillStyleTabPage(eFillType, m_xFillTab.get(), GetDialogController(), m_rXFSet);
+ if (m_xFillTabPage)
+ {
+ m_xFillTabPage->SetDialogController(GetDialogController());
+ CreatePage(eFillType, *m_xFillTabPage);
+ }
+ }
+}
+
+void SvxAreaTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxColorListItem* pColorListItem = aSet.GetItem<SvxColorListItem>(SID_COLOR_TABLE, false);
+ const SvxGradientListItem* pGradientListItem = aSet.GetItem<SvxGradientListItem>(SID_GRADIENT_LIST, false);
+ const SvxHatchListItem* pHatchingListItem = aSet.GetItem<SvxHatchListItem>(SID_HATCH_LIST, false);
+ const SvxBitmapListItem* pBitmapListItem = aSet.GetItem<SvxBitmapListItem>(SID_BITMAP_LIST, false);
+ const SvxPatternListItem* pPatternListItem = aSet.GetItem<SvxPatternListItem>(SID_PATTERN_LIST, false);
+
+ if (pColorListItem)
+ SetColorList(pColorListItem->GetColorList());
+ if (pGradientListItem)
+ SetGradientList(pGradientListItem->GetGradientList());
+ if (pHatchingListItem)
+ SetHatchingList(pHatchingListItem->GetHatchList());
+ if (pBitmapListItem)
+ SetBitmapList(pBitmapListItem->GetBitmapList());
+ if (pPatternListItem)
+ SetPatternList(pPatternListItem->GetPatternList());
+}
+
+void SvxAreaTabPage::CreatePage(sal_Int32 nId, SfxTabPage& rTab)
+{
+ if(nId == SOLID )
+ {
+ auto& rColorTab = static_cast<SvxColorTabPage&>(rTab);
+ rColorTab.SetColorList(m_pColorList);
+ rColorTab.SetColorChgd(m_pnColorListState);
+ rColorTab.Construct();
+ rColorTab.ActivatePage(m_rXFSet);
+ rColorTab.Reset(&m_rXFSet);
+ rColorTab.set_visible(true);
+ }
+ else if(nId == GRADIENT)
+ {
+ auto& rGradientTab = static_cast<SvxGradientTabPage&>(rTab);
+ rGradientTab.SetColorList(m_pColorList);
+ rGradientTab.SetGradientList(m_pGradientList);
+ rGradientTab.SetGrdChgd(m_pnGradientListState);
+ rGradientTab.SetColorChgd(m_pnColorListState);
+ rGradientTab.Construct();
+ rGradientTab.ActivatePage(m_rXFSet);
+ rGradientTab.Reset(&m_rXFSet);
+ rGradientTab.set_visible(true);
+ }
+ else if(nId == HATCH)
+ {
+ auto& rHatchTab = static_cast<SvxHatchTabPage&>(rTab);
+ rHatchTab.SetColorList(m_pColorList);
+ rHatchTab.SetHatchingList(m_pHatchingList);
+ rHatchTab.SetHtchChgd(m_pnHatchingListState);
+ rHatchTab.SetColorChgd(m_pnColorListState);
+ rHatchTab.Construct();
+ rHatchTab.ActivatePage(m_rXFSet);
+ rHatchTab.Reset(&m_rXFSet);
+ rHatchTab.set_visible(true);
+ }
+ else if(nId == BITMAP)
+ {
+ auto& rBitmapTab = static_cast<SvxBitmapTabPage&>(rTab);
+ rBitmapTab.SetBitmapList(m_pBitmapList);
+ rBitmapTab.SetBmpChgd(m_pnBitmapListState);
+ rBitmapTab.Construct();
+ rBitmapTab.ActivatePage(m_rXFSet);
+ rBitmapTab.Reset(&m_rXFSet);
+ rBitmapTab.set_visible(true);
+ }
+ else if(nId == PATTERN)
+ {
+ auto& rPatternTab = static_cast<SvxPatternTabPage&>(rTab);
+ rPatternTab.SetColorList(m_pColorList);
+ rPatternTab.SetPatternList(m_pPatternList);
+ rPatternTab.SetPtrnChgd(m_pnPatternListState);
+ rPatternTab.SetColorChgd(m_pnColorListState);
+ rPatternTab.Construct();
+ rPatternTab.ActivatePage(m_rXFSet);
+ rPatternTab.Reset(&m_rXFSet);
+ rPatternTab.set_visible(true);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx
new file mode 100644
index 000000000..bf3b742a1
--- /dev/null
+++ b/cui/source/tabpages/tpbitmap.cxx
@@ -0,0 +1,824 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <stdlib.h>
+#include <tools/urlobj.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbmsxy.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbmsli.hxx>
+#include <svx/xflbmpit.hxx>
+#include <svx/xflboxy.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <cuitabarea.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/opengrf.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svxdlg.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <sal/log.hxx>
+#include <comphelper/lok.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace com::sun::star;
+
+namespace {
+
+enum BitmapStyle
+{
+ CUSTOM,
+ TILED,
+ STRETCHED
+};
+
+enum TileOffset
+{
+ ROW,
+ COLUMN
+};
+
+}
+
+SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/imagetabpage.ui", "ImageTabPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnBitmapListState(nullptr)
+ , m_fObjectWidth(0.0)
+ , m_fObjectHeight(0.0)
+ , m_bLogicalSize(false)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , mpView(nullptr)
+ , m_xBitmapLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("imagewin", true)))
+ , m_xBitmapStyleLB(m_xBuilder->weld_combo_box("imagestyle"))
+ , m_xSizeBox(m_xBuilder->weld_container("sizebox"))
+ , m_xTsbScale(m_xBuilder->weld_check_button("scaletsb"))
+ , m_xBitmapWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PERCENT))
+ , m_xBitmapHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PERCENT))
+ , m_xPositionBox(m_xBuilder->weld_container("posbox"))
+ , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
+ , m_xPositionOffBox(m_xBuilder->weld_container("posoffbox"))
+ , m_xPositionOffX(m_xBuilder->weld_metric_spin_button("posoffx", FieldUnit::PERCENT))
+ , m_xPositionOffY(m_xBuilder->weld_metric_spin_button("posoffy", FieldUnit::PERCENT))
+ , m_xTileOffBox(m_xBuilder->weld_container("tileoffbox"))
+ , m_xTileOffLB(m_xBuilder->weld_combo_box("tileofflb"))
+ , m_xTileOffset(m_xBuilder->weld_metric_spin_button("tileoffmtr", FieldUnit::PERCENT))
+ , m_xBtnImport(m_xBuilder->weld_button("BTN_IMPORT"))
+ , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, "CTL_IMAGE_PREVIEW", m_aCtlBitmapPreview))
+ , m_xBitmapLBWin(new weld::CustomWeld(*m_xBuilder, "IMAGE", *m_xBitmapLB))
+{
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
+ m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+
+ m_xBitmapLB->SetSelectHdl( LINK(this, SvxBitmapTabPage, ModifyBitmapHdl) );
+ m_xBitmapLB->SetRenameHdl( LINK(this, SvxBitmapTabPage, ClickRenameHdl) );
+ m_xBitmapLB->SetDeleteHdl( LINK(this, SvxBitmapTabPage, ClickDeleteHdl) );
+ m_xBitmapStyleLB->connect_changed( LINK(this, SvxBitmapTabPage, ModifyBitmapStyleHdl) );
+ Link<weld::MetricSpinButton&, void> aLink1( LINK(this, SvxBitmapTabPage, ModifyBitmapSizeHdl) );
+ m_xBitmapWidth->connect_value_changed( aLink1 );
+ m_xBitmapHeight->connect_value_changed( aLink1 );
+ m_xTsbScale->connect_toggled(LINK(this, SvxBitmapTabPage, ClickScaleHdl));
+ m_xPositionLB->connect_changed( LINK( this, SvxBitmapTabPage, ModifyBitmapPositionHdl ) );
+ Link<weld::MetricSpinButton&, void> aLink( LINK( this, SvxBitmapTabPage, ModifyPositionOffsetHdl ) );
+ m_xPositionOffX->connect_value_changed(aLink);
+ m_xPositionOffY->connect_value_changed(aLink);
+ m_xTileOffset->connect_value_changed( LINK( this, SvxBitmapTabPage, ModifyTileOffsetHdl ) );
+ m_xBtnImport->connect_clicked( LINK(this, SvxBitmapTabPage, ClickImportHdl) );
+ if (comphelper::LibreOfficeKit::isActive())
+ m_xBtnImport->hide();
+
+ // Calculate size of display boxes
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlBitmapPreview.GetDrawingArea()->get_ref_device());
+ m_xBitmapLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlBitmapPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ SfxItemPool* pPool = m_rXFSet.GetPool();
+ mePoolUnit = pPool->GetMetric( XATTR_FILLBMP_SIZEX );
+ meFieldUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xBitmapWidth, meFieldUnit, true );
+ SetFieldUnit( *m_xBitmapHeight, meFieldUnit, true );
+
+ m_xBitmapLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if( pViewShell )
+ mpView = pViewShell->GetDrawView();
+ DBG_ASSERT( mpView, "no valid view (!)" );
+}
+
+SvxBitmapTabPage::~SvxBitmapTabPage()
+{
+ m_xBitmapLBWin.reset();
+ m_xBitmapLB.reset();
+ m_xCtlBitmapPreview.reset();
+}
+
+void SvxBitmapTabPage::Construct()
+{
+ m_xBitmapLB->FillPresetListBox( *m_pBitmapList );
+}
+
+void SvxBitmapTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ XFillBitmapItem aItem( rSet.Get(XATTR_FILLBITMAP) );
+
+ sal_Int32 nPos( 0 );
+ if ( !aItem.isPattern() )
+ {
+ nPos = SearchBitmapList( aItem.GetGraphicObject() );
+ if (nPos == -1)
+ return;
+ }
+ else
+ {
+ m_xBitmapWidth->set_value( 100, FieldUnit::NONE );
+ m_xBitmapHeight->set_value( 100, FieldUnit::NONE );
+ const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeXItem( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) ) );
+ const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeYItem( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) ) );
+ }
+
+ sal_uInt16 nId = m_xBitmapLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xBitmapLB->SelectItem( nId );
+}
+
+DeactivateRC SvxBitmapTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxBitmapTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ rAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ const XBitmapEntry* pXBitmapEntry = m_pBitmapList->GetBitmap(nPos);
+ const OUString aString(m_xBitmapLB->GetItemText( m_xBitmapLB->GetSelectedItemId() ));
+ rAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
+ }
+
+ BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
+ bool bIsStretched( eStylePos == STRETCHED );
+ bool bIsTiled( eStylePos == TILED );
+
+ rAttrs->Put( XFillBmpTileItem(bIsTiled) );
+ rAttrs->Put( XFillBmpStretchItem(bIsStretched) );
+
+ if(!bIsStretched)
+ {
+ Size aSetBitmapSize;
+ switch(eStylePos)
+ {
+ case CUSTOM:
+ case TILED:
+ {
+ sal_Int64 nWidthPercent = m_xBitmapWidth->get_value(FieldUnit::NONE);
+ sal_Int64 nHeightPercent = m_xBitmapHeight->get_value(FieldUnit::NONE);
+ if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ aSetBitmapSize.setWidth( -nWidthPercent );
+ aSetBitmapSize.setHeight( -nHeightPercent );
+ }
+ else if (!m_bLogicalSize)
+ {
+ aSetBitmapSize.setWidth( GetCoreValue(*m_xBitmapWidth, mePoolUnit) );
+ aSetBitmapSize.setHeight( GetCoreValue(*m_xBitmapHeight, mePoolUnit) );
+ }
+ else
+ {
+ rAttrs->Put( XFillBmpSizeLogItem(true) );
+ aSetBitmapSize.setWidth( 0 );
+ aSetBitmapSize.setHeight( 0 );
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ rAttrs->Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
+ rAttrs->Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
+ }
+
+ if (m_xPositionLB->get_sensitive())
+ rAttrs->Put( XFillBmpPosItem( static_cast<RectPoint>( m_xPositionLB->get_active() ) ) );
+ if (m_xPositionOffX->get_sensitive())
+ rAttrs->Put( XFillBmpPosOffsetXItem(m_xPositionOffX->get_value(FieldUnit::PERCENT)));
+ if (m_xPositionOffY->get_sensitive())
+ rAttrs->Put( XFillBmpPosOffsetYItem(m_xPositionOffY->get_value(FieldUnit::PERCENT)));
+ if (m_xTileOffBox->get_sensitive())
+ {
+ TileOffset eValue = static_cast<TileOffset>(m_xTileOffLB->get_active());
+ sal_uInt16 nOffsetValue = static_cast<sal_uInt16>(m_xTileOffset->get_value(FieldUnit::PERCENT));
+ sal_uInt16 nRowOff = (eValue == ROW) ? nOffsetValue : 0;
+ sal_uInt16 nColOff = (eValue == COLUMN) ? nOffsetValue : 0;
+ rAttrs->Put( XFillBmpTileOffsetXItem(nRowOff) );
+ rAttrs->Put( XFillBmpTileOffsetYItem(nColOff) );
+ }
+ return true;
+}
+
+
+void SvxBitmapTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ double transfWidth = 0.0;
+ double transfHeight = 0.0;
+ double fUIScale = 1.0;
+ if (mpView)
+ {
+ fUIScale = ( mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0);
+
+
+ if (mpView->AreObjectsMarked())
+ {
+ SfxItemSet rGeoAttr(mpView->GetGeoAttrFromMarked());
+ transfWidth = static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_WIDTH )->GetValue());
+ transfHeight= static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_HEIGHT )->GetValue());
+ }
+ }
+ m_fObjectWidth = std::max( transfWidth, 1.0 );
+ m_fObjectHeight = std::max( transfHeight, 1.0 );
+ double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectWidth), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
+ m_fObjectWidth = fTmpWidth;
+
+ double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectHeight), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
+ m_fObjectHeight = fTmpHeight;
+
+ XFillBitmapItem aItem( rAttrs->Get(XATTR_FILLBITMAP) );
+
+ if(!aItem.isPattern())
+ {
+ m_rXFSet.Put( aItem );
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+ }
+ else
+ m_xCtlBitmapPreview->set_sensitive(false);
+
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ pGraphicObject.reset( new GraphicObject(aItem.GetGraphicObject()) );
+
+ BitmapEx aBmpEx(pGraphicObject->GetGraphic().GetBitmapEx());
+ Size aTempBitmapSize = aBmpEx.GetSizePixel();
+ rBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aTempBitmapSize, MapMode(MapUnit::Map100thMM));
+ CalculateBitmapPresetSize();
+
+ bool bTiled = false; bool bStretched = false;
+ if(rAttrs->GetItemState( XATTR_FILLBMP_TILE ) != SfxItemState::DONTCARE)
+ bTiled = rAttrs->Get( XATTR_FILLBMP_TILE ).GetValue();
+ if(rAttrs->GetItemState( XATTR_FILLBMP_STRETCH ) != SfxItemState::DONTCARE)
+ bStretched = rAttrs->Get( XATTR_FILLBMP_STRETCH ).GetValue();
+
+ if (bTiled)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(TILED));
+ else if (bStretched)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(STRETCHED));
+ else
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
+
+ tools::Long nWidth = 0;
+ tools::Long nHeight = 0;
+
+ if(rAttrs->GetItemState(XATTR_FILLBMP_SIZELOG) != SfxItemState::DONTCARE)
+ {
+ if (rAttrs->Get( XATTR_FILLBMP_SIZELOG ).GetValue())
+ {
+ m_xTsbScale->set_state(TRISTATE_FALSE);
+ m_bLogicalSize = true;
+ }
+ else
+ {
+ m_xTsbScale->set_state(TRISTATE_TRUE);
+ m_bLogicalSize = false;
+ }
+ }
+ else
+ m_xTsbScale->set_state(TRISTATE_INDET);
+
+ TriState eRelative = TRISTATE_FALSE;
+ if(rAttrs->GetItemState(XATTR_FILLBMP_SIZEX) != SfxItemState::DONTCARE)
+ {
+ nWidth = static_cast<const XFillBmpSizeXItem&>( rAttrs->Get( XATTR_FILLBMP_SIZEX ) ).GetValue();
+ if(nWidth == 0)
+ nWidth = rBitmapSize.Width();
+ else if(nWidth < 0)
+ {
+ eRelative = TRISTATE_TRUE;
+ nWidth = std::abs(nWidth);
+ }
+ }
+
+ if(rAttrs->GetItemState( XATTR_FILLBMP_SIZEY ) != SfxItemState::DONTCARE)
+ {
+ nHeight = rAttrs->Get( XATTR_FILLBMP_SIZEY ).GetValue();
+ if(nHeight == 0)
+ nHeight = rBitmapSize.Height();
+ else if(nHeight < 0)
+ {
+ eRelative = TRISTATE_TRUE;
+ nHeight = std::abs(nHeight);
+ }
+ }
+ m_xTsbScale->set_state(eRelative);
+ ClickScaleHdl(*m_xTsbScale);
+
+
+ if(!rBitmapSize.IsEmpty())
+ {
+ if (eRelative == TRISTATE_TRUE)
+ {
+ m_xBitmapWidth->set_value(nWidth, FieldUnit::NONE);
+ m_xBitmapHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+ else
+ {
+ SetMetricValue(*m_xBitmapWidth, nWidth, mePoolUnit);
+ SetMetricValue(*m_xBitmapHeight, nHeight, mePoolUnit);
+ }
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POS ) != SfxItemState::DONTCARE )
+ {
+ RectPoint eValue = rAttrs->Get( XATTR_FILLBMP_POS ).GetValue();
+ m_xPositionLB->set_active( static_cast< sal_Int32 >(eValue) );
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETX ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETX ).GetValue();
+ m_xPositionOffX->set_value(nValue, FieldUnit::PERCENT);
+ }
+ else
+ m_xPositionOffX->set_text("");
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETY ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETY ).GetValue();
+ m_xPositionOffY->set_value(nValue, FieldUnit::PERCENT);
+ }
+ else
+ m_xPositionOffY->set_text("");
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETX ) != SfxItemState::DONTCARE)
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETX ).GetValue();
+ if(nValue > 0)
+ {
+ m_xTileOffLB->set_active(static_cast<sal_Int32>(ROW));
+ m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
+ }
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETY ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETY ).GetValue();
+ if(nValue > 0)
+ {
+ m_xTileOffLB->set_active(static_cast<sal_Int32>(COLUMN));
+ m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
+ }
+ }
+
+ ClickBitmapHdl_Impl();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxBitmapTabPage>(pPage, pController, *rAttrs);
+}
+
+void SvxBitmapTabPage::ClickBitmapHdl_Impl()
+{
+ m_xBitmapLBWin->set_sensitive(true);
+ m_xCtlBitmapPreview->set_sensitive(true);
+
+ ModifyBitmapHdl(m_xBitmapLB.get());
+}
+
+void SvxBitmapTabPage::CalculateBitmapPresetSize()
+{
+ if(rBitmapSize.IsEmpty())
+ return;
+
+ tools::Long nObjectWidth = static_cast<tools::Long>(m_fObjectWidth);
+ tools::Long nObjectHeight = static_cast<tools::Long>(m_fObjectHeight);
+
+ if(std::abs(rBitmapSize.Width() - nObjectWidth) < std::abs(rBitmapSize.Height() - nObjectHeight))
+ {
+ rFilledSize.setWidth( nObjectWidth );
+ rFilledSize.setHeight( rBitmapSize.Height()*nObjectWidth/rBitmapSize.Width() );
+ rZoomedSize.setWidth( rBitmapSize.Width()*nObjectHeight/rBitmapSize.Height() );
+ rZoomedSize.setHeight( nObjectHeight );
+ }
+ else
+ {
+ rFilledSize.setWidth( rBitmapSize.Width()*nObjectHeight/rBitmapSize.Height() );
+ rFilledSize.setHeight( nObjectHeight );
+ rZoomedSize.setWidth( nObjectWidth );
+ rZoomedSize.setHeight( rBitmapSize.Height()*nObjectWidth/rBitmapSize.Width() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, ValueSet*, void)
+{
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
+ }
+ else
+ {
+ if(const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLSTYLE)))
+ {
+ const drawing::FillStyle eXFS(pFillStyleItem->GetValue());
+
+ const XFillBitmapItem* pBitmapItem;
+ if((drawing::FillStyle_BITMAP == eXFS) && (pBitmapItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLBITMAP))))
+ {
+ pGraphicObject.reset(new GraphicObject(pBitmapItem->GetGraphicObject()));
+ }
+ }
+
+ if(!pGraphicObject)
+ {
+ sal_uInt16 nId = m_xBitmapLB->GetItemId(0);
+ m_xBitmapLB->SelectItem(nId);
+
+ if(0 != nId)
+ {
+ pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap(0)->GetGraphicObject()));
+ }
+ }
+ }
+
+ if(pGraphicObject)
+ {
+ BitmapEx aBmpEx(pGraphicObject->GetGraphic().GetBitmapEx());
+ Size aTempBitmapSize = aBmpEx.GetSizePixel();
+ const double fUIScale = ( (mpView && mpView->GetModel()) ? double(mpView->GetModel()->GetUIScale()) : 1.0);
+ Size aBitmapSize100mm = o3tl::convert(aTempBitmapSize, o3tl::Length::pt, o3tl::Length::mm100);
+
+ rBitmapSize.setWidth(aBitmapSize100mm.Width() / fUIScale);
+ rBitmapSize.setHeight(aBitmapSize100mm.Height() / fUIScale);
+ CalculateBitmapPresetSize();
+ ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
+ ModifyBitmapPositionHdl( *m_xPositionLB );
+
+ m_rXFSet.ClearItem(XATTR_FILLBITMAP);
+ m_rXFSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ m_rXFSet.Put(XFillBitmapItem(OUString(), *pGraphicObject));
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+ }
+ else
+ {
+ SAL_WARN("cui.tabpages", "SvxBitmapTabPage::ModifyBitmapHdl(): null pGraphicObject");
+ }
+
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_NEW_BITMAP ) );
+ OUString aName( m_pBitmapList->GetBitmap( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nBitmapPos = SearchBitmapList( aName );
+ bool bValidBitmapName = (nBitmapPos == static_cast<sal_Int32>(nPos) ) || (nBitmapPos == -1);
+
+ if(bValidBitmapName)
+ {
+ bLoop = false;
+ m_pBitmapList->GetBitmap(nPos)->SetName(aName);
+
+ m_xBitmapLB->SetItemText(nId, aName);
+ m_xBitmapLB->SelectItem( nId );
+
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickDeleteHdl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletebitmapdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelBitmapDialog"));
+
+ if (xQueryBox->run() != RET_YES)
+ return;
+
+ sal_uInt16 nNextId = m_xBitmapLB->GetItemId(nPos + 1);
+ if (!nNextId)
+ nNextId = m_xBitmapLB->GetItemId(nPos - 1);
+
+ m_pBitmapList->Remove( static_cast<sal_uInt16>(nPos) );
+ m_xBitmapLB->RemoveItem( nId );
+
+ m_xBitmapLB->SelectItem(nNextId);
+
+ m_aCtlBitmapPreview.Invalidate();
+ ModifyBitmapHdl(m_xBitmapLB.get());
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapSizeHdl, weld::MetricSpinButton&, void )
+{
+ m_bLogicalSize = false;
+ if (m_xTsbScale->get_state() != TRISTATE_TRUE && static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active()) != TILED)
+ {
+ sal_Int64 nWidthPercent = m_xBitmapWidth->denormalize(m_xBitmapWidth->get_value(FieldUnit::NONE));
+ sal_Int64 nHeightPercent = m_xBitmapHeight->denormalize(m_xBitmapHeight->get_value(FieldUnit::NONE));
+ if (nWidthPercent == 100 && nHeightPercent == 100)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
+ }
+ ModifyBitmapStyleHdl(*m_xBitmapStyleLB);
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ClickScaleHdl, weld::Toggleable&, void )
+{
+ if (m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ m_xBitmapWidth->set_digits( 0 );
+ m_xBitmapWidth->set_unit(FieldUnit::PERCENT);
+ m_xBitmapWidth->set_value(100, FieldUnit::NONE);
+ m_xBitmapWidth->set_range(0, 100, FieldUnit::NONE);
+
+ m_xBitmapHeight->set_digits( 0 );
+ m_xBitmapHeight->set_unit(FieldUnit::PERCENT);
+ m_xBitmapHeight->set_value(100, FieldUnit::NONE);
+ m_xBitmapHeight->set_range(0, 100, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xBitmapWidth->set_digits( 2 );
+ m_xBitmapWidth->set_unit(meFieldUnit);
+ m_xBitmapWidth->set_value(100, FieldUnit::NONE);
+ m_xBitmapWidth->set_range(0, 999900, FieldUnit::NONE);
+
+ m_xBitmapHeight->set_digits( 2 );
+ m_xBitmapHeight->set_unit(meFieldUnit);
+ m_xBitmapHeight->set_value(100, FieldUnit::NONE);
+ m_xBitmapHeight->set_range(0, 999900, FieldUnit::NONE);
+ }
+
+ ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapStyleHdl, weld::ComboBox&, void )
+{
+ BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
+ bool bIsStretched( eStylePos == STRETCHED );
+ bool bIsTiled( eStylePos == TILED );
+
+ m_xSizeBox->set_sensitive( !bIsStretched );
+ m_xPositionBox->set_sensitive( !bIsStretched );
+ m_xPositionOffBox->set_sensitive( bIsTiled );
+ m_xTileOffBox->set_sensitive( bIsTiled );
+
+ m_rXFSet.Put( XFillBmpTileItem( bIsTiled ) );
+ m_rXFSet.Put( XFillBmpStretchItem( bIsStretched ) );
+
+ if(!bIsStretched)
+ {
+ Size aSetBitmapSize;
+ switch(eStylePos)
+ {
+ case CUSTOM:
+ case TILED:
+ {
+ if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ aSetBitmapSize.setWidth(-m_xBitmapWidth->get_value(FieldUnit::NONE));
+ aSetBitmapSize.setHeight(-m_xBitmapHeight->get_value(FieldUnit::NONE));
+ }
+ else
+ {
+ aSetBitmapSize.setWidth( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) );
+ aSetBitmapSize.setHeight( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ m_rXFSet.Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
+ m_rXFSet.Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
+ }
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapPositionHdl, weld::ComboBox&, void)
+{
+ if (m_xPositionLB->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosItem( static_cast< RectPoint >( m_xPositionLB->get_active() ) ) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyPositionOffsetHdl, weld::MetricSpinButton&, void)
+{
+ if (m_xPositionOffX->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosOffsetXItem( m_xPositionOffX->get_value(FieldUnit::PERCENT) ) );
+
+ if (m_xPositionOffY->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosOffsetYItem( m_xPositionOffY->get_value(FieldUnit::PERCENT) ) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyTileOffsetHdl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nTileXOff = 0;
+ sal_uInt16 nTileYOff = 0;
+
+ if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(ROW))
+ nTileXOff = m_xTileOffset->get_value(FieldUnit::PERCENT);
+
+ if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(COLUMN))
+ nTileYOff = m_xTileOffset->get_value(FieldUnit::PERCENT);
+
+ m_rXFSet.Put( XFillBmpTileOffsetXItem(nTileXOff) );
+ m_rXFSet.Put( XFillBmpTileOffsetYItem(nTileYOff) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickImportHdl, weld::Button&, void)
+{
+ weld::Window* pDialogFrameWeld = GetFrameWeld();
+
+ SvxOpenGraphicDialog aDlg(CuiResId(RID_CUISTR_ADD_IMAGE), pDialogFrameWeld);
+ aDlg.EnableLink(false);
+ tools::Long nCount = m_pBitmapList->Count();
+
+ if( aDlg.Execute() )
+ return;
+
+ Graphic aGraphic;
+
+ std::unique_ptr<weld::WaitObject> xWait(new weld::WaitObject(pDialogFrameWeld));
+ ErrCode nError = aDlg.GetGraphic( aGraphic );
+ xWait.reset();
+
+ if( !nError )
+ {
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_EXT_BITMAP));
+
+ // convert file URL to UI name
+ OUString aName;
+ INetURLObject aURL( aDlg.GetPath() );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(
+ pDialogFrameWeld, aURL.GetLastName().getToken(0, '.'), aDesc));
+ nError = ErrCode(1);
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bool bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if( aName == m_pBitmapList->GetBitmap( i )->GetName() )
+ bDifferent = false;
+
+ if( bDifferent ) {
+ nError = ERRCODE_NONE;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ m_pBitmapList->Insert(std::make_unique<XBitmapEntry>(aGraphic, aName), nCount);
+
+ sal_Int32 nId = m_xBitmapLB->GetItemId( nCount - 1 );
+ BitmapEx aBitmap = m_pBitmapList->GetBitmapForPreview( nCount, m_xBitmapLB->GetIconSize() );
+
+ m_xBitmapLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xBitmapLB->SelectItem( nId + 1 );
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+
+ ModifyBitmapHdl(m_xBitmapLB.get());
+ }
+ }
+ else
+ {
+ // graphic couldn't be loaded
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+}
+
+sal_Int32 SvxBitmapTabPage::SearchBitmapList(const GraphicObject& rGraphicObject)
+{
+ tools::Long nCount = m_pBitmapList->Count();
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount;i++)
+ {
+ if(rGraphicObject.GetUniqueID() == m_pBitmapList->GetBitmap( i )->GetGraphicObject().GetUniqueID())
+ {
+ nPos = i;
+ break;
+ }
+ }
+ return nPos;
+}
+
+sal_Int32 SvxBitmapTabPage::SearchBitmapList(std::u16string_view rBitmapName)
+{
+ tools::Long nCount = m_pBitmapList->Count();
+ bool bValidBitmapName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidBitmapName;i++)
+ {
+ if(rBitmapName == m_pBitmapList->GetBitmap( i )->GetName())
+ {
+ nPos = i;
+ bValidBitmapName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpcolor.cxx b/cui/source/tabpages/tpcolor.cxx
new file mode 100644
index 000000000..e65c49617
--- /dev/null
+++ b/cui/source/tabpages/tpcolor.cxx
@@ -0,0 +1,794 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <i18nutil/unicode.hxx>
+#include <svtools/colrdlg.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xtable.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <cuitabline.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <officecfg/Office/Common.hxx>
+#include <osl/diagnose.h>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+using namespace com::sun::star;
+
+SvxColorTabPage::SvxColorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/colorpage.ui", "ColorPage", &rInAttrs)
+ , rOutAttrs ( rInAttrs )
+ // All the horrific pointers we store and should not
+ , pnColorListState( nullptr )
+ , aXFillAttr( rInAttrs.GetPool() )
+ , rXFSet( aXFillAttr.GetItemSet() )
+ , eCM( ColorModel::RGB )
+ , m_xValSetColorList(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("colorsetwin", true)))
+ , m_xValSetRecentList(new SvxColorValueSet(nullptr))
+ , m_xSelectPalette(m_xBuilder->weld_combo_box("paletteselector"))
+ , m_xRbRGB(m_xBuilder->weld_radio_button("RGB"))
+ , m_xRbCMYK(m_xBuilder->weld_radio_button("CMYK"))
+ , m_xRGBcustom(m_xBuilder->weld_widget("rgbcustom"))
+ , m_xRGBpreset(m_xBuilder->weld_widget("rgbpreset"))
+ , m_xRpreset(m_xBuilder->weld_entry("R_preset"))
+ , m_xGpreset(m_xBuilder->weld_entry("G_preset"))
+ , m_xBpreset(m_xBuilder->weld_entry("B_preset"))
+ , m_xRcustom(m_xBuilder->weld_spin_button("R_custom"))
+ , m_xGcustom(m_xBuilder->weld_spin_button("G_custom"))
+ , m_xBcustom(m_xBuilder->weld_spin_button("B_custom"))
+ , m_xHexpreset(new weld::HexColorControl(m_xBuilder->weld_entry("hex_preset")))
+ , m_xHexcustom(new weld::HexColorControl(m_xBuilder->weld_entry("hex_custom")))
+ , m_xCMYKcustom(m_xBuilder->weld_widget("cmykcustom"))
+ , m_xCMYKpreset(m_xBuilder->weld_widget("cmykpreset"))
+ , m_xCpreset(m_xBuilder->weld_entry("C_preset"))
+ , m_xYpreset(m_xBuilder->weld_entry("Y_preset"))
+ , m_xMpreset(m_xBuilder->weld_entry("M_preset"))
+ , m_xKpreset(m_xBuilder->weld_entry("K_preset"))
+ , m_xCcustom(m_xBuilder->weld_metric_spin_button("C_custom", FieldUnit::PERCENT))
+ , m_xYcustom(m_xBuilder->weld_metric_spin_button("Y_custom", FieldUnit::PERCENT))
+ , m_xMcustom(m_xBuilder->weld_metric_spin_button("M_custom", FieldUnit::PERCENT))
+ , m_xKcustom(m_xBuilder->weld_metric_spin_button("K_custom", FieldUnit::PERCENT))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnDelete(m_xBuilder->weld_button("delete"))
+ , m_xBtnWorkOn(m_xBuilder->weld_button("edit"))
+ , m_xMoreColors(m_xBuilder->weld_button("btnMoreColors"))
+ , m_xCtlPreviewOld(new weld::CustomWeld(*m_xBuilder, "oldpreview", m_aCtlPreviewOld))
+ , m_xCtlPreviewNew(new weld::CustomWeld(*m_xBuilder, "newpreview", m_aCtlPreviewNew))
+ , m_xValSetColorListWin(new weld::CustomWeld(*m_xBuilder, "colorset", *m_xValSetColorList))
+ , m_xValSetRecentListWin(new weld::CustomWeld(*m_xBuilder, "recentcolorset", *m_xValSetRecentList))
+{
+ Size aSize(m_xBtnWorkOn->get_approximate_digit_width() * 25,
+ m_xBtnWorkOn->get_text_height() * 10);
+ m_xValSetColorList->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xBtnWorkOn->get_approximate_digit_width() * 8,
+ m_xBtnWorkOn->get_text_height() * 3);
+ m_aCtlPreviewOld.set_size_request(aSize.Width(), aSize.Height());
+ m_aCtlPreviewNew.set_size_request(aSize.Width(), aSize.Height());
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // setting the output device
+ rXFSet.Put( XFillStyleItem(drawing::FillStyle_SOLID) );
+ rXFSet.Put( XFillColorItem(OUString(), COL_BLACK) );
+ m_aCtlPreviewOld.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ // set handler
+ m_xSelectPalette->connect_changed(LINK(this, SvxColorTabPage, SelectPaletteLBHdl));
+ Link<ValueSet*, void> aValSelectLink = LINK(this, SvxColorTabPage, SelectValSetHdl_Impl);
+ m_xValSetColorList->SetSelectHdl(aValSelectLink);
+ m_xValSetRecentList->SetSelectHdl(aValSelectLink);
+
+ Link<weld::SpinButton&,void> aSpinLink = LINK(this, SvxColorTabPage, SpinValueHdl_Impl);
+ m_xRcustom->connect_value_changed(aSpinLink);
+ m_xGcustom->connect_value_changed(aSpinLink);
+ m_xBcustom->connect_value_changed(aSpinLink);
+ Link<weld::Entry&,void> aEntryLink = LINK(this, SvxColorTabPage, ModifiedHdl_Impl);
+ m_xHexcustom->connect_changed(aEntryLink);
+ Link<weld::MetricSpinButton&,void> aMetricSpinLink = LINK(this, SvxColorTabPage, MetricSpinValueHdl_Impl);
+ m_xCcustom->connect_value_changed(aMetricSpinLink);
+ m_xYcustom->connect_value_changed(aMetricSpinLink);
+ m_xMcustom->connect_value_changed(aMetricSpinLink);
+ m_xKcustom->connect_value_changed(aMetricSpinLink);
+
+ Link<weld::Toggleable&,void> aLink2 = LINK( this, SvxColorTabPage, SelectColorModeHdl_Impl );
+ m_xRbRGB->connect_toggled(aLink2);
+ m_xRbCMYK->connect_toggled(aLink2);
+ SetColorModel( eCM );
+ ChangeColorModel();
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxColorTabPage, ClickAddHdl_Impl ) );
+ m_xBtnWorkOn->connect_clicked( LINK( this, SvxColorTabPage, ClickWorkOnHdl_Impl ) );
+ m_xBtnDelete->connect_clicked( LINK( this, SvxColorTabPage, ClickDeleteHdl_Impl ) );
+ // disable modify buttons
+ // Color palettes can't be modified
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR1) );
+
+ m_xMoreColors->set_from_icon_name("cmd/sc_additionsdialog.png");
+ m_xMoreColors->connect_clicked(LINK(this, SvxColorTabPage, OnMoreColorsClick));
+
+ // disable preset color values
+ m_xRGBpreset->set_sensitive(false);
+ m_xCMYKpreset->set_sensitive(false);
+
+ // ValueSet
+ m_xValSetColorList->SetStyle(m_xValSetColorList->GetStyle() |
+ WB_FLATVALUESET | WB_ITEMBORDER | WB_NO_DIRECTSELECT | WB_TABSTOP);
+ m_xValSetColorList->Show();
+
+ m_xValSetRecentList->SetStyle(m_xValSetRecentList->GetStyle() |
+ WB_FLATVALUESET | WB_ITEMBORDER | WB_NO_DIRECTSELECT | WB_TABSTOP);
+ m_xValSetRecentList->Show();
+
+ maPaletteManager.ReloadRecentColorSet(*m_xValSetRecentList);
+ aSize = m_xValSetRecentList->layoutAllVisible(maPaletteManager.GetRecentColorCount());
+ m_xValSetRecentList->set_size_request(aSize.Width(), aSize.Height());
+}
+
+SvxColorTabPage::~SvxColorTabPage()
+{
+ m_xValSetRecentListWin.reset();
+ m_xValSetRecentList.reset();
+ m_xValSetColorListWin.reset();
+ m_xValSetColorList.reset();
+}
+
+void SvxColorTabPage::ImpColorCountChanged()
+{
+ if (!pColorList.is())
+ return;
+ m_xValSetColorList->SetColCount(SvxColorValueSet::getColumnCount());
+ m_xValSetRecentList->SetColCount(SvxColorValueSet::getColumnCount());
+}
+
+void SvxColorTabPage::FillPaletteLB()
+{
+ m_xSelectPalette->clear();
+ std::vector<OUString> aPaletteList = maPaletteManager.GetPaletteList();
+ for (auto const& palette : aPaletteList)
+ {
+ m_xSelectPalette->append_text(palette);
+ }
+ OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
+ m_xSelectPalette->set_active_text(aPaletteName);
+ if (m_xSelectPalette->get_active() != -1)
+ {
+ SelectPaletteLBHdl(*m_xSelectPalette);
+ }
+}
+
+void SvxColorTabPage::Construct()
+{
+ if (pColorList.is())
+ {
+ FillPaletteLB();
+ ImpColorCountChanged();
+ }
+}
+
+void SvxColorTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( !pColorList.is() )
+ return;
+
+ if( const XFillColorItem* pFillColorItem = rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLCOLOR ) ) )
+ {
+ SetColorModel( ColorModel::RGB );
+ ChangeColorModel();
+
+ const Color aColor = pFillColorItem->GetColorValue();
+ svx::NamedThemedColor aThemedColor;
+ aThemedColor.m_aColor = aColor;
+ ChangeColor( aThemedColor );
+ sal_Int32 nPos = FindInPalette( aColor );
+
+ if ( nPos != -1 )
+ m_xValSetColorList->SelectItem(m_xValSetColorList->GetItemId(nPos));
+ // else search in other palettes?
+
+ }
+
+ m_aCtlPreviewOld.SetAttributes(aXFillAttr.GetItemSet());
+ m_aCtlPreviewOld.Invalidate();
+
+ SelectValSetHdl_Impl(m_xValSetColorList.get());
+}
+
+DeactivateRC SvxColorTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxColorTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ Color aColor = m_xValSetColorList->GetItemColor( m_xValSetColorList->GetSelectedItemId() );
+ OUString sColorName;
+ if ( aCurrentColor.m_aColor == aColor )
+ sColorName = m_xValSetColorList->GetItemText( m_xValSetColorList->GetSelectedItemId() );
+ else
+ sColorName = "#" + aCurrentColor.m_aColor.AsRGBHexString().toAsciiUpperCase();
+ maPaletteManager.AddRecentColor( aCurrentColor.m_aColor, sColorName );
+ XFillColorItem aColorItem( sColorName, aCurrentColor.m_aColor );
+ if (aCurrentColor.m_nThemeIndex != -1)
+ {
+ aColorItem.GetThemeColor().SetThemeIndex(aCurrentColor.m_nThemeIndex);
+ }
+ if (aCurrentColor.m_nLumMod != 10000)
+ {
+ aColorItem.GetThemeColor().SetLumMod(aCurrentColor.m_nLumMod);
+ }
+ if (aCurrentColor.m_nLumOff != 0)
+ {
+ aColorItem.GetThemeColor().SetLumOff(aCurrentColor.m_nLumOff);
+ }
+ rSet->Put( aColorItem );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
+ return true;
+}
+
+void SvxColorTabPage::UpdateModified()
+{
+ bool bEnable = pColorList.is() && pColorList->Count();
+ m_xBtnWorkOn->set_sensitive(bEnable);
+}
+
+void SvxColorTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemState nState = rSet->GetItemState( XATTR_FILLCOLOR );
+
+ Color aNewColor;
+
+ if ( nState >= SfxItemState::DEFAULT )
+ {
+ XFillColorItem aColorItem( rSet->Get( XATTR_FILLCOLOR ) );
+ aPreviousColor = aColorItem.GetColorValue();
+ aNewColor = aColorItem.GetColorValue();
+ }
+
+ // set color model
+ OUString aStr = GetUserData();
+ eCM = static_cast<ColorModel>(aStr.toInt32());
+ SetColorModel( eCM );
+ ChangeColorModel();
+
+ svx::NamedThemedColor aThemedColor;
+ aThemedColor.m_aColor = aNewColor;
+ ChangeColor(aThemedColor);
+
+ UpdateModified();
+}
+
+std::unique_ptr<SfxTabPage> SvxColorTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxColorTabPage>(pPage, pController, *rOutAttrs);
+}
+
+// is called when the content of the MtrFields is changed for color values
+IMPL_LINK_NOARG(SvxColorTabPage, SpinValueHdl_Impl, weld::SpinButton&, void)
+{
+ // read current MtrFields, if cmyk, then k-value as transparency
+ aCurrentColor.m_aColor = Color(static_cast<sal_uInt8>(PercentToColor_Impl(m_xRcustom->get_value())),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xGcustom->get_value())),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xBcustom->get_value())));
+ UpdateColorValues();
+
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, MetricSpinValueHdl_Impl, weld::MetricSpinButton&, void)
+{
+ // read current MtrFields, if cmyk, then k-value as transparency
+ aCurrentColor.m_aColor = Color(ColorTransparency, static_cast<sal_uInt8>(PercentToColor_Impl(m_xKcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xCcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xYcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xMcustom->get_value(FieldUnit::NONE))));
+ ConvertColorValues (aCurrentColor.m_aColor, ColorModel::RGB);
+
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ModifiedHdl_Impl, weld::Entry&, void)
+{
+ aCurrentColor.m_aColor = m_xHexcustom->GetColor();
+ UpdateColorValues();
+
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_COLOR ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_COLOR ) );
+ OUString aName;
+
+ tools::Long j = 1;
+ bool bValidColorName = false;
+ // check if name is already existing
+ while (!bValidColorName)
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidColorName = (FindInCustomColors(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName( aName );
+
+ bValidColorName = (FindInCustomColors(aName) == -1);
+ if (bValidColorName)
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if (!nError)
+ {
+ m_xSelectPalette->set_active(0);
+ SelectPaletteLBHdl(*m_xSelectPalette);
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ css::uno::Sequence< sal_Int32 > aCustomColorList(officecfg::Office::Common::UserColors::CustomColor::get());
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ sal_Int32 nSize = aCustomColorList.getLength();
+ aCustomColorList.realloc( nSize + 1 );
+ aCustomColorNameList.realloc( nSize + 1 );
+ aCustomColorList.getArray()[nSize] = sal_Int32(aCurrentColor.m_aColor);
+ aCustomColorNameList.getArray()[nSize] = aName;
+ officecfg::Office::Common::UserColors::CustomColor::set(aCustomColorList, batch);
+ officecfg::Office::Common::UserColors::CustomColorName::set(aCustomColorNameList, batch);
+ batch->commit();
+ sal_uInt16 nId = m_xValSetColorList->GetItemId(nSize - 1);
+ m_xValSetColorList->InsertItem( nId + 1 , aCurrentColor.m_aColor, aName );
+ m_xValSetColorList->SelectItem( nId + 1 );
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR2) );
+ ImpColorCountChanged();
+ }
+
+ UpdateModified();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickWorkOnHdl_Impl, weld::Button&, void)
+{
+ SvColorDialog aColorDlg;
+
+ aColorDlg.SetColor (aCurrentColor.m_aColor);
+ aColorDlg.SetMode( svtools::ColorPickerMode::Modify );
+
+ if (aColorDlg.Execute(GetFrameWeld()) == RET_OK)
+ {
+ Color aPreviewColor = aColorDlg.GetColor();
+ aCurrentColor.m_aColor = aPreviewColor;
+ UpdateColorValues( false );
+ // fill ItemSet and pass it on to XOut
+ rXFSet.Put( XFillColorItem( OUString(), aPreviewColor ) );
+ //m_aCtlPreviewOld.SetAttributes( aXFillAttr );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xValSetColorList->GetSelectedItemId();
+ size_t nPos = m_xValSetColorList->GetSelectItemPos();
+ if (m_xSelectPalette->get_active() != 0 || nPos == VALUESET_ITEM_NOTFOUND)
+ return;
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ css::uno::Sequence< sal_Int32 > aCustomColorList(officecfg::Office::Common::UserColors::CustomColor::get());
+ auto aCustomColorListRange = asNonConstRange(aCustomColorList);
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ auto aCustomColorNameListRange = asNonConstRange(aCustomColorNameList);
+ sal_Int32 nSize = aCustomColorList.getLength() - 1;
+ for(sal_Int32 nIndex = static_cast<sal_Int32>(nPos);nIndex < nSize;nIndex++)
+ {
+ aCustomColorListRange[nIndex] = aCustomColorList[nIndex+1];
+ aCustomColorNameListRange[nIndex] = aCustomColorNameList[nIndex+1];
+ }
+ aCustomColorList.realloc(nSize);
+ aCustomColorNameList.realloc(nSize);
+ officecfg::Office::Common::UserColors::CustomColor::set(aCustomColorList, batch);
+ officecfg::Office::Common::UserColors::CustomColorName::set(aCustomColorNameList, batch);
+ batch->commit();
+ m_xValSetColorList->RemoveItem(nId);
+ if (m_xValSetColorList->GetItemCount() != 0)
+ {
+ nId = m_xValSetColorList->GetItemId(0);
+ m_xValSetColorList->SelectItem(nId);
+ SelectValSetHdl_Impl(m_xValSetColorList.get());
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR2) );
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, SelectPaletteLBHdl, weld::ComboBox&, void)
+{
+ m_xValSetColorList->Clear();
+ sal_Int32 nPos = m_xSelectPalette->get_active();
+ maPaletteManager.SetPalette( nPos );
+ maPaletteManager.ReloadColorSet(*m_xValSetColorList);
+
+ if(nPos != maPaletteManager.GetPaletteCount() - 1 && nPos != 0)
+ {
+ XColorListRef pList = XPropertyList::AsColorList(
+ XPropertyList::CreatePropertyListFromURL(
+ XPropertyListType::Color, maPaletteManager.GetSelectedPalettePath()));
+ pList->SetName(maPaletteManager.GetPaletteName());
+ if(pList->Load())
+ {
+ SfxOkDialogController* pController = GetDialogController();
+ SvxAreaTabDialog* pArea = dynamic_cast<SvxAreaTabDialog*>(pController);
+ SvxLineTabDialog* pLine = dynamic_cast<SvxLineTabDialog*>(pController);
+ pColorList = pList;
+ if( pArea )
+ pArea->SetNewColorList(pList);
+ else if( pLine )
+ pLine->SetNewColorList(pList);
+ else
+ SetColorList(pList);
+ *pnColorListState |= ChangeType::CHANGED;
+ *pnColorListState &= ~ChangeType::MODIFIED;
+ }
+ }
+ if (nPos != 0)
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR1) );
+ }
+
+ m_xValSetColorList->Resize();
+}
+
+IMPL_LINK(SvxColorTabPage, SelectValSetHdl_Impl, ValueSet*, pValSet, void)
+{
+ sal_Int32 nPos = pValSet->GetSelectedItemId();
+ if( nPos == 0 )
+ return;
+
+ Color aColor = pValSet->GetItemColor( nPos );
+
+ rXFSet.Put( XFillColorItem( OUString(), aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlPreviewNew.Invalidate();
+
+ bool bThemePaletteSelected = false;
+ if (pValSet == m_xValSetColorList.get())
+ {
+ bThemePaletteSelected = maPaletteManager.IsThemePaletteSelected();
+ }
+ svx::NamedThemedColor aThemedColor;
+ aThemedColor.m_aColor = aColor;
+ if (bThemePaletteSelected)
+ {
+ PaletteManager::GetThemeIndexLumModOff(nPos, aThemedColor.m_nThemeIndex, aThemedColor.m_nLumMod, aThemedColor.m_nLumOff);
+ }
+
+ ChangeColor(aThemedColor, false);
+
+ if (pValSet == m_xValSetColorList.get())
+ {
+ m_xValSetRecentList->SetNoSelection();
+ if (m_xSelectPalette->get_active() == 0 && m_xValSetColorList->GetSelectedItemId() != 0)
+ {
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnDelete->set_tooltip_text("");
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR1) );
+ }
+ }
+ if (pValSet == m_xValSetRecentList.get())
+ {
+ m_xValSetColorList->SetNoSelection();
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( CuiResId(RID_CUISTR_DELETEUSERCOLOR2) );
+ }
+}
+
+void SvxColorTabPage::ConvertColorValues (Color& rColor, ColorModel eModell)
+{
+ switch (eModell)
+ {
+ case ColorModel::RGB:
+ {
+ CmykToRgb_Impl (rColor, static_cast<sal_uInt16>(255 - rColor.GetAlpha()) );
+ rColor.SetAlpha (255);
+ }
+ break;
+
+ case ColorModel::CMYK:
+ {
+ sal_uInt16 nK;
+ RgbToCmyk_Impl (rColor, nK );
+ rColor.SetAlpha (255 - static_cast<sal_uInt8>(nK));
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, SelectColorModeHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xRbRGB->get_active())
+ eCM = ColorModel::RGB;
+ else if (m_xRbCMYK->get_active())
+ eCM = ColorModel::CMYK;
+ ChangeColorModel();
+ UpdateColorValues();
+}
+
+
+IMPL_STATIC_LINK_NOARG(SvxColorTabPage, OnMoreColorsClick, weld::Button&, void)
+{
+ css::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
+ "AdditionsTag", OUString("Color Palette")) };
+ comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
+}
+
+void SvxColorTabPage::ChangeColor(const svx::NamedThemedColor &rNewColor, bool bUpdatePreset )
+{
+ aPreviousColor = rNewColor.m_aColor;
+ aCurrentColor = rNewColor;
+ UpdateColorValues( bUpdatePreset );
+ // fill ItemSet and pass it on to XOut
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor.m_aColor ) );
+ m_aCtlPreviewNew.SetAttributes(aXFillAttr.GetItemSet());
+ m_aCtlPreviewNew.Invalidate();
+}
+
+void SvxColorTabPage::SetColorModel( ColorModel eModel )
+{
+ if (eModel == ColorModel::RGB)
+ m_xRbRGB->set_active(true);
+ else if (eModel == ColorModel::CMYK)
+ m_xRbCMYK->set_active(true);
+}
+
+void SvxColorTabPage::ChangeColorModel()
+{
+ switch( eCM )
+ {
+ case ColorModel::RGB:
+ {
+ m_xRGBcustom->show();
+ m_xRGBpreset->show();
+ m_xCMYKcustom->hide();
+ m_xCMYKpreset->hide();
+ }
+ break;
+
+ case ColorModel::CMYK:
+ {
+ m_xCMYKcustom->show();
+ m_xCMYKpreset->show();
+ m_xRGBcustom->hide();
+ m_xRGBpreset->hide();
+ }
+ break;
+ }
+}
+
+void SvxColorTabPage::UpdateColorValues( bool bUpdatePreset )
+{
+ if (eCM != ColorModel::RGB)
+ {
+ ConvertColorValues (aPreviousColor, eCM );
+ ConvertColorValues (aCurrentColor.m_aColor, eCM);
+
+ m_xCcustom->set_value( ColorToPercent_Impl( aCurrentColor.m_aColor.GetRed() ), FieldUnit::PERCENT );
+ m_xMcustom->set_value( ColorToPercent_Impl( aCurrentColor.m_aColor.GetBlue() ), FieldUnit::PERCENT );
+ m_xYcustom->set_value( ColorToPercent_Impl( aCurrentColor.m_aColor.GetGreen() ), FieldUnit::PERCENT );
+ m_xKcustom->set_value( ColorToPercent_Impl( 255 - aCurrentColor.m_aColor.GetAlpha() ), FieldUnit::PERCENT );
+
+ if( bUpdatePreset )
+ {
+ m_xCpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetRed()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xMpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetBlue()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xYpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetGreen()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xKpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(255 - aPreviousColor.GetAlpha()),
+ Application::GetSettings().GetUILanguageTag()));
+ }
+
+ ConvertColorValues (aPreviousColor, ColorModel::RGB);
+ ConvertColorValues (aCurrentColor.m_aColor, ColorModel::RGB);
+ }
+ else
+ {
+ m_xRcustom->set_value( ColorToPercent_Impl( aCurrentColor.m_aColor.GetRed() ) );
+ m_xGcustom->set_value( ColorToPercent_Impl( aCurrentColor.m_aColor.GetGreen() ) );
+ m_xBcustom->set_value( ColorToPercent_Impl( aCurrentColor.m_aColor.GetBlue() ) );
+ m_xHexcustom->SetColor( aCurrentColor.m_aColor );
+
+ if( bUpdatePreset )
+ {
+ m_xRpreset->set_text(OUString::number(ColorToPercent_Impl(aPreviousColor.GetRed())));
+ m_xGpreset->set_text(OUString::number(ColorToPercent_Impl(aPreviousColor.GetGreen())));
+ m_xBpreset->set_text(OUString::number(ColorToPercent_Impl(aPreviousColor.GetBlue())));
+ m_xHexpreset->SetColor( aPreviousColor );
+ }
+ }
+}
+
+sal_Int32 SvxColorTabPage::FindInCustomColors(std::u16string_view aColorName)
+{
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ tools::Long nCount = aCustomColorNameList.getLength();
+ bool bValidColorName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidColorName;i++)
+ {
+ if(aColorName == aCustomColorNameList[i])
+ {
+ nPos = i;
+ bValidColorName = false;
+ }
+ }
+ return nPos;
+}
+
+sal_Int32 SvxColorTabPage::FindInPalette( const Color& rColor )
+{
+ return pColorList->GetIndexOfColor(rColor);
+}
+
+// A RGB value is converted to a CMYK value - not in an ideal way as
+// R is converted into C, G into M and B into Y. The K value is held in an
+// extra variable. For further color models one should develop own
+// classes which should contain the respective casts.
+
+void SvxColorTabPage::RgbToCmyk_Impl( Color& rColor, sal_uInt16& rK )
+{
+ sal_uInt16 const nColor1 = 255 - rColor.GetRed();
+ sal_uInt16 const nColor2 = 255 - rColor.GetGreen();
+ sal_uInt16 const nColor3 = 255 - rColor.GetBlue();
+
+ rK = std::min( std::min( nColor1, nColor2 ), nColor3 );
+
+ rColor.SetRed( sal::static_int_cast< sal_uInt8 >( nColor1 - rK ) );
+ rColor.SetGreen( sal::static_int_cast< sal_uInt8 >( nColor2 - rK ) );
+ rColor.SetBlue( sal::static_int_cast< sal_uInt8 >( nColor3 - rK ) );
+}
+
+
+// reverse case to RgbToCmyk_Impl (see above)
+
+void SvxColorTabPage::CmykToRgb_Impl( Color& rColor, const sal_uInt16 nK )
+{
+ tools::Long lTemp;
+
+ lTemp = 255 - ( rColor.GetRed() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetRed( static_cast<sal_uInt8>(lTemp) );
+
+ lTemp = 255 - ( rColor.GetGreen() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetGreen( static_cast<sal_uInt8>(lTemp) );
+
+ lTemp = 255 - ( rColor.GetBlue() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetBlue( static_cast<sal_uInt8>(lTemp) );
+}
+
+
+sal_uInt16 SvxColorTabPage::ColorToPercent_Impl( sal_uInt16 nColor )
+{
+ sal_uInt16 nValue = 0;
+
+ switch (eCM)
+ {
+ case ColorModel::RGB :
+ nValue = nColor;
+ break;
+
+ case ColorModel::CMYK:
+ nValue = static_cast<sal_uInt16>( static_cast<double>(nColor) * 100.0 / 255.0 + 0.5 );
+ break;
+ }
+
+ return nValue;
+}
+
+
+sal_uInt16 SvxColorTabPage::PercentToColor_Impl( sal_uInt16 nPercent )
+{
+ sal_uInt16 nValue = 0;
+
+ switch (eCM)
+ {
+ case ColorModel::RGB :
+ nValue = nPercent;
+ break;
+
+ case ColorModel::CMYK:
+ nValue = static_cast<sal_uInt16>( static_cast<double>(nPercent) * 255.0 / 100.0 + 0.5 );
+ break;
+ }
+
+ return nValue;
+}
+
+
+void SvxColorTabPage::FillUserData()
+{
+ // the color model is saved in the Ini-file
+ SetUserData( OUString::number( static_cast<int>(eCM) ) );
+}
+
+
+void SvxColorTabPage::SetPropertyList( XPropertyListType t, const XPropertyListRef &xRef )
+{
+ OSL_ASSERT( t == XPropertyListType::Color );
+ pColorList = XColorListRef( static_cast<XColorList *>(xRef.get() ) );
+}
+
+void SvxColorTabPage::SetColorList( const XColorListRef& pColList )
+{
+ SetPropertyList( XPropertyListType::Color, XPropertyListRef( ( pColList.get() ) ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpgradnt.cxx b/cui/source/tabpages/tpgradnt.cxx
new file mode 100644
index 000000000..31a846d9c
--- /dev/null
+++ b/cui/source/tabpages/tpgradnt.cxx
@@ -0,0 +1,633 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dialoghelper.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xgrscit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <sal/log.hxx>
+
+#define DEFAULT_GRADIENTSTEP 64
+
+using namespace com::sun::star;
+
+SvxGradientTabPage::SvxGradientTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/gradientpage.ui", "GradientPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnGradientListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xLbGradientType(m_xBuilder->weld_combo_box("gradienttypelb"))
+ , m_xFtCenter(m_xBuilder->weld_label("centerft"))
+ , m_xMtrCenterX(m_xBuilder->weld_metric_spin_button("centerxmtr", FieldUnit::PERCENT))
+ , m_xMtrCenterY(m_xBuilder->weld_metric_spin_button("centerymtr", FieldUnit::PERCENT))
+ , m_xFtAngle(m_xBuilder->weld_label("angleft"))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("anglemtr", FieldUnit::DEGREE))
+ , m_xSliderAngle(m_xBuilder->weld_scale("angleslider"))
+ , m_xMtrBorder(m_xBuilder->weld_metric_spin_button("bordermtr", FieldUnit::PERCENT))
+ , m_xSliderBorder(m_xBuilder->weld_scale("borderslider"))
+ , m_xLbColorFrom(new ColorListBox(m_xBuilder->weld_menu_button("colorfromlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMtrColorFrom(m_xBuilder->weld_metric_spin_button("colorfrommtr", FieldUnit::PERCENT))
+ , m_xLbColorTo(new ColorListBox(m_xBuilder->weld_menu_button("colortolb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMtrColorTo(m_xBuilder->weld_metric_spin_button("colortomtr", FieldUnit::PERCENT))
+ , m_xGradientLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("gradientpresetlistwin", true)))
+ , m_xMtrIncrement(m_xBuilder->weld_spin_button("incrementmtr"))
+ , m_xCbIncrement(m_xBuilder->weld_check_button("autoincrement"))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnModify(m_xBuilder->weld_button("modify"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "previewctl", m_aCtlPreview))
+ , m_xGradientLBWin(new weld::CustomWeld(*m_xBuilder, "gradientpresetlist", *m_xGradientLB))
+{
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xGradientLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // as long as NOT supported by the item
+
+ m_xMtrColorTo->set_value(100, FieldUnit::PERCENT);
+ m_xMtrColorFrom->set_value(100, FieldUnit::PERCENT);
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_GRADIENT) );
+ m_rXFSet.Put( XFillGradientItem(OUString(), XGradient( COL_BLACK, COL_WHITE )) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+
+ // set handler
+ m_xGradientLB->SetSelectHdl( LINK( this, SvxGradientTabPage, ChangeGradientHdl ) );
+ m_xGradientLB->SetRenameHdl( LINK( this, SvxGradientTabPage, ClickRenameHdl_Impl ) );
+ m_xGradientLB->SetDeleteHdl( LINK( this, SvxGradientTabPage, ClickDeleteHdl_Impl ) );
+ m_xBtnAdd->connect_clicked(LINK(this, SvxGradientTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK(this, SvxGradientTabPage, ClickModifyHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxGradientTabPage, ModifiedMetricHdl_Impl );
+ Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxGradientTabPage, ModifiedListBoxHdl_Impl );
+ m_xLbGradientType->connect_changed( aLink2 );
+ m_xCbIncrement->connect_toggled(LINK(this, SvxGradientTabPage, ChangeAutoStepHdl_Impl));
+ m_xMtrIncrement->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedEditHdl_Impl));
+ m_xMtrCenterX->connect_value_changed( aLink );
+ m_xMtrCenterY->connect_value_changed( aLink );
+ m_xMtrAngle->connect_value_changed( aLink );
+ m_xSliderAngle->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
+ m_xMtrBorder->connect_value_changed( aLink );
+ m_xSliderBorder->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
+ m_xMtrColorFrom->connect_value_changed( aLink );
+ Link<ColorListBox&,void> aLink3 = LINK( this, SvxGradientTabPage, ModifiedColorListBoxHdl_Impl );
+ m_xLbColorFrom->SetSelectHdl( aLink3 );
+ m_xMtrColorTo->connect_value_changed( aLink );
+ m_xLbColorTo->SetSelectHdl( aLink3 );
+
+ m_xGradientLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+
+ // #i76307# always paint the preview in LTR, because this is what the document does
+ m_aCtlPreview.EnableRTL(false);
+}
+
+SvxGradientTabPage::~SvxGradientTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xGradientLBWin.reset();
+ m_xGradientLB.reset();
+ m_xLbColorTo.reset();
+ m_xLbColorFrom.reset();
+}
+
+void SvxGradientTabPage::Construct()
+{
+ m_xGradientLB->FillPresetListBox( *m_pGradientList );
+}
+
+void SvxGradientTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+
+ ModifiedHdl_Impl( this );
+ }
+
+ // determining (and possibly cutting) the name and
+ // displaying it in the GroupBox
+ OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pGradientList->GetPath() );
+
+ aURL.Append( m_pGradientList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if ( aURL.getBase().getLength() > 18 )
+ {
+ aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ sal_Int32 nPos = SearchGradientList( rSet.Get(XATTR_FILLGRADIENT).GetName() );
+ if ( nPos != -1)
+ {
+ sal_uInt16 nId = m_xGradientLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xGradientLB->SelectItem( nId );
+ }
+ // colors could have been deleted
+ ChangeGradientHdl_Impl();
+}
+
+
+DeactivateRC SvxGradientTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxGradientTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ std::unique_ptr<XGradient> pXGradient;
+ size_t nPos = m_xGradientLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xGradientLB->GetSelectItemPos();
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pXGradient.reset(new XGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetGradient() ));
+ OUString aString = m_xGradientLB->GetItemText( m_xGradientLB->GetSelectedItemId() );
+ rSet->Put( XFillGradientItem( aString, *pXGradient ) );
+ }
+ else
+ // gradient was passed (unidentified)
+ {
+ pXGradient.reset(new XGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) ));
+ rSet->Put( XFillGradientItem( OUString(), *pXGradient ) );
+ }
+
+ sal_uInt16 nValue = 0;
+ if (!m_xCbIncrement->get_active())
+ nValue = m_xMtrIncrement->get_value();
+
+ assert( pXGradient && "XGradient could not be created" );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_GRADIENT ) );
+ rSet->Put( XGradientStepCountItem( nValue ) );
+ return true;
+}
+
+void SvxGradientTabPage::Reset( const SfxItemSet* )
+{
+ m_xMtrIncrement->set_value(DEFAULT_GRADIENTSTEP);
+ ChangeGradientHdl_Impl();
+
+ // determine state of the buttons
+ if( m_pGradientList->Count() )
+ m_xBtnModify->set_sensitive(true);
+ else
+ m_xBtnModify->set_sensitive(false);
+}
+
+std::unique_ptr<SfxTabPage> SvxGradientTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs )
+{
+ return std::make_unique<SvxGradientTabPage>(pPage, pController, *rOutAttrs);
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ // gradient params changed, it is no longer one of the presets
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedEditHdl_Impl, weld::SpinButton&, rBox, void )
+{
+ ModifiedHdl_Impl(&rBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedMetricHdl_Impl, weld::MetricSpinButton&, rBox, void )
+{
+ ModifiedHdl_Impl(&rBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
+{
+ ModifiedHdl_Impl(&rSlider);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK_NOARG( SvxGradientTabPage, ChangeAutoStepHdl_Impl, weld::Toggleable&, void )
+{
+ if (m_xCbIncrement->get_active())
+ {
+ m_xMtrIncrement->set_sensitive(false);
+ }
+ else
+ {
+ m_xMtrIncrement->set_sensitive(true);
+ }
+ ModifiedHdl_Impl(m_xMtrIncrement.get());
+}
+
+void SvxGradientTabPage::ModifiedHdl_Impl( void const * pControl )
+{
+ if (pControl == m_xMtrBorder.get())
+ m_xSliderBorder->set_value(m_xMtrBorder->get_value(FieldUnit::NONE));
+ if (pControl == m_xSliderBorder.get())
+ m_xMtrBorder->set_value(m_xSliderBorder->get_value(), FieldUnit::NONE);
+ if (pControl == m_xMtrAngle.get())
+ m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
+ if (pControl == m_xSliderAngle.get())
+ m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
+
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active());
+
+ XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ eXGS,
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) );
+
+ // enable/disable controls
+ if (pControl == m_xLbGradientType.get() || pControl == this)
+ SetControlState_Impl( eXGS );
+
+ sal_uInt16 nValue = 0;
+ if (!m_xCbIncrement->get_active())
+ nValue = static_cast<sal_uInt16>(m_xMtrIncrement->get_value());
+ m_rXFSet.Put( XGradientStepCountItem( nValue ) );
+
+ // displaying in XOutDev
+ m_rXFSet.Put( XFillGradientItem( OUString(), aXGradient ) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_GRADIENT ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_GRADIENT ) );
+ OUString aName;
+
+ tools::Long nCount = m_pGradientList->Count();
+ tools::Long j = 1;
+ bool bValidGradientName = false;
+
+ while( !bValidGradientName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidGradientName = (SearchGradientList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName( aName );
+
+ bValidGradientName = (SearchGradientList(aName) == -1);
+
+ if (bValidGradientName)
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) );
+
+ m_pGradientList->Insert(std::make_unique<XGradientEntry>(aXGradient, aName), nCount);
+
+ sal_Int32 nId = m_xGradientLB->GetItemId(nCount - 1); //calculate the last ID
+ BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( nCount, m_xGradientLB->GetIconSize() );
+ m_xGradientLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xGradientLB->SelectItem( nId + 1 );
+ m_xGradientLB->Resize();
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+
+ ChangeGradientHdl_Impl();
+ }
+
+ // determine button state
+ if (m_pGradientList->Count())
+ m_xBtnModify->set_sensitive(true);
+}
+
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) );
+
+ m_pGradientList->Replace(std::make_unique<XGradientEntry>(aXGradient, aName), nPos);
+
+ BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xGradientLB->GetIconSize() );
+ m_xGradientLB->RemoveItem( nId );
+ m_xGradientLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xGradientLB->SelectItem( nId );
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletegradientdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelGradientDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pGradientList->Remove(nPos);
+ m_xGradientLB->RemoveItem( nId );
+ nId = m_xGradientLB->GetItemId( 0 );
+ m_xGradientLB->SelectItem( nId );
+ m_xGradientLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+
+ ChangeGradientHdl_Impl();
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+ }
+ }
+ // determine button state
+ if( !m_pGradientList->Count() )
+ m_xBtnModify->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_GRADIENT ) );
+ OUString aName( m_pGradientList->GetGradient( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nGradientPos = SearchGradientList(aName);
+ bool bValidGradientName = (nGradientPos == static_cast<sal_Int32>(nPos) ) || (nGradientPos == -1);
+
+ if( bValidGradientName )
+ {
+ bLoop = false;
+ m_pGradientList->GetGradient(nPos)->SetName(aName);
+
+ m_xGradientLB->SetItemText( nId, aName );
+ m_xGradientLB->SelectItem( nId );
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ChangeGradientHdl, ValueSet*, void)
+{
+ ChangeGradientHdl_Impl();
+}
+
+void SvxGradientTabPage::ChangeGradientHdl_Impl()
+{
+ std::unique_ptr<XGradient> pGradient;
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pGradient.reset(new XGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>( nPos ) )->GetGradient() ));
+ else
+ {
+ if( const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLSTYLE ) ) )
+ {
+ const XFillGradientItem* pGradientItem;
+ if( ( drawing::FillStyle_GRADIENT == pFillStyleItem->GetValue() ) &&
+ ( pGradientItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLGRADIENT ) ) ) )
+ {
+ pGradient.reset(new XGradient( pGradientItem->GetGradientValue() ));
+ }
+ }
+ if( !pGradient )
+ {
+ sal_uInt16 nPosition = m_xGradientLB->GetItemId(0);
+ m_xGradientLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ pGradient.reset(new XGradient( m_pGradientList->GetGradient( 0 )->GetGradient() ));
+ }
+ }
+
+ if( !pGradient )
+ return;
+
+ css::awt::GradientStyle eXGS = pGradient->GetGradientStyle();
+ sal_uInt16 nValue = pGradient->GetSteps();
+ if( nValue == 0 )
+ {
+ m_xCbIncrement->set_state(TRISTATE_TRUE);
+ m_xMtrIncrement->set_sensitive(false);
+ }
+ else
+ {
+ m_xCbIncrement->set_state(TRISTATE_FALSE);
+ m_xMtrIncrement->set_sensitive(true);
+ m_xMtrIncrement->set_value( nValue );
+ }
+ m_xLbGradientType->set_active(
+ sal::static_int_cast< sal_Int32 >( eXGS ) );
+ // if the entry is not in the listbox,
+ // colors are added temporarily
+ m_xLbColorFrom->SetNoSelection();
+ m_xLbColorFrom->SelectEntry( pGradient->GetStartColor() );
+
+ m_xLbColorTo->SetNoSelection();
+ m_xLbColorTo->SelectEntry( pGradient->GetEndColor() );
+
+ m_xMtrAngle->set_value(pGradient->GetAngle().get() / 10, FieldUnit::NONE); // should be changed in resource
+ m_xSliderAngle->set_value(pGradient->GetAngle().get() / 10);
+ m_xMtrBorder->set_value(pGradient->GetBorder(), FieldUnit::NONE);
+ m_xSliderBorder->set_value(pGradient->GetBorder());
+ m_xMtrCenterX->set_value(pGradient->GetXOffset(), FieldUnit::NONE);
+ m_xMtrCenterY->set_value(pGradient->GetYOffset(), FieldUnit::NONE);
+ m_xMtrColorFrom->set_value(pGradient->GetStartIntens(), FieldUnit::NONE);
+ m_xMtrColorTo->set_value(pGradient->GetEndIntens(), FieldUnit::NONE);
+
+ // disable/enable controls
+ SetControlState_Impl( eXGS );
+
+ // fill ItemSet and pass it on to aCtlPreview
+ m_rXFSet.Put( XFillGradientItem( OUString(), *pGradient ) );
+ m_rXFSet.Put( XGradientStepCountItem( nValue ) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxGradientTabPage::SetControlState_Impl( css::awt::GradientStyle eXGS )
+{
+ switch( eXGS )
+ {
+ case css::awt::GradientStyle_LINEAR:
+ case css::awt::GradientStyle_AXIAL:
+ m_xFtCenter->set_sensitive(false);
+ m_xMtrCenterX->set_sensitive(false);
+ m_xMtrCenterY->set_sensitive(false);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_RADIAL:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(false);
+ m_xMtrAngle->set_sensitive(false);
+ m_xSliderAngle->set_sensitive(false);
+ break;
+
+ case css::awt::GradientStyle_ELLIPTICAL:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_SQUARE:
+ case css::awt::GradientStyle_RECT:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+}
+
+sal_Int32 SvxGradientTabPage::SearchGradientList(std::u16string_view rGradientName)
+{
+ tools::Long nCount = m_pGradientList->Count();
+ bool bValidGradientName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidGradientName;i++)
+ {
+ if(rGradientName == m_pGradientList->GetGradient( i )->GetName())
+ {
+ nPos = i;
+ bValidGradientName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tphatch.cxx b/cui/source/tabpages/tphatch.cxx
new file mode 100644
index 000000000..1a3511473
--- /dev/null
+++ b/cui/source/tabpages/tphatch.cxx
@@ -0,0 +1,562 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dialoghelper.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbckit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+#include <sal/log.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace com::sun::star;
+
+SvxHatchTabPage::SvxHatchTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/hatchpage.ui", "HatchPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnHatchingListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("distancemtr", FieldUnit::MM))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("anglemtr", FieldUnit::DEGREE))
+ , m_xSliderAngle(m_xBuilder->weld_scale("angleslider"))
+ , m_xLbLineType(m_xBuilder->weld_combo_box("linetypelb"))
+ , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xCbBackgroundColor(m_xBuilder->weld_check_button("backgroundcolor"))
+ , m_xLbBackgroundColor(new ColorListBox(m_xBuilder->weld_menu_button("backgroundcolorlb"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xHatchLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("hatchpresetlistwin", true)))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnModify(m_xBuilder->weld_button("modify"))
+ , m_xHatchLBWin(new weld::CustomWeld(*m_xBuilder, "hatchpresetlist", *m_xHatchLB))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "previewctl", m_aCtlPreview))
+{
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xHatchLBWin->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMtrDistance, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ assert( pPool && "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SID_ATTR_FILL_HATCH );
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_HATCH) );
+ m_rXFSet.Put( XFillHatchItem(OUString(), XHatch()) );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_xHatchLB->SetSelectHdl( LINK( this, SvxHatchTabPage, ChangeHatchHdl ) );
+ m_xHatchLB->SetRenameHdl( LINK( this, SvxHatchTabPage, ClickRenameHdl_Impl ) );
+ m_xHatchLB->SetDeleteHdl( LINK( this, SvxHatchTabPage, ClickDeleteHdl_Impl ) );
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxHatchTabPage, ModifiedEditHdl_Impl );
+ Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxHatchTabPage, ModifiedListBoxHdl_Impl );
+ m_xMtrDistance->connect_value_changed( aLink );
+ m_xMtrAngle->connect_value_changed( aLink );
+ m_xSliderAngle->connect_value_changed(LINK(this, SvxHatchTabPage, ModifiedSliderHdl_Impl));
+ m_xLbLineType->connect_changed( aLink2 );
+ Link<ColorListBox&,void> aLink3 = LINK( this, SvxHatchTabPage, ModifiedColorListBoxHdl_Impl );
+ m_xLbLineColor->SetSelectHdl( aLink3 );
+ m_xCbBackgroundColor->connect_toggled( LINK( this, SvxHatchTabPage, ToggleHatchBackgroundColor_Impl ) );
+ m_xLbBackgroundColor->SetSelectHdl( LINK( this, SvxHatchTabPage, ModifiedBackgroundHdl_Impl ) );
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxHatchTabPage, ClickAddHdl_Impl ) );
+ m_xBtnModify->connect_clicked( LINK( this, SvxHatchTabPage, ClickModifyHdl_Impl ) );
+
+ m_xHatchLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+
+ m_aCtlPreview.SetDrawMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode() ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR);
+}
+
+SvxHatchTabPage::~SvxHatchTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xHatchLBWin.reset();
+ m_xHatchLB.reset();
+ m_xLbBackgroundColor.reset();
+ m_xLbLineColor.reset();
+}
+
+void SvxHatchTabPage::Construct()
+{
+ m_xHatchLB->FillPresetListBox(*m_pHatchingList);
+}
+
+void SvxHatchTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( m_pColorList.is() )
+ {
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+
+ ModifiedHdl_Impl( this );
+ }
+
+ // determining (possibly cutting) the name
+ // and displaying it in the GroupBox
+ OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pHatchingList->GetPath() );
+
+ aURL.Append( m_pHatchingList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if ( aURL.getBase().getLength() > 18 )
+ {
+ aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ sal_Int32 nPos = SearchHatchList( rSet.Get(XATTR_FILLHATCH).GetName() );
+ if( nPos != -1)
+ {
+ sal_uInt16 nId = m_xHatchLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xHatchLB->SelectItem( nId );
+ }
+ // colors could have been deleted
+ ChangeHatchHdl_Impl();
+ }
+
+ XFillBackgroundItem aBckItem( rSet.Get(XATTR_FILLBACKGROUND));
+ m_rXFSet.Put( aBckItem );
+
+ if (aBckItem.GetValue())
+ {
+ m_xCbBackgroundColor->set_state(TRISTATE_TRUE);
+ XFillColorItem aColorItem( rSet.Get(XATTR_FILLCOLOR) );
+ Color aColor(aColorItem.GetColorValue());
+ m_xLbBackgroundColor->SelectEntry(aColor);
+ m_xLbBackgroundColor->set_sensitive(true);
+ m_rXFSet.Put( aColorItem );
+ }
+ else
+ {
+ m_xCbBackgroundColor->set_state(TRISTATE_FALSE);
+ m_xLbBackgroundColor->SelectEntry(COL_AUTO);
+ m_xLbBackgroundColor->set_sensitive(false);
+ }
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+DeactivateRC SvxHatchTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+sal_Int32 SvxHatchTabPage::SearchHatchList(std::u16string_view rHatchName)
+{
+ tools::Long nCount = m_pHatchingList->Count();
+ bool bValidHatchName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidHatchName;i++)
+ {
+ if(rHatchName == m_pHatchingList->GetHatch( i )->GetName())
+ {
+ nPos = i;
+ bValidHatchName = false;
+ }
+ }
+ return nPos;
+}
+
+bool SvxHatchTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ std::unique_ptr<XHatch> pXHatch;
+ OUString aString;
+ size_t nPos = m_xHatchLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xHatchLB->GetSelectItemPos();
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pXHatch.reset(new XHatch( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetHatch() ));
+ aString = m_xHatchLB->GetItemText( m_xHatchLB->GetSelectedItemId() );
+ }
+ // unidentified hatch has been passed
+ else
+ {
+ pXHatch.reset(new XHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) ));
+ }
+ assert( pXHatch && "XHatch couldn't be created" );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_HATCH ) );
+ rSet->Put( XFillHatchItem( aString, *pXHatch ) );
+ rSet->Put( XFillBackgroundItem( m_xCbBackgroundColor->get_active() ) );
+ if (m_xCbBackgroundColor->get_active())
+ {
+ NamedColor aColor = m_xLbBackgroundColor->GetSelectedEntry();
+ rSet->Put(XFillColorItem(aColor.second, aColor.first));
+ }
+ return true;
+}
+
+void SvxHatchTabPage::Reset( const SfxItemSet* rSet )
+{
+ ChangeHatchHdl_Impl();
+
+ XFillColorItem aColItem( rSet->Get(XATTR_FILLCOLOR) );
+ m_xLbBackgroundColor->SelectEntry(aColItem.GetColorValue());
+ m_rXFSet.Put( aColItem );
+
+ XFillBackgroundItem aBckItem( rSet->Get(XATTR_FILLBACKGROUND) );
+ if(aBckItem.GetValue())
+ m_xCbBackgroundColor->set_state(TRISTATE_TRUE);
+ else
+ m_xCbBackgroundColor->set_state(TRISTATE_FALSE);
+ m_rXFSet.Put( aBckItem );
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+std::unique_ptr<SfxTabPage> SvxHatchTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxHatchTabPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ // hatch params have changed, it is no longer one of the presets
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK_NOARG( SvxHatchTabPage, ToggleHatchBackgroundColor_Impl, weld::Toggleable&, void )
+{
+ if (m_xCbBackgroundColor->get_active())
+ m_xLbBackgroundColor->set_sensitive(true);
+ else
+ m_xLbBackgroundColor->set_sensitive(false);
+ m_rXFSet.Put( XFillBackgroundItem( m_xCbBackgroundColor->get_active() ) );
+ ModifiedBackgroundHdl_Impl(*m_xLbBackgroundColor);
+}
+
+IMPL_LINK_NOARG( SvxHatchTabPage, ModifiedBackgroundHdl_Impl, ColorListBox&, void )
+{
+ Color aColor(COL_TRANSPARENT);
+ if (m_xCbBackgroundColor->get_active())
+ {
+ aColor = m_xLbBackgroundColor->GetSelectEntryColor();
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+ m_rXFSet.Put(XFillColorItem( OUString(), aColor ));
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedEditHdl_Impl, weld::MetricSpinButton&, rEdit, void )
+{
+ ModifiedHdl_Impl(&rEdit);
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
+{
+ ModifiedHdl_Impl(&rSlider);
+ m_xHatchLB->SetNoSelection();
+}
+
+void SvxHatchTabPage::ModifiedHdl_Impl( void const * p )
+{
+ if (p == m_xMtrAngle.get())
+ m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
+
+ if (p == m_xSliderAngle.get())
+ m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) );
+
+ m_rXFSet.Put( XFillHatchItem( OUString(), aXHatch ) );
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ChangeHatchHdl, ValueSet*, void)
+{
+ ChangeHatchHdl_Impl();
+}
+
+void SvxHatchTabPage::ChangeHatchHdl_Impl()
+{
+ std::unique_ptr<XHatch> pHatch;
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pHatch.reset(new XHatch( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetHatch() ));
+ else
+ {
+ if( const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLSTYLE ) ) )
+ {
+ const XFillHatchItem* pFillHatchItem;
+ if( ( drawing::FillStyle_HATCH == pFillStyleItem->GetValue() ) &&
+ ( pFillHatchItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLHATCH ) ) ) )
+ {
+ pHatch.reset(new XHatch( pFillHatchItem->GetHatchValue() ));
+ }
+ }
+ if( !pHatch )
+ {
+ sal_uInt16 nPosition = m_xHatchLB->GetItemId( 0 );
+ m_xHatchLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ pHatch.reset( new XHatch( m_pHatchingList->GetHatch( 0 )->GetHatch() ) );
+ }
+ }
+ if( pHatch )
+ {
+ m_xLbLineType->set_active(
+ sal::static_int_cast< sal_Int32 >( pHatch->GetHatchStyle() ) );
+ m_xLbLineColor->SetNoSelection();
+ m_xLbLineColor->SelectEntry( pHatch->GetColor() );
+ SetMetricValue( *m_xMtrDistance, pHatch->GetDistance(), m_ePoolUnit );
+ tools::Long nHatchAngle = pHatch->GetAngle().get() / 10;
+ m_xMtrAngle->set_value(nHatchAngle, FieldUnit::NONE);
+ m_xSliderAngle->set_value(nHatchAngle);
+
+ // fill ItemSet and pass it on to m_aCtlPreview
+ m_rXFSet.Put( XFillHatchItem( OUString(), *pHatch ) );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+
+ m_aCtlPreview.Invalidate();
+ pHatch.reset();
+ }
+ m_xMtrDistance->save_value();
+ m_xMtrAngle->save_value();
+ m_xLbLineType->save_value();
+ m_xLbLineColor->SaveValue();
+ m_xLbBackgroundColor->SaveValue();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_HATCH ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_HATCH ) );
+ OUString aName;
+
+ tools::Long nCount = m_pHatchingList->Count();
+ tools::Long j = 1;
+ bool bValidHatchName = false;
+
+ while( !bValidHatchName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidHatchName = (SearchHatchList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bValidHatchName = (SearchHatchList(aName) == -1);
+ if( bValidHatchName )
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+ pDlg.disposeAndClear();
+
+ if( nError )
+ return;
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) );
+
+ m_pHatchingList->Insert(std::make_unique<XHatchEntry>(aXHatch, aName), nCount);
+
+ sal_Int32 nId = m_xHatchLB->GetItemId(nCount - 1); // calculate the last ID
+ BitmapEx aBitmap = m_pHatchingList->GetBitmapForPreview( nCount, m_xHatchLB->GetIconSize() );
+ // Insert the new entry at the next ID
+ m_xHatchLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xHatchLB->SelectItem( nId + 1 );
+ m_xHatchLB->Resize();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+
+ ChangeHatchHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)) );
+
+ m_pHatchingList->Replace(std::make_unique<XHatchEntry>(aXHatch, aName), nPos);
+
+ BitmapEx aBitmap = m_pHatchingList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xHatchLB->GetIconSize() );
+ m_xHatchLB->RemoveItem( nId );
+ m_xHatchLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xHatchLB->SelectItem( nId );
+
+ // save values for changes recognition (-> method)
+ m_xMtrDistance->save_value();
+ m_xMtrAngle->save_value();
+ m_xLbLineType->save_value();
+ m_xLbLineColor->SaveValue();
+ m_xLbBackgroundColor->SaveValue();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletehatchdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelHatchDialog"));
+ if (xQueryBox->run() != RET_YES)
+ return;
+
+ m_pHatchingList->Remove(nPos);
+ m_xHatchLB->RemoveItem( nId );
+ nId = m_xHatchLB->GetItemId(0);
+ m_xHatchLB->SelectItem( nId );
+ m_xHatchLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+
+ ChangeHatchHdl_Impl();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void )
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_HATCH ) );
+ OUString aName( m_pHatchingList->GetHatch( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nHatchPos = SearchHatchList( aName );
+ bool bValidHatchName = (nHatchPos == static_cast<sal_Int32>(nPos) ) || (nHatchPos == -1);
+
+ if(bValidHatchName)
+ {
+ bLoop = false;
+ m_pHatchingList->GetHatch(nPos)->SetName(aName);
+
+ m_xHatchLB->SetItemText(nId, aName);
+ m_xHatchLB->SelectItem( nId );
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpline.cxx b/cui/source/tabpages/tpline.cxx
new file mode 100644
index 000000000..04eaa41b9
--- /dev/null
+++ b/cui/source/tabpages/tpline.cxx
@@ -0,0 +1,1695 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <editeng/sizeitem.hxx>
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+
+#include <strings.hrc>
+#include <svx/colorbox.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlncapit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnedcit.hxx>
+
+
+#include <svx/tabline.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+#include <cuitabline.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svxgraphicitem.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <svx/gallery.hxx>
+#include <sfx2/opengrf.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/svxids.hrc>
+#include <svx/strings.hrc>
+#include <cuitabarea.hxx>
+#include <svtools/unitconv.hxx>
+#include <comphelper/lok.hxx>
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+
+using namespace com::sun::star;
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxLineTabPage::pLineRanges(svl::Items<
+ XATTR_LINETRANSPARENCE, XATTR_LINETRANSPARENCE,
+ SID_ATTR_LINE_STYLE, SID_ATTR_LINE_ENDCENTER
+>);
+
+SvxLineTabPage::SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/linetabpage.ui", "LineTabPage", &rInAttrs)
+ , m_pSymbolList(nullptr)
+ , m_bNewSize(false)
+ , m_nSymbolType(SVX_SYMBOLTYPE_UNKNOWN) // unknown respectively unchanged
+ , m_bLastWidthModified(false)
+ , m_aSymbolLastSize(Size(0,0))
+ , m_bSymbols(false)
+ , m_rOutAttrs(rInAttrs)
+ , m_bObjSelected(false)
+ , m_aXLineAttr(rInAttrs.GetPool())
+ , m_rXLSet(m_aXLineAttr.GetItemSet())
+ , m_pnLineEndListState(nullptr)
+ , m_pnDashListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_nPageType(PageType::Area)
+ , m_nDlgType(0)
+ , m_pPosDashLb(nullptr)
+ , m_pPosLineEndLb(nullptr)
+ , m_xBoxColor(m_xBuilder->weld_widget("boxCOLOR"))
+ , m_xLbLineStyle(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINE_STYLE")))
+ , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xBoxWidth(m_xBuilder->weld_widget("boxWIDTH"))
+ , m_xMtrLineWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_WIDTH", FieldUnit::CM))
+ , m_xBoxTransparency(m_xBuilder->weld_widget("boxTRANSPARENCY"))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_LINE_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xFlLineEnds(m_xBuilder->weld_widget("FL_LINE_ENDS"))
+ , m_xBoxArrowStyles(m_xBuilder->weld_widget("boxARROW_STYLES"))
+ , m_xLbStartStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_START_STYLE")))
+ , m_xBoxStart(m_xBuilder->weld_widget("boxSTART"))
+ , m_xMtrStartWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_START_WIDTH", FieldUnit::CM))
+ , m_xTsbCenterStart(m_xBuilder->weld_check_button("TSB_CENTER_START"))
+ , m_xBoxEnd(m_xBuilder->weld_widget("boxEND"))
+ , m_xLbEndStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_END_STYLE")))
+ , m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_END_WIDTH", FieldUnit::CM))
+ , m_xTsbCenterEnd(m_xBuilder->weld_check_button("TSB_CENTER_END"))
+ , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+ , m_xFLEdgeStyle(m_xBuilder->weld_widget("FL_EDGE_STYLE"))
+ , m_xGridEdgeCaps(m_xBuilder->weld_widget("gridEDGE_CAPS"))
+ , m_xLBEdgeStyle(m_xBuilder->weld_combo_box("LB_EDGE_STYLE"))
+ , m_xLBCapStyle(m_xBuilder->weld_combo_box("LB_CAP_STYLE")) // LineCaps
+ , m_xFlSymbol(m_xBuilder->weld_widget("FL_SYMBOL_FORMAT")) //#58425# Symbols on a line (e.g. StarChart)
+ , m_xGridIconSize(m_xBuilder->weld_widget("gridICON_SIZE"))
+ , m_xSymbolMB(m_xBuilder->weld_menu_button("MB_SYMBOL_BITMAP"))
+ , m_xSymbolWidthMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_WIDTH", FieldUnit::CM))
+ , m_xSymbolHeightMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_HEIGHT", FieldUnit::CM))
+ , m_xSymbolRatioCB(m_xBuilder->weld_check_button("CB_SYMBOL_RATIO"))
+{
+ // This Page requires ExchangeSupport
+ SetExchangeSupport();
+
+ // Metric set
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ [[fallthrough]]; // we now have mm
+ case FieldUnit::MM:
+ m_xMtrLineWidth->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrStartWidth->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrEndWidth->set_increments(50, 500, FieldUnit::NONE);
+ break;
+
+ case FieldUnit::INCH:
+ m_xMtrLineWidth->set_increments(2, 20, FieldUnit::NONE);
+ m_xMtrStartWidth->set_increments(2, 20, FieldUnit::NONE);
+ m_xMtrEndWidth->set_increments(2, 20, FieldUnit::NONE);
+ break;
+ default: ;// prevent warning
+ }
+ SetFieldUnit( *m_xMtrLineWidth, eFUnit );
+ SetFieldUnit( *m_xMtrStartWidth, eFUnit );
+ SetFieldUnit( *m_xMtrEndWidth, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
+
+ m_xLbLineStyle->connect_changed(LINK(this, SvxLineTabPage, ClickInvisibleHdl_Impl));
+ m_xLbColor->SetSelectHdl( LINK( this, SvxLineTabPage, ChangePreviewListBoxHdl_Impl ) );
+ m_xMtrLineWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangePreviewModifyHdl_Impl));
+ m_xMtrTransparent->connect_value_changed(LINK( this, SvxLineTabPage, ChangeTransparentHdl_Impl));
+
+ m_xLbStartStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeStartListBoxHdl_Impl));
+ m_xLbEndStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeEndListBoxHdl_Impl));
+ m_xMtrStartWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangeStartModifyHdl_Impl));
+ m_xMtrEndWidth->connect_value_changed(LINK( this, SvxLineTabPage, ChangeEndModifyHdl_Impl));
+ m_xTsbCenterStart->connect_toggled(LINK(this, SvxLineTabPage, ChangeStartClickHdl_Impl));
+ m_xTsbCenterEnd->connect_toggled(LINK(this, SvxLineTabPage, ChangeEndClickHdl_Impl));
+
+ Link<weld::ComboBox&,void> aEdgeStyle = LINK(this, SvxLineTabPage, ChangeEdgeStyleHdl_Impl);
+ m_xLBEdgeStyle->connect_changed(aEdgeStyle);
+
+ // LineCaps
+ Link<weld::ComboBox&,void> aCapStyle = LINK(this, SvxLineTabPage, ChangeCapStyleHdl_Impl);
+ m_xLBCapStyle->connect_changed(aCapStyle);
+
+ // Symbols on a line (eg star charts), MB-handler set
+ m_xSymbolMB->connect_selected(LINK(this, SvxLineTabPage, GraphicHdl_Impl));
+ m_xSymbolMB->connect_toggled(LINK(this, SvxLineTabPage, MenuCreateHdl_Impl));
+ m_xSymbolWidthMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
+ m_xSymbolHeightMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
+ m_xSymbolRatioCB->connect_toggled(LINK(this, SvxLineTabPage, RatioHdl_Impl));
+
+ m_xSymbolRatioCB->set_active(true);
+ ShowSymbolControls(false);
+
+ m_nActLineWidth = -1;
+}
+
+void SvxLineTabPage::ShowSymbolControls(bool bOn)
+{
+ // Symbols on a line (e.g. StarCharts), symbol-enable controls
+
+ m_bSymbols=bOn;
+ m_xFlSymbol->set_visible(bOn);
+ m_aCtlPreview.ShowSymbol(bOn);
+}
+
+SvxLineTabPage::~SvxLineTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbEndStyle.reset();
+ m_xLbStartStyle.reset();
+ m_xLbColor.reset();
+ m_xLbLineStyle.reset();
+ m_aGalleryBrushItems.clear();
+ m_aSymbolBrushItems.clear();
+}
+
+void SvxLineTabPage::Construct()
+{
+ FillListboxes();
+}
+
+void SvxLineTabPage::FillListboxes()
+{
+ // Line styles
+ auto nOldSelect = m_xLbLineStyle->get_active();
+ // aLbLineStyle.FillStyles();
+ m_xLbLineStyle->Fill( m_pDashList );
+ m_xLbLineStyle->set_active( nOldSelect );
+
+ // Line end style
+ OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
+ : SvxResId( RID_SVXSTR_NONE ) );
+ nOldSelect = m_xLbStartStyle->get_active();
+ m_xLbStartStyle->clear();
+ m_xLbStartStyle->append_text(sNone);
+ m_xLbStartStyle->Fill(m_pLineEndList);
+ m_xLbStartStyle->set_active(nOldSelect);
+ nOldSelect = m_xLbEndStyle->get_active();
+ m_xLbEndStyle->clear();
+ m_xLbEndStyle->append_text(sNone);
+ m_xLbEndStyle->Fill(m_pLineEndList, false);
+ m_xLbEndStyle->set_active(nOldSelect);
+}
+
+void SvxLineTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ const CntUInt16Item* pPageTypeItem = rSet.GetItem<CntUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if( m_nDlgType == 0 && m_pDashList.is() )
+ {
+ sal_Int32 nPos;
+ sal_Int32 nCount;
+
+ // Dash list
+ if( ( *m_pnDashListState & ChangeType::MODIFIED ) ||
+ ( *m_pnDashListState & ChangeType::CHANGED ) )
+ {
+ if( *m_pnDashListState & ChangeType::CHANGED )
+ m_pDashList = static_cast<SvxLineTabDialog*>(GetDialogController() )->GetNewDashList();
+
+ *m_pnDashListState = ChangeType::NONE;
+
+ // Style list
+ nPos = m_xLbLineStyle->get_active();
+
+ m_xLbLineStyle->clear();
+ m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_INVISIBLE));
+ m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_SOLID));
+ m_xLbLineStyle->Fill(m_pDashList);
+ nCount = m_xLbLineStyle->get_count();
+
+ if ( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbLineStyle->set_active(0);
+ else
+ m_xLbLineStyle->set_active(nPos);
+ }
+
+ INetURLObject aDashURL( m_pDashList->GetPath() );
+
+ aDashURL.Append( m_pDashList->GetName() );
+ DBG_ASSERT( aDashURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ // LineEnd list
+ if( ( *m_pnLineEndListState & ChangeType::MODIFIED ) || ( *m_pnLineEndListState & ChangeType::CHANGED ) )
+ {
+ if( *m_pnLineEndListState & ChangeType::CHANGED )
+ m_pLineEndList = static_cast<SvxLineTabDialog*>(GetDialogController())->GetNewLineEndList();
+
+ *m_pnLineEndListState = ChangeType::NONE;
+
+ nPos = m_xLbLineStyle->get_active();
+ OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
+ : SvxResId( RID_SVXSTR_NONE ) );
+
+ m_xLbStartStyle->clear();
+ m_xLbStartStyle->append_text(sNone);
+
+ m_xLbStartStyle->Fill( m_pLineEndList );
+ nCount = m_xLbStartStyle->get_count();
+ if( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbStartStyle->set_active(0);
+ else
+ m_xLbStartStyle->set_active(nPos);
+
+ m_xLbEndStyle->clear();
+ m_xLbEndStyle->append_text(sNone);
+
+ m_xLbEndStyle->Fill( m_pLineEndList, false );
+ nCount = m_xLbEndStyle->get_count();
+
+ if( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbEndStyle->set_active(0);
+ else
+ m_xLbEndStyle->set_active(nPos);
+ }
+ INetURLObject aLineURL( m_pLineEndList->GetPath() );
+
+ aLineURL.Append( m_pLineEndList->GetName() );
+ DBG_ASSERT( aLineURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ // Evaluate if another TabPage set another fill type
+ if( m_xLbLineStyle->get_active() != 0 )
+ {
+ if( m_nPageType == PageType::Hatch ) // 1
+ {
+ m_xLbLineStyle->set_active(*m_pPosDashLb + 2); // +2 due to SOLID and INVISIBLE
+ ChangePreviewHdl_Impl( nullptr );
+ }
+ if( m_nPageType == PageType::Bitmap )
+ {
+ m_xLbStartStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
+ m_xLbEndStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
+ ChangePreviewHdl_Impl( nullptr );
+ }
+ }
+
+ // ColorList
+ if( *m_pnColorListState != ChangeType::NONE )
+ {
+ ChangePreviewHdl_Impl( nullptr );
+ }
+
+ m_nPageType = PageType::Area;
+ }
+ // Page does not yet exist in the ctor, that's why we do it here!
+
+ else if (m_nDlgType == 1101) // nNoArrowNoShadowDlg from chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
+ {
+ m_xFlLineEnds->hide();
+ m_xFLEdgeStyle->hide();
+ }
+}
+
+
+DeactivateRC SvxLineTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( m_nDlgType == 0 ) // Line dialog
+ {
+ m_nPageType = PageType::Gradient; // possibly for extensions
+ *m_pPosDashLb = m_xLbLineStyle->get_active() - 2;// First entry SOLID!!!
+ sal_Int32 nPos = m_xLbStartStyle->get_active();
+ if (nPos != -1)
+ nPos--;
+ *m_pPosLineEndLb = nPos;
+ }
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxLineTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ const SfxPoolItem* pOld = nullptr;
+ sal_Int32 nPos;
+ bool bModified = false;
+
+ // To prevent modifications to the list, we do not set other page's items.
+ if( m_nDlgType != 0 || m_nPageType != PageType::Hatch )
+ {
+ nPos = m_xLbLineStyle->get_active();
+ if( nPos != -1 &&
+ m_xLbLineStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineStyleItem> pStyleItem;
+
+ if( nPos == 0 )
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_NONE ));
+ else if( nPos == 1 )
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_SOLID ));
+ else
+ {
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_DASH ));
+
+ // For added security
+ if( m_pDashList->Count() > static_cast<tools::Long>( nPos - 2 ) )
+ {
+ XLineDashItem aDashItem( m_xLbLineStyle->get_active_text(),
+ m_pDashList->GetDash( nPos - 2 )->GetDash() );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEDASH );
+ if ( !pOld || !( *static_cast<const XLineDashItem*>(pOld) == aDashItem ) )
+ {
+ rAttrs->Put( aDashItem );
+ bModified = true;
+ }
+ }
+ }
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTYLE );
+ if ( !pOld || !( *static_cast<const XLineStyleItem*>(pOld) == *pStyleItem ) )
+ {
+ rAttrs->Put( std::move(pStyleItem) );
+ bModified = true;
+ }
+ }
+ }
+ // Line width
+ // GetSavedValue() returns OUString!
+ if( m_xMtrLineWidth->get_value_changed_from_saved() )
+ {
+ XLineWidthItem aItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEWIDTH );
+ if ( !pOld || !( *static_cast<const XLineWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ // Width line start
+ if( m_xMtrStartWidth->get_value_changed_from_saved() )
+ {
+ XLineStartWidthItem aItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTARTWIDTH );
+ if ( !pOld || !( *static_cast<const XLineStartWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ // Width line end
+ if( m_xMtrEndWidth->get_value_changed_from_saved() )
+ {
+ XLineEndWidthItem aItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEENDWIDTH );
+ if ( !pOld || !( *static_cast<const XLineEndWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // Line color
+ if (m_xLbColor->IsValueChangedFromSaved())
+ {
+ NamedColor aColor = m_xLbColor->GetSelectedEntry();
+ XLineColorItem aItem(aColor.second, aColor.first);
+ pOld = GetOldItem( *rAttrs, XATTR_LINECOLOR );
+ if ( !pOld || !( *static_cast<const XLineColorItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ if( m_nDlgType != 0 || m_nPageType != PageType::Bitmap )
+ {
+ // Line start
+ nPos = m_xLbStartStyle->get_active();
+ if( nPos != -1 && m_xLbStartStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineStartItem> pItem;
+ if( nPos == 0 )
+ pItem.reset(new XLineStartItem());
+ else if( m_pLineEndList->Count() > static_cast<tools::Long>( nPos - 1 ) )
+ pItem.reset(new XLineStartItem( m_xLbStartStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTART );
+ if( pItem && ( !pOld || *pOld != *pItem ) )
+ {
+ rAttrs->Put( std::move(pItem) );
+ bModified = true;
+ }
+ }
+ // Line end
+ nPos = m_xLbEndStyle->get_active();
+ if( nPos != -1 && m_xLbEndStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineEndItem> pItem;
+ if( nPos == 0 )
+ pItem.reset(new XLineEndItem());
+ else if( m_pLineEndList->Count() > static_cast<tools::Long>( nPos - 1 ) )
+ pItem.reset(new XLineEndItem( m_xLbEndStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
+ pOld = GetOldItem( *rAttrs, XATTR_LINEEND );
+ if( pItem &&
+ ( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
+ {
+ rAttrs->Put( std::move(pItem) );
+ bModified = true;
+ }
+ }
+ }
+
+ // Centered line end
+ TriState eState = m_xTsbCenterStart->get_state();
+ if( m_xTsbCenterStart->get_state_changed_from_saved() )
+ {
+ XLineStartCenterItem aItem( eState != TRISTATE_FALSE );
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTARTCENTER );
+ if ( !pOld || !( *static_cast<const XLineStartCenterItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ eState = m_xTsbCenterEnd->get_state();
+ if( m_xTsbCenterEnd->get_state_changed_from_saved() )
+ {
+ XLineEndCenterItem aItem( eState != TRISTATE_FALSE );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEENDCENTER );
+ if ( !pOld || !( *static_cast<const XLineEndCenterItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // Transparency
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ if( m_xMtrTransparent->get_value_changed_from_saved() )
+ {
+ XLineTransparenceItem aItem( nVal );
+ pOld = GetOldItem( *rAttrs, XATTR_LINETRANSPARENCE );
+ if ( !pOld || !( *static_cast<const XLineTransparenceItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ nPos = m_xLBEdgeStyle->get_active();
+ if (nPos != -1 && m_xLBEdgeStyle->get_value_changed_from_saved())
+ {
+ std::unique_ptr<XLineJointItem> pNew;
+
+ switch(nPos)
+ {
+ case 0: // Rounded, default
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_ROUND));
+ break;
+ }
+ case 1: // - none -
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_NONE));
+ break;
+ }
+ case 2: // Miter
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_MITER));
+ break;
+ }
+ case 3: // Bevel
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_BEVEL));
+ break;
+ }
+ }
+
+ if(pNew)
+ {
+ pOld = GetOldItem( *rAttrs, XATTR_LINEJOINT );
+
+ if(!pOld || !(*static_cast<const XLineJointItem*>(pOld) == *pNew))
+ {
+ rAttrs->Put( std::move(pNew) );
+ bModified = true;
+ }
+ }
+ }
+
+ // LineCaps
+ nPos = m_xLBCapStyle->get_active();
+ if (nPos != -1 && m_xLBCapStyle->get_value_changed_from_saved())
+ {
+ std::unique_ptr<XLineCapItem> pNew;
+
+ switch(nPos)
+ {
+ case 0: // Butt (=Flat), default
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_BUTT));
+ break;
+ }
+ case 1: // Round
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_ROUND));
+ break;
+ }
+ case 2: // Square
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_SQUARE));
+ break;
+ }
+ }
+
+ if(pNew)
+ {
+ pOld = GetOldItem( *rAttrs, XATTR_LINECAP );
+
+ if(!pOld || !(*static_cast<const XLineCapItem*>(pOld) == *pNew))
+ {
+ rAttrs->Put( std::move(pNew) );
+ bModified = true;
+ }
+ }
+ }
+
+ if(m_nSymbolType!=SVX_SYMBOLTYPE_UNKNOWN || m_bNewSize)
+ {
+ // Was set by selection or the size is different
+ SvxSizeItem aSItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),m_aSymbolSize);
+ const SfxPoolItem* pSOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE) );
+ m_bNewSize = pSOld ? *static_cast<const SvxSizeItem *>(pSOld) != aSItem : m_bNewSize ;
+ if(m_bNewSize)
+ {
+ rAttrs->Put(aSItem);
+ bModified=true;
+ }
+
+ SfxInt32Item aTItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),m_nSymbolType);
+ const SfxPoolItem* pTOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE) );
+ bool bNewType = pTOld == nullptr || *static_cast<const SfxInt32Item*>(pTOld) != aTItem;
+ if(bNewType && m_nSymbolType==SVX_SYMBOLTYPE_UNKNOWN)
+ bNewType=false; // a small fix, type wasn't set -> don't create a type item after all!
+ if(bNewType)
+ {
+ rAttrs->Put(aTItem);
+ bModified=true;
+ }
+
+ if(m_nSymbolType!=SVX_SYMBOLTYPE_NONE)
+ {
+ SvxBrushItem aBItem(m_aSymbolGraphic,GPOS_MM,rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH));
+ const SfxPoolItem* pBOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH) );
+ bool bNewBrush =
+ pBOld == nullptr || *static_cast<const SvxBrushItem*>(pBOld) != aBItem;
+ if(bNewBrush)
+ {
+ rAttrs->Put(aBItem);
+ bModified=true;
+ }
+ }
+ }
+ rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
+ return bModified;
+}
+
+
+void SvxLineTabPage::FillXLSet_Impl()
+{
+ sal_Int32 nPos;
+
+ if (m_xLbLineStyle->get_active() == -1)
+ {
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
+ }
+ else if (m_xLbLineStyle->get_active() == 0)
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
+ else if (m_xLbLineStyle->get_active() == 1)
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
+ else
+ {
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
+
+ nPos = m_xLbLineStyle->get_active();
+ if (nPos != -1)
+ {
+ m_rXLSet.Put( XLineDashItem( m_xLbLineStyle->get_active_text(),
+ m_pDashList->GetDash( nPos - 2 )->GetDash() ) );
+ }
+ }
+
+ nPos = m_xLbStartStyle->get_active();
+ if (nPos != -1)
+ {
+ if( nPos == 0 )
+ m_rXLSet.Put( XLineStartItem() );
+ else
+ m_rXLSet.Put( XLineStartItem( m_xLbStartStyle->get_active_text(),
+ m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
+ }
+ nPos = m_xLbEndStyle->get_active();
+ if (nPos != -1)
+ {
+ if( nPos == 0 )
+ m_rXLSet.Put( XLineEndItem() );
+ else
+ m_rXLSet.Put( XLineEndItem( m_xLbEndStyle->get_active_text(),
+ m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
+ }
+
+ nPos = m_xLBEdgeStyle->get_active();
+ if (nPos != -1)
+ {
+ switch(nPos)
+ {
+ case 0: // Rounded, default
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_ROUND));
+ break;
+ }
+ case 1: // - none -
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_NONE));
+ break;
+ }
+ case 2: // Miter
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_MITER));
+ break;
+ }
+ case 3: // Bevel
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_BEVEL));
+ break;
+ }
+ }
+ }
+
+ // LineCaps
+ nPos = m_xLBCapStyle->get_active();
+ if (nPos != -1)
+ {
+ switch(nPos)
+ {
+ case 0: // Butt (=Flat), default
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_BUTT));
+ break;
+ }
+ case 1: // Round
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_ROUND));
+ break;
+ }
+ case 2: // Square
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_SQUARE));
+ break;
+ }
+ }
+ }
+
+ m_rXLSet.Put( XLineStartWidthItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) ) );
+ m_rXLSet.Put( XLineEndWidthItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) ) );
+
+ m_rXLSet.Put( XLineWidthItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) ) );
+ NamedColor aColor = m_xLbColor->GetSelectedEntry();
+ m_rXLSet.Put(XLineColorItem(aColor.second, aColor.first));
+
+ // Centered line end
+ if( m_xTsbCenterStart->get_state() == TRISTATE_TRUE )
+ m_rXLSet.Put( XLineStartCenterItem( true ) );
+ else if( m_xTsbCenterStart->get_state() == TRISTATE_FALSE )
+ m_rXLSet.Put( XLineStartCenterItem( false ) );
+
+ if( m_xTsbCenterEnd->get_state() == TRISTATE_TRUE )
+ m_rXLSet.Put( XLineEndCenterItem( true ) );
+ else if( m_xTsbCenterEnd->get_state() == TRISTATE_FALSE )
+ m_rXLSet.Put( XLineEndCenterItem( false ) );
+
+ // Transparency
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ m_rXLSet.Put( XLineTransparenceItem( nVal ) );
+
+ m_aCtlPreview.SetLineAttributes(m_aXLineAttr.GetItemSet());
+}
+
+
+void SvxLineTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ drawing::LineStyle eXLS; // drawing::LineStyle_NONE, drawing::LineStyle_SOLID, drawing::LineStyle_DASH
+
+ // Line style
+ tools::Long nSymType=SVX_SYMBOLTYPE_UNKNOWN;
+ bool bPrevSym=false;
+ bool bEnable=true;
+ bool bIgnoreGraphic=false;
+ bool bIgnoreSize=false;
+ if(const SfxInt32Item* pSymbolTypeItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE)))
+ {
+ nSymType = pSymbolTypeItem->GetValue();
+ }
+
+ if(nSymType == SVX_SYMBOLTYPE_AUTO)
+ {
+ m_aSymbolGraphic=m_aAutoSymbolGraphic;
+ m_aSymbolSize=m_aSymbolLastSize=m_aAutoSymbolGraphic.GetPrefSize();
+ bPrevSym=true;
+ }
+ else if(nSymType == SVX_SYMBOLTYPE_NONE)
+ {
+ bEnable=false;
+ bIgnoreGraphic=true;
+ bIgnoreSize=true;
+ }
+ else if(nSymType >= 0)
+ {
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
+
+ std::unique_ptr<SdrModel> pModel(
+ new SdrModel(nullptr, nullptr, true));
+ pModel->GetItemPool().FreezeIdRanges();
+ rtl::Reference<SdrPage> pPage = new SdrPage( *pModel, false );
+ pPage->SetSize(Size(1000,1000));
+ pModel->InsertPage( pPage.get(), 0 );
+ {
+ SdrView aView( *pModel, pVDev );
+ aView.hideMarkHandles();
+ aView.ShowSdrPage(pPage.get());
+ size_t nSymTmp = static_cast<size_t>(nSymType);
+ if(m_pSymbolList)
+ {
+ if(m_pSymbolList->GetObjCount())
+ {
+ nSymTmp %= m_pSymbolList->GetObjCount(); // Treat list as cyclic!
+ SdrObject *pObj=m_pSymbolList->GetObj(nSymTmp);
+ if(pObj)
+ {
+ // directly clone to target SdrModel
+ pObj = pObj->CloneSdrObject(*pModel);
+
+ if(m_xSymbolAttr)
+ {
+ pObj->SetMergedItemSet(*m_xSymbolAttr);
+ }
+ else
+ {
+ pObj->SetMergedItemSet(m_rOutAttrs);
+ }
+
+ pPage->NbcInsertObject(pObj);
+
+ // Generate invisible square to give all symbol types a
+ // bitmap size, which is independent from specific glyph
+ SdrObject* pInvisibleSquare(m_pSymbolList->GetObj(0));
+
+ // directly clone to target SdrModel
+ pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
+
+ pPage->NbcInsertObject(pInvisibleSquare);
+ pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
+ pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
+
+ aView.MarkAll();
+ GDIMetaFile aMeta(aView.GetMarkedObjMetaFile());
+
+ m_aSymbolGraphic=Graphic(aMeta);
+ m_aSymbolSize=pObj->GetSnapRect().GetSize();
+ m_aSymbolGraphic.SetPrefSize(pInvisibleSquare->GetSnapRect().GetSize());
+ m_aSymbolGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
+ bPrevSym=true;
+ bEnable=true;
+ bIgnoreGraphic=true;
+
+ aView.UnmarkAll();
+ pInvisibleSquare=pPage->RemoveObject(1);
+ SdrObject::Free( pInvisibleSquare);
+ pObj=pPage->RemoveObject(0);
+ SdrObject::Free( pObj );
+ }
+ }
+ }
+ }
+ }
+ if(const SvxBrushItem* pBrushItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH)))
+ {
+ const Graphic* pGraphic = pBrushItem->GetGraphic();
+ if( pGraphic )
+ {
+ if(!bIgnoreGraphic)
+ {
+ m_aSymbolGraphic=*pGraphic;
+ }
+ if(!bIgnoreSize)
+ {
+ m_aSymbolSize=OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode(),
+ MapMode(MapUnit::Map100thMM));
+ }
+ bPrevSym=true;
+ }
+ }
+
+ if(const SvxSizeItem* pSymbolSizeItem = rAttrs->GetItemIfSet(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE)))
+ {
+ m_aSymbolSize = pSymbolSizeItem->GetSize();
+ }
+
+ m_xGridIconSize->set_sensitive(bEnable);
+
+ if(bPrevSym)
+ {
+ SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
+ SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(),m_ePoolUnit);
+ m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
+ m_aSymbolLastSize=m_aSymbolSize;
+ }
+
+ if( rAttrs->GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
+ {
+ eXLS = rAttrs->Get( XATTR_LINESTYLE ).GetValue();
+
+ switch( eXLS )
+ {
+ case drawing::LineStyle_NONE:
+ m_xLbLineStyle->set_active(0);
+ break;
+ case drawing::LineStyle_SOLID:
+ m_xLbLineStyle->set_active(1);
+ break;
+
+ case drawing::LineStyle_DASH:
+ m_xLbLineStyle->set_active(-1);
+ m_xLbLineStyle->set_active_text(rAttrs->Get( XATTR_LINEDASH ).GetName());
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ m_xLbLineStyle->set_active(-1);
+ }
+
+ // Line strength
+ if( rAttrs->GetItemState( XATTR_LINEWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrLineWidth, rAttrs->Get( XATTR_LINEWIDTH ).GetValue(), m_ePoolUnit );
+ }
+ else
+ m_xMtrLineWidth->set_text("");
+
+ // Line color
+ m_xLbColor->SetNoSelection();
+
+ if ( rAttrs->GetItemState( XATTR_LINECOLOR ) != SfxItemState::DONTCARE )
+ {
+ Color aCol = rAttrs->Get( XATTR_LINECOLOR ).GetColorValue();
+ m_xLbColor->SelectEntry( aCol );
+ }
+
+ // Line start
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTART ) == SfxItemState::DEFAULT )
+ {
+ m_xLbStartStyle->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTART ) != SfxItemState::DONTCARE )
+ {
+ // #86265# select entry using list and polygon, not string
+ bool bSelected(false);
+ const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINESTART).GetLineStartValue();
+
+ for(tools::Long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
+ {
+ const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
+ const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
+
+ if(rItemPolygon == rEntryPolygon)
+ {
+ // select this entry
+ m_xLbStartStyle->set_active(a + 1);
+ bSelected = true;
+ }
+ }
+
+ if(!bSelected)
+ m_xLbStartStyle->set_active(0);
+ }
+ else
+ {
+ m_xLbStartStyle->set_active(-1);
+ }
+
+ // Line end
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEEND ) == SfxItemState::DEFAULT )
+ {
+ m_xLbEndStyle->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEEND ) != SfxItemState::DONTCARE )
+ {
+ // #86265# select entry using list and polygon, not string
+ bool bSelected(false);
+ const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINEEND).GetLineEndValue();
+
+ for(tools::Long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
+ {
+ const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
+ const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
+
+ if(rItemPolygon == rEntryPolygon)
+ {
+ // select this entry
+ m_xLbEndStyle->set_active(a + 1);
+ bSelected = true;
+ }
+ }
+
+ if(!bSelected)
+ m_xLbEndStyle->set_active(0);
+ }
+ else
+ {
+ m_xLbEndStyle->set_active(-1);
+ }
+
+ // Line start strength
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) == SfxItemState::DEFAULT )
+ {
+ m_xMtrStartWidth->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrStartWidth,
+ rAttrs->Get( XATTR_LINESTARTWIDTH ).GetValue(),
+ m_ePoolUnit );
+ }
+ else
+ m_xMtrStartWidth->set_text( "" );
+
+ // Line end strength
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDWIDTH ) == SfxItemState::DEFAULT )
+ {
+ m_xMtrEndWidth->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEENDWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrEndWidth,
+ rAttrs->Get( XATTR_LINEENDWIDTH ).GetValue(),
+ m_ePoolUnit );
+ }
+ else
+ m_xMtrEndWidth->set_text("");
+
+ // Centered line end (start)
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTCENTER ) == SfxItemState::DEFAULT )
+ {
+ m_xTsbCenterStart->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTARTCENTER ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( XATTR_LINESTARTCENTER ).GetValue() )
+ m_xTsbCenterStart->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbCenterStart->set_state(TRISTATE_FALSE);
+ }
+ else
+ {
+ m_xTsbCenterStart->set_state(TRISTATE_INDET);
+ }
+
+ // Centered line end (end)
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDCENTER ) == SfxItemState::DEFAULT )
+ {
+ m_xTsbCenterEnd->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEENDCENTER ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( XATTR_LINEENDCENTER ).GetValue() )
+ m_xTsbCenterEnd->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbCenterEnd->set_state(TRISTATE_FALSE);
+ }
+ else
+ {
+ m_xTsbCenterEnd->set_state(TRISTATE_INDET);
+ }
+
+ // Transparency
+ if( rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nTransp = rAttrs->Get( XATTR_LINETRANSPARENCE ).GetValue();
+ m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
+ ChangeTransparentHdl_Impl(*m_xMtrTransparent);
+ }
+ else
+ m_xMtrTransparent->set_text( "" );
+
+ if( !m_xLbStartStyle->get_sensitive() &&
+ !m_xLbEndStyle->get_sensitive() &&
+ !m_xMtrStartWidth->get_sensitive() &&
+ !m_xMtrEndWidth->get_sensitive() &&
+ !m_xTsbCenterStart->get_sensitive()&&
+ !m_xTsbCenterEnd->get_sensitive() )
+ {
+ m_xCbxSynchronize->set_sensitive(false);
+ m_xFlLineEnds->set_sensitive(false);
+ }
+
+ // Synchronize
+ // We get the value from the INI file now
+ OUString aStr = GetUserData();
+ m_xCbxSynchronize->set_active(aStr.toInt32() != 0);
+
+ if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINEJOINT))
+ {
+// maFTEdgeStyle.set_sensitive(false);
+ m_xLBEdgeStyle->set_sensitive(false);
+ }
+ else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINEJOINT))
+ {
+ const css::drawing::LineJoint eLineJoint = rAttrs->Get(XATTR_LINEJOINT).GetValue();
+
+ switch(eLineJoint)
+ {
+ case css::drawing::LineJoint::LineJoint_MAKE_FIXED_SIZE: // fallback to round, unused value
+ case css::drawing::LineJoint_ROUND : m_xLBEdgeStyle->set_active(0); break;
+ case css::drawing::LineJoint_NONE : m_xLBEdgeStyle->set_active(1); break;
+ case css::drawing::LineJoint_MIDDLE : // fallback to mitre, unused value
+ case css::drawing::LineJoint_MITER : m_xLBEdgeStyle->set_active(2); break;
+ case css::drawing::LineJoint_BEVEL : m_xLBEdgeStyle->set_active(3); break;
+ }
+ }
+ else
+ {
+ m_xLBEdgeStyle->set_active(-1);
+ }
+
+ // fdo#43209
+ if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINECAP))
+ {
+ m_xLBCapStyle->set_sensitive(false);
+ }
+ else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINECAP))
+ {
+ const css::drawing::LineCap eLineCap(rAttrs->Get(XATTR_LINECAP).GetValue());
+
+ switch(eLineCap)
+ {
+ case css::drawing::LineCap_ROUND: m_xLBCapStyle->set_active(1); break;
+ case css::drawing::LineCap_SQUARE : m_xLBCapStyle->set_active(2); break;
+ default /*css::drawing::LineCap_BUTT*/: m_xLBCapStyle->set_active(0); break;
+ }
+ }
+ else
+ {
+ m_xLBCapStyle->set_active(-1);
+ }
+
+ // Save values
+ m_xLbLineStyle->save_value();
+ m_xMtrLineWidth->save_value();
+ m_xLbColor->SaveValue();
+ m_xLbStartStyle->save_value();
+ m_xLbEndStyle->save_value();
+ m_xMtrStartWidth->save_value();
+ m_xMtrEndWidth->save_value();
+ m_xTsbCenterStart->save_state();
+ m_xTsbCenterEnd->save_state();
+ m_xMtrTransparent->save_value();
+
+ m_xLBEdgeStyle->save_value();
+
+ // LineCaps
+ m_xLBCapStyle->save_value();
+
+ ClickInvisibleHdl_Impl();
+
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+std::unique_ptr<SfxTabPage> SvxLineTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxLineTabPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangePreviewListBoxHdl_Impl, ColorListBox&, void)
+{
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK(SvxLineTabPage, ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, rEdit, void)
+{
+ ChangePreviewHdl_Impl(&rEdit);
+}
+
+void SvxLineTabPage::ChangePreviewHdl_Impl(const weld::MetricSpinButton* pCntrl)
+{
+ if (pCntrl == m_xMtrLineWidth.get())
+ {
+ // Line width and start end width
+ sal_Int32 nNewLineWidth = GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit );
+ if(m_nActLineWidth == -1)
+ {
+ // Don't initialize yet, get the start value
+ const SfxPoolItem* pOld = GetOldItem( m_rXLSet, XATTR_LINEWIDTH );
+ sal_Int32 nStartLineWidth = 0;
+ if(pOld)
+ nStartLineWidth = static_cast<const XLineWidthItem *>(pOld)->GetValue();
+ m_nActLineWidth = nStartLineWidth;
+ }
+
+ if(m_nActLineWidth != nNewLineWidth)
+ {
+ // Adapt start/end width
+ sal_Int32 nValAct = GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit );
+ sal_Int32 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
+ if(nValNew < 0)
+ nValNew = 0;
+ SetMetricValue( *m_xMtrStartWidth, nValNew, m_ePoolUnit );
+
+ nValAct = GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit );
+ nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
+ if(nValNew < 0)
+ nValNew = 0;
+ SetMetricValue( *m_xMtrEndWidth, nValNew, m_ePoolUnit );
+ }
+
+ // Remember current value
+ m_nActLineWidth = nNewLineWidth;
+ }
+
+ FillXLSet_Impl();
+ m_aCtlPreview.Invalidate();
+
+ // Make transparency accessible accordingly
+ if( m_xLbLineStyle->get_active() == 0 ) // invisible
+ {
+ m_xBoxTransparency->set_sensitive(false);
+ }
+ else
+ {
+ m_xBoxTransparency->set_sensitive(true);
+ }
+
+ const bool bHasLineStyle = m_xLbLineStyle->get_active() !=0;
+ const bool bHasLineStart = m_xLbStartStyle->get_active() != 0;
+
+ m_xBoxStart->set_sensitive(bHasLineStart && bHasLineStyle);
+
+ const bool bHasLineEnd = m_xLbEndStyle->get_active() != 0;
+
+ m_xBoxEnd->set_sensitive(bHasLineEnd && bHasLineStyle);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartClickHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xTsbCenterEnd->set_state(m_xTsbCenterStart->get_state());
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xLbEndStyle->set_active(m_xLbStartStyle->get_active());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xMtrEndWidth->set_value(m_xMtrStartWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void)
+{
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+// fdo#43209
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeCapStyleHdl_Impl, weld::ComboBox&, void)
+{
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ClickInvisibleHdl_Impl, weld::ComboBox&, void)
+{
+ ClickInvisibleHdl_Impl();
+}
+
+void SvxLineTabPage::ClickInvisibleHdl_Impl()
+{
+ if( m_xLbLineStyle->get_active() == 0 ) // invisible
+ {
+ if(!m_bSymbols)
+ m_xBoxColor->set_sensitive(false);
+
+ m_xBoxWidth->set_sensitive(false);
+
+ if( m_xFlLineEnds->get_sensitive() )
+ {
+ m_xBoxStart->set_sensitive(false);
+ m_xBoxArrowStyles->set_sensitive(false);
+ m_xGridEdgeCaps->set_sensitive(false);
+ }
+ }
+ else
+ {
+ // set cap style associated to the line style
+ sal_Int32 nPos = m_xLbLineStyle->get_active();
+ if( nPos > 1 && m_pDashList->Count() > static_cast<tools::Long>( nPos - 2 ) )
+ {
+ css::drawing::DashStyle eStyle =
+ m_pDashList->GetDash( nPos - 2 )->GetDash().GetDashStyle();
+ if ( eStyle == drawing::DashStyle_RECT || eStyle == drawing::DashStyle_RECTRELATIVE)
+ m_xLBCapStyle->set_active(0);
+ else
+ m_xLBCapStyle->set_active(1);
+ }
+
+ m_xBoxColor->set_sensitive(true);
+ m_xBoxWidth->set_sensitive(true);
+
+ if (m_xFlLineEnds->get_sensitive())
+ {
+ m_xBoxArrowStyles->set_sensitive(true);
+ m_xGridEdgeCaps->set_sensitive(true);
+ }
+ }
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndClickHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xTsbCenterStart->set_state(m_xTsbCenterEnd->get_state());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xLbStartStyle->set_active(m_xLbEndStyle->get_active());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xMtrStartWidth->set_value(m_xMtrEndWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+
+ m_rXLSet.Put(XLineTransparenceItem(nVal));
+
+ FillXLSet_Impl();
+
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxLineTabPage::FillUserData()
+{
+ // Write the synched value to the INI file
+ OUString aStrUserData = OUString::boolean(m_xCbxSynchronize->get_active());
+ SetUserData( aStrUserData );
+}
+
+// #58425# Symbols on a list (e.g. StarChart)
+// Handler for the symbol selection's popup menu (NumMenueButton)
+// The following link originates from SvxNumOptionsTabPage
+IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::Toggleable&, void)
+{
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+
+ // Initialize popup
+ if (!m_xGalleryMenu)
+ {
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+ // Get gallery entries
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames);
+
+ sal_uInt32 i = 0;
+ for (auto const& grfName : m_aGrfNames)
+ {
+ const OUString *pUIName = &grfName;
+
+ // Convert URL encodings to UI characters (e.g. %20 for spaces)
+ OUString aPhysicalName;
+ if (osl::FileBase::getSystemPathFromFileURL(grfName, aPhysicalName)
+ == osl::FileBase::E_None)
+ {
+ pUIName = &aPhysicalName;
+ }
+
+ SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
+ pInfo->pBrushItem.reset(new SvxBrushItem(grfName, "", GPOS_AREA, SID_ATTR_BRUSH));
+ pInfo->sItemId = "gallery" + OUString::number(i);
+ m_aGalleryBrushItems.emplace_back(pInfo);
+ const Graphic* pGraphic = pInfo->pBrushItem->GetGraphic();
+
+ if(pGraphic)
+ {
+ BitmapEx aBitmap(pGraphic->GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(pInfo->sItemId, *pUIName);
+ }
+ ++i;
+ }
+
+ if (m_aGrfNames.empty())
+ m_xSymbolMB->set_item_sensitive("gallery", false);
+ }
+
+ if (m_xSymbolsMenu || !m_pSymbolList)
+ return;
+
+ m_xSymbolsMenu = m_xBuilder->weld_menu("symbolssubmenu");
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
+ std::unique_ptr<SdrModel> pModel(
+ new SdrModel(nullptr, nullptr, true));
+ pModel->GetItemPool().FreezeIdRanges();
+ // Page
+ rtl::Reference<SdrPage> pPage = new SdrPage( *pModel, false );
+ pPage->SetSize(Size(1000,1000));
+ pModel->InsertPage( pPage.get(), 0 );
+ {
+ // 3D View
+ SdrView aView( *pModel, pVDev );
+ aView.hideMarkHandles();
+ aView.ShowSdrPage(pPage.get());
+
+ // Generate invisible square to give all symbols a
+ // bitmap size, which is independent from specific glyph
+ SdrObject *pInvisibleSquare=m_pSymbolList->GetObj(0);
+
+ // directly clone to target SdrModel
+ pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
+
+ pPage->NbcInsertObject(pInvisibleSquare);
+ pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
+ pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
+
+ for(size_t i=0; i < m_pSymbolList->GetObjCount(); ++i)
+ {
+ SdrObject *pObj=m_pSymbolList->GetObj(i);
+ assert(pObj);
+
+ // directly clone to target SdrModel
+ pObj = pObj->CloneSdrObject(*pModel);
+
+ m_aGrfNames.emplace_back("");
+ pPage->NbcInsertObject(pObj);
+ if(m_xSymbolAttr)
+ {
+ pObj->SetMergedItemSet(*m_xSymbolAttr);
+ }
+ else
+ {
+ pObj->SetMergedItemSet(m_rOutAttrs);
+ }
+ aView.MarkAll();
+ BitmapEx aBitmapEx(aView.GetMarkedObjBitmapEx());
+ GDIMetaFile aMeta(aView.GetMarkedObjMetaFile());
+ aView.UnmarkAll();
+ pObj=pPage->RemoveObject(1);
+ SdrObject::Free(pObj);
+
+ SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
+ pInfo->pBrushItem.reset(new SvxBrushItem(Graphic(aMeta), GPOS_AREA, SID_ATTR_BRUSH));
+ pInfo->sItemId = "symbol" + OUString::number(i);
+ m_aSymbolBrushItems.emplace_back(pInfo);
+
+ Size aSize(aBitmapEx.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmapEx.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel());
+ pVD->DrawBitmapEx(Point(), aBitmapEx);
+ m_xSymbolsMenu->append(pInfo->sItemId, "", *pVD);
+ }
+ pInvisibleSquare=pPage->RemoveObject(0);
+ SdrObject::Free(pInvisibleSquare);
+
+ if (m_aGrfNames.empty())
+ m_xSymbolMB->set_item_sensitive("symbols", false);
+ }
+}
+
+// #58425# Symbols on a list (e.g. StarChart)
+// Handler for menu button
+IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
+{
+ const Graphic* pGraphic = nullptr;
+ Graphic aGraphic;
+ bool bResetSize = false;
+ bool bEnable = true;
+ tools::Long nPreviousSymbolType = m_nSymbolType;
+
+ OString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[sNumber.toUInt32()].get();
+ pGraphic = pInfo->pBrushItem->GetGraphic();
+ m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
+ }
+ else if (rIdent.startsWith("symbol", &sNumber))
+ {
+ m_nSymbolType = sNumber.toUInt32();
+ SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
+ pGraphic = pInfo->pBrushItem->GetGraphic();
+ }
+ else if (rIdent == "automatic")
+ {
+ pGraphic=&m_aAutoSymbolGraphic;
+ m_aAutoSymbolGraphic.SetPrefSize( Size(253,253) );
+ m_nSymbolType=SVX_SYMBOLTYPE_AUTO;
+ }
+ else if (rIdent == "none")
+ {
+ m_nSymbolType=SVX_SYMBOLTYPE_NONE;
+ pGraphic=nullptr;
+ bEnable = false;
+ }
+ else if (rIdent == "file")
+ {
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_CUISTR_EDIT_GRAPHIC), GetFrameWeld());
+ aGrfDlg.EnableLink(false);
+ aGrfDlg.AsLink(false);
+ if( !aGrfDlg.Execute() )
+ {
+ // Remember selected filters
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ m_nSymbolType=SVX_SYMBOLTYPE_BRUSHITEM;
+ pGraphic = &aGraphic;
+ bResetSize = true;
+ }
+ }
+ if( !pGraphic )
+ return;
+ }
+
+ if (pGraphic)
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
+ m_aSymbolGraphic=*pGraphic;
+ if( bResetSize )
+ {
+ m_aSymbolSize=aSize;
+ }
+ else if( nPreviousSymbolType == SVX_SYMBOLTYPE_BRUSHITEM )
+ { //#i31097# Data Point Symbol size changes when a different symbol is chosen(maoyg)
+ if( m_aSymbolSize.Width() != m_aSymbolSize.Height() )
+ {
+ aSize.setWidth( static_cast<tools::Long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
+ aSize.setHeight( static_cast<tools::Long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
+ m_aSymbolSize = aSize;
+ }
+ }
+ m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
+ }
+ else
+ {
+ m_aSymbolGraphic=Graphic();
+ m_aCtlPreview.SetSymbol(nullptr,m_aSymbolSize);
+ bEnable = false;
+ }
+ m_aSymbolLastSize=m_aSymbolSize;
+ SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
+ SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(), m_ePoolUnit);
+
+ m_xGridIconSize->set_sensitive(bEnable);
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK( SvxLineTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ m_bNewSize = true;
+ bool bWidth = &rField == m_xSymbolWidthMF.get();
+ m_bLastWidthModified = bWidth;
+ bool bRatio = m_xSymbolRatioCB->get_active();
+ tools::Long nWidthVal = static_cast<tools::Long>(m_xSymbolWidthMF->denormalize(m_xSymbolWidthMF->get_value(FieldUnit::MM_100TH)));
+ tools::Long nHeightVal= static_cast<tools::Long>(m_xSymbolHeightMF->denormalize(m_xSymbolHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic(nWidthVal,MapUnit::Map100thMM, m_ePoolUnit );
+ nHeightVal = OutputDevice::LogicToLogic(nHeightVal,MapUnit::Map100thMM, m_ePoolUnit);
+ m_aSymbolSize = Size(nWidthVal,nHeightVal);
+ double fSizeRatio = double(1);
+
+ if(bRatio)
+ {
+ if (m_aSymbolLastSize.Height() && m_aSymbolLastSize.Width())
+ fSizeRatio = static_cast<double>(m_aSymbolLastSize.Width()) / m_aSymbolLastSize.Height();
+ }
+
+ if (bWidth)
+ {
+ tools::Long nDelta = nWidthVal - m_aSymbolLastSize.Width();
+ m_aSymbolSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ m_aSymbolSize.setHeight( m_aSymbolLastSize.Height() + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_aSymbolSize.setHeight( OutputDevice::LogicToLogic( m_aSymbolSize.Height(), m_ePoolUnit, MapUnit::Map100thMM ) );
+//TODO m_xSymbolHeightMF->SetUserValue(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
+ m_xSymbolHeightMF->set_value(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ tools::Long nDelta = nHeightVal - m_aSymbolLastSize.Height();
+ m_aSymbolSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ m_aSymbolSize.setWidth( m_aSymbolLastSize.Width() + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_aSymbolSize.setWidth( OutputDevice::LogicToLogic( m_aSymbolSize.Width(), m_ePoolUnit, MapUnit::Map100thMM ) );
+//TODO m_xSymbolWidthMF->SetUserValue(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
+ m_xSymbolWidthMF->set_value(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
+ }
+ }
+ m_aCtlPreview.ResizeSymbol(m_aSymbolSize);
+ m_aSymbolLastSize=m_aSymbolSize;
+}
+
+IMPL_LINK(SvxLineTabPage, RatioHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (m_bLastWidthModified)
+ SizeHdl_Impl(*m_xSymbolWidthMF);
+ else
+ SizeHdl_Impl(*m_xSymbolHeightMF);
+ }
+}
+
+void SvxLineTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxDashListItem* pDashListItem = aSet.GetItem<SvxDashListItem>(SID_DASH_LIST, false);
+ const SvxLineEndListItem* pLineEndListItem = aSet.GetItem<SvxLineEndListItem>(SID_LINEEND_LIST, false);
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+ const OfaPtrItem* pSdrObjListItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+ const SfxTabDialogItem* pSymbolAttrItem = aSet.GetItem<SfxTabDialogItem>(SID_ATTR_SET, false);
+ const SvxGraphicItem* pGraphicItem = aSet.GetItem<SvxGraphicItem>(SID_GRAPHIC, false);
+
+ if (pDashListItem)
+ SetDashList(pDashListItem->GetDashList());
+ if (pLineEndListItem)
+ SetLineEndList(pLineEndListItem->GetLineEndList());
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+ Construct();
+
+ if(pSdrObjListItem) //symbols
+ {
+ ShowSymbolControls(true);
+ m_pSymbolList = static_cast<SdrObjList*>(pSdrObjListItem->GetValue());
+ if (pSymbolAttrItem)
+ m_xSymbolAttr.reset(new SfxItemSet(pSymbolAttrItem->GetItemSet()));
+ if(pGraphicItem)
+ m_aAutoSymbolGraphic = pGraphicItem->GetGraphic();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tplnedef.cxx b/cui/source/tabpages/tplnedef.cxx
new file mode 100644
index 000000000..66fea1aba
--- /dev/null
+++ b/cui/source/tabpages/tplnedef.cxx
@@ -0,0 +1,840 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <strings.hrc>
+
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xtable.hxx>
+
+#include <svx/dlgctrl.hxx>
+#include <cuitabline.hxx>
+#include <defdlgname.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+#include <cuitabarea.hxx>
+#include <svtools/unitconv.hxx>
+#include <osl/diagnose.h>
+
+#define XOUT_WIDTH 150
+
+using namespace com::sun::star;
+
+
+SvxLineDefTabPage::SvxLineDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/linestyletabpage.ui", "LineStylePage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aXLineAttr(rInAttrs.GetPool())
+ , rXLSet(aXLineAttr.GetItemSet())
+ , pnDashListState(nullptr)
+ , pPageType(nullptr)
+ , nDlgType(0)
+ , pPosDashLb(nullptr)
+ , m_xLbLineStyles(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINESTYLES")))
+ , m_xLbType1(m_xBuilder->weld_combo_box("LB_TYPE_1"))
+ , m_xLbType2(m_xBuilder->weld_combo_box("LB_TYPE_2"))
+ , m_xNumFldNumber1(m_xBuilder->weld_spin_button("NUM_FLD_1"))
+ , m_xNumFldNumber2(m_xBuilder->weld_spin_button("NUM_FLD_2"))
+ , m_xMtrLength1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_1", FieldUnit::CM))
+ , m_xMtrLength2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_2", FieldUnit::CM))
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
+ , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
+ , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
+ , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ; //prevent warning
+ }
+ SetFieldUnit(*m_xMtrDistance, eFUnit);
+ SetFieldUnit(*m_xMtrLength1, eFUnit);
+ SetFieldUnit(*m_xMtrLength2, eFUnit);
+
+ // determine PoolUnit
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
+
+ rXLSet.Put( XLineStyleItem(drawing::LineStyle_DASH) );
+ rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
+ rXLSet.Put( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT, 3, 7, 2, 40, 15 ) ) );
+ rXLSet.Put( XLineColorItem(OUString(), COL_BLACK) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+
+ m_xBtnAdd->connect_clicked(LINK(this, SvxLineDefTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK(this, SvxLineDefTabPage, ClickModifyHdl_Impl));
+ m_xBtnDelete->connect_clicked(LINK(this, SvxLineDefTabPage, ClickDeleteHdl_Impl));
+ m_xBtnLoad->connect_clicked(LINK(this, SvxLineDefTabPage, ClickLoadHdl_Impl));
+ m_xBtnSave->connect_clicked(LINK(this, SvxLineDefTabPage, ClickSaveHdl_Impl));
+
+ m_xNumFldNumber1->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber1Hdl_Impl));
+ m_xNumFldNumber2->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber2Hdl_Impl));
+ m_xLbLineStyles->connect_changed(LINK(this, SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl));
+
+ // #i122042# switch off default adding of 'none' and 'solid' entries
+ // for this ListBox; we want to select only editable/dashed styles
+ m_xLbLineStyles->setAddStandardFields(false);
+
+ // absolute (in mm) or relative (in %)
+ m_xCbxSynchronize->connect_toggled(LINK(this, SvxLineDefTabPage, ChangeMetricHdl_Impl));
+
+ // preview must be updated when there's something changed
+ Link<weld::ComboBox&, void> aLink = LINK(this, SvxLineDefTabPage, SelectTypeListBoxHdl_Impl);
+ m_xLbType1->connect_changed(aLink);
+ m_xLbType2->connect_changed(aLink);
+ Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, SvxLineDefTabPage, ChangePreviewHdl_Impl );
+ m_xMtrLength1->connect_value_changed(aLink2);
+ m_xMtrLength2->connect_value_changed(aLink2);
+ m_xMtrDistance->connect_value_changed(aLink2);
+
+ pDashList = nullptr;
+}
+
+SvxLineDefTabPage::~SvxLineDefTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbLineStyles.reset();
+}
+
+void SvxLineDefTabPage::Construct()
+{
+ // Line style fill; do *not* add default fields here
+ m_xLbLineStyles->Fill( pDashList );
+}
+
+void SvxLineDefTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( nDlgType != 0 ) // area dialog
+ return;
+
+ // ActivatePage() is called before the dialog receives PageCreated() !!!
+ if( !pDashList.is() )
+ return;
+
+ if (*pPageType == PageType::Gradient &&
+ *pPosDashLb != -1)
+ {
+ m_xLbLineStyles->set_active(*pPosDashLb);
+ }
+ // so that a possibly existing line style is discarded
+ SelectLinestyleHdl_Impl( nullptr );
+
+ // determining (and possibly cutting) the name
+ // and displaying it in the GroupBox
+// OUString aString( CuiResId( RID_CUISTR_TABLE ) );
+// aString += ": ";
+ INetURLObject aURL( pDashList->GetPath() );
+
+ aURL.Append( pDashList->GetName() );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ *pPageType = PageType::Area; // 2
+ *pPosDashLb = -1;
+}
+
+
+DeactivateRC SvxLineDefTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ CheckChanges_Impl();
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxLineDefTabPage::CheckChanges_Impl()
+{
+ // is here used to NOT lose changes
+ //css::drawing::DashStyle eXDS;
+
+ if( m_xNumFldNumber1->get_value_changed_from_saved() ||
+ m_xMtrLength1->get_value_changed_from_saved() ||
+ m_xLbType1->get_value_changed_from_saved() ||
+ m_xNumFldNumber2->get_value_changed_from_saved() ||
+ m_xMtrLength2->get_value_changed_from_saved() ||
+ m_xLbType2->get_value_changed_from_saved() ||
+ m_xMtrDistance->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<weld::MessageDialog> xMessDlg(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Cancel,
+ CuiResId(RID_CUISTR_ASK_CHANGE_LINESTYLE)));
+ xMessDlg->set_title(SvxResId(RID_SVXSTR_LINESTYLE));
+ xMessDlg->add_button(CuiResId(RID_CUISTR_CHANGE), RET_BTN_1);
+ xMessDlg->add_button(CuiResId(RID_CUISTR_ADD), RET_BTN_2);
+
+ short nRet = xMessDlg->run();
+
+ switch( nRet )
+ {
+ case RET_BTN_1:
+ {
+ ClickModifyHdl_Impl(*m_xBtnModify);
+ }
+ break;
+
+ case RET_BTN_2:
+ {
+ ClickAddHdl_Impl(*m_xBtnAdd);
+ }
+ break;
+
+ case RET_CANCEL:
+ break;
+ }
+ }
+
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos != -1)
+ {
+ *pPosDashLb = nPos;
+ }
+}
+
+
+bool SvxLineDefTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ if( nDlgType == 0 ) // line dialog
+ {
+ if( *pPageType == PageType::Hatch )
+ {
+ FillDash_Impl();
+
+ OUString aString(m_xLbLineStyles->get_active_text());
+ rAttrs->Put( XLineStyleItem( drawing::LineStyle_DASH ) );
+ rAttrs->Put( XLineDashItem( aString, aDash ) );
+ }
+ }
+ return true;
+}
+
+
+void SvxLineDefTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ if( rAttrs->GetItemState( GetWhich( XATTR_LINESTYLE ) ) != SfxItemState::DONTCARE )
+ {
+ drawing::LineStyle eXLS = rAttrs->Get( GetWhich( XATTR_LINESTYLE ) ).GetValue();
+
+ switch( eXLS )
+ {
+ case drawing::LineStyle_NONE:
+ case drawing::LineStyle_SOLID:
+ m_xLbLineStyles->set_active(0);
+ break;
+ case drawing::LineStyle_DASH:
+ {
+ const XLineDashItem& rDashItem = rAttrs->Get( XATTR_LINEDASH );
+ aDash = rDashItem.GetDashValue();
+
+ m_xLbLineStyles->set_active(-1);
+ m_xLbLineStyles->set_active_text(rDashItem.GetName());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ SelectLinestyleHdl_Impl( nullptr );
+
+ // determine button state
+ if( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxLineDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs )
+{
+ return std::make_unique<SvxLineDefTabPage>(pPage, pController, *rOutAttrs);
+}
+
+IMPL_LINK(SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ SelectLinestyleHdl_Impl(&rListBox);
+}
+
+void SvxLineDefTabPage::SelectLinestyleHdl_Impl(const weld::ComboBox* p)
+{
+ if(!pDashList->Count())
+ return;
+
+ int nTmp = m_xLbLineStyles->get_active();
+ if (nTmp == -1)
+ {
+ OSL_ENSURE(false, "OOps, non-existent LineDash selected (!)");
+ nTmp = 1;
+ }
+
+ aDash = pDashList->GetDash( nTmp )->GetDash();
+
+ FillDialog_Impl();
+
+ rXLSet.Put( XLineDashItem( OUString(), aDash ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+
+ // Is not set before, in order to take the new style
+ // only if there was an entry selected in the ListBox.
+ // If it was called via Reset(), then p is == NULL
+ if( p )
+ *pPageType = PageType::Hatch;
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangePreviewHdl_Impl, weld::MetricSpinButton&, void)
+{
+ FillDash_Impl();
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber1Hdl_Impl, weld::SpinButton&, void)
+{
+ if (m_xNumFldNumber1->get_value() == 0)
+ {
+ m_xNumFldNumber2->set_min(1);
+ }
+ else
+ {
+ m_xNumFldNumber2->set_min(0);
+ }
+
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber2Hdl_Impl, weld::SpinButton&, void)
+{
+ if (m_xNumFldNumber2->get_value() == 0)
+ {
+ m_xNumFldNumber1->set_min(1);
+ }
+ else
+ {
+ m_xNumFldNumber1->set_min(0);
+ }
+
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK( SvxLineDefTabPage, ChangeMetricHdl_Impl, weld::Toggleable&, r, void)
+{
+ ChangeMetricHdl_Impl(&r);
+}
+
+void SvxLineDefTabPage::ChangeMetricHdl_Impl(const weld::Toggleable* p)
+{
+ if( !m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != eFUnit )
+ {
+ tools::Long nTmp1, nTmp2, nTmp3;
+
+ // was changed with Control
+ if( p )
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * XOUT_WIDTH / 100;
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * XOUT_WIDTH / 100;
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * XOUT_WIDTH / 100;
+ }
+ else
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
+ }
+ m_xMtrLength1->set_digits(2);
+ m_xMtrLength2->set_digits(2);
+ m_xMtrDistance->set_digits(2);
+
+ // adjust metric
+ m_xMtrLength1->set_unit(eFUnit);
+ m_xMtrLength2->set_unit(eFUnit);
+ m_xMtrDistance->set_unit(eFUnit);
+
+ // tdf#126736 max 5cm
+ m_xMtrLength1->set_range(0, 500, FieldUnit::CM);
+ m_xMtrLength2->set_range(0, 500, FieldUnit::CM);
+ m_xMtrDistance->set_range(0, 500, FieldUnit::CM);
+
+ SetMetricValue( *m_xMtrLength1, nTmp1, ePoolUnit );
+ SetMetricValue( *m_xMtrLength2, nTmp2, ePoolUnit );
+ SetMetricValue( *m_xMtrDistance, nTmp3, ePoolUnit );
+ }
+ else if( m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != FieldUnit::PERCENT )
+ {
+ tools::Long nTmp1, nTmp2, nTmp3;
+
+ // was changed with Control
+ if( p )
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * 100 / XOUT_WIDTH;
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * 100 / XOUT_WIDTH;
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * 100 / XOUT_WIDTH;
+ }
+ else
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
+ }
+
+ m_xMtrLength1->set_digits(0);
+ m_xMtrLength2->set_digits(0);
+ m_xMtrDistance->set_digits(0);
+
+ m_xMtrLength1->set_unit(FieldUnit::PERCENT);
+ m_xMtrLength2->set_unit(FieldUnit::PERCENT);
+ m_xMtrDistance->set_unit(FieldUnit::PERCENT);
+
+ // tdf#126736 800%
+ m_xMtrLength1->set_range(0, 800, FieldUnit::PERCENT);
+ m_xMtrLength2->set_range(0, 800, FieldUnit::PERCENT);
+ m_xMtrDistance->set_range(0, 800, FieldUnit::PERCENT);
+
+ m_xMtrLength1->set_value(nTmp1, FieldUnit::PERCENT);
+ m_xMtrLength2->set_value(nTmp2, FieldUnit::PERCENT);
+ m_xMtrDistance->set_value(nTmp3, FieldUnit::PERCENT);
+ }
+ SelectTypeHdl_Impl( nullptr );
+}
+
+IMPL_LINK( SvxLineDefTabPage, SelectTypeListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ SelectTypeHdl_Impl(&rListBox);
+}
+
+void SvxLineDefTabPage::SelectTypeHdl_Impl(const weld::ComboBox* p)
+{
+ if (p == m_xLbType1.get() || !p)
+ {
+ if (m_xLbType1->get_active() == 0)
+ {
+ m_xMtrLength1->set_sensitive(false);
+ m_xMtrLength1->set_text("");
+ }
+ else if (!m_xMtrLength1->get_sensitive())
+ {
+ m_xMtrLength1->set_sensitive(true);
+ m_xMtrLength1->reformat();
+ }
+ }
+
+ if (p == m_xLbType2.get() || !p)
+ {
+ if (m_xLbType2->get_active() == 0)
+ {
+ m_xMtrLength2->set_sensitive(false);
+ m_xMtrLength2->set_text("");
+ }
+ else if (!m_xMtrLength2->get_sensitive())
+ {
+ m_xMtrLength2->set_sensitive(true);
+ m_xMtrLength2->reformat();
+ }
+ }
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName(SvxResId(RID_SVXSTR_LINESTYLE));
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINESTYLE));
+ OUString aName;
+
+ tools::Long nCount = pDashList->Count();
+ tools::Long j = 1;
+ bool bDifferent = false;
+
+ while ( !bDifferent )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bDifferent = true;
+
+ for ( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pDashList->GetDash( i )->GetName() )
+ bDifferent = false;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pDashList->GetDash( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ {
+ bLoop = false;
+ FillDash_Impl();
+
+ tools::Long nDashCount = pDashList->Count();
+ pDashList->Insert( std::make_unique<XDashEntry>(aDash, aName), nDashCount );
+ m_xLbLineStyles->Append( *pDashList->GetDash(nDashCount), pDashList->GetUiBitmap(nDashCount) );
+
+ m_xLbLineStyles->set_active(m_xLbLineStyles->get_count() - 1);
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Hatch;
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+ pDlg.disposeAndClear();
+
+ // determine button state
+ if ( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos == -1)
+ return;
+
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINESTYLE));
+ OUString aName( pDashList->GetDash( nPos )->GetName() );
+ OUString aOldName = aName;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ tools::Long nCount = pDashList->Count();
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bool bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pDashList->GetDash( i )->GetName() &&
+ aName != aOldName )
+ bDifferent = false;
+ }
+
+ if ( bDifferent )
+ {
+ bLoop = false;
+ FillDash_Impl();
+
+ pDashList->Replace(std::make_unique<XDashEntry>(aDash, aName), nPos);
+ m_xLbLineStyles->Modify(*pDashList->GetDash(nPos), nPos, pDashList->GetUiBitmap(nPos));
+
+ m_xLbLineStyles->set_active(nPos);
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Hatch;
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos != -1)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelinestyledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineStyleDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ pDashList->Remove(nPos);
+ m_xLbLineStyles->remove(nPos);
+ m_xLbLineStyles->set_active(0);
+
+ SelectLinestyleHdl_Impl( nullptr );
+ *pPageType = PageType::Area; // style should not be taken
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ ChangePreviewHdl_Impl( *m_xMtrLength1 );
+ }
+ }
+
+ // determine button state
+ if ( !pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nReturn = RET_YES;
+
+ if ( *pnDashListState & ChangeType::MODIFIED )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
+
+ nReturn = xBox->run();
+
+ if ( nReturn == RET_YES )
+ pDashList->Save();
+ }
+
+ if ( nReturn != RET_CANCEL )
+ {
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.sod" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ XDashListRef pDshLst = XPropertyList::AsDashList(XPropertyList::CreatePropertyList( XPropertyListType::Dash, aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), "" ));
+ pDshLst->SetName( aURL.getName() );
+
+ if( pDshLst->Load() )
+ {
+ pDashList = pDshLst;
+ static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewDashList( pDashList );
+
+ m_xLbLineStyles->clear();
+ m_xLbLineStyles->Fill( pDashList );
+ Reset( &rOutAttrs );
+
+ pDashList->SetName( aURL.getName() );
+
+ *pnDashListState |= ChangeType::CHANGED;
+ *pnDashListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+ }
+ }
+
+ // determine button state
+ if ( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
+{
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.sod" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( !pDashList->GetName().isEmpty() )
+ {
+ aFile.Append( pDashList->GetName() );
+
+ if( aFile.getExtension().isEmpty() )
+ aFile.SetExtension( u"sod" );
+ }
+
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( aDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ pDashList->SetName( aURL.getName() );
+ pDashList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( pDashList->Save() )
+ {
+ *pnDashListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
+ xBox->run();
+ }
+}
+
+void SvxLineDefTabPage::FillDash_Impl()
+{
+ css::drawing::DashStyle eXDS;
+
+ if (m_xCbxSynchronize->get_active())
+ eXDS = css::drawing::DashStyle_RECTRELATIVE;
+ else
+ eXDS = css::drawing::DashStyle_RECT;
+
+ aDash.SetDashStyle( eXDS );
+ aDash.SetDots( static_cast<sal_uInt8>(m_xNumFldNumber1->get_value()) );
+ aDash.SetDotLen( m_xLbType1->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength1, ePoolUnit ) );
+ aDash.SetDashes( static_cast<sal_uInt8>(m_xNumFldNumber2->get_value()) );
+ aDash.SetDashLen( m_xLbType2->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength2, ePoolUnit ) );
+ aDash.SetDistance( GetCoreValue( *m_xMtrDistance, ePoolUnit ) );
+
+ rXLSet.Put( XLineDashItem( OUString(), aDash ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+}
+
+void SvxLineDefTabPage::FillDialog_Impl()
+{
+ css::drawing::DashStyle eXDS = aDash.GetDashStyle(); // css::drawing::DashStyle_RECT, css::drawing::DashStyle_ROUND
+ if( eXDS == css::drawing::DashStyle_RECTRELATIVE )
+ m_xCbxSynchronize->set_active(true);
+ else
+ m_xCbxSynchronize->set_active(false);
+
+ m_xNumFldNumber1->set_value(aDash.GetDots());
+ SetMetricValue( *m_xMtrLength1, aDash.GetDotLen(), ePoolUnit );
+ m_xLbType1->set_active(aDash.GetDotLen() == 0 ? 0 : 1);
+ m_xNumFldNumber2->set_value(aDash.GetDashes());
+ SetMetricValue( *m_xMtrLength2, aDash.GetDashLen(), ePoolUnit );
+ m_xLbType2->set_active(aDash.GetDashLen() == 0 ? 0 : 1);
+ SetMetricValue( *m_xMtrDistance, aDash.GetDistance(), ePoolUnit );
+
+ ChangeMetricHdl_Impl(nullptr);
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tplneend.cxx b/cui/source/tabpages/tplneend.cxx
new file mode 100644
index 000000000..951b27632
--- /dev/null
+++ b/cui/source/tabpages/tplneend.cxx
@@ -0,0 +1,610 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <cuitabline.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/strings.hrc>
+#include <osl/diagnose.h>
+
+#define XOUT_WIDTH 150
+
+SvxLineEndDefTabPage::SvxLineEndDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/lineendstabpage.ui", "LineEndPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , pPolyObj(nullptr)
+ , aXLineAttr(rInAttrs.GetPool())
+ , rXLSet(aXLineAttr.GetItemSet())
+ , pnLineEndListState(nullptr)
+ , pPageType(nullptr)
+ , nDlgType(0)
+ , pPosLineEndLb(nullptr)
+ , m_xEdtName(m_xBuilder->weld_entry("EDT_NAME"))
+ , m_xLbLineEnds(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_LINEENDS")))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
+ , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
+ , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ rXLSet.Put( XLineStyleItem(css::drawing::LineStyle_SOLID) );
+ rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
+ rXLSet.Put( XLineColorItem( OUString(), COL_BLACK ) );
+ rXLSet.Put( XLineStartWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
+ rXLSet.Put( XLineEndWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+
+ m_xBtnAdd->connect_clicked(LINK(this, SvxLineEndDefTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickModifyHdl_Impl));
+ m_xBtnDelete->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickDeleteHdl_Impl));
+ m_xBtnLoad->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickLoadHdl_Impl));
+ m_xBtnSave->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickSaveHdl_Impl));
+
+ m_xLbLineEnds->connect_changed(LINK(this, SvxLineEndDefTabPage, SelectLineEndHdl_Impl));
+}
+
+SvxLineEndDefTabPage::~SvxLineEndDefTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbLineEnds.reset();
+}
+
+void SvxLineEndDefTabPage::Construct()
+{
+ m_xLbLineEnds->Fill( pLineEndList );
+
+ bool bCreateArrowPossible = true;
+
+ if( !pPolyObj )
+ {
+ bCreateArrowPossible = false;
+ }
+ else if( nullptr == dynamic_cast<const SdrPathObj*>( pPolyObj) )
+ {
+ SdrObjTransformInfoRec aInfoRec;
+ pPolyObj->TakeObjInfo( aInfoRec );
+ SdrObjectUniquePtr pNewObj;
+ if( aInfoRec.bCanConvToPath )
+ pNewObj = pPolyObj->ConvertToPolyObj( true, false );
+
+ bCreateArrowPossible = nullptr != dynamic_cast<const SdrPathObj*>( pNewObj.get());
+ }
+
+ if( !bCreateArrowPossible )
+ m_xBtnAdd->set_sensitive(false);
+}
+
+void SvxLineEndDefTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( nDlgType != 0 ) // area dialog
+ return;
+
+ // ActivatePage() is called before the dialog receives PageCreated() !!!
+ if( !pLineEndList.is() )
+ return;
+
+ if( *pPosLineEndLb != -1)
+ {
+ m_xLbLineEnds->set_active(*pPosLineEndLb);
+ SelectLineEndHdl_Impl();
+ }
+ INetURLObject aURL( pLineEndList->GetPath() );
+
+ aURL.Append( pLineEndList->GetName() );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ *pPageType = PageType::Area; // 3
+ *pPosLineEndLb = -1;
+}
+
+
+DeactivateRC SvxLineEndDefTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ CheckChanges_Impl();
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+void SvxLineEndDefTabPage::CheckChanges_Impl()
+{
+ int nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ {
+ OUString aString = m_xEdtName->get_text();
+
+ if( aString != m_xLbLineEnds->get_active_text() )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querychangelineenddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskChangeLineEndDialog"));
+ if (xQueryBox->run() == RET_YES)
+ ClickModifyHdl_Impl(*m_xBtnModify);
+ }
+ }
+ nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ *pPosLineEndLb = nPos;
+}
+
+
+bool SvxLineEndDefTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( nDlgType == 0 ) // line dialog
+ {
+ if( *pPageType == PageType::Bitmap )
+ {
+ CheckChanges_Impl();
+
+ int nPos = m_xLbLineEnds->get_active();
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ rSet->Put( XLineStartItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
+ rSet->Put( XLineEndItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
+ }
+ }
+ return true;
+}
+
+void SvxLineEndDefTabPage::Reset( const SfxItemSet* )
+{
+ m_xLbLineEnds->set_active(0);
+
+ // Update lineend
+ if( pLineEndList->Count() > 0 )
+ {
+ int nPos = m_xLbLineEnds->get_active();
+
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
+
+ rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
+ rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+ }
+
+ // determine button state
+ if( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxLineEndDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxLineEndDefTabPage>(pPage, pController, *rSet );
+}
+
+void SvxLineEndDefTabPage::SelectLineEndHdl_Impl()
+{
+ if( pLineEndList->Count() <= 0 )
+ return;
+
+ int nPos = m_xLbLineEnds->get_active();
+
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
+
+ rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
+ rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+
+ // Is not set before, in order to only take the new style,
+ // if there is an entry selected in the ListBox
+ *pPageType = PageType::Bitmap;
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, SelectLineEndHdl_Impl, weld::ComboBox&, void)
+{
+ SelectLineEndHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineEnds->get_active();
+ if (nPos == -1)
+ return;
+
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINEEND));
+ OUString aName(m_xEdtName->get_text());
+ tools::Long nCount = pLineEndList->Count();
+ bool bDifferent = true;
+
+ // check whether the name is existing already
+ for ( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+
+ // if yes, repeat and demand a new name
+ if ( !bDifferent )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarningBox->run();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ bool bLoop = true;
+
+ while( !bDifferent && bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ bLoop = false;
+ else
+ xWarningBox->run();
+ }
+ }
+
+ // if not existing, enter the entry
+ if( !bDifferent )
+ return;
+
+ const XLineEndEntry* pOldEntry = pLineEndList->GetLineEnd(nPos);
+
+ if(pOldEntry)
+ {
+ // #123497# Need to replace the existing entry with a new one
+ pLineEndList->Replace(std::make_unique<XLineEndEntry>(pOldEntry->GetLineEnd(), aName), nPos);
+
+ m_xEdtName->set_text(aName);
+
+ m_xLbLineEnds->Modify(*pLineEndList->GetLineEnd(nPos), nPos, pLineEndList->GetUiBitmap(nPos));
+ m_xLbLineEnds->set_active(nPos);
+
+ // set flag for modified
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Bitmap;
+ }
+ else
+ {
+ OSL_ENSURE(false, "LineEnd to be modified not existing (!)");
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ if( pPolyObj )
+ {
+ const SdrObject* pNewObj;
+ SdrObjectUniquePtr pConvPolyObj;
+
+ if( nullptr != dynamic_cast<const SdrPathObj*>( pPolyObj) )
+ {
+ pNewObj = pPolyObj;
+ }
+ else
+ {
+ SdrObjTransformInfoRec aInfoRec;
+ pPolyObj->TakeObjInfo( aInfoRec );
+
+ if( aInfoRec.bCanConvToPath )
+ {
+ pConvPolyObj = pPolyObj->ConvertToPolyObj( true, false );
+ pNewObj = pConvPolyObj.get();
+
+ if( !pNewObj || nullptr == dynamic_cast<const SdrPathObj*>( pNewObj) )
+ return; // cancel, additional safety, which
+ // has no use for group objects though.
+ }
+ else return; // cancel
+ }
+
+ basegfx::B2DPolyPolygon aNewPolyPolygon(static_cast<const SdrPathObj*>(pNewObj)->GetPathPoly());
+ basegfx::B2DRange aNewRange(basegfx::utils::getRange(aNewPolyPolygon));
+
+ // normalize
+ aNewPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix( -aNewRange.getMinX(), -aNewRange.getMinY()));
+
+ pConvPolyObj.reset();
+
+ OUString aNewName(SvxResId(RID_SVXSTR_LINEEND));
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_LINEEND));
+ OUString aName;
+
+ tools::Long nCount = pLineEndList->Count();
+ tools::Long j = 1;
+ bool bDifferent = false;
+
+ while ( !bDifferent )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc ));
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( tools::Long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ {
+ bLoop = false;
+
+ auto nLineEndCount = pLineEndList->Count();
+ pLineEndList->Insert(std::make_unique<XLineEndEntry>(aNewPolyPolygon, aName), nLineEndCount);
+
+ // add to the ListBox
+ m_xLbLineEnds->Append(*pLineEndList->GetLineEnd(nLineEndCount), pLineEndList->GetUiBitmap(nLineEndCount));
+ m_xLbLineEnds->set_active(m_xLbLineEnds->get_count() - 1);
+
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ SelectLineEndHdl_Impl();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarningBox->run();
+ }
+ }
+ }
+ else
+ m_xBtnAdd->set_sensitive(false);
+
+ // determine button state
+ if ( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelineenddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineEndDialog"));
+
+ if (xQueryBox->run() == RET_YES)
+ {
+ pLineEndList->Remove(nPos);
+ m_xLbLineEnds->remove(nPos);
+ m_xLbLineEnds->set_active(0);
+
+ SelectLineEndHdl_Impl();
+ *pPageType = PageType::Area; // LineEnd shall not be taken over
+
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ m_aCtlPreview.Invalidate();
+ }
+ }
+ // determine button state
+ if( !pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nReturn = RET_YES;
+
+ if ( *pnLineEndListState & ChangeType::MODIFIED )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
+
+ nReturn = xBox->run();
+
+ if ( nReturn == RET_YES )
+ pLineEndList->Save();
+ }
+
+ if ( nReturn != RET_CANCEL )
+ {
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.soe" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ XLineEndListRef pLeList = XPropertyList::AsLineEndList(
+ XPropertyList::CreatePropertyList(
+ XPropertyListType::LineEnd,
+ aPathURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), ""));
+ pLeList->SetName( aURL.getName() );
+ if( pLeList->Load() )
+ {
+ pLineEndList = pLeList;
+ static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewLineEndList( pLineEndList );
+ m_xLbLineEnds->clear();
+ m_xLbLineEnds->Fill( pLineEndList );
+ Reset( &rOutAttrs );
+
+ pLineEndList->SetName( aURL.getName() );
+
+ *pnLineEndListState |= ChangeType::CHANGED;
+ *pnLineEndListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+ }
+ }
+
+ // determine button state
+ if ( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
+{
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.soe" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( !pLineEndList->GetName().isEmpty() )
+ {
+ aFile.Append( pLineEndList->GetName() );
+
+ if( aFile.getExtension().isEmpty() )
+ aFile.SetExtension( u"soe" );
+ }
+
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( aDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ pLineEndList->SetName( aURL.getName() );
+ pLineEndList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( pLineEndList->Save() )
+ {
+ *pnLineEndListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
+ xBox->run();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tppattern.cxx b/cui/source/tabpages/tppattern.cxx
new file mode 100644
index 000000000..4976a0a0e
--- /dev/null
+++ b/cui/source/tabpages/tppattern.cxx
@@ -0,0 +1,553 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/dialmgr.hxx>
+#include <vcl/BitmapTools.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/strings.hrc>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbmtit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <sal/log.hxx>
+
+using namespace com::sun::star;
+
+/*************************************************************************
+|* Preview control for the display of bitmaps
+\************************************************************************/
+
+class SvxBitmapCtl
+{
+private:
+ Color aPixelColor, aBackgroundColor;
+ std::array<sal_uInt8,64> const * pBmpArray;
+
+public:
+ // Constructor: BitmapCtl for SvxPixelCtl
+ SvxBitmapCtl()
+ : pBmpArray(nullptr)
+ {
+ }
+
+ // BitmapCtl: Returns the Bitmap
+ BitmapEx GetBitmapEx() const
+ {
+ if (!pBmpArray)
+ return BitmapEx();
+ return vcl::bitmap::createHistorical8x8FromArray(*pBmpArray, aPixelColor, aBackgroundColor);
+ }
+
+ void SetBmpArray( std::array<sal_uInt8,64> const & pPixel ) { pBmpArray = &pPixel; }
+ void SetPixelColor( Color aColor ) { aPixelColor = aColor; }
+ void SetBackgroundColor( Color aColor ) { aBackgroundColor = aColor; }
+};
+
+SvxPatternTabPage::SvxPatternTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/patterntabpage.ui", "PatternTabPage", rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnPatternListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xCtlPixel(new SvxPixelCtl(this))
+ , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xLbBackgroundColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_BACKGROUND_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xPatternLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("patternpresetlistwin", true)))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xCtlPixelWin(new weld::CustomWeld(*m_xBuilder, "CTL_PIXEL", *m_xCtlPixel))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+ , m_xPatternLBWin(new weld::CustomWeld(*m_xBuilder, "patternpresetlist", *m_xPatternLB))
+{
+ // size of the bitmap display
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xPatternLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xBitmapCtl.reset(new SvxBitmapCtl);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
+ m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxPatternTabPage, ClickAddHdl_Impl ) );
+ m_xBtnModify->connect_clicked( LINK( this, SvxPatternTabPage, ClickModifyHdl_Impl ) );
+
+ m_xPatternLB->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangePatternHdl_Impl ) );
+ m_xPatternLB->SetRenameHdl( LINK( this, SvxPatternTabPage, ClickRenameHdl_Impl ) );
+ m_xPatternLB->SetDeleteHdl( LINK( this, SvxPatternTabPage, ClickDeleteHdl_Impl ) );
+ m_xLbColor->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangeColorHdl_Impl ) );
+ m_xLbBackgroundColor->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangeColorHdl_Impl ) );
+
+ m_xPatternLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
+}
+
+SvxPatternTabPage::~SvxPatternTabPage()
+{
+ m_xPatternLBWin.reset();
+ m_xCtlPreview.reset();
+ m_xCtlPixelWin.reset();
+ m_xPatternLB.reset();
+ m_xLbBackgroundColor.reset();
+ m_xLbColor.reset();
+ m_xCtlPixel.reset();
+}
+
+void SvxPatternTabPage::Construct()
+{
+ m_xPatternLB->FillPresetListBox( *m_pPatternList );
+}
+
+void SvxPatternTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+ }
+
+ // determining (possibly cutting) the name and
+ // displaying it in the GroupBox
+ OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pPatternList->GetPath() );
+
+ aURL.Append( m_pPatternList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if( aURL.getBase().getLength() > 18 )
+ {
+ aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ XFillBitmapItem aItem( rSet.Get( XATTR_FILLBITMAP ) );
+
+ if ( aItem.isPattern() )
+ {
+ sal_Int32 nPos = SearchPatternList( aItem.GetName() );
+ if ( nPos != -1)
+ {
+ sal_uInt16 nId = m_xPatternLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xPatternLB->SelectItem( nId );
+ }
+ }
+ else
+ m_xPatternLB->SelectItem( m_xPatternLB->GetItemId( static_cast<size_t>( 0 ) ) );
+}
+
+
+DeactivateRC SvxPatternTabPage::DeactivatePage( SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxPatternTabPage::FillItemSet( SfxItemSet* _rOutAttrs )
+{
+ _rOutAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ size_t nPos = m_xPatternLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xPatternLB->GetSelectItemPos();
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ const XBitmapEntry* pXBitmapEntry = m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) );
+ const OUString aString( m_xPatternLB->GetItemText( m_xPatternLB->GetSelectedItemId() ) );
+
+ _rOutAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
+ }
+ else
+ {
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ _rOutAttrs->Put(XFillBitmapItem(OUString(), Graphic(aBitmapEx)));
+ }
+ _rOutAttrs->Put(XFillBmpTileItem(true));
+ return true;
+}
+
+
+void SvxPatternTabPage::Reset( const SfxItemSet* )
+{
+ m_xBitmapCtl->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBmpArray( m_xCtlPixel->GetBitmapPixelPtr() );
+
+ // get bitmap and display it
+ const XFillBitmapItem aBmpItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx()));
+ if(aBmpItem.isPattern())
+ {
+ m_rXFSet.Put( aBmpItem );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+
+ // determine button state
+ if( m_pPatternList.is() && m_pPatternList->Count() )
+ {
+ m_xBtnAdd->set_sensitive(true);
+ m_xBtnModify->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxPatternTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxPatternTabPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ChangePatternHdl_Impl, ValueSet*, void)
+{
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ pGraphicObject.reset(new GraphicObject(m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
+ }
+ else
+ {
+ if(const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLSTYLE)))
+ {
+ const drawing::FillStyle eXFS(pFillStyleItem->GetValue());
+
+ const XFillBitmapItem* pBitmapItem;
+ if((drawing::FillStyle_BITMAP == eXFS) && (pBitmapItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_FILLBITMAP))))
+ {
+ pGraphicObject.reset(new GraphicObject(pBitmapItem->GetGraphicObject()));
+ }
+ }
+
+ if(!pGraphicObject)
+ {
+ sal_uInt16 nPosition = m_xPatternLB->GetItemId( 0 );
+ m_xPatternLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ {
+ pGraphicObject.reset(new GraphicObject(m_pPatternList->GetBitmap(0)->GetGraphicObject()));
+ }
+ }
+ }
+
+ if(!pGraphicObject)
+ return;
+
+ Color aBackColor;
+ Color aPixelColor;
+ bool bIs8x8(vcl::bitmap::isHistorical8x8(pGraphicObject->GetGraphic().GetBitmapEx(), aBackColor, aPixelColor));
+
+ m_xLbColor->SetNoSelection();
+ m_xLbBackgroundColor->SetNoSelection();
+
+ if(bIs8x8)
+ {
+ m_xCtlPixel->SetPaintable( true );
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnAdd->set_sensitive(true);
+
+ // setting the pixel control
+
+ m_xCtlPixel->SetXBitmap(pGraphicObject->GetGraphic().GetBitmapEx());
+
+ m_xLbColor->SelectEntry( aPixelColor );
+ m_xLbBackgroundColor->SelectEntry( aBackColor );
+
+ // update m_xBitmapCtl, rXFSet and m_aCtlPreview
+ m_xBitmapCtl->SetPixelColor( aPixelColor );
+ m_xBitmapCtl->SetBackgroundColor( aBackColor );
+ m_rXFSet.ClearItem();
+ m_rXFSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+ else
+ {
+ m_xCtlPixel->Reset();
+ m_xCtlPixel->SetPaintable( false );
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnAdd->set_sensitive(false);
+ }
+
+ m_xCtlPixel->Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+
+ OUString aNewName( SvxResId( RID_SVXSTR_PATTERN_UNTITLED ) );
+ OUString aDesc( CuiResId( RID_CUISTR_DESC_NEW_PATTERN ) );
+ OUString aName;
+
+ tools::Long nCount = m_pPatternList->Count();
+ tools::Long j = 1;
+ bool bValidPatternName = false;
+
+ while( !bValidPatternName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidPatternName = (SearchPatternList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError(1);
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bValidPatternName = (SearchPatternList(aName) == -1);
+
+ if( bValidPatternName ) {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ std::unique_ptr<XBitmapEntry> pEntry;
+ if( m_xCtlPixel->IsEnabled() )
+ {
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ pEntry.reset(new XBitmapEntry(Graphic(aBitmapEx), aName));
+ }
+ else // it must be a not existing imported bitmap
+ {
+ if(const XFillBitmapItem* pFillBmpItem = m_rOutAttrs.GetItemIfSet(XATTR_FILLBITMAP))
+ {
+ pEntry.reset(new XBitmapEntry(pFillBmpItem->GetGraphicObject(), aName));
+ }
+ else
+ assert(!"SvxPatternTabPage::ClickAddHdl_Impl(), XBitmapEntry* pEntry == nullptr ?");
+ }
+
+ if( pEntry )
+ {
+ m_pPatternList->Insert(std::move(pEntry), nCount);
+ sal_Int32 nId = m_xPatternLB->GetItemId( nCount - 1 );
+ BitmapEx aBitmap = m_pPatternList->GetBitmapForPreview( nCount, m_xPatternLB->GetIconSize() );
+ m_xPatternLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xPatternLB->SelectItem( nId + 1 );
+ m_xPatternLB->Resize();
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+ }
+ }
+
+ // determine button state
+ if( m_pPatternList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ // #i123497# Need to replace the existing entry with a new one (old returned needs to be deleted)
+ m_pPatternList->Replace(std::make_unique<XBitmapEntry>(Graphic(aBitmapEx), aName), nPos);
+
+ BitmapEx aBitmap = m_pPatternList->GetBitmapForPreview( static_cast<sal_uInt16>( nPos ), m_xPatternLB->GetIconSize() );
+ m_xPatternLB->RemoveItem(nId);
+ m_xPatternLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xPatternLB->SelectItem( nId );
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+}
+
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
+{
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+ sal_Int32 nId = m_xPatternLB->GetSelectedItemId();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc(CuiResId(RID_CUISTR_DESC_NEW_PATTERN));
+ OUString aName(m_pPatternList->GetBitmap(nPos)->GetName());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nPatternPos = SearchPatternList(aName);
+ bool bValidPatternName = (nPatternPos == static_cast<sal_Int32>(nPos) ) || (nPatternPos == -1);
+
+ if( bValidPatternName )
+ {
+ bLoop = false;
+
+ m_pPatternList->GetBitmap(nPos)->SetName(aName);
+
+ m_xPatternLB->SetItemText( nId, aName );
+ m_xPatternLB->SelectItem( nId );
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarnBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletebitmapdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelBitmapDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pPatternList->Remove(nPos);
+ m_xPatternLB->RemoveItem( nId );
+ nId = m_xPatternLB->GetItemId(0);
+ m_xPatternLB->SelectItem( nId );
+ m_xPatternLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+ m_xCtlPixel->Invalidate();
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+ }
+ }
+ // determine button state
+ if( !m_pPatternList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ChangeColorHdl_Impl, ColorListBox&, void)
+{
+ ChangeColor_Impl();
+ m_xPatternLB->SetNoSelection();
+}
+
+void SvxPatternTabPage::ChangeColor_Impl()
+{
+ m_xCtlPixel->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xCtlPixel->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+ m_xCtlPixel->Invalidate();
+
+ m_xBitmapCtl->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+
+ // get bitmap and display it
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxPatternTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint)
+{
+ if (pDrawingArea == m_xCtlPixel->GetDrawingArea())
+ {
+ m_xBitmapCtl->SetBmpArray(m_xCtlPixel->GetBitmapPixelPtr());
+
+ // get bitmap and display it
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+
+ m_xPatternLB->SetNoSelection();
+}
+
+sal_Int32 SvxPatternTabPage::SearchPatternList(std::u16string_view rPatternName)
+{
+ tools::Long nCount = m_pPatternList->Count();
+ bool bValidPatternName = true;
+ sal_Int32 nPos = -1;
+
+ for(tools::Long i = 0;i < nCount && bValidPatternName;i++)
+ {
+ if(rPatternName == m_pPatternList->GetBitmap( i )->GetName())
+ {
+ nPos = i;
+ bValidPatternName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpshadow.cxx b/cui/source/tabpages/tpshadow.cxx
new file mode 100644
index 000000000..795a57f13
--- /dev/null
+++ b/cui/source/tabpages/tpshadow.cxx
@@ -0,0 +1,515 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/colorbox.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/sdooitm.hxx>
+#include <svx/sdprcitm.hxx>
+#include <svx/sdshcitm.hxx>
+#include <svx/sdshitm.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/sdsxyitm.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xfltrit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/dlgutil.hxx>
+#include <cuitabline.hxx>
+
+using namespace com::sun::star;
+
+const WhichRangesContainer SvxShadowTabPage::pShadowRanges(svl::Items<
+ SDRATTR_SHADOWCOLOR, SDRATTR_SHADOWTRANSPARENCE,
+ SDRATTR_SHADOWBLUR, SDRATTR_SHADOWBLUR,
+ SID_ATTR_FILL_SHADOW, SID_ATTR_FILL_SHADOW,
+ SID_ATTR_SHADOW_BLUR, SID_ATTR_SHADOW_BLUR,
+ SID_ATTR_SHADOW_TRANSPARENCE, SID_ATTR_SHADOW_YDISTANCE
+>);
+
+SvxShadowTabPage::SvxShadowTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/shadowtabpage.ui", "ShadowTabPage", rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnColorListState(nullptr)
+ , m_nPageType(PageType::Area)
+ , m_nDlgType(0)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_aCtlPosition(this)
+ , m_xTsbShowShadow(m_xBuilder->weld_check_button("TSB_SHOW_SHADOW"))
+ , m_xGridShadow(m_xBuilder->weld_widget("gridSHADOW"))
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
+ , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_SHADOW_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_SHADOW_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xLbShadowBlurMetric(m_xBuilder->weld_metric_spin_button("LB_SHADOW_BLUR", FieldUnit::POINT))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder, "CTL_COLOR_PREVIEW", m_aCtlXRectPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMtrDistance, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SDRATTR_SHADOWXDIST );
+
+ // setting the output device
+ drawing::FillStyle eXFS = drawing::FillStyle_SOLID;
+ if( m_rOutAttrs.GetItemState( XATTR_FILLSTYLE ) != SfxItemState::DONTCARE )
+ {
+ eXFS = m_rOutAttrs.Get( GetWhich( XATTR_FILLSTYLE ) ).GetValue();
+ switch( eXFS )
+ {
+ case drawing::FillStyle_SOLID:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLCOLOR ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLCOLOR ) );
+ }
+ break;
+
+ case drawing::FillStyle_GRADIENT:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLGRADIENT ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLGRADIENT ) );
+ }
+ break;
+
+ case drawing::FillStyle_HATCH:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLHATCH ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLHATCH ) );
+ }
+ break;
+
+ case drawing::FillStyle_BITMAP:
+ {
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLBITMAP ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLBITMAP ) );
+ }
+ }
+ break;
+ case drawing::FillStyle_NONE : break;
+ default: break;
+ }
+ }
+ else
+ {
+ m_rXFSet.Put( XFillColorItem( OUString(), COL_LIGHTRED ) );
+ }
+
+ if(drawing::FillStyle_NONE == eXFS)
+ {
+ // #i96350#
+ // fallback to solid fillmode when no fill mode is provided to have
+ // a reasonable shadow preview. The used color will be a set one or
+ // the default (currently blue8)
+ eXFS = drawing::FillStyle_SOLID;
+ }
+
+ m_rXFSet.Put( XFillStyleItem( eXFS ) );
+ m_aCtlXRectPreview.SetRectangleAttributes(m_aXFillAttr.GetItemSet());
+
+ m_xTsbShowShadow->connect_toggled(LINK( this, SvxShadowTabPage, ClickShadowHdl_Impl));
+ m_xLbShadowColor->SetSelectHdl( LINK( this, SvxShadowTabPage, SelectShadowHdl_Impl ) );
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxShadowTabPage, ModifyShadowHdl_Impl );
+ m_xLbShadowBlurMetric->connect_value_changed(aLink);
+ m_xMtrTransparent->connect_value_changed(aLink);
+ m_xMtrDistance->connect_value_changed(aLink);
+}
+
+SvxShadowTabPage::~SvxShadowTabPage()
+{
+ m_xCtlXRectPreview.reset();
+ m_xLbShadowColor.reset();
+ m_xCtlPosition.reset();
+ m_xLbShadowBlurMetric.reset();
+}
+
+void SvxShadowTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ const SfxUInt16Item* pPageTypeItem = rSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+
+ if( m_nDlgType != 0 )
+ return;
+
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ if( *m_pnColorListState & ChangeType::CHANGED )
+ {
+ SvxAreaTabDialog* pArea = dynamic_cast<SvxAreaTabDialog*>(GetDialogController());
+ if( pArea )
+ {
+ m_pColorList = pArea->GetNewColorList();
+ }
+ else
+ {
+ SvxLineTabDialog* pLine = dynamic_cast<SvxLineTabDialog*>(GetDialogController());
+ if( pLine )
+ m_pColorList = pLine->GetNewColorList();
+ }
+ }
+
+ SfxItemSet rAttribs( rSet );
+ // rSet contains shadow attributes too, but we want
+ // to use it for updating rectangle attributes only,
+ // so set the shadow to none here
+ SdrOnOffItem aItem( makeSdrShadowItem( false ));
+ rAttribs.Put( aItem );
+
+ m_aCtlXRectPreview.SetRectangleAttributes( rAttribs );
+ ModifyShadowHdl_Impl( *m_xMtrTransparent );
+ }
+ m_nPageType = PageType::Shadow;
+}
+
+
+DeactivateRC SvxShadowTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxShadowTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ bool bModified = false;
+
+ const SfxPoolItem* pOld = nullptr;
+
+ if (m_xTsbShowShadow->get_state_changed_from_saved())
+ {
+ TriState eState = m_xTsbShowShadow->get_state();
+ assert(eState != TRISTATE_INDET);
+ // given how m_xTsbShowShadow is set up and saved in Reset(),
+ // eState == TRISTATE_INDET would imply
+ // !IsValueChangedFromSaved()
+ SdrOnOffItem aItem( makeSdrShadowItem(eState == TRISTATE_TRUE) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOW );
+ if ( !pOld || !( *static_cast<const SdrOnOffItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // shadow removal
+ // a bit intricate inquiry whether there was something changed,
+ // as the items can't be displayed directly on controls
+ sal_Int32 nX = 0, nY = 0;
+ sal_Int32 nXY = GetCoreValue( *m_xMtrDistance, m_ePoolUnit );
+
+ switch (m_aCtlPosition.GetActualRP())
+ {
+ case RectPoint::LT: nX = nY = -nXY; break;
+ case RectPoint::MT: nY = -nXY; break;
+ case RectPoint::RT: nX = nXY; nY = -nXY; break;
+ case RectPoint::LM: nX = -nXY; break;
+ case RectPoint::RM: nX = nXY; break;
+ case RectPoint::LB: nX = -nXY; nY = nXY; break;
+ case RectPoint::MB: nY = nXY; break;
+ case RectPoint::RB: nX = nY = nXY; break;
+ case RectPoint::MM: break;
+ }
+
+ // If the values of the shadow distances==SfxItemState::DONTCARE and the displayed
+ // string in the respective MetricField=="", then the comparison of the old
+ // and the new distance values would return a wrong result because in such a
+ // case the new distance values would match the default values of the MetricField !!!!
+ if ( !m_xMtrDistance->get_text().isEmpty() ||
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE ||
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nOldX = 9876543; // impossible value, so DontCare
+ sal_Int32 nOldY = 9876543;
+ if( m_rOutAttrs.GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE &&
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ nOldX = m_rOutAttrs.Get( SDRATTR_SHADOWXDIST ).GetValue();
+ nOldY = m_rOutAttrs.Get( SDRATTR_SHADOWYDIST ).GetValue();
+ }
+ SdrMetricItem aXItem( makeSdrShadowXDistItem(nX) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWXDIST );
+ if ( nX != nOldX &&
+ ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aXItem ) ) )
+ {
+ rAttrs->Put( aXItem );
+ bModified = true;
+ }
+ SdrMetricItem aYItem( makeSdrShadowYDistItem(nY) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWYDIST );
+ if ( nY != nOldY &&
+ ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aYItem ) ) )
+ {
+ rAttrs->Put( aYItem );
+ bModified = true;
+ }
+ }
+
+ // ShadowColor
+ {
+ XColorItem aItem(makeSdrShadowColorItem(m_xLbShadowColor->GetSelectEntryColor()));
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWCOLOR );
+ if ( !pOld || !( *static_cast<const XColorItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // transparency
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
+ if (m_xMtrTransparent->get_value_changed_from_saved())
+ {
+ SdrPercentItem aItem( makeSdrShadowTransparenceItem(nVal) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWTRANSPARENCE );
+ if ( !pOld || !( *static_cast<const SdrPercentItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ if (m_xLbShadowBlurMetric->get_value_changed_from_saved())
+ {
+ SdrMetricItem aItem(SDRATTR_SHADOWBLUR, m_xLbShadowBlurMetric->get_value(FieldUnit::MM_100TH));
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWBLUR );
+ if ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
+
+ return bModified;
+}
+
+
+void SvxShadowTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ // all objects can have a shadow
+ // at the moment there are only 8 possible positions where a shadow can be set
+
+ // has a shadow been set?
+ if( rAttrs->GetItemState( SDRATTR_SHADOW ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( SDRATTR_SHADOW ).GetValue() )
+ m_xTsbShowShadow->set_state(TRISTATE_TRUE);
+ else
+ {
+ m_xTsbShowShadow->set_state(TRISTATE_FALSE);
+ }
+ }
+ else
+ m_xTsbShowShadow->set_state(TRISTATE_INDET);
+
+ // distance (only 8 possible positions),
+ // so there is only one item evaluated
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE &&
+ rAttrs->GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nX = rAttrs->Get( SDRATTR_SHADOWXDIST ).GetValue();
+ sal_Int32 nY = rAttrs->Get( SDRATTR_SHADOWYDIST ).GetValue();
+
+ if( nX != 0 )
+ SetMetricValue( *m_xMtrDistance, nX < 0 ? -nX : nX, m_ePoolUnit );
+ else
+ SetMetricValue( *m_xMtrDistance, nY < 0 ? -nY : nY, m_ePoolUnit );
+
+ // setting the shadow control
+ if ( nX < 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::LT );
+ else if( nX == 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::MT );
+ else if( nX > 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::RT );
+ else if( nX < 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::LM );
+ // there's no center point anymore
+ else if( nX == 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::RB );
+ else if( nX > 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::RM );
+ else if( nX < 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::LB );
+ else if( nX == 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::MB );
+ else if( nX > 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::RB );
+ }
+ else
+ {
+ // determine default-distance
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ {
+ sal_Int32 n = pPool->GetDefaultItem(SDRATTR_SHADOWXDIST).GetValue();
+ if (n == 0)
+ n = pPool->GetDefaultItem(SDRATTR_SHADOWYDIST).GetValue();
+ SetMetricValue(*m_xMtrDistance, std::abs(n), m_ePoolUnit);
+ }
+
+ // Tristate, e. g. multiple objects have been marked of which some have a shadow and some don't.
+ // The text (which shall be displayed) of the MetricFields is set to "" and serves as an
+ // identification in the method FillItemSet for the fact that the distance value was NOT changed !!!!
+ m_xMtrDistance->set_text( "" );
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ }
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWCOLOR ) != SfxItemState::DONTCARE )
+ {
+ m_xLbShadowColor->SelectEntry( rAttrs->Get( SDRATTR_SHADOWCOLOR ).GetColorValue() );
+ }
+ else
+ m_xLbShadowColor->SetNoSelection();
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWTRANSPARENCE ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nTransp = rAttrs->Get( SDRATTR_SHADOWTRANSPARENCE ).GetValue();
+ m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
+ }
+ else
+ m_xMtrTransparent->set_text("");
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWBLUR ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nBlur = rAttrs->Get( SDRATTR_SHADOWBLUR ).GetValue();
+ m_xLbShadowBlurMetric->set_value(nBlur, FieldUnit::MM_100TH);
+ }
+ else
+ m_xLbShadowBlurMetric->set_text("");
+
+ //aCtlPosition
+ m_xMtrDistance->save_value();
+ m_xLbShadowColor->SaveValue();
+ m_xTsbShowShadow->save_state();
+ m_xLbShadowBlurMetric->save_value();
+
+ // #66832# This field was not saved, but used to determine changes.
+ // Why? Seems to be the error.
+ // It IS the error.
+ m_xMtrTransparent->save_value();
+
+ ClickShadowHdl_Impl(*m_xTsbShowShadow);
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+std::unique_ptr<SfxTabPage> SvxShadowTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs )
+{
+ return std::make_unique<SvxShadowTabPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, ClickShadowHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xTsbShowShadow->get_state() == TRISTATE_FALSE)
+ {
+ m_xGridShadow->set_sensitive(false);
+ m_xCtlPosition->set_sensitive(false);
+ }
+ else
+ {
+ m_xGridShadow->set_sensitive(true);
+ m_xCtlPosition->set_sensitive(true);
+ }
+ m_aCtlPosition.Invalidate();
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, SelectShadowHdl_Impl, ColorListBox&, void)
+{
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, ModifyShadowHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xTsbShowShadow->get_state() == TRISTATE_TRUE)
+ m_rXFSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
+ else
+ m_rXFSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+
+ m_rXFSet.Put( XFillColorItem( OUString(), m_xLbShadowColor->GetSelectEntryColor() ) );
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
+ m_rXFSet.Put( XFillTransparenceItem( nVal ) );
+
+ // shadow removal
+ sal_Int32 nX = 0, nY = 0;
+ sal_Int32 nXY = GetCoreValue( *m_xMtrDistance, m_ePoolUnit );
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT: nX = nY = -nXY; break;
+ case RectPoint::MT: nY = -nXY; break;
+ case RectPoint::RT: nX = nXY; nY = -nXY; break;
+ case RectPoint::LM: nX = -nXY; break;
+ case RectPoint::RM: nX = nXY; break;
+ case RectPoint::LB: nX = -nXY; nY = nXY; break;
+ case RectPoint::MB: nY = nXY; break;
+ case RectPoint::RB: nX = nY = nXY; break;
+ case RectPoint::MM: break;
+ }
+
+ m_aCtlXRectPreview.SetShadowPosition(Point(nX, nY));
+
+ m_aCtlXRectPreview.SetShadowAttributes(m_aXFillAttr.GetItemSet());
+ m_aCtlXRectPreview.Invalidate();
+}
+
+void SvxShadowTabPage::PointChanged( weld::DrawingArea*, RectPoint )
+{
+ // repaint shadow
+ ModifyShadowHdl_Impl( *m_xMtrTransparent );
+}
+
+void SvxShadowTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxColorListItem* pColorListItem = aSet.GetItem<SvxColorListItem>(SID_COLOR_TABLE, false);
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+
+ if (pColorListItem)
+ SetColorList(pColorListItem->GetColorList());
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tptrans.cxx b/cui/source/tabpages/tptrans.cxx
new file mode 100644
index 000000000..75180022f
--- /dev/null
+++ b/cui/source/tabpages/tptrans.cxx
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/xfltrit.hxx>
+#include <cuitabarea.hxx>
+#include <svl/intitem.hxx>
+
+using namespace com::sun::star;
+
+const WhichRangesContainer SvxTransparenceTabPage::pTransparenceRanges(svl::Items<
+ XATTR_FILLTRANSPARENCE, XATTR_FILLTRANSPARENCE,
+ XATTR_FILLFLOATTRANSPARENCE, XATTR_FILLFLOATTRANSPARENCE,
+ SDRATTR_SHADOWTRANSPARENCE, SDRATTR_SHADOWTRANSPARENCE
+>);
+
+/*************************************************************************
+|*
+|* Dialog for transparence
+|*
+\************************************************************************/
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransOffHdl_Impl, weld::Toggleable&, void)
+{
+ // disable all other controls
+ ActivateLinear(false);
+ ActivateGradient(false);
+
+ // Preview
+ rXFSet.ClearItem(XATTR_FILLTRANSPARENCE);
+ rXFSet.ClearItem(XATTR_FILLFLOATTRANSPARENCE);
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+
+ InvalidatePreview(false);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransLinearHdl_Impl, weld::Toggleable&, void)
+{
+ // enable linear, disable other
+ ActivateLinear(true);
+ ActivateGradient(false);
+
+ // preview
+ rXFSet.ClearItem (XATTR_FILLFLOATTRANSPARENCE);
+ ModifyTransparentHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransGradientHdl_Impl, weld::Toggleable&, void)
+{
+ // enable gradient, disable other
+ ActivateLinear(false);
+ ActivateGradient(true);
+
+ // preview
+ rXFSet.ClearItem (XATTR_FILLTRANSPARENCE);
+ ModifiedTrgrHdl_Impl(nullptr);
+}
+
+SvxTransparenceTabPage::~SvxTransparenceTabPage()
+{
+}
+
+void SvxTransparenceTabPage::ActivateLinear(bool bActivate)
+{
+ m_xMtrTransparent->set_sensitive(bActivate);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ModifyTransparentHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nPos = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ rXFSet.Put(XFillTransparenceItem(nPos));
+
+ // preview
+ InvalidatePreview();
+}
+
+IMPL_LINK(SvxTransparenceTabPage, ModifiedTrgrListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ ModifiedTrgrHdl_Impl(&rListBox);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ModifiedTrgrEditHdl_Impl, weld::MetricSpinButton&, void)
+{
+ ModifiedTrgrHdl_Impl(nullptr);
+}
+
+void SvxTransparenceTabPage::ModifiedTrgrHdl_Impl(const weld::ComboBox* pControl)
+{
+ if (pControl == m_xLbTrgrGradientType.get())
+ {
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active());
+ SetControlState_Impl( eXGS );
+ }
+
+ // preview
+ sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ XGradient aTmpGradient(
+ Color(nStartCol, nStartCol, nStartCol),
+ Color(nEndCol, nEndCol, nEndCol),
+ static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterY->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrBorder->get_value(FieldUnit::PERCENT)),
+ 100, 100);
+
+ XFillFloatTransparenceItem aItem( aTmpGradient);
+ rXFSet.Put ( aItem );
+
+ InvalidatePreview();
+}
+
+void SvxTransparenceTabPage::ActivateGradient(bool bActivate)
+{
+ m_xGridGradient->set_sensitive(bActivate);
+
+ if (bActivate)
+ {
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active());
+ SetControlState_Impl( eXGS );
+ }
+}
+
+void SvxTransparenceTabPage::SetControlState_Impl(css::awt::GradientStyle eXGS)
+{
+ switch(eXGS)
+ {
+ case css::awt::GradientStyle_LINEAR:
+ case css::awt::GradientStyle_AXIAL:
+ m_xFtTrgrCenterX->set_sensitive(false);
+ m_xMtrTrgrCenterX->set_sensitive(false);
+ m_xFtTrgrCenterY->set_sensitive(false);
+ m_xMtrTrgrCenterY->set_sensitive(false);
+ m_xFtTrgrAngle->set_sensitive(true);
+ m_xMtrTrgrAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_RADIAL:
+ m_xFtTrgrCenterX->set_sensitive(true);
+ m_xMtrTrgrCenterX->set_sensitive(true);
+ m_xFtTrgrCenterY->set_sensitive(true);
+ m_xMtrTrgrCenterY->set_sensitive(true);
+ m_xFtTrgrAngle->set_sensitive(false);
+ m_xMtrTrgrAngle->set_sensitive(false);
+ break;
+
+ case css::awt::GradientStyle_ELLIPTICAL:
+ case css::awt::GradientStyle_SQUARE:
+ case css::awt::GradientStyle_RECT:
+ m_xFtTrgrCenterX->set_sensitive(true);
+ m_xMtrTrgrCenterX->set_sensitive(true);
+ m_xFtTrgrCenterY->set_sensitive(true);
+ m_xMtrTrgrCenterY->set_sensitive(true);
+ m_xFtTrgrAngle->set_sensitive(true);
+ m_xMtrTrgrAngle->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+}
+
+SvxTransparenceTabPage::SvxTransparenceTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/transparencytabpage.ui", "TransparencyTabPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , nPageType(PageType::Area)
+ , nDlgType(0)
+ , bBitmap(false)
+ , aXFillAttr(rInAttrs.GetPool())
+ , rXFSet(aXFillAttr.GetItemSet())
+ , m_xRbtTransOff(m_xBuilder->weld_radio_button("RBT_TRANS_OFF"))
+ , m_xRbtTransLinear(m_xBuilder->weld_radio_button("RBT_TRANS_LINEAR"))
+ , m_xRbtTransGradient(m_xBuilder->weld_radio_button("RBT_TRANS_GRADIENT"))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xGridGradient(m_xBuilder->weld_widget("gridGradient"))
+ , m_xLbTrgrGradientType(m_xBuilder->weld_combo_box("LB_TRGR_GRADIENT_TYPES"))
+ , m_xFtTrgrCenterX(m_xBuilder->weld_label("FT_TRGR_CENTER_X"))
+ , m_xMtrTrgrCenterX(m_xBuilder->weld_metric_spin_button("MTR_TRGR_CENTER_X", FieldUnit::PERCENT))
+ , m_xFtTrgrCenterY(m_xBuilder->weld_label("FT_TRGR_CENTER_Y"))
+ , m_xMtrTrgrCenterY(m_xBuilder->weld_metric_spin_button("MTR_TRGR_CENTER_Y", FieldUnit::PERCENT))
+ , m_xFtTrgrAngle(m_xBuilder->weld_label("FT_TRGR_ANGLE"))
+ , m_xMtrTrgrAngle(m_xBuilder->weld_metric_spin_button("MTR_TRGR_ANGLE", FieldUnit::DEGREE))
+ , m_xMtrTrgrBorder(m_xBuilder->weld_metric_spin_button("MTR_TRGR_BORDER", FieldUnit::PERCENT))
+ , m_xMtrTrgrStartValue(m_xBuilder->weld_metric_spin_button("MTR_TRGR_START_VALUE", FieldUnit::PERCENT))
+ , m_xMtrTrgrEndValue(m_xBuilder->weld_metric_spin_button("MTR_TRGR_END_VALUE", FieldUnit::PERCENT))
+ , m_xCtlBitmapBorder(m_xBuilder->weld_widget("bitmap_border"))
+ , m_xCtlXRectBorder(m_xBuilder->weld_widget("trans_border"))
+ , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, "CTL_IMAGE_PREVIEW", m_aCtlBitmapPreview))
+ , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder, "CTL_TRANS_PREVIEW", m_aCtlXRectPreview))
+{
+ // main selection
+ m_xRbtTransOff->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransOffHdl_Impl));
+ m_xRbtTransLinear->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransLinearHdl_Impl));
+ m_xRbtTransGradient->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransGradientHdl_Impl));
+
+ // linear transparency
+ m_xMtrTransparent->set_value(50, FieldUnit::PERCENT);
+ m_xMtrTransparent->connect_value_changed(LINK(this, SvxTransparenceTabPage, ModifyTransparentHdl_Impl));
+
+ // gradient transparency
+ m_xMtrTrgrEndValue->set_value(100, FieldUnit::PERCENT);
+ m_xMtrTrgrStartValue->set_value(0, FieldUnit::PERCENT);
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxTransparenceTabPage, ModifiedTrgrEditHdl_Impl);
+ m_xLbTrgrGradientType->connect_changed(LINK(this, SvxTransparenceTabPage, ModifiedTrgrListBoxHdl_Impl));
+ m_xMtrTrgrCenterX->connect_value_changed( aLink );
+ m_xMtrTrgrCenterY->connect_value_changed( aLink );
+ m_xMtrTrgrAngle->connect_value_changed( aLink );
+ m_xMtrTrgrBorder->connect_value_changed( aLink );
+ m_xMtrTrgrStartValue->connect_value_changed( aLink );
+ m_xMtrTrgrEndValue->connect_value_changed( aLink );
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+}
+
+std::unique_ptr<SfxTabPage> SvxTransparenceTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTransparenceTabPage>(pPage, pController, *rAttrs);
+}
+
+bool SvxTransparenceTabPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ const SfxPoolItem* pGradientItem = nullptr;
+ const SfxPoolItem* pLinearItem = nullptr;
+ SfxItemState eStateGradient(rOutAttrs.GetItemState(XATTR_FILLFLOATTRANSPARENCE, true, &pGradientItem));
+ SfxItemState eStateLinear(rOutAttrs.GetItemState(XATTR_FILLTRANSPARENCE, true, &pLinearItem));
+ bool bGradActive = (eStateGradient == SfxItemState::SET && static_cast<const XFillFloatTransparenceItem*>(pGradientItem)->IsEnabled());
+ bool bLinearActive = (eStateLinear == SfxItemState::SET && static_cast<const XFillTransparenceItem*>(pLinearItem)->GetValue() != 0);
+
+ bool bGradUsed = (eStateGradient == SfxItemState::DONTCARE);
+ bool bLinearUsed = (eStateLinear == SfxItemState::DONTCARE);
+
+ bool bModified(false);
+ bool bSwitchOffLinear(false);
+ bool bSwitchOffGradient(false);
+
+ if (m_xMtrTransparent->get_sensitive())
+ {
+ // linear transparence
+ sal_uInt16 nPos = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ if (m_xMtrTransparent->get_value_changed_from_saved() || !bLinearActive)
+ {
+ XFillTransparenceItem aItem(nPos);
+ SdrPercentItem aShadowItem(makeSdrShadowTransparenceItem(nPos));
+ const SfxPoolItem* pOld = GetOldItem(*rAttrs, XATTR_FILLTRANSPARENCE);
+ if(!pOld || !(*static_cast<const XFillTransparenceItem*>(pOld) == aItem) || !bLinearActive)
+ {
+ rAttrs->Put(aItem);
+ rAttrs->Put(aShadowItem);
+ bModified = true;
+ bSwitchOffGradient = true;
+ }
+ }
+ }
+ else if (m_xGridGradient->get_sensitive())
+ {
+ // transparence gradient, fill ItemSet from values
+ if (!bGradActive
+ || m_xLbTrgrGradientType->get_value_changed_from_saved()
+ || m_xMtrTrgrAngle->get_value_changed_from_saved()
+ || m_xMtrTrgrCenterX->get_value_changed_from_saved()
+ || m_xMtrTrgrCenterY->get_value_changed_from_saved()
+ || m_xMtrTrgrBorder->get_value_changed_from_saved()
+ || m_xMtrTrgrStartValue->get_value_changed_from_saved()
+ || m_xMtrTrgrEndValue->get_value_changed_from_saved())
+ {
+ sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ XGradient aTmpGradient(
+ Color(nStartCol, nStartCol, nStartCol),
+ Color(nEndCol, nEndCol, nEndCol),
+ static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
+ Degree10(static_cast<sal_Int16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterY->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrBorder->get_value(FieldUnit::PERCENT)),
+ 100, 100);
+
+ XFillFloatTransparenceItem aItem(aTmpGradient);
+ const SfxPoolItem* pOld = GetOldItem(*rAttrs, XATTR_FILLFLOATTRANSPARENCE);
+
+ if(!pOld || !(*static_cast<const XFillFloatTransparenceItem*>(pOld) == aItem) || !bGradActive)
+ {
+ rAttrs->Put(aItem);
+ bModified = true;
+ bSwitchOffLinear = true;
+ }
+ }
+ }
+ else
+ {
+ // no transparence
+ bSwitchOffGradient = true;
+ bSwitchOffLinear = true;
+ }
+
+ // disable unused XFillFloatTransparenceItem
+ if(bSwitchOffGradient && (bGradActive || bGradUsed))
+ {
+ XGradient aGrad(COL_BLACK, COL_WHITE);
+ aGrad.SetStartIntens(100);
+ aGrad.SetEndIntens(100);
+ XFillFloatTransparenceItem aItem(aGrad);
+ aItem.SetEnabled(false);
+ rAttrs->Put(aItem);
+ bModified = true;
+ }
+
+ // disable unused XFillFloatTransparenceItem
+ if(bSwitchOffLinear && (bLinearActive || bLinearUsed))
+ {
+ XFillTransparenceItem aItem(0);
+ SdrPercentItem aShadowItem(makeSdrShadowTransparenceItem(0));
+ rAttrs->Put(aItem);
+ rAttrs->Put(aShadowItem);
+ bModified = true;
+ }
+ rAttrs->Put(CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(nPageType)));
+ return bModified;
+}
+
+void SvxTransparenceTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ const XFillFloatTransparenceItem* pGradientItem =
+ rAttrs->GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE);
+ bool bGradActive = (pGradientItem && pGradientItem->IsEnabled());
+ if(!pGradientItem)
+ pGradientItem = &rAttrs->Get(XATTR_FILLFLOATTRANSPARENCE);
+
+ const XFillTransparenceItem* pLinearItem =
+ rAttrs->GetItemIfSet(XATTR_FILLTRANSPARENCE);
+ bool bLinearActive = (pLinearItem && pLinearItem->GetValue() != 0);
+ if(!pLinearItem)
+ pLinearItem = &rAttrs->Get(XATTR_FILLTRANSPARENCE);
+
+ // transparence gradient
+ const XGradient& rGradient = pGradientItem->GetGradientValue();
+ css::awt::GradientStyle eXGS(rGradient.GetGradientStyle());
+ m_xLbTrgrGradientType->set_active(sal::static_int_cast< sal_Int32 >(eXGS));
+ m_xMtrTrgrAngle->set_value(rGradient.GetAngle().get() / 10, FieldUnit::DEGREE);
+ m_xMtrTrgrBorder->set_value(rGradient.GetBorder(), FieldUnit::PERCENT);
+ m_xMtrTrgrCenterX->set_value(rGradient.GetXOffset(), FieldUnit::PERCENT);
+ m_xMtrTrgrCenterY->set_value(rGradient.GetYOffset(), FieldUnit::PERCENT);
+ m_xMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetStartColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
+ m_xMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetEndColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
+
+ // linear transparence
+ sal_uInt16 nTransp = pLinearItem->GetValue();
+ m_xMtrTransparent->set_value(bLinearActive ? nTransp : 50, FieldUnit::PERCENT);
+ ModifyTransparentHdl_Impl(*m_xMtrTransparent);
+
+ // select the correct radio button
+ if(bGradActive)
+ {
+ // transparence gradient, set controls appropriate to item
+ m_xRbtTransGradient->set_active(true);
+ ClickTransGradientHdl_Impl(*m_xRbtTransGradient);
+ }
+ else if(bLinearActive)
+ {
+ // linear transparence
+ m_xRbtTransLinear->set_active(true);
+ ClickTransLinearHdl_Impl(*m_xRbtTransLinear);
+ }
+ else
+ {
+ // no transparence
+ m_xRbtTransOff->set_active(true);
+ ClickTransOffHdl_Impl(*m_xRbtTransOff);
+ ModifiedTrgrHdl_Impl(nullptr);
+ }
+
+ // save values
+ ChangesApplied();
+ bool bActive = InitPreview ( *rAttrs );
+ InvalidatePreview ( bActive );
+}
+
+void SvxTransparenceTabPage::ChangesApplied()
+{
+ m_xMtrTransparent->save_value();
+ m_xLbTrgrGradientType->save_value();
+ m_xMtrTrgrCenterX->save_value();
+ m_xMtrTrgrCenterY->save_value();
+ m_xMtrTrgrAngle->save_value();
+ m_xMtrTrgrBorder->save_value();
+ m_xMtrTrgrStartValue->save_value();
+ m_xMtrTrgrEndValue->save_value();
+}
+
+void SvxTransparenceTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const CntUInt16Item* pPageTypeItem = rSet.GetItem<CntUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+
+ if(nDlgType == 0) // area dialog
+ nPageType = PageType::Transparence;
+
+ InitPreview ( rSet );
+}
+
+DeactivateRC SvxTransparenceTabPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+// Preview-Methods
+
+bool SvxTransparenceTabPage::InitPreview(const SfxItemSet& rSet)
+{
+ // set transparencetype for preview
+ if (m_xRbtTransOff->get_active())
+ {
+ ClickTransOffHdl_Impl(*m_xRbtTransOff);
+ }
+ else if (m_xRbtTransLinear->get_active())
+ {
+ ClickTransLinearHdl_Impl(*m_xRbtTransLinear);
+ }
+ else if (m_xRbtTransGradient->get_active())
+ {
+ ClickTransGradientHdl_Impl(*m_xRbtTransGradient);
+ }
+
+ // Get fillstyle for preview
+ rXFSet.Put ( rSet.Get(XATTR_FILLSTYLE) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLCOLOR) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLGRADIENT) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLHATCH) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLBACKGROUND) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLBITMAP) );
+
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+
+ bBitmap = rSet.Get(XATTR_FILLSTYLE).GetValue() == drawing::FillStyle_BITMAP;
+
+ // show the right preview window
+ if ( bBitmap )
+ {
+ m_xCtlBitmapBorder->show();
+ m_xCtlXRectBorder->hide();
+ }
+ else
+ {
+ m_xCtlBitmapBorder->hide();
+ m_xCtlXRectBorder->show();
+ }
+
+ return !m_xRbtTransOff->get_active();
+}
+
+void SvxTransparenceTabPage::InvalidatePreview (bool bEnable)
+{
+ if ( bBitmap )
+ {
+ if ( bEnable )
+ {
+ m_xCtlBitmapPreview->set_sensitive(true);
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ }
+ else
+ m_xCtlBitmapPreview->set_sensitive(false);
+ m_xCtlBitmapPreview->queue_draw();
+ }
+ else
+ {
+ if ( bEnable )
+ {
+ m_xCtlXRectPreview->set_sensitive(true);
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ }
+ else
+ m_xCtlXRectPreview->set_sensitive(false);
+ m_xCtlXRectPreview->queue_draw();
+ }
+}
+
+void SvxTransparenceTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx
new file mode 100644
index 000000000..c9fd14095
--- /dev/null
+++ b/cui/source/tabpages/transfrm.cxx
@@ -0,0 +1,1562 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <algorithm>
+
+#include <svx/EnhancedCustomShape2d.hxx>
+#include <svx/sdangitm.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/sderitm.hxx>
+#include <svx/svxids.hrc>
+#include <svx/transfrmhelper.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <transfrm.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/anchorid.hxx>
+#include <svl/rectitem.hxx>
+#include <swpossizetabpage.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/fieldvalues.hxx>
+
+// static ----------------------------------------------------------------
+
+const WhichRangesContainer SvxPositionSizeTabPage::pPosSizeRanges(svl::Items<
+ SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
+ SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
+ SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_AUTOHEIGHT,
+ SID_ATTR_TRANSFORM_ANCHOR, SID_ATTR_TRANSFORM_VERT_ORIENT
+>);
+
+const WhichRangesContainer SvxAngleTabPage::pAngleRanges(svl::Items<
+ SID_ATTR_TRANSFORM_ROT_X, SID_ATTR_TRANSFORM_ANGLE,
+ SID_ATTR_TRANSFORM_INTERN, SID_ATTR_TRANSFORM_INTERN
+>);
+
+const WhichRangesContainer SvxSlantTabPage::pSlantRanges(svl::Items<
+ SDRATTR_CORNER_RADIUS, SDRATTR_CORNER_RADIUS,
+ SID_ATTR_TRANSFORM_INTERN, SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_SHEAR, SID_ATTR_TRANSFORM_SHEAR_VERTICAL
+>);
+
+/*************************************************************************
+|*
+|* constructor of the tab dialog: adds the pages to the dialog
+|*
+\************************************************************************/
+
+SvxTransformTabDialog::SvxTransformTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ const SdrView* pSdrView, SvxAnchorIds nAnchorTypes)
+ : SfxTabDialogController(pParent, "cui/ui/positionsizedialog.ui", "PositionAndSizeDialog", pAttr)
+ , pView(pSdrView)
+ , nAnchorCtrls(nAnchorTypes)
+{
+ DBG_ASSERT(pView, "no valid view (!)");
+
+ //different positioning page in Writer
+ if(nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
+ {
+ AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create, SvxSwPosSizeTabPage::GetRanges);
+ RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
+ }
+ else
+ {
+ AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create, SvxPositionSizeTabPage::GetRanges);
+ RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
+ }
+
+ AddTabPage("RID_SVXPAGE_ANGLE", SvxAngleTabPage::Create, SvxAngleTabPage::GetRanges);
+ AddTabPage("RID_SVXPAGE_SLANT", SvxSlantTabPage::Create, SvxSlantTabPage::GetRanges);
+}
+
+
+void SvxTransformTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_POSITION_SIZE")
+ {
+ SvxPositionSizeTabPage& rSvxPos = static_cast<SvxPositionSizeTabPage&>(rPage);
+ rSvxPos.SetView(pView);
+ rSvxPos.Construct();
+
+ if(nAnchorCtrls & SvxAnchorIds::NoResize)
+ {
+ rSvxPos.DisableResize();
+ }
+
+ if(nAnchorCtrls & SvxAnchorIds::NoProtect)
+ {
+ rSvxPos.DisableProtect();
+ rSvxPos.UpdateControlStates();
+ }
+ }
+ else if (rId == "RID_SVXPAGE_SWPOSSIZE")
+ {
+ SvxSwPosSizeTabPage& rSwPos = static_cast<SvxSwPosSizeTabPage&>(rPage);
+
+ rSwPos.EnableAnchorTypes(nAnchorCtrls);
+ rSwPos.SetValidateFramePosLink(aValidateLink);
+ rSwPos.SetView(pView);
+ }
+ else if (rId == "RID_SVXPAGE_ANGLE")
+ {
+ SvxAngleTabPage& rSvxAng = static_cast<SvxAngleTabPage&>(rPage);
+
+ rSvxAng.SetView( pView );
+ rSvxAng.Construct();
+ }
+ else if (rId == "RID_SVXPAGE_SLANT")
+ {
+ SvxSlantTabPage& rSvxSlnt = static_cast<SvxSlantTabPage&>(rPage);
+
+ rSvxSlnt.SetView( pView );
+ rSvxSlnt.Construct();
+ }
+}
+
+void SvxTransformTabDialog::SetValidateFramePosLink(const Link<SvxSwFrameValidation&,void>& rLink)
+{
+ aValidateLink = rLink;
+}
+
+/*************************************************************************
+|*
+|* dialog for changing the positions of the rotation
+|* angle and the rotation angle of the graphic objects
+|*
+\************************************************************************/
+SvxAngleTabPage::SvxAngleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/rotationtabpage.ui", "Rotation", rInAttrs)
+ , pView(nullptr)
+ , eDlgUnit(FieldUnit::NONE)
+ , m_aCtlRect(this)
+ , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
+ , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
+ , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
+ , m_xCtlRect(new weld::CustomWeld(*m_xBuilder, "CTL_RECT", m_aCtlRect))
+ , m_xFlAngle(m_xBuilder->weld_widget("FL_ANGLE"))
+ , m_xNfAngle(m_xBuilder->weld_metric_spin_button("NF_ANGLE", FieldUnit::DEGREE))
+ , m_xCtlAngle(new svx::DialControl)
+ , m_xCtlAngleWin(new weld::CustomWeld(*m_xBuilder, "CTL_ANGLE", *m_xCtlAngle))
+{
+ // calculate PoolUnit
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ DBG_ASSERT( pPool, "no pool (!)" );
+ ePoolUnit = pPool->GetMetric(SID_ATTR_TRANSFORM_POS_X);
+
+ m_xCtlAngle->SetLinkedField(m_xNfAngle.get(), 2);
+}
+
+SvxAngleTabPage::~SvxAngleTabPage()
+{
+}
+
+void SvxAngleTabPage::Construct()
+{
+ DBG_ASSERT(pView, "No valid view (!)");
+ eDlgUnit = GetModuleFieldUnit(GetItemSet());
+ SetFieldUnit(*m_xMtrPosX, eDlgUnit, true);
+ SetFieldUnit(*m_xMtrPosY, eDlgUnit, true);
+
+ if (FieldUnit::MILE == eDlgUnit || FieldUnit::KM == eDlgUnit)
+ {
+ m_xMtrPosX->set_digits(3);
+ m_xMtrPosY->set_digits(3);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // Take anchor into account (Writer)
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if(rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
+
+ if(!maAnchor.equalZero()) // -> Writer
+ {
+ maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
+ }
+ }
+
+ // take scale into account
+ const Fraction aUIScale(pView->GetModel()->GetUIScale());
+ TransfrmHelper::ScaleRect(maRange, aUIScale);
+
+ // take UI units into account
+ sal_uInt16 nDigits(m_xMtrPosX->get_digits());
+ TransfrmHelper::ConvertRect(maRange, nDigits, ePoolUnit, eDlgUnit);
+
+ if(!pView->IsRotateAllowed())
+ {
+ m_xFlPosition->set_sensitive(false);
+ m_xFlAngle->set_sensitive(false);
+ }
+}
+
+bool SvxAngleTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ bool bModified = false;
+
+ if (m_xCtlAngle->IsValueModified() || m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
+ {
+ const double fUIScale(double(pView->GetModel()->GetUIScale()));
+ const double fTmpX((GetCoreValue(*m_xMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale);
+ const double fTmpY((GetCoreValue(*m_xMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale);
+
+ rSet->Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, m_xCtlAngle->GetRotation()));
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(fTmpX)));
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(fTmpY)));
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+
+void SvxAngleTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ const double fUIScale(double(pView->GetModel()->GetUIScale()));
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ROT_X );
+ if(pItem)
+ {
+ const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getX()) / fUIScale);
+ SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrPosX->set_text(OUString());
+ }
+
+ pItem = GetItem(*rAttrs, SID_ATTR_TRANSFORM_ROT_Y);
+ if(pItem)
+ {
+ const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getY()) / fUIScale);
+ SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrPosY->set_text(OUString());
+ }
+
+ pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ANGLE );
+ if(pItem)
+ {
+ m_xCtlAngle->SetRotation(static_cast<const SdrAngleItem*>(pItem)->GetValue());
+ }
+ else
+ {
+ m_xCtlAngle->SetRotation(0_deg100);
+ }
+ m_xCtlAngle->SaveValue();
+ m_xMtrPosX->save_value();
+ m_xMtrPosY->save_value();
+}
+
+std::unique_ptr<SfxTabPage> SvxAngleTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxAngleTabPage>(pPage, pController, *rSet);
+}
+
+void SvxAngleTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ if(SfxBoolItem const * bPosProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_POS, false ))
+ {
+ m_xFlPosition->set_sensitive(!bPosProtect->GetValue());
+ m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
+ }
+}
+
+DeactivateRC SvxAngleTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxAngleTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
+{
+ if (pDrawingArea != m_aCtlRect.GetDrawingArea())
+ return;
+
+ switch(eRP)
+ {
+ case RectPoint::LT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* dialog for changing slant and corner radius
+|*
+\************************************************************************/
+SvxSlantTabPage::SvxSlantTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/slantcornertabpage.ui", "SlantAndCornerRadius", &rInAttrs)
+ , pView(nullptr)
+ , eDlgUnit(FieldUnit::NONE)
+ , m_xFlRadius(m_xBuilder->weld_widget("FL_RADIUS"))
+ , m_xMtrRadius(m_xBuilder->weld_metric_spin_button("MTR_FLD_RADIUS", FieldUnit::CM))
+ , m_xFlAngle(m_xBuilder->weld_widget("FL_SLANT"))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("MTR_FLD_ANGLE", FieldUnit::DEGREE))
+{
+ for (int i = 0; i < 2; ++i)
+ {
+ m_aControlGroups[i] = m_xBuilder->weld_widget("controlgroups" + OString::number(i+1));
+ m_aControlGroupX[i] = m_xBuilder->weld_widget("controlgroupx" + OString::number(i+1));
+ m_aControlX[i] = m_xBuilder->weld_metric_spin_button("controlx" + OString::number(i+1), FieldUnit::CM);
+ m_aControlGroupY[i] = m_xBuilder->weld_widget("controlgroupy" + OString::number(i+1));
+ m_aControlY[i] = m_xBuilder->weld_metric_spin_button("controly" + OString::number(i+1), FieldUnit::CM);
+ }
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // evaluate PoolUnit
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ assert(pPool && "no pool (!)");
+ ePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
+}
+
+SvxSlantTabPage::~SvxSlantTabPage()
+{
+}
+
+void SvxSlantTabPage::Construct()
+{
+ // get the range
+ DBG_ASSERT(pView, "no valid view (!)");
+ eDlgUnit = GetModuleFieldUnit(GetItemSet());
+ SetFieldUnit(*m_xMtrRadius, eDlgUnit, true);
+ for (int i = 0; i < 2; ++i)
+ {
+ SetFieldUnit(*m_aControlX[i], eDlgUnit, true);
+ SetFieldUnit(*m_aControlY[i], eDlgUnit, true);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ }
+}
+
+bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+
+ if (m_xMtrRadius->get_value_changed_from_saved())
+ {
+ Fraction aUIScale = pView->GetModel()->GetUIScale();
+ tools::Long nTmp = tools::Long(GetCoreValue(*m_xMtrRadius, ePoolUnit) * aUIScale);
+
+ rAttrs->Put( makeSdrEckenradiusItem( nTmp ) );
+ bModified = true;
+ }
+
+ if (m_xMtrAngle->get_value_changed_from_saved())
+ {
+ sal_Int32 nValue = static_cast<sal_Int32>(m_xMtrAngle->get_value(FieldUnit::NONE));
+ rAttrs->Put( SdrAngleItem( SID_ATTR_TRANSFORM_SHEAR, Degree100(nValue) ) );
+ bModified = true;
+ }
+
+ if( bModified )
+ {
+ // set reference points
+ ::tools::Rectangle aObjectRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aObjectRect);
+ Point aPt = aObjectRect.Center();
+
+ rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X, aPt.X()));
+ rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y, aPt.Y()));
+ rAttrs->Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, false ) );
+ }
+
+ bool bControlPointsChanged = false;
+ for (int i = 0; i < 2; ++i)
+ {
+ bControlPointsChanged |= (m_aControlX[i]->get_value_changed_from_saved() ||
+ m_aControlY[i]->get_value_changed_from_saved());
+ }
+
+ if (!bControlPointsChanged)
+ return bModified;
+
+ bool bSelectionIsSdrObjCustomShape(false);
+
+ while(true)
+ {
+ if(nullptr == pView)
+ {
+ break;
+ }
+
+ if(0 == pView->GetMarkedObjectList().GetMarkCount())
+ {
+ break;
+ }
+
+ SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr == pCandidate)
+ {
+ break;
+ }
+
+ if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+ {
+ break;
+ }
+
+ bSelectionIsSdrObjCustomShape = true;
+ break;
+ }
+
+ if(bSelectionIsSdrObjCustomShape)
+ {
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast< SdrObjCustomShape& >(
+ *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+ SdrModel& rModel(rSdrObjCustomShape.getSdrModelFromSdrObject());
+ std::unique_ptr<SdrUndoAction> pUndo;
+ if (rModel.IsUndoEnabled())
+ pUndo = rModel.GetSdrUndoFactory().CreateUndoAttrObject(rSdrObjCustomShape);
+
+ if(pUndo)
+ {
+ rModel.BegUndo(pUndo->GetComment());
+ }
+
+ EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+ ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (m_aControlX[i]->get_value_changed_from_saved() || m_aControlY[i]->get_value_changed_from_saved())
+ {
+ Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
+ GetCoreValue(*m_aControlY[i], ePoolUnit));
+ aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
+
+ css::awt::Point aPosition;
+ aPosition.X = aNewPosition.X();
+ aPosition.Y = aNewPosition.Y();
+
+ aShape.SetHandleControllerPosition(i, aPosition);
+ }
+ }
+
+ rSdrObjCustomShape.SetChanged();
+ rSdrObjCustomShape.BroadcastObjectChange();
+ bModified = true;
+
+ if (pUndo)
+ {
+ rModel.AddUndo(std::move(pUndo));
+ rModel.EndUndo();
+ }
+ }
+
+ return bModified;
+}
+
+void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ // if the view has selected objects, items with SfxItemState::DEFAULT need to be disabled
+ const SfxPoolItem* pItem;
+
+ // corner radius
+ if(!pView->IsEdgeRadiusAllowed())
+ {
+ m_xMtrRadius->set_text("");
+ m_xFlRadius->set_sensitive(false);
+ }
+ else
+ {
+ pItem = GetItem( *rAttrs, SDRATTR_CORNER_RADIUS );
+
+ if( pItem )
+ {
+ const double fUIScale(double(pView->GetModel()->GetUIScale()));
+ const double fTmp(static_cast<double>(static_cast<const SdrMetricItem*>(pItem)->GetValue()) / fUIScale);
+ SetMetricValue(*m_xMtrRadius, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrRadius->set_text("");
+ }
+ }
+
+ m_xMtrRadius->save_value();
+
+ // slant: angle
+ if( !pView->IsShearAllowed() )
+ {
+ m_xMtrAngle->set_text( "" );
+ m_xFlAngle->set_sensitive(false);
+ }
+ else
+ {
+ pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_SHEAR );
+
+ if( pItem )
+ {
+ m_xMtrAngle->set_value(static_cast<const SdrAngleItem*>(pItem)->GetValue().get(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xMtrAngle->set_text("");
+ }
+ }
+
+ m_xMtrAngle->save_value();
+
+ bool bSelectionIsSdrObjCustomShape(false);
+
+ while(true)
+ {
+ if(1 != pView->GetMarkedObjectList().GetMarkCount())
+ {
+ break;
+ }
+
+ SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr == pCandidate)
+ {
+ break;
+ }
+
+ if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+ {
+ break;
+ }
+
+ bSelectionIsSdrObjCustomShape = true;
+ break;
+ }
+
+ if(bSelectionIsSdrObjCustomShape)
+ {
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast< SdrObjCustomShape& >(
+ *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+
+ //save geometry
+ const bool bOrigModelChangeState = pView->GetModel()->IsChanged();
+ SdrCustomShapeGeometryItem aInitialGeometry(rSdrObjCustomShape.GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
+ EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ Point aInitialPosition;
+ if (!aShape.GetHandlePosition(i, aInitialPosition))
+ break;
+ m_aControlGroups[i]->set_sensitive(true);
+ css::awt::Point aPosition;
+
+ aPosition.X = SAL_MAX_INT32/2;
+ aPosition.Y = SAL_MAX_INT32/2;
+ aShape.SetHandleControllerPosition(i, aPosition);
+ Point aMaxPosition;
+ aShape.GetHandlePosition(i, aMaxPosition);
+
+ aPosition.X = SAL_MIN_INT32/2;
+ aPosition.Y = SAL_MIN_INT32/2;
+ aShape.SetHandleControllerPosition(i, aPosition);
+ Point aMinPosition;
+ aShape.GetHandlePosition(i, aMinPosition);
+
+ ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+ aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+ aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+ aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+
+ SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
+ SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
+
+ if (aMaxPosition.X() == aMinPosition.X())
+ m_aControlGroupX[i]->set_sensitive(false);
+ else
+ m_aControlX[i]->set_range(aMinPosition.X(), aMaxPosition.X(), FieldUnit::MM);
+ if (aMaxPosition.Y() == aMinPosition.Y())
+ m_aControlGroupY[i]->set_sensitive(false);
+ else
+ m_aControlY[i]->set_range(aMinPosition.Y(), aMaxPosition.Y(), FieldUnit::MM);
+ }
+
+ //restore geometry
+ rSdrObjCustomShape.SetMergedItem(aInitialGeometry);
+ pView->GetModel()->SetChanged(bOrigModelChangeState);
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ m_aControlX[i]->save_value();
+ m_aControlY[i]->save_value();
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxSlantTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxSlantTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if(SfxBoolItem const * bPosProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_POS, false ))
+ {
+ m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
+ }
+ if(SfxBoolItem const * bSizeProtect = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_PROTECT_SIZE, false ))
+ {
+ m_xFlAngle->set_sensitive(!bSizeProtect->GetValue());
+ }
+
+}
+
+DeactivateRC SvxSlantTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+
+/*************************************************************************
+|*
+|* Dialog for changing position and size of graphic objects
+|*
+\************************************************************************/
+SvxPositionSizeTabPage::SvxPositionSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/possizetabpage.ui", "PositionAndSize", rInAttrs)
+ , mrOutAttrs(rInAttrs)
+ , mpView(nullptr)
+ , meDlgUnit(FieldUnit::NONE)
+ , mnProtectSizeState(TRISTATE_FALSE)
+ , mbPageDisabled(false)
+ , mbProtectDisabled(false)
+ , mbSizeDisabled(false)
+ , mbAdjustDisabled(true)
+ , mbIgnoreAutoGrowWidth(true)
+ , mbIgnoreAutoGrowHeight(true)
+ , mfOldWidth(0.0)
+ , mfOldHeight(0.0)
+ , m_aCtlPos(this)
+ , m_aCtlSize(this)
+ , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
+ , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
+ , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
+ , m_xCtlPos(new weld::CustomWeld(*m_xBuilder, "CTL_POSRECT", m_aCtlPos))
+ , m_xFlSize(m_xBuilder->weld_widget("FL_SIZE"))
+ , m_xFtWidth(m_xBuilder->weld_label("FT_WIDTH"))
+ , m_xMtrWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_WIDTH", FieldUnit::CM))
+ , m_xFtHeight(m_xBuilder->weld_label("FT_HEIGHT"))
+ , m_xMtrHeight(m_xBuilder->weld_metric_spin_button("MTR_FLD_HEIGHT", FieldUnit::CM))
+ , m_xCbxScale(m_xBuilder->weld_check_button("CBX_SCALE"))
+ , m_xCtlSize(new weld::CustomWeld(*m_xBuilder, "CTL_SIZERECT", m_aCtlSize))
+ , m_xFlProtect(m_xBuilder->weld_widget("FL_PROTECT"))
+ , m_xTsbPosProtect(m_xBuilder->weld_check_button("TSB_POSPROTECT"))
+ , m_xTsbSizeProtect(m_xBuilder->weld_check_button("TSB_SIZEPROTECT"))
+ , m_xFlAdjust(m_xBuilder->weld_widget("FL_ADJUST"))
+ , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
+ , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // evaluate PoolUnit
+ SfxItemPool* pPool = mrOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "no pool (!)" );
+ mePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
+
+ m_aCtlPos.SetActualRP(RectPoint::LT);
+ m_aCtlSize.SetActualRP(RectPoint::LT);
+ meRP = RectPoint::LT; // see above
+
+ m_xMtrWidth->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeWidthHdl ) );
+ m_xMtrHeight->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeHeightHdl ) );
+ m_xCbxScale->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickAutoHdl ) );
+
+ m_xFlAdjust->set_sensitive(false);
+
+ // #i2379# disable controls when protected
+ m_xTsbPosProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangePosProtectHdl ) );
+ m_xTsbSizeProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangeSizeProtectHdl ) );
+}
+
+SvxPositionSizeTabPage::~SvxPositionSizeTabPage()
+{
+}
+
+void SvxPositionSizeTabPage::Construct()
+{
+ // get range and work area
+ DBG_ASSERT( mpView, "no valid view (!)" );
+ meDlgUnit = GetModuleFieldUnit( GetItemSet() );
+ SetFieldUnit( *m_xMtrPosX, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrPosY, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrWidth, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrHeight, meDlgUnit, true );
+
+ if(FieldUnit::MILE == meDlgUnit || FieldUnit::KM == meDlgUnit)
+ {
+ m_xMtrPosX->set_digits( 3 );
+ m_xMtrPosY->set_digits( 3 );
+ m_xMtrWidth->set_digits( 3 );
+ m_xMtrHeight->set_digits( 3 );
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetWorkArea());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maWorkRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // take anchor into account (Writer)
+ const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
+
+ if(rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
+
+ if(!maAnchor.equalZero()) // -> Writer
+ {
+ for(size_t i = 1; i < rMarkList.GetMarkCount(); ++i)
+ {
+ pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ if(maAnchor != basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y()))
+ {
+ // different anchor positions
+ m_xMtrPosX->set_text("");
+ m_xMtrPosY->set_text("");
+ mbPageDisabled = true;
+ return;
+ }
+ }
+
+ // translate ranges about anchor
+ maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
+ maWorkRange = basegfx::B2DRange(maWorkRange.getMinimum() - maAnchor, maWorkRange.getMaximum() - maAnchor);
+ }
+ }
+
+ // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
+ if(1 == rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ const SdrObjKind eKind(pObj->GetObjIdentifier());
+
+ if((pObj->GetObjInventor() == SdrInventor::Default) &&
+ (SdrObjKind::Text == eKind || SdrObjKind::TitleText == eKind || SdrObjKind::OutlineText == eKind) &&
+ pObj->HasText())
+ {
+ mbAdjustDisabled = false;
+
+ m_xFlAdjust->set_sensitive(true);
+
+ m_xTsbAutoGrowWidth->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
+ m_xTsbAutoGrowHeight->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
+
+ // is used as flag to evaluate if it's selectable
+ mbIgnoreAutoGrowWidth = false;
+ mbIgnoreAutoGrowHeight = false;
+ }
+ }
+
+ // take scale into account
+ const Fraction aUIScale(mpView->GetModel()->GetUIScale());
+ TransfrmHelper::ScaleRect( maWorkRange, aUIScale );
+ TransfrmHelper::ScaleRect( maRange, aUIScale );
+
+ // take UI units into account
+ const sal_uInt16 nDigits(m_xMtrPosX->get_digits());
+ TransfrmHelper::ConvertRect( maWorkRange, nDigits, mePoolUnit, meDlgUnit );
+ TransfrmHelper::ConvertRect( maRange, nDigits, mePoolUnit, meDlgUnit );
+
+ SetMinMaxPosition();
+}
+
+
+bool SvxPositionSizeTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ bool bModified(false);
+
+ if ( m_xMtrWidth->has_focus() )
+ {
+ ChangeWidthHdl( *m_xMtrWidth );
+ }
+
+ if ( m_xMtrHeight->has_focus() )
+ {
+ ChangeHeightHdl( *m_xMtrHeight );
+ }
+
+ if( !mbPageDisabled )
+ {
+ if (m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
+ {
+ const double fUIScale(double(mpView->GetModel()->GetUIScale()));
+ double fX((GetCoreValue( *m_xMtrPosX, mePoolUnit ) + maAnchor.getX()) * fUIScale);
+ double fY((GetCoreValue( *m_xMtrPosY, mePoolUnit ) + maAnchor.getY()) * fUIScale);
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // #101581# GetTopLeftPosition(...) needs coordinates after UI scaling, in real PagePositions
+ GetTopLeftPosition(fX, fY, maRange);
+
+ rOutAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X, basegfx::fround(fX)));
+ rOutAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y, basegfx::fround(fY)));
+
+ bModified = true;
+ }
+
+ if (m_xTsbPosProtect->get_state_changed_from_saved())
+ {
+ if( m_xTsbPosProtect->get_inconsistent() )
+ {
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
+ }
+ else
+ {
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xTsbPosProtect->get_active() ) );
+ }
+
+ bModified = true;
+ }
+ }
+
+ if (m_xMtrWidth->get_value_changed_from_saved() || m_xMtrHeight->get_value_changed_from_saved())
+ {
+ Fraction aUIScale = mpView->GetModel()->GetUIScale();
+
+ // get Width
+ double nWidth = static_cast<double>(m_xMtrWidth->get_value(FieldUnit::MM_100TH));
+ tools::Long lWidth = tools::Long(nWidth * static_cast<double>(aUIScale));
+ lWidth = OutputDevice::LogicToLogic( lWidth, MapUnit::Map100thMM, mePoolUnit );
+ lWidth = static_cast<tools::Long>(m_xMtrWidth->denormalize( lWidth ));
+
+ // get Height
+ double nHeight = static_cast<double>(m_xMtrHeight->get_value(FieldUnit::MM_100TH));
+ tools::Long lHeight = tools::Long(nHeight * static_cast<double>(aUIScale));
+ lHeight = OutputDevice::LogicToLogic( lHeight, MapUnit::Map100thMM, mePoolUnit );
+ lHeight = static_cast<tools::Long>(m_xMtrHeight->denormalize( lHeight ));
+
+ // put Width & Height to itemset
+ rOutAttrs->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_WIDTH, static_cast<sal_uInt32>(lWidth) ) );
+ rOutAttrs->Put( SfxUInt32Item( SID_ATTR_TRANSFORM_HEIGHT, static_cast<sal_uInt32>(lHeight) ) );
+ rOutAttrs->Put( SfxUInt16Item( SID_ATTR_TRANSFORM_SIZE_POINT, sal::static_int_cast< sal_uInt16 >( meRP ) ) );
+ bModified = true;
+ }
+
+ if (m_xTsbSizeProtect->get_state_changed_from_saved())
+ {
+ if ( m_xTsbSizeProtect->get_inconsistent() )
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ else
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xTsbSizeProtect->get_active() ) );
+ bModified = true;
+ }
+
+ if (m_xTsbAutoGrowWidth->get_state_changed_from_saved())
+ {
+ if (!mbIgnoreAutoGrowWidth)
+ {
+ if( m_xTsbAutoGrowWidth->get_inconsistent() )
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOWIDTH );
+ else
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_AUTOWIDTH,
+ m_xTsbAutoGrowWidth->get_active() ) );
+ }
+ bModified = true;
+ }
+
+ if (m_xTsbAutoGrowHeight->get_state_changed_from_saved())
+ {
+ if (!mbIgnoreAutoGrowHeight)
+ {
+ if (m_xTsbAutoGrowHeight->get_inconsistent())
+ {
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOHEIGHT );
+ }
+ else
+ {
+ rOutAttrs->Put(
+ SfxBoolItem( SID_ATTR_TRANSFORM_AUTOHEIGHT,
+ m_xTsbAutoGrowHeight->get_active() ) );
+ }
+ }
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxPositionSizeTabPage::Reset( const SfxItemSet* )
+{
+ const SfxPoolItem* pItem;
+ const double fUIScale(double(mpView->GetModel()->GetUIScale()));
+
+ if ( !mbPageDisabled )
+ {
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_X );
+ if ( pItem )
+ {
+ const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getX()) / fUIScale);
+ SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), mePoolUnit);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_Y );
+ if ( pItem )
+ {
+ const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getY()) / fUIScale);
+ SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), mePoolUnit);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_POS );
+ if ( pItem )
+ {
+ bool bProtected = static_cast<const SfxBoolItem*>( pItem )->GetValue();
+ m_xTsbPosProtect->set_active(bProtected);
+ }
+ else
+ {
+ m_xTsbPosProtect->set_inconsistent(true);
+ }
+
+ m_xTsbPosProtect->save_state();
+ m_aCtlPos.Reset();
+
+ // #i2379# Disable controls for protected objects
+ ChangePosProtectHdl(*m_xTsbPosProtect);
+ }
+
+ { // #i75273# set width
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_WIDTH );
+ mfOldWidth = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
+ double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldWidth), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
+ if (m_xMtrWidth->get_digits())
+ fTmpWidth *= pow(10.0, m_xMtrWidth->get_digits());
+ m_xMtrWidth->set_value(fTmpWidth, FieldUnit::MM_100TH);
+ }
+
+ { // #i75273# set height
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_HEIGHT );
+ mfOldHeight = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
+ double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldHeight), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
+ if (m_xMtrHeight->get_digits())
+ fTmpHeight *= pow(10.0, m_xMtrHeight->get_digits());
+ m_xMtrHeight->set_value(fTmpHeight, FieldUnit::MM_100TH);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ if ( pItem )
+ {
+ m_xTsbSizeProtect->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ }
+ else
+ m_xTsbSizeProtect->set_inconsistent(true);
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOWIDTH );
+ if ( pItem )
+ {
+ m_xTsbAutoGrowWidth->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
+ }
+ else
+ m_xTsbAutoGrowWidth->set_inconsistent(true);
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOHEIGHT );
+ if ( pItem )
+ {
+ m_xTsbAutoGrowHeight->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
+ }
+ else
+ m_xTsbAutoGrowHeight->set_inconsistent(true);
+
+ // Is matching set?
+ OUString aStr = GetUserData();
+ m_xCbxScale->set_active(aStr.toInt32() != 0);
+
+ m_xMtrPosX->save_value();
+ m_xMtrPosY->save_value();
+ m_xMtrWidth->save_value();
+ m_xMtrHeight->save_value();
+
+ m_xTsbSizeProtect->save_state();
+ m_xTsbAutoGrowWidth->save_state();
+ m_xTsbAutoGrowHeight->save_state();
+ ClickSizeProtectHdl(*m_xTsbAutoGrowHeight);
+
+ // #i2379# Disable controls for protected objects
+ ChangeSizeProtectHdl(*m_xTsbSizeProtect);
+}
+
+std::unique_ptr<SfxTabPage> SvxPositionSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxPositionSizeTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxPositionSizeTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( SfxRectangleItem const * pRectItem = rSet.GetItemIfSet( SID_ATTR_TRANSFORM_INTERN, false ) )
+ {
+ { // #i75273#
+ const ::tools::Rectangle aTempRect(pRectItem->GetValue());
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ SetMinMaxPosition();
+ }
+}
+
+
+DeactivateRC SvxPositionSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ {
+ double fX(static_cast<double>(m_xMtrPosX->get_value(FieldUnit::NONE)));
+ double fY(static_cast<double>(m_xMtrPosY->get_value(FieldUnit::NONE)));
+
+ GetTopLeftPosition(fX, fY, maRange);
+ const ::tools::Rectangle aOutRectangle(
+ basegfx::fround(fX), basegfx::fround(fY),
+ basegfx::fround(fX + maRange.getWidth()), basegfx::fround(fY + maRange.getHeight()));
+ _pSet->Put(SfxRectangleItem(SID_ATTR_TRANSFORM_INTERN, aOutRectangle));
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_POS,
+ m_xTsbPosProtect->get_state() == TRISTATE_TRUE ));
+ _pSet->Put(SfxBoolItem( SID_ATTR_TRANSFORM_PROTECT_SIZE,
+ m_xTsbSizeProtect->get_state() == TRISTATE_TRUE ));
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangePosProtectHdl, weld::Toggleable&, void)
+{
+ // #106572# Remember user's last choice
+ m_xTsbSizeProtect->set_state(m_xTsbPosProtect->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : mnProtectSizeState);
+ UpdateControlStates();
+}
+
+
+void SvxPositionSizeTabPage::UpdateControlStates()
+{
+ const bool bPosProtect = m_xTsbPosProtect->get_state() == TRISTATE_TRUE;
+ const bool bSizeProtect = m_xTsbSizeProtect->get_state() == TRISTATE_TRUE;
+ const bool bHeightChecked = !mbIgnoreAutoGrowHeight && (m_xTsbAutoGrowHeight->get_active());
+ const bool bWidthChecked = !mbIgnoreAutoGrowWidth && (m_xTsbAutoGrowWidth->get_active());
+
+ m_xFlPosition->set_sensitive(!bPosProtect && !mbPageDisabled);
+
+ m_xTsbPosProtect->set_sensitive( !mbProtectDisabled && !mbPageDisabled );
+
+ m_xFlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect );
+
+ m_xFtWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
+ m_xMtrWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
+
+ m_xFtHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
+ m_xMtrHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
+
+ m_xCbxScale->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked && !bWidthChecked );
+ m_xCtlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect && (!bHeightChecked || !bWidthChecked) );
+
+ m_xFlProtect->set_sensitive( !mbProtectDisabled );
+ m_xTsbSizeProtect->set_sensitive( !mbProtectDisabled && !bPosProtect );
+
+ m_xFlAdjust->set_sensitive( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
+
+ m_aCtlSize.Invalidate();
+ m_aCtlPos.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeSizeProtectHdl, weld::Toggleable&, void)
+{
+ if (m_xTsbSizeProtect->get_sensitive())
+ {
+ // #106572# Remember user's last choice
+
+ // Note: this works only as long as the dialog is open. When
+ // the user closes the dialog, there is no way to remember
+ // whether size was enabled or disabled before pos protect was
+ // clicked. Thus, if pos protect is selected, the dialog is
+ // closed and reopened again, unchecking pos protect will
+ // always uncheck size protect, too. That's life.
+ mnProtectSizeState = m_xTsbSizeProtect->get_state();
+ }
+
+ UpdateControlStates();
+}
+
+void SvxPositionSizeTabPage::SetMinMaxPosition()
+{
+ // position
+ double fLeft(maWorkRange.getMinX());
+ double fTop(maWorkRange.getMinY());
+ double fRight(maWorkRange.getMaxX());
+ double fBottom(maWorkRange.getMaxY());
+
+ switch (m_aCtlPos.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ fRight -= maRange.getWidth();
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::MT:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::RT:
+ {
+ fLeft += maRange.getWidth();
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::LM:
+ {
+ fRight -= maRange.getWidth();
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::MM:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::RM:
+ {
+ fLeft += maRange.getWidth();
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::LB:
+ {
+ fRight -= maRange.getWidth();
+ fTop += maRange.getHeight();
+ break;
+ }
+ case RectPoint::MB:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fTop += maRange.getHeight();
+ break;
+ }
+ case RectPoint::RB:
+ {
+ fLeft += maRange.getWidth();
+ fTop += maRange.getHeight();
+ break;
+ }
+ }
+
+ const double fMaxLong(vcl::ConvertValue(std::numeric_limits<sal_Int64>::max(), 0, MapUnit::Map100thMM, meDlgUnit) - 1);
+ fLeft = std::clamp(fLeft, -fMaxLong, fMaxLong);
+ fRight = std::clamp(fRight, -fMaxLong, fMaxLong);
+ fTop = std::clamp(fTop, - fMaxLong, fMaxLong);
+ fBottom = std::clamp(fBottom, -fMaxLong, fMaxLong);
+
+ // #i75273# normalizing when setting the min/max values was wrong, removed
+ m_xMtrPosX->set_range(basegfx::fround64(fLeft), basegfx::fround64(fRight), FieldUnit::NONE);
+ m_xMtrPosY->set_range(basegfx::fround64(fTop), basegfx::fround64(fBottom), FieldUnit::NONE);
+
+ // size
+ fLeft = maWorkRange.getMinX();
+ fTop = maWorkRange.getMinY();
+ fRight = maWorkRange.getMaxX();
+ fBottom = maWorkRange.getMaxY();
+ double fNewX(0);
+ double fNewY(0);
+
+ switch (m_aCtlSize.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
+ break;
+ }
+ case RectPoint::MM:
+ {
+ const double f1(maRange.getCenter().getX() - fLeft);
+ const double f2(fRight - maRange.getCenter().getX());
+ const double f3(std::min(f1, f2));
+ const double f4(maRange.getCenter().getY() - fTop);
+ const double f5(fBottom - maRange.getCenter().getY());
+ const double f6(std::min(f4, f5));
+
+ fNewX = f3 * 2.0;
+ fNewY = f6 * 3.0;
+
+ break;
+ }
+ case RectPoint::RM:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
+ break;
+ }
+ case RectPoint::LB:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
+ fNewY = maWorkRange.getHeight() - ( maRange.getMaxY() - fBottom );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
+ break;
+ }
+ }
+
+ // #i75273# normalizing when setting the min/max values was wrong, removed
+ m_xMtrWidth->set_max(basegfx::fround64(fNewX), FieldUnit::NONE);
+ m_xMtrHeight->set_max(basegfx::fround64(fNewY), FieldUnit::NONE);
+}
+
+void SvxPositionSizeTabPage::GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange)
+{
+ switch (m_aCtlPos.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ break;
+ }
+ case RectPoint::MT:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ break;
+ }
+ case RectPoint::RT:
+ {
+ rfX -= rRange.getWidth();
+ break;
+ }
+ case RectPoint::LM:
+ {
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::MM:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::RM:
+ {
+ rfX -= rRange.getWidth();
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::LB:
+ {
+ rfY -= rRange.getHeight();
+ break;
+ }
+ case RectPoint::MB:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ rfY -= rRange.getHeight();
+ break;
+ }
+ case RectPoint::RB:
+ {
+ rfX -= rRange.getWidth();
+ rfY -= rRange.getHeight();
+ break;
+ }
+ }
+}
+
+void SvxPositionSizeTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
+{
+ if (pDrawingArea == m_aCtlPos.GetDrawingArea())
+ {
+ SetMinMaxPosition();
+ switch( eRP )
+ {
+ case RectPoint::LT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ }
+ }
+ else
+ {
+ meRP = eRP;
+ SetMinMaxPosition();
+ }
+}
+
+void SvxPositionSizeTabPage::DisableResize()
+{
+ mbSizeDisabled = true;
+}
+
+
+void SvxPositionSizeTabPage::DisableProtect()
+{
+ mbProtectDisabled = true;
+}
+
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeWidthHdl, weld::MetricSpinButton&, void)
+{
+ if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
+ return;
+
+ sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(m_xMtrWidth->get_value(FieldUnit::NONE))) / mfOldWidth));
+ sal_Int64 nMin, nMax;
+ m_xMtrHeight->get_range(nMin, nMax, FieldUnit::NONE);
+
+ if (nHeight <= nMax)
+ {
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+ else
+ {
+ nHeight = nMax;
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+
+ const sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(nHeight)) / mfOldHeight));
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeHeightHdl, weld::MetricSpinButton&, void)
+{
+ if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
+ return;
+
+ sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(m_xMtrHeight->get_value(FieldUnit::NONE))) / mfOldHeight));
+ sal_Int64 nMin, nMax;
+ m_xMtrWidth->get_range(nMin, nMax, FieldUnit::NONE);
+
+ if (nWidth <= nMax)
+ {
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+ }
+ else
+ {
+ nWidth = nMax;
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+
+ const sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(nWidth)) / mfOldWidth));
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickSizeProtectHdl, weld::Toggleable&, void)
+{
+ UpdateControlStates();
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickAutoHdl, weld::Toggleable&, void)
+{
+ if (m_xCbxScale->get_active())
+ {
+ mfOldWidth = std::max( static_cast<double>(GetCoreValue( *m_xMtrWidth, mePoolUnit )), 1.0 );
+ mfOldHeight = std::max( static_cast<double>(GetCoreValue( *m_xMtrHeight, mePoolUnit )), 1.0 );
+ }
+}
+
+void SvxPositionSizeTabPage::FillUserData()
+{
+ // matching is saved in the Ini-file
+ OUString aStr = m_xCbxScale->get_active() ? OUString("1") : OUString("0");
+ SetUserData( aStr );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/util/FontFeatures.cxx b/cui/source/util/FontFeatures.cxx
new file mode 100644
index 000000000..f50980aab
--- /dev/null
+++ b/cui/source/util/FontFeatures.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <FontFeatures.hxx>
+
+std::vector<vcl::font::Feature> getFontFeatureList(OUString const& rFontName, VirtualDevice& rVDev)
+{
+ rVDev.SetOutputSizePixel(Size(10, 10));
+
+ vcl::Font aFont = rVDev.GetFont();
+ aFont.SetFamilyName(rFontName);
+ rVDev.SetFont(aFont);
+
+ std::vector<vcl::font::Feature> vFontFeatures;
+
+ if (!rVDev.GetFontFeatures(vFontFeatures))
+ {
+ vFontFeatures.clear();
+ }
+
+ return vFontFeatures;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file
diff --git a/cui/uiconfig/ui/aboutconfigdialog.ui b/cui/uiconfig/ui/aboutconfigdialog.ui
new file mode 100644
index 000000000..1dc4cbd08
--- /dev/null
+++ b/cui/uiconfig/ui/aboutconfigdialog.ui
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text1 -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name text3 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="AboutConfig">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="aboutconfigdialog|AboutConfig">Expert Configuration</property>
+ <property name="modal">True</property>
+ <property name="type_hint">normal</property>
+ <property name="skip_taskbar_hint">True</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="aboutconfigdialog|edit">Edit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|edit">Opens a dialog to edit the preference.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="aboutconfigdialog|reset">Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="reset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|reset">Undo changes done so far in this dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="searchEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="searchEntry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|searchEntry">Type the preference you want to display in the text area</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="searchButton">
+ <property name="label" translatable="yes" context="aboutconfigdialog|searchButton">_Search</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="searchButton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|searchButton">Click to search your preference text in the Preferences tree.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="preferences">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="aboutconfigdialog|preference">Preference Name</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="aboutconfigdialog|property">Property</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext3"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="aboutconfigdialog|type">Type</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="aboutconfigdialog|value">Value</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="text">4</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preferences-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|preferences">List the preferences organized hierarchically in a tree layout.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="102">edit</action-widget>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/aboutconfigvaluedialog.ui b/cui/uiconfig/ui/aboutconfigvaluedialog.ui
new file mode 100644
index 000000000..e4c33bc4d
--- /dev/null
+++ b/cui/uiconfig/ui/aboutconfigvaluedialog.ui
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="AboutConfigValueDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="aboutconfigvaluedialog|AboutConfigValueDialog">Name</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="aboutconfigvaluedialog|label1">Value:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">valuebox</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="valuebox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="width_chars">50</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/aboutdialog.ui b/cui/uiconfig/ui/aboutdialog.ui
new file mode 100644
index 000000000..80e975055
--- /dev/null
+++ b/cui/uiconfig/ui/aboutdialog.ui
@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="imCopy">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">edit-copy</property>
+ </object>
+ <object class="GtkDialog" id="AboutDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="aboutdialog|AboutDialog">About %PRODUCTNAME</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can-focus">False</property>
+ <property name="margin-top">12</property>
+ <property name="hexpand">True</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="btnClose">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=7 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkImage" id="imAbout">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">24</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="height">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="imBrand">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="margin-top">24</property>
+ <property name="margin-bottom">24</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=6 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="lbVersion">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbVersion">Version:</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="lbVersionString"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbBuild">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbBuild">Build:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="lbBuildString"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbEnvironment">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbEnvironment">Environment:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="lbEnvString"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbVersionString">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">7.0</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">40</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbVersion"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbEnvString">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">8 cores</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">40</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbEnvironment"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="lbBuildString">
+ <property name="label">0815</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbBuild"/>
+ </accessibility>
+ <style>
+ <class name="small-button"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbMisc">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbExtra">Misc:</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="lbMiscString"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbMiscString">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">Calc</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">40</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbMisc"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbLocale">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbLocale">Locale:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="lbLocaleString"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbLocaleString">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">English</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">40</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbLocale"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbUI">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbUI">User Interface:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="lbUIString"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbUIString">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label">VCL: gtk</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">40</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbUI"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAbout">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label" translatable="yes" context="aboutdialog|description">%PRODUCTNAME is a modern, easy-to-use, open source productivity suite for word processing, spreadsheets, presentations and more.</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">60</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCopyright">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label" context="aboutdialog|copyright">%COPYRIGHT</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">60</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLinkButton" id="btnCredits">
+ <property name="label" translatable="yes" context="aboutdialog|credits">Credits</property>
+ <property name="name">lbCredit</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="btnWebsite">
+ <property name="label" translatable="yes" context="aboutdialog|website">Website</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ <property name="uri">https://www.libreoffice.org/</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="btnReleaseNotes">
+ <property name="label" translatable="yes" context="aboutdialog|releasenotes">Release Notes</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="lbVersionInfo">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="aboutdialog|lbVersionInfo">Version Information</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">btnCopyVersion</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCopyVersion">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="aboutdialog|btnCopyVersionTooltip">Copy all version information in English</property>
+ <property name="image">imCopy</property>
+ <property name="always-show-image">True</property>
+ <accelerator key="c" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">btnClose</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/accelconfigpage.ui b/cui/uiconfig/ui/accelconfigpage.ui
new file mode 100644
index 000000000..f64eec364
--- /dev/null
+++ b/cui/uiconfig/ui/accelconfigpage.ui
@@ -0,0 +1,581 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name weight1 -->
+ <column type="gint"/>
+ <!-- column-name weight2 -->
+ <column type="gint"/>
+ <!-- column-name sensitive1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore4">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkGrid" id="AccelConfigPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="shortcuts">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="accelconfigpage|tooltip|shortcuts">To quickly find a shortcut in this list, simply press the key combination.</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="sensitive">5</attribute>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="shortcuts-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|shortcuts">Lists the shortcut keys and the associated commands. To assign or modify the shortcut key for the command selected in the Function list, click a shortcut in this list, and then click Modify.
+To quickly find a shortcut in this list, simply press the key combination.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="accelconfigpage|label21">Shortcu_t Keys</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">shortcuts</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box17">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box18">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="office">
+ <property name="label" translatable="yes" context="accelconfigpage|office">%PRODUCTNAME</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="office-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|office">Displays shortcut keys that are common to all the office suite applications.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="module">
+ <property name="label" translatable="yes" context="accelconfigpage|module">$(MODULE)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">office</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="module-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|module">Displays shortcut keys for the current office suite application.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="change">
+ <property name="label" translatable="yes" context="accelconfigpage|change">_Modify</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="change-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|change">Assigns the key combination selected in the Shortcut keys list to the command selected in the Function list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|delete">Deletes the selected element or elements without requiring confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="load">
+ <property name="label" translatable="yes" context="accelconfigpage|load">_Load...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="load-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|load">Replaces the shortcut key configuration with one that was previously saved.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="save">
+ <property name="label" translatable="yes" context="accelconfigpage|save">_Save...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="save-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|save">Saves the current shortcut key configuration, so that you can load it later.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="accelconfigpage|tooltip|reset">Unsaved modifications to shortcut keys are reverted.</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="reset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|reset">Revert any changes made to keyboard shortcuts to the assignments that were present when this dialog was opened.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkEntry" id="searchEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_bottom">5</property>
+ <property name="placeholder_text" translatable="yes" context="accelconfigpage|searchEntry">Type to search</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="searchEntry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|searchEntry">Type here to search in the list of functions.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label23">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="accelconfigpage|label23">_Category</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">category</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label24">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="accelconfigpage|label24">_Function</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">function</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="accelconfigpage|label25">_Keys</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">keys</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="category">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="category-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|category">Lists the available function categories. To assign shortcuts to Styles, open the "Styles" category.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="function">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection3"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="function-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|function">Select a function that you want to assign a shortcut key to, click a key combination in the Shortcut keys list, and then click Modify. If the selected function already has a shortcut key, it is displayed in the Keys list.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="keys">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore4</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection4"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn6">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer7"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="keys-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|keys">Displays the shortcut keys that are assigned to the selected function.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="accelconfigpage|label22">F_unctions</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">searchEntry</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AccelConfigPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="accelconfigpage|extended_tip|AccelConfigPage">Assigns or edits the shortcut keys for the office suite commands, or Basic macros.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/acorexceptpage.ui b/cui/uiconfig/ui/acorexceptpage.ui
new file mode 100644
index 000000000..e5c681c35
--- /dev/null
+++ b/cui/uiconfig/ui/acorexceptpage.ui
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="AcorExceptPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkEntry" id="abbrev">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="abbrev-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|abbrev">Type an abbreviation followed by a period, and then click New. This prevents automatic capitalization of the first letter of the word that comes after the period at the end of the abbreviation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autoabbrev">
+ <property name="label" translatable="yes" context="acorexceptpage|autoabbrev">Auto_Include</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="tooltip_text" translatable="yes" context="acorexceptpage|autoabbrev">Automatically add to the exception list if autocorrection is immediately undone.</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autoabbrev-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|autoabbrev">Adds autocorrected abbreviations to the list of exceptions, if the autocorrection is immediately undone. This feature is only effective when Capitalize first letter of every sentence option is selected in the [T] column on the Options tab of this dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="newabbrev">
+ <property name="label" translatable="yes" context="stock">_New</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newabbrev-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|newabbrev-atkobject">New abbreviations</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replace">
+ <property name="label" translatable="yes" context="acorexceptpage|replace">_Replace</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delabbrev">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">start</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delabbrev-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|delabbrev-atkobject">Delete abbreviations</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="abbrevlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="abbrevlist-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|abbrevlist">Lists the abbreviations that are not automatically corrected.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="acorexceptpage|label1">Abbreviations (no Subsequent Capital)</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkEntry" id="double">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="double-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|double">Type the word or abbreviation that starts with two capital letters or a small initial that you do not want automatically changed to one initial capital. For example, enter PC to prevent a change from PC to Pc, or enter eBook to prevent a change to Ebook.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autodouble">
+ <property name="label" translatable="yes" context="acorexceptpage|autodouble">A_utoInclude</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="tooltip_text" translatable="yes" context="acorexceptpage|autodouble">Automatically add to the exception list if autocorrection is immediately undone.</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autodouble-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|autodouble">Adds autocorrected words that start with two capital letters to the list of exceptions, if the autocorrection is immediately undone. This feature is only effective if the Correct TWo INitial CApitals option is selected in the [T] column on the Options tab of this dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="newdouble">
+ <property name="label" translatable="yes" context="stock">_New</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newdouble-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|newdouble-atkobject">New words with two initial capitals or small initial</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replace1">
+ <property name="label" translatable="yes" context="acorexceptpage|replace1">_Replace</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="deldouble">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">start</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="deldouble-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|deldouble-atkobject">Delete words with two initial capitals or small initial</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="doublelist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="doublelist-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|doublelist">Lists the words or abbreviations that start with two initial capitals that are not automatically corrected. All words which start with two capital letters are listed in the field.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="acorexceptpage|label2">Words With TWo INitial CApitals or sMALL iNITIAL</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AcorExceptPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorexceptpage|extended_tip|AcorExceptPage">Specify the abbreviations or letter combinations that you do not want corrected automatically.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="newabbrev"/>
+ <widget name="replace"/>
+ <widget name="delabbrev"/>
+ <widget name="newdouble"/>
+ <widget name="replace1"/>
+ <widget name="deldouble"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/acoroptionspage.ui b/cui/uiconfig/ui/acoroptionspage.ui
new file mode 100644
index 000000000..711ff0675
--- /dev/null
+++ b/cui/uiconfig/ui/acoroptionspage.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="AutocorrectOptionsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="checklist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AutocorrectOptionsPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acoroptionspage|extended_tip|AutocorrectOptionsPage">Select the options for automatically correcting errors as you type, and then click OK.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/acorreplacepage.ui b/cui/uiconfig/ui/acorreplacepage.ui
new file mode 100644
index 000000000..48015f822
--- /dev/null
+++ b/cui/uiconfig/ui/acorreplacepage.ui
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkListStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="AcorReplacePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkBox" id="buttonbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="new">
+ <property name="label" translatable="yes" context="stock">_New</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="new-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|new">Adds or replaces an entry in the replacement table.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replace">
+ <property name="label" translatable="yes" context="acorreplacepage|replace">_Replace</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|replace">Adds or replaces an entry in the replacement table.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|delete">Deletes the selected element or elements without requiring confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="tabview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="fixed_height_mode">True</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="sizing">fixed</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="sizing">fixed</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="tabview-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|tabview">Lists the entries for automatically replacing words, abbreviations or word parts while you type. To add an entry, enter text in the Replace and With boxes, and then click New. To edit an entry, select it, change the text in the With box, and then click Replace. To delete an entry, select it, and then click Delete.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="newtext">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="width_chars">25</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newtext-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|newtext">Enter the replacement text, graphic, frame, or OLE object that you want to replace the text in the Replace box. If you have selected text, a graphic, a frame, or an OLE object in your document, the relevant information is already entered here.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="origtext">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="width_chars">25</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="origtext-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|origtext">Enter the word, abbreviation or word part that you want to replace while you type. Wildcard character sequence .* in the end of word results the replacement of the word before arbitrary suffixes, too. Wildcard character sequence .* before the word results the replacement after arbitrary prefixes, too. For example, the pattern "i18n.*" with the replacement text "internationalization" finds and replaces "i18ns" with "internationalizations", or the pattern ".*..." with the replacement text "…" finds and replaces three dots in "word..." with the typographically correct precomposed Unicode horizontal ellipsis ("word…").</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="acorreplacepage|label1">Repla_ce</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">origtext</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="acorreplacepage|label2">_With</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">newtext</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="textonly">
+ <property name="label" translatable="yes" context="acorreplacepage|textonly">_Text only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="textonly-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|textonly">Saves the entry in the With box without formatting. When the replacement is made, the text uses the same format as the document text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AcorReplacePage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="acorreplacepage|extended_tip|AcorReplacePage">Edits the replacement table for automatically correcting or replacing words or abbreviations in your document.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/additionsdialog.ui b/cui/uiconfig/ui/additionsdialog.ui
new file mode 100644
index 000000000..aa8970c90
--- /dev/null
+++ b/cui/uiconfig/ui/additionsdialog.ui
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMenu" id="additionsmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkCheckMenuItem" id="gear_activeVersionOnly">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customanimationfragment|90">Active version only</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="gear_separator1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="sort">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|gallery">Sort by</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="sortSubMenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkRadioMenuItem" id="gear_sort_voting">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_textOnly">Voting</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">gear_sort_downloads</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="gear_sort_downloads">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_textOnly">Downloads</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">gear_sort_voting</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="gear_sort_comments">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_textOnly">Comments</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">gear_sort_voting</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="gear_separator2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="gear_detailView">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_iconAndText">Detail view</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">gear_condensedList</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="gear_condensedList">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_iconAndText">Condensed list</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">gear_detailView</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkImage" id="imageGear">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ </object>
+ <object class="GtkDialog" id="AdditionsDialog">
+ <property name="width_request">550</property>
+ <property name="height_request">600</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="additionsdialog|AdditionsDialog">Additions</property>
+ <property name="modal">True</property>
+ <property name="default_width">300</property>
+ <property name="default_height">400</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkBox">
+ <property name="width_request">200</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="labelProgress">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="additionsdialog|ProgressLabel">Progress Label</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="labelProgress-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="additionsdialog|ProgressLabel">ProgressLabel</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="additionsdialog|ProgressLabel">This label shows that the progress of the operations such as loading extensions, not found, etc.</property>
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="buttonClose">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">end</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entrySearch">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">50</property>
+ <property name="max_width_chars">50</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entrySearch-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="additionsdialog|searchEntry">searchEntry</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="additionsdialog|searchEntry">searchEntry</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="buttonGear">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="margin-start">1</property>
+ <property name="image">imageGear</property>
+ <property name="always_show_image">True</property>
+ <property name="popup">additionsmenu</property>
+ <property name="use_popover">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="buttonGear-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="additionsdialog|buttonGear">Gear Menu</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="additionsdialog|buttonGear">Contains commands to modify settings of the additions list such as sorting type or view type.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="contentWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="contentGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">buttonClose</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/additionsfragment.ui b/cui/uiconfig/ui/additionsfragment.ui
new file mode 100644
index 000000000..143c7c446
--- /dev/null
+++ b/cui/uiconfig/ui/additionsfragment.ui
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="additionsEntry">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="row-spacing">24</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkButton" id="buttonShowMore">
+ <property name="label" translatable="yes" context="additionsDialog|buttonShowMore">Show More Extensions</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="buttonShowMore-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="additionsDialog|buttonShowMore">ButtonShowMore</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="additionsDialog|buttonShowMore">This button shows more extensions.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=8 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="labelDescription">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="margin-bottom">3</property>
+ <property name="label">description</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">word-char</property>
+ <property name="width-chars">40</property>
+ <property name="max-width-chars">40</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="imageScreenshot"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="votingLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="additionsEntry|votingLabel">Voting:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="imageVoting1"/>
+ <relation type="label-for" target="imageVoting2"/>
+ <relation type="label-for" target="imageVoting3"/>
+ <relation type="label-for" target="imageVoting4"/>
+ <relation type="label-for" target="imageVoting5"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelLicense">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="additionsEntry|labelLicense">License:</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="labelLicense-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelVersion">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="additionsEntry|labelVersion">Required version:</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="labelVersion-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelComments">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="additionsEntry|labelComments">Comments:</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="labelComments-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelComments1">
+ <property name="visible">False</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="additionsEntry|labelComments">Downloads:</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="labelComments1-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelDownloadNumber">
+ <property name="visible">False</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">label</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="labelDownloadNumber-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="linkButtonComments">
+ <property name="label">button</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ <property name="uri">http://glade.gnome.org</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbVersionText">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">label</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lbVersionText-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbLicenseText">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">label</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lbLicenseText-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkImage" id="imageVoting1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="icon-name">cmd/sc_stars-empty.png</property>
+ <accessibility>
+ <relation type="labelled-by" target="votingLabel"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="imageVoting2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="icon-name">cmd/sc_stars-empty.png</property>
+ <accessibility>
+ <relation type="labelled-by" target="votingLabel"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="imageVoting3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="icon-name">cmd/sc_stars-empty.png</property>
+ <accessibility>
+ <relation type="labelled-by" target="votingLabel"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="imageVoting4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="icon-name">cmd/sc_stars-empty.png</property>
+ <accessibility>
+ <relation type="labelled-by" target="votingLabel"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="imageVoting5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="icon-name">cmd/sc_stars-empty.png</property>
+ <accessibility>
+ <relation type="labelled-by" target="votingLabel"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="imageScreenshot">
+ <property name="width-request">180</property>
+ <property name="height-request">120</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="labelled-by" target="labelDescription"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="height">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="buttonInstall">
+ <property name="label" translatable="yes" context="additionsEntry|buttonInstall">Install</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="valign">end</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="btnWebsite">
+ <property name="label" translatable="yes" context="additionsEntry|buttonWebsite">Website</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ <property name="uri">http://glade.gnome.org</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">7</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbName">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-bottom">6</property>
+ <property name="label">Name</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lbName-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/agingdialog.ui b/cui/uiconfig/ui/agingdialog.ui
new file mode 100644
index 000000000..a6c2b24d0
--- /dev/null
+++ b/cui/uiconfig/ui/agingdialog.ui
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="AgingDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="agingdialog|AgingDialog">Aging</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="value">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="value-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="agingdialog|extended_tip|value">Specifies the number of colors to which the image is to be reduced.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="agingdialog|label2">Aging degree:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">value</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="agingdialog|label1">Parameters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AgingDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="agingdialog|extended_tip|AgingDialog">All pixels are set to their gray values, and then the green and blue color channels are reduced by the amount you specify. The red color channel is not changed.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/applyautofmtpage.ui b/cui/uiconfig/ui/applyautofmtpage.ui
new file mode 100644
index 000000000..ad5501926
--- /dev/null
+++ b/cui/uiconfig/ui/applyautofmtpage.ui
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name check2 -->
+ <column type="gboolean"/>
+ <!-- column-name check3 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis2 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis3 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri2 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri3 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="ApplyAutoFmtPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="applyautofmtpage|edit">_Edit...</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applyautofmtpage|extended_tip|edit">Modifies the selected AutoCorrect option.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applyautofmtpage|label1">[M]: Replace while modifying existing text</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applyautofmtpage|label2">[T]: AutoCorrect while typing</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="applyautofmtpage|m">[M]</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer0"/>
+ <attributes>
+ <attribute name="visible">5</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="visible">6</attribute>
+ <attribute name="active">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="applyautofmtpage|t">[T]</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="visible">7</attribute>
+ <attribute name="active">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer3"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ApplyAutoFmtPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applyautofmtpage|extended_tip|ApplyAutoFmtPage">Select the options for automatically correcting errors as you type, and then click OK.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/applylocalizedpage.ui b/cui/uiconfig/ui/applylocalizedpage.ui
new file mode 100644
index 000000000..9cb7842b8
--- /dev/null
+++ b/cui/uiconfig/ui/applylocalizedpage.ui
@@ -0,0 +1,630 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name check2 -->
+ <column type="gboolean"/>
+ <!-- column-name check3 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis2 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis3 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri2 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri3 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="ApplyLocalizedPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="applylocalizedpage|m">[M]</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="visible">5</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer9"/>
+ <attributes>
+ <attribute name="visible">6</attribute>
+ <attribute name="active">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="applylocalizedpage|t">[T]</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="visible">7</attribute>
+ <attribute name="active">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer3"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="list-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|list">Select to apply the replacements while you type [T], or when you modify existing text [M].</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="checklist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checklist-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|checklist">Select to apply the replacements while you type [T], or when you modify existing text [M].</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkCheckButton" id="singlereplace">
+ <property name="label" translatable="yes" context="applylocalizedpage|singlereplace">Repla_ce</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="singlereplace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|singlereplace">Automatically replaces the default system symbol for the given type of quotation marks with the special character that you specify.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="startquoteft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|startquoteft">_Start quote:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">startsingle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="startsingle">
+ <property name="label"> ' </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="startsingle-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="applylocalizedpage|startsingle-atkobject">Start quote of single quotes</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|startsingle">Select the special character that will automatically replace the current opening quotation mark in your document when you choose Tools - AutoCorrect - Apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="singlestartex">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|singlestartex">Default</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="defaultsingle">
+ <property name="label" translatable="yes" context="applylocalizedpage|defaultsingle">_Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="defaultsingle-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="applylocalizedpage|defaultsingle-atkobject">Single quotes default</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|defaultsingle">Resets the quotation marks to the default symbols.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="endquoteft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|endquoteft">_End quote:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">endsingle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="endsingle">
+ <property name="label"> ' </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="endsingle-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="applylocalizedpage|endsingle-atkobject">End quote of single quotes</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|endsingle">Select the special character that will automatically replace the current closing quotation mark in your document when you choose Tools - AutoCorrect - Apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="singleendex">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|singleendex">Default</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|label1">Single Quotes</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkCheckButton" id="doublereplace">
+ <property name="label" translatable="yes" context="applylocalizedpage|doublereplace">Repla_ce</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="doublereplace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|doublereplace">Automatically replaces the default system symbol for the given type of quotation marks with the special character that you specify.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|label6">_Start quote:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">startdouble</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="startdouble">
+ <property name="label"> " </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="startdouble-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="applylocalizedpage|startdouble-atkobject">Start quote of double quotes</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|startdouble">Select the special character that will automatically replace the current opening quotation mark in your document when you choose Tools - AutoCorrect - Apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="doublestartex">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|doublestartex">Default</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="defaultdouble">
+ <property name="label" translatable="yes" context="applylocalizedpage|defaultdouble">_Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="defaultdouble-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="applylocalizedpage|defaultdouble-atkobject">Double quotes default</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|defaultdouble">Resets the quotation marks to the default symbols.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|label8">_End quote:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">enddouble</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="enddouble">
+ <property name="label"> " </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="enddouble-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="applylocalizedpage|enddouble-atkobject">End quote of double quotes</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|enddouble">Select the special character that will automatically replace the current closing quotation mark in your document when you choose Tools - AutoCorrect - Apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="doubleendex">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|doubleendex">Default</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="applylocalizedpage|label10">Double Quotes</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ApplyLocalizedPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="applylocalizedpage|extended_tip|ApplyLocalizedPage">Specify the AutoCorrect options for quotation marks and for options that are specific to the language of the text.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="startsingle"/>
+ <widget name="endsingle"/>
+ <widget name="startdouble"/>
+ <widget name="enddouble"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/areadialog.ui b/cui/uiconfig/ui/areadialog.ui
new file mode 100644
index 000000000..ec9b33759
--- /dev/null
+++ b/cui/uiconfig/ui/areadialog.ui
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="AreaDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="areadialog|AreaDialog">Area</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_AREA">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="areadialog|RID_SVXPAGE_AREA">Area</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_SHADOW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="areadialog|RID_SVXPAGE_SHADOW">Shadow</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_TRANSPARENCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="areadialog|RID_SVXPAGE_TRANSPARENCE">Transparency</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AreaDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areadialog|extended_tip|AreaDialog">Sets the fill properties of the selected drawing object.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/areatabpage.ui b/cui/uiconfig/ui/areatabpage.ui
new file mode 100644
index 000000000..4555c0df0
--- /dev/null
+++ b/cui/uiconfig/ui/areatabpage.ui
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="AreaTabPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="margin-top">3</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkComboBoxText" id="tablelb">
+ <property name="can-focus">False</property>
+ <property name="active">0</property>
+ <items>
+ <item id="cellid" translatable="yes" context="areatabpage|tablelb">Cell</item>
+ <item id="rowid" translatable="yes" context="areatabpage|tablelb">Row</item>
+ <item id="tableid" translatable="yes" context="areatabpage|tablelb">Table</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="tablelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|tablelb">Set the fill options for the selected drawing object or document element.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btnnone">
+ <property name="label" translatable="yes" context="areatabpage|btnnone">None</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btnnone-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btnnone">Do not fill the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btncolor">
+ <property name="label" translatable="yes" context="areatabpage|btncolor">Color</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btncolor-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btncolor">Fills the object with a color selected on this page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btngradient">
+ <property name="label" translatable="yes" context="areatabpage|btngradient">Gradient</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btngradient-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btngradient">Fills the object with a gradient selected on this page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btnbitmap">
+ <property name="label" translatable="yes" context="areatabpage|btnbitmap">Image</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btnbitmap-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btnbitmap">Fills the object with a bitmap image selected on this page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btnpattern">
+ <property name="label" translatable="yes" context="areatabpage|btnpattern">Pattern</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btnpattern-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btnpattern">Fills the object with a dot pattern selected on this page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btnhatch">
+ <property name="label" translatable="yes" context="areatabpage|btnhatch">Hatch</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btnhatch-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btnhatch">Fills the object with a hatching pattern selected on this page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="btnusebackground">
+ <property name="label" translatable="yes" context="areatabpage|btnusebackground">Use Background</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btnusebackground-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|btnusebackground">Displays the underlying slide background.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="fillstylebox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AreaTabPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="areatabpage|extended_tip|AreaTabPage">Set the fill options for the selected drawing object or document element.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/asiantypography.ui b/cui/uiconfig/ui/asiantypography.ui
new file mode 100644
index 000000000..6f7db08e9
--- /dev/null
+++ b/cui/uiconfig/ui/asiantypography.ui
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="AsianTypography">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkForbidList">
+ <property name="label" translatable="yes" context="asiantypography|checkForbidList">Apply list of forbidden characters to the beginning and end of lines</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkHangPunct">
+ <property name="label" translatable="yes" context="asiantypography|checkHangPunct">Allow hanging punctuation</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkApplySpacing">
+ <property name="label" translatable="yes" context="asiantypography|checkApplySpacing">Apply spacing between Asian and non-Asian text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelLineChange">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="asiantypography|labelLineChange">Line Change</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/assigncomponentdialog.ui b/cui/uiconfig/ui/assigncomponentdialog.ui
new file mode 100644
index 000000000..6977373ad
--- /dev/null
+++ b/cui/uiconfig/ui/assigncomponentdialog.ui
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="AssignComponent">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="assigncomponentdialog|AssignComponent">Assign Component</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="assigncomponentdialog|label1">Component method name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">methodEntry</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="methodEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/autocorrectdialog.ui b/cui/uiconfig/ui/autocorrectdialog.ui
new file mode 100644
index 000000000..80b354c97
--- /dev/null
+++ b/cui/uiconfig/ui/autocorrectdialog.ui
@@ -0,0 +1,519 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="AutoCorrectDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="autocorrectdialog|AutoCorrectDialog">AutoCorrect</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="reset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="autocorrectdialog|extended_tip|reset">Resets modified values back to the tab page previous values.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ok-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="autocorrectdialog|extended_tip|ok">Saves all changes and closes dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cancel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="autocorrectdialog|extended_tip|cancel">Closes dialog and discards all changes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="langbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|label1">Replacements and exceptions for language:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">lang</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="lang">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lang-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="autocorrectdialog|extended_tip|lang">Select the language for which you want to create or edit the replacement rules.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="replace">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|replace">Replace</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="exceptions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|exceptions">Exceptions</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="options">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|options">Options</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="applypage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|apply">Options</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="localized">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|localized">Localized Options</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="wordcompletion">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|wordcompletion">Word Completion</property>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="smarttags">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="autocorrectdialog|smarttags">Smart Tags</property>
+ </object>
+ <packing>
+ <property name="position">6</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/baselinksdialog.ui b/cui/uiconfig/ui/baselinksdialog.ui
new file mode 100644
index 000000000..14e46c20c
--- /dev/null
+++ b/cui/uiconfig/ui/baselinksdialog.ui
@@ -0,0 +1,429 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name text3 -->
+ <column type="gchararray"/>
+ <!-- column-name text4 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="BaseLinksDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="baselinksdialog|BaseLinksDialog">Edit Links</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="CHANGE_SOURCE">
+ <property name="label" translatable="yes" context="baselinksdialog|CHANGE_SOURCE">_Modify...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CHANGE_SOURCE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|CHANGE_SOURCE">Change the source file for the selected link.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BREAK_LINK">
+ <property name="label" translatable="yes" context="baselinksdialog|BREAK_LINK">_Break Link</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BREAK_LINK-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|BREAK_LINK">Breaks the link between the source file and the current document. The most recently updated contents of the source file are kept in the current document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="UPDATE_NOW">
+ <property name="label" translatable="yes" context="baselinksdialog|UPDATE_NOW">_Update</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="UPDATE_NOW-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|UPDATE_NOW">Updates the selected link so that the most recently saved version of the linked file is displayed in the current document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="TB_LINKS">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn0">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="baselinksdialog|FILES">Source file</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer0"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="baselinksdialog|LINKS">Element</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="baselinksdialog|TYPE">Type</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="baselinksdialog|STATUS">Status</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer3"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TB_LINKS-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|TB_LINKS">Double-click a link in the list to open a file dialog where you can select another object for this link.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FILES2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="baselinksdialog|FILES2">Source file</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">TB_LINKS</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="SOURCE2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="baselinksdialog|SOURCE2">Element:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="TYPE2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="baselinksdialog|TYPE2">Type:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="UPDATE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="baselinksdialog|UPDATE">Update:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box_hexpand">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLinkButton" id="FULL_FILE_NAME">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FULL_SOURCE_NAME">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FULL_TYPE_NAME">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="AUTOMATIC">
+ <property name="label" translatable="yes" context="baselinksdialog|AUTOMATIC">_Automatic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="AUTOMATIC-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|AUTOMATIC">Automatically updates the contents of the link when you open the file. Any changes made in the source file are then displayed in the file containing the link. Linked graphic files can only be updated manually.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="MANUAL">
+ <property name="label" translatable="yes" context="baselinksdialog|MANUAL">Ma_nual</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">AUTOMATIC</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MANUAL-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|MANUAL">Only updates the link when you click the Update button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-7">close</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BaseLinksDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="baselinksdialog|extended_tip|BaseLinksDialog">Lets you edit the properties of each link in the current document, including the path to the source file. This command is not available if the current document does not contain links to other files.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/borderareatransparencydialog.ui b/cui/uiconfig/ui/borderareatransparencydialog.ui
new file mode 100644
index 000000000..7be5710ac
--- /dev/null
+++ b/cui/uiconfig/ui/borderareatransparencydialog.ui
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="BorderAreaTransparencyDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="borderareatransparencydialog|BorderAreaTransparencyDialog">Border / Background</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="borders">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="borderareatransparencydialog|borders">Borders</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="area">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="borderareatransparencydialog|area">Area</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="transparence">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="borderareatransparencydialog|transparence">Transparency</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">reset</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/borderbackgrounddialog.ui b/cui/uiconfig/ui/borderbackgrounddialog.ui
new file mode 100644
index 000000000..fb9a2e46c
--- /dev/null
+++ b/cui/uiconfig/ui/borderbackgrounddialog.ui
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="BorderBackgroundDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="borderbackgrounddialog|BorderBackgroundDialog">Border / Background</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="borders">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="borderbackgrounddialog|borders">Borders</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="background">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="borderbackgrounddialog|background">Background</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">reset</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/borderpage.ui b/cui/uiconfig/ui/borderpage.ui
new file mode 100644
index 000000000..af57dbcb0
--- /dev/null
+++ b/cui/uiconfig/ui/borderpage.ui
@@ -0,0 +1,739 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">0.05</property>
+ <property name="upper">9</property>
+ <property name="value">0.05</property>
+ <property name="step-increment">0.25</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">50</property>
+ <property name="step-increment">0.10</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">0.5</property>
+ <property name="upper">50</property>
+ <property name="step-increment">0.10</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="upper">50</property>
+ <property name="step-increment">0.10</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="upper">50</property>
+ <property name="step-increment">0.10</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="upper">50</property>
+ <property name="step-increment">0.10</property>
+ <property name="page-increment">1</property>
+ </object>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="BorderPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="row-spacing">12</property>
+ <property name="column-spacing">24</property>
+ <child>
+ <object class="GtkFrame" id="arrangement">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=5 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="frameselwin">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="framesel">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="userdefft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="tooltip-text" translatable="yes" context="borderpage|userdefft">Click edge or corner to cycle through three states: set, unchanged, remove.</property>
+ <property name="label" translatable="yes" context="borderpage|userdefft">_User-defined:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">framesel</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="borderpage|label14">Pr_esets:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">presets</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="presets">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="rmadjcellbordersft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|rmadjcellbordersft">_Adjacent Cells:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">rmadjcellborders</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="rmadjcellborders">
+ <property name="label" translatable="yes" context="borderpage|rmadjcellborders">Remove border</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label8">Line Arrangement</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="Line">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label15">St_yle:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">linestylelb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label16">_Width:</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="linewidthlb"/>
+ <relation type="label-for" target="linewidthmf"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label17">_Color:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">linecolorlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="linestylelb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="linecolorlb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkComboBoxText" id="linewidthlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">False</property>
+ <items>
+ <item id="0" translatable="yes" context="borderpage|linewidthlb">Hairline (0.05pt)</item>
+ <item id="1" translatable="yes" context="borderpage|linewidthlb">Very thin (0.5pt)</item>
+ <item id="2" translatable="yes" context="borderpage|linewidthlb">Thin (0.75pt)</item>
+ <item id="3" translatable="yes" context="borderpage|linewidthlb">Medium (1.5pt)</item>
+ <item id="4" translatable="yes" context="borderpage|linewidthlb">Thick (2.25pt)</item>
+ <item id="5" translatable="yes" context="borderpage|linewidthlb">Extra thick (4.5pt)</item>
+ <item id="6" translatable="yes" context="borderpage|linewidthlb">Custom</item>
+ </items>
+ <accessibility>
+ <relation type="labelled-by" target="label16"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="linewidthmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="value">0.05</property>
+ <accessibility>
+ <relation type="labelled-by" target="label16"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label9">Line</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="padding">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=5 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="leftmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="valign">center</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="topmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment5</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="rightmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="bottommf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="leftft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="borderpage|leftft">_Left:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">leftmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="rightft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|rightft">Right:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">rightmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="topft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|topft">_Top:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">topmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bottomft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|bottomft">_Bottom:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">bottommf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="sync">
+ <property name="label" translatable="yes" context="borderpage|sync">Synchronize</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label10">Padding</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="shadow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkDrawingArea" id="shadows">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label22">_Position:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">shadows</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="distanceft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="tooltip-text" translatable="yes" context="borderpage|distanceft">Width of shadow</property>
+ <property name="label" translatable="yes" context="borderpage|distanceft">Distan_ce:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">distancemf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="distancemf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="value">0.5</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="shadowcolorft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|shadowcolorft">C_olor:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">shadowcolorlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="shadowcolorlb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label11">Shadow Style</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="properties">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="mergewithnext">
+ <property name="label" translatable="yes" context="borderpage|mergewithnext">_Merge with next paragraph</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="tooltip-text" translatable="yes" context="borderpage|mergewithnext">Merge indent, border and shadow style of current paragraph with next paragraph, if they are the same.</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="mergeadjacent">
+ <property name="label" translatable="yes" context="borderpage|mergeadjacent">_Merge adjacent line styles</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="borderpage|label12">Properties</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel1">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="label14"/>
+ <widget name="label15"/>
+ <widget name="label16"/>
+ <widget name="label17"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel2">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="leftft"/>
+ <widget name="rightft"/>
+ <widget name="topft"/>
+ <widget name="bottomft"/>
+ <widget name="label22"/>
+ <widget name="shadowcolorft"/>
+ <widget name="distanceft"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupVertical1">
+ <property name="mode">vertical</property>
+ <widgets>
+ <widget name="label14"/>
+ <widget name="leftft"/>
+ <widget name="leftmf"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupVertical2">
+ <property name="mode">vertical</property>
+ <widgets>
+ <widget name="label15"/>
+ <widget name="linestylelb"/>
+ <widget name="label22"/>
+ <widget name="shadows"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupWidgets">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="presets"/>
+ <widget name="frameselwin"/>
+ <widget name="linestylelb"/>
+ <widget name="linecolorlb"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/breaknumberoption.ui b/cui/uiconfig/ui/breaknumberoption.ui
new file mode 100644
index 000000000..71fa24cb7
--- /dev/null
+++ b/cui/uiconfig/ui/breaknumberoption.ui
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">2</property>
+ <property name="upper">9</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">2</property>
+ <property name="upper">9</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">2</property>
+ <property name="upper">9</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="BreakNumberOption">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="breaknumberoption|BreakNumberOption">Hyphenation</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="beforeframe">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkSpinButton" id="beforebreak">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="beforebreak-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="beforebreak">Sets the minimum number of characters of the word to be hyphenated that must remain at the end of the line.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="beforelabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="breaknumberoption|beforelabel">Characters Before Break</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="afterframe">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkSpinButton" id="afterbreak">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="afterbreak-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="afterbreak">Specifies the minimum number of characters of a hyphenated word required at the next line.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="afterlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="breaknumberoption|afterlabel">Characters After Break</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="miniframe">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkSpinButton" id="wordlength">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="wordlength-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordlength">Specifies the minimum number of characters required for automatic hyphenation to be applied.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="minimallabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="breaknumberoption|minimallabel">Minimal Word Length</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/bulletandposition.ui b/cui/uiconfig/ui/bulletandposition.ui
new file mode 100644
index 000000000..573babf76
--- /dev/null
+++ b/cui/uiconfig/ui/bulletandposition.ui
@@ -0,0 +1,1150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">19.989999999999998</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">65535</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">1</property>
+ <property name="upper">400</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="upper">19.989999999999998</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="lower">-19.989999999999998</property>
+ <property name="upper">19.989999999999998</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment7">
+ <property name="upper">19.989999999999998</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkMenu" id="bitmapmenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="fromfile">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|fromfile">From file...</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="gallery">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|gallery">Gallery</property>
+ <property name="use-underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="gallerysubmenu">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">cmd/sc_alignleft.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">cmd/sc_alignhorizontalcenter.png</property>
+ </object>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">cmd/sc_alignright.png</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="BulletAndPosition">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="bulletandposition|DrawPRTLDialog">Bullets and Numbering</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="NumberingOptionsPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="margin-top">6</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="levellb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <property name="width-request">75</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|label1">Level</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="properties">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <!-- n-columns=2 n-rows=5 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|label4">Type:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">numfmtlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="numfmtlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numfmtlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|numfmtlb">Select the level(s) that you want to modify. To apply the options to all the levels, select “1-10”.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="startatft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|startatft">Start at:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">startat</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="startat">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates-default">True</property>
+ <property name="text" translatable="yes" context="bulletandposition|startat">1</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="value">1</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="startat-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|startat">For ordered lists, select the value of first item of the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bulletft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|bulletft">Character:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">bullet</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="bullet">
+ <property name="label" translatable="yes" context="bulletandposition|bullet">Select...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="bullet-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|bullet">Select the character for the unordered list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="bitmap">
+ <property name="label" translatable="yes" context="bulletandposition|bitmap">Select image...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="popup">bitmapmenu</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="bitmap-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|bitmap">Select a graphic bullet.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="colorft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|colorft">Color:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">color</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="color">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="color-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|color">Select the color of the list characters for ordered and unordered lists.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|label2">Properties</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="beforeafter">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="prefixft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|prefixft">Before:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">prefix</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="suffixft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|suffixft">After:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">suffix</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="suffix">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="suffix-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|suffix">Enter the text to display after the numbering.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="prefix">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="prefix-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|prefix">Enter the text to display before the numbering.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="beforeafter1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|beforeafter">Separator</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="colorb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkBox" id="whbox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="widthft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|widthft">Width:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">widthmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="heightft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|heightft">Height:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">heightmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="widthmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="widthmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|widthmf"> Enter the width of the graphic bullet character. </property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="heightmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment5</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="heightmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|heightmf"> Enter the height of the graphic bullet character. </property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="relsize">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="text" translatable="yes" context="bulletandposition|relsize">100</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="value">100</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relsize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|relsize">For character unordered and ordered lists, set the relative size of the list character. The relative size applies to the Before and After text as well.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="relsizeft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|relsizeft">_Rel. size:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">relsize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="keepratiobox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="keepratio">
+ <property name="label" translatable="yes" context="bulletandposition|keepratio">Keep ratio</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="keepratio-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|keepratio">Check this box to preserve the height to width ratio of the graphic bullet.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="size">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|beforeafter">Size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="positions">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="indent">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|indent">Indent:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">indentmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="numberingwidth">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|numberingwidth">Width:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">numberingwidthmf</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="indentmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="text" translatable="yes" context="bulletandposition|indentmf">0,00</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indentmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|indentmf">Enter the distance from the left edge of the containing object to the start of all lines in the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="numberingwidthmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="text" translatable="yes" context="bulletandposition|numberingwidthmf">0,00</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment7</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numberingwidthmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|numberingwidthmf"> Enter or select the width of the list element. </property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="relative">
+ <property name="label" translatable="yes" context="bulletandposition|relative">Relati_ve</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relative-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|relative">Relative to the upper list level. The entered value is added to that of this field in the level before. If “Indent: 20mm” on list level 1 and “Indent: 10mm Relative” on list level 2 will result in an effective indent of 30mm for level 2.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=1 -->
+ <object class="GtkGrid" id="alignmentgr">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkToggleButton" id="center">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="center-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|center">Align bullet on the center of the list element.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="left">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="left-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="bulletandposition|extended_tip|left">Align bullet on the left of the list element.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="right">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="image">image3</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="right-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|right">Align bullet on the right of the list element.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="ALlabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|ALlabel">Alignment:</property>
+ <property name="mnemonic-widget">left</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="position">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|position">Position</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="scope">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="sliderb">
+ <property name="label" translatable="yes" context="bulletandposition|sliderb">Slide</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="sliderb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|sliderb">Applies the modification to the whole slide or page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="selectionrb">
+ <property name="label" translatable="yes" context="bulletandposition|selectionrb">Selection</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">sliderb</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="selectionrb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|left">Applies the modification to the selection.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="applytomaster">
+ <property name="label" translatable="yes" context="bulletandposition|applytomaster">Apply to Master</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="applytomaster-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="bulletandposition|extended_tip|applytomaster">Click to apply the modification to all slides that use the current master slide.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="scopelb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|scopelb">Scope</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="width-request">150</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="bulletandposition|label">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel">
+ <widgets>
+ <widget name="label4"/>
+ <widget name="bulletft"/>
+ <widget name="startatft"/>
+ <widget name="colorft"/>
+ <widget name="prefixft"/>
+ <widget name="suffixft"/>
+ <widget name="widthft"/>
+ <widget name="heightft"/>
+ <widget name="relsizeft"/>
+ <widget name="indent"/>
+ <widget name="numberingwidth"/>
+ <widget name="ALlabel"/>
+ <widget name="sliderb"/>
+ <widget name="selectionrb"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupSpin">
+ <widgets>
+ <widget name="startat"/>
+ <widget name="suffix"/>
+ <widget name="prefix"/>
+ <widget name="widthmf"/>
+ <widget name="heightmf"/>
+ <widget name="relsize"/>
+ <widget name="indentmf"/>
+ <widget name="numberingwidthmf"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/calloutdialog.ui b/cui/uiconfig/ui/calloutdialog.ui
new file mode 100644
index 000000000..fff41067a
--- /dev/null
+++ b/cui/uiconfig/ui/calloutdialog.ui
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="CalloutDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="calloutdialog|CalloutDialog">Position and Size</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_POSITION_SIZE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutdialog|RID_SVXPAGE_POSITION_SIZE">Position and Size</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_SWPOSSIZE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutdialog|RID_SVXPAGE_SWPOSSIZE">Position and Size</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_CAPTION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutdialog|RID_SVXPAGE_CAPTION">Callout</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/calloutpage.ui b/cui/uiconfig/ui/calloutpage.ui
new file mode 100644
index 000000000..d1e6f3e80
--- /dev/null
+++ b/cui/uiconfig/ui/calloutpage.ui
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">2400</property>
+ <property name="step_increment">0.5</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">2400</property>
+ <property name="step_increment">0.5</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">2400</property>
+ <property name="step_increment">0.5</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="CalloutPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="valuesetwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="valueset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="valueset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|valueset">Click the Callout style that you want to apply to the selected callout.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">18</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutpage|label2">_Extension:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">extension</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="extension">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item id="4" translatable="yes" context="calloutpage|liststore1">Optimal</item>
+ <item id="3" translatable="yes" context="calloutpage|liststore1">From top</item>
+ <item id="3" translatable="yes" context="calloutpage|liststore1">From left</item>
+ <item id="1" translatable="yes" context="calloutpage|liststore1">Horizontal</item>
+ <item id="2" translatable="yes" context="calloutpage|liststore1">Vertical</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="extension-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|extension">Select where you want to extend the callout line from, in relation to the callout box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkSpinButton" id="length">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="text">0.00</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="length-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|length">Enter the length of the callout line segment that extends from the callout box to the inflection point of the line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lengthft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutpage|lengthft">_Length:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">length</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="optimal">
+ <property name="label" translatable="yes" context="calloutpage|optimal">_Optimal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="optimal-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|optimal">Click here to display a single-angled line in an optimal way.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="positionft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutpage|positionft">_Position:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">position</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="byft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutpage|byft">_By:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">by</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="position">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="calloutpage|position">Top</item>
+ <item translatable="yes" context="calloutpage|position">Middle</item>
+ <item translatable="yes" context="calloutpage|position">Bottom</item>
+ <item translatable="yes" context="calloutpage|position">Left</item>
+ <item translatable="yes" context="calloutpage|position">Center</item>
+ <item translatable="yes" context="calloutpage|position">Right</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="position-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|position">Select where you want to extend the callout line from, in relation to the callout box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="by">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="text">0.00</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="by-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|by">Select where you want to extend the callout line from, in relation to the callout box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="calloutpage|label1">_Spacing:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spacing</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spacing">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="text">0.00</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spacing-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|spacing">Enter the amount of space that you want to leave between the end of the callout line, and the callout box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="linetypes">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <items>
+ <item translatable="yes" context="calloutpage|linetypes">Straight Line</item>
+ <item translatable="yes" context="calloutpage|linetypes">Angled Line</item>
+ <item translatable="yes" context="calloutpage|linetypes">Angled Connector Line</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CalloutPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="calloutpage|extended_tip|CalloutPage">Click the Callout style that you want to apply to the selected callout.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="label2"/>
+ <widget name="lengthft"/>
+ <widget name="label1"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="positionft"/>
+ <widget name="byft"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup3">
+ <property name="mode">both</property>
+ <widgets>
+ <widget name="position"/>
+ <widget name="by"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup4">
+ <property name="mode">both</property>
+ <widgets>
+ <widget name="extension"/>
+ <widget name="length"/>
+ <widget name="spacing"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/cellalignment.ui b/cui/uiconfig/ui/cellalignment.ui
new file mode 100644
index 000000000..1f01eeec3
--- /dev/null
+++ b/cui/uiconfig/ui/cellalignment.ui
@@ -0,0 +1,564 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentIndent">
+ <property name="upper">990</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentSpinDegrees">
+ <property name="upper">359</property>
+ <property name="step_increment">5</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="CellAlignPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="orientation">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="labelDegrees">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelDegrees">_Degrees:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinDegrees</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelRefEdge">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelRefEdge">_Reference edge:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">references</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinDegrees">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentSpinDegrees</property>
+ <property name="wrap">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinDegrees-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|spinDegrees">Enter the rotation angle from 0 to 360 for the text in the selected cell(s).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="references">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="halign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="references-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|references">Specify the cell edge from which to write the rotated text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkVertStack">
+ <property name="label" translatable="yes" context="cellalignment|checkVertStack">Vertically s_tacked</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkVertStack-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|checkVertStack">Text direction vertically.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkAsianMode">
+ <property name="label" translatable="yes" context="cellalignment|checkAsianMode">Asian layout _mode</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">12</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkAsianMode-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|checkAsianMode">Aligns Asian characters one below the other in the selected cell(s). If the cell contains more than one line of text, the lines are converted to text columns that are arranged from right to left. Western characters in the converted text are rotated 90 degrees to the right. Asian characters are not rotated.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="dialcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="dialcontrol-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|dialcontrol">Click in the dial to set the text orientation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelTextOrient">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelTextOrient">Text Orientation</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="properties">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">1</property>
+ <child>
+ <object class="GtkCheckButton" id="checkWrapTextAuto">
+ <property name="label" translatable="yes" context="cellalignment|checkWrapTextAuto">_Wrap text automatically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkWrapTextAuto-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|checkWrapTextAuto">Wraps text onto another line at the cell border. The number of lines depends on the width of the cell.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkShrinkFitCellSize">
+ <property name="label" translatable="yes" context="cellalignment|checkShrinkFitCellSize">_Shrink to fit cell size</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkShrinkFitCellSize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|checkShrinkFitCellSize">Reduces the apparent size of the font so that the contents of the cell fit into the current cell width. You cannot apply this command to a cell that contains line breaks.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkHyphActive">
+ <property name="label" translatable="yes" context="cellalignment|checkHyphActive">Hyphenation _active</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="margin-start">12</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkHyphActive-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|checkHyphActive">Enables word hyphenation for text wrapping to the next line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxDirection">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="LabelTxtDir">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|LabelTxtDir">Te_xt direction:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboTextDirBox</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboTextDirBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelProperties">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelProperties">Properties</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="alignment">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkSpinButton" id="spinIndentFrom">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentIndent</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinIndentFrom-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|spinIndentFrom">Indents from the left edge of the cell by the amount that you enter.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelHorzAlign">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelHorzAlign">Hori_zontal:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboboxHorzAlign</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelVertAlign">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelVertAlign">_Vertical:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboboxVertAlign</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelIndent">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelIndent">I_ndent:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinIndentFrom</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboboxHorzAlign">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="cellalignment|liststoreHorzAlign">Default</item>
+ <item id="1" translatable="yes" context="cellalignment|liststoreHorzAlign">Left</item>
+ <item id="2" translatable="yes" context="cellalignment|liststoreHorzAlign">Center</item>
+ <item id="3" translatable="yes" context="cellalignment|liststoreHorzAlign">Right</item>
+ <item id="4" translatable="yes" context="cellalignment|liststoreHorzAlign">Justified</item>
+ <item id="5" translatable="yes" context="cellalignment|liststoreHorzAlign">Filled</item>
+ <item id="6" translatable="yes" context="cellalignment|liststoreHorzAlign">Distributed</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="comboboxHorzAlign-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|comboboxHorzAlign">Select the horizontal alignment option that you want to apply to the cell contents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboboxVertAlign">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="cellalignment|liststoreVertAlign">Default</item>
+ <item id="1" translatable="yes" context="cellalignment|liststoreVertAlign">Top</item>
+ <item id="2" translatable="yes" context="cellalignment|liststoreVertAlign">Middle</item>
+ <item id="3" translatable="yes" context="cellalignment|liststoreVertAlign">Bottom</item>
+ <item id="4" translatable="yes" context="cellalignment|liststoreVertAlign">Justified</item>
+ <item id="5" translatable="yes" context="cellalignment|liststoreVertAlign">Distributed</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="comboboxVertAlign-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|comboboxVertAlign">Select the vertical alignment option that you want to apply to the cell contents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="LabelTextAlig">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|LabelTextAlig">Text Alignment</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxStrings">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="labelSTR_BOTTOMLOCK">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelSTR_BOTTOMLOCK">Text Extension From Lower Cell Border</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelSTR_TOPLOCK">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelSTR_TOPLOCK">Text Extension From Upper Cell Border</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelSTR_CELLLOCK">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelSTR_CELLLOCK">Text Extension Inside Cell</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelABCD">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="cellalignment|labelABCD">ABCD</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CellAlignPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cellalignment|extended_tip|CellAlignPage">Sets the alignment options for the contents of the current cell, or the selected cells.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel">
+ <widgets>
+ <widget name="labelHorzAlign"/>
+ <widget name="labelVertAlign"/>
+ <widget name="labelDegrees"/>
+ <widget name="labelRefEdge"/>
+ <widget name="LabelTxtDir"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupWidget">
+ <widgets>
+ <widget name="comboboxHorzAlign"/>
+ <widget name="comboboxVertAlign"/>
+ <widget name="spinDegrees"/>
+ <widget name="references"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/certdialog.ui b/cui/uiconfig/ui/certdialog.ui
new file mode 100644
index 000000000..8f3545e31
--- /dev/null
+++ b/cui/uiconfig/ui/certdialog.ui
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="CertDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="certdialog|CertDialog">Certificate Path</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="type_hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="certdialog|add">_Select NSS path...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="certdialog|extended_tip|add">Opens a file picker dialog to add a new Network Security Services Certificate directory to the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="certdialog|label2">Select or add the correct Network Security Services Certificate directory to use for digital signatures:</property>
+ <property name="use_underline">True</property>
+ <property name="wrap">True</property>
+ <property name="mnemonic_widget">paths</property>
+ <property name="width_chars">60</property>
+ <property name="max_width_chars">60</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <child>
+ <object class="GtkLabel" id="manual">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="certdialog|manual">manual</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="certdir">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="certdialog|certdir">Select a Certificate directory</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="paths">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="certdialog|profile">Profile</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5">
+ <property name="radio">True</property>
+ </object>
+ <attributes>
+ <attribute name="visible">4</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="certdialog|dir">Directory</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="certdialog|label1">Certificate Path</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">add</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CertDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="certdialog|extended_tip|CertDialog">Select or add the correct Network Security Services Certificate directory to use for digital signatures.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/chapterfragment.ui b/cui/uiconfig/ui/chapterfragment.ui
new file mode 100644
index 000000000..6ed4fb34a
--- /dev/null
+++ b/cui/uiconfig/ui/chapterfragment.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="ChapterFragment">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox" id="contents">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="chapter">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/charnamepage.ui b/cui/uiconfig/ui/charnamepage.ui
new file mode 100644
index 000000000..4721506d5
--- /dev/null
+++ b/cui/uiconfig/ui/charnamepage.ui
@@ -0,0 +1,920 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore4">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore5">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore6">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore7">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="CharNamePage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkNotebook" id="nbWestern">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="show-border">False</property>
+ <child>
+ <!-- n-columns=3 n-rows=6 -->
+ <object class="GtkGrid" id="gdWestern">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="lbWestFontname">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" context="charnamepage|westfontnameft-cjk">Name:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">edWestFontName</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbWestLanguage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|westlangft-cjk">Language:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbWestLanguage</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="cbWestLanguage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore5</property>
+ <property name="has-entry">True</property>
+ <property name="entry-text-column">0</property>
+ <property name="id-column">1</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbWestLanguage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|westlanglb-cjk">Sets the language that the spellchecker uses for the selected text or the text that you type. Available language modules have a check mark in front of them.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbWestStyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" context="charnamepage|weststyleft-cjk">Style:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbWestStyle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="cbWestStyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbWestStyle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|weststylelb-cjk">Select the formatting that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbWestSize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|westsizeft-cjk">Size:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbWestSize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="cbWestSize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbWestSize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|westsizelb-cjk">Enter or select the font size that you want to apply. For scalable fonts, you can also enter decimal values.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnWestFeatures">
+ <property name="label" translatable="yes" context="charnamepage|west_features_button-cjk">Features...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="trWestFontName">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="trWestFontName-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|westfontnamelb-nocjk">Select the font that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edWestFontName">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbWestFontinfo">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="wrap">True</property>
+ <property name="width-chars">30</property>
+ <property name="max-width-chars">30</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="lbWestern">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|Tab_Western">Western</property>
+ </object>
+ <packing>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="nbCJKCTL">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="show-border">False</property>
+ <child>
+ <!-- n-columns=3 n-rows=6 -->
+ <object class="GtkGrid" id="gdCJK">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="lbCJKSize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|eastsizeft">Size:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbCJKSize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCJKLanguage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|eastlangft">Language:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbCJKLanguage</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="cbCJKStyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCJKStyle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|eaststylelb">Select the formatting that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="cbCJKSize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCJKSize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|eastsizelb">Enter or select the font size that you want to apply. For scalable fonts, you can also enter decimal values.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCJKStyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" context="charnamepage|eaststyleft">Style:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbCJKStyle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCJKFeatures">
+ <property name="label" translatable="yes" context="charnamepage|east_features_button">Features...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCJKFontname">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" context="charnamepage|eastfontnameft">Name:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">edCJKFontName</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="trCJKFontName">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="trCJKFontName-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|trCJKFontName">Select the font that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edCJKFontName">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="cbCJKLanguage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore6</property>
+ <property name="has-entry">True</property>
+ <property name="entry-text-column">0</property>
+ <property name="id-column">1</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCJKLanguage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|eastlanglb">Sets the language that the spellchecker uses for the selected text or the text that you type. Available language modules have a check mark in front of them.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCJKFontinfo">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="wrap">True</property>
+ <property name="width-chars">30</property>
+ <property name="max-width-chars">30</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="nbCJK">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|Tab_Asian">Asian</property>
+ </object>
+ <packing>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=6 -->
+ <object class="GtkGrid" id="gdCTL">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="lbCTLFontname">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" context="charnamepage|ctlfontnameft">Name:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">edCTLFontName</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCTLStyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" context="charnamepage|ctlstyleft">Style:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbCTLStyle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCTLSize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|ctlsizeft">Size:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbCTLSize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="cbCTLStyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCTLStyle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|ctlstylelb">Select the formatting that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="cbCTLSize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCTLSize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|ctlsizelb">Enter or select the font size that you want to apply. For scalable fonts, you can also enter decimal values.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCTLLanguage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|ctllangft">Language:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cbCTLLanguage</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCTLFeatures">
+ <property name="label" translatable="yes" context="charnamepage|ctl_features_button">Features...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="cbCTLLanguage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore7</property>
+ <property name="has-entry">True</property>
+ <property name="entry-text-column">0</property>
+ <property name="id-column">1</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext11"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCTLLanguage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|ctllanglb">Sets the language that the spellchecker uses for the selected text or the text that you type. Available language modules have a check mark in front of them.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="trCTLFontName">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext3"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="trCTLFontName-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="charnamepage|extended_tip|trCTLFontName">Select the font that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edCTLFontName">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbCTLFontinfo">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="wrap">True</property>
+ <property name="width-chars">30</property>
+ <property name="max-width-chars">30</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="nbCTL">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="charnamepage|Tab_Complex">Complex</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab-fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="swPreview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">end</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport" id="vpPreview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="charnamepage|preview-atkobject">Preview</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/colorconfigwin.ui b/cui/uiconfig/ui/colorconfigwin.ui
new file mode 100644
index 000000000..319ac0e48
--- /dev/null
+++ b/cui/uiconfig/ui/colorconfigwin.ui
@@ -0,0 +1,2002 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="ColorConfigWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frmGeneral">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=11 -->
+ <object class="GtkGrid" id="gdGeneral">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="doccolor">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|doccolor">Document background</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">doccolor_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="doccolor_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="docboundaries">
+ <property name="label" translatable="yes" context="colorconfigwin|docboundaries">Text boundaries</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="docboundaries_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="docboundaries_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="docboundaries"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="docboundaries_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|docboundaries_lb">Text boundaries color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="appback">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|appback">Application background</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">appback_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="appback_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="objboundaries">
+ <property name="label" translatable="yes" context="colorconfigwin|objboundaries">Object boundaries</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="objboundaries_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="objboundaries_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="objboundaries"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="objboundaries_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|objboundaries_lb">Object boundaries color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="tblboundaries">
+ <property name="label" translatable="yes" context="colorconfigwin|tblboundaries">Table boundaries</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="tblboundaries_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="tblboundaries_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="tblboundaries"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="tblboundaries_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|tblboundaries_lb">Table boundaries color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="font">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|font">Font color</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">font_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="font_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="unvisitedlinks">
+ <property name="label" translatable="yes" context="colorconfigwin|unvisitedlinks">Unvisited links</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="unvisitedlinks_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="unvisitedlinks_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="unvisitedlinks"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="unvisitedlinks_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|unvisitedlinks_lb">Unvisited links color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="visitedlinks">
+ <property name="label" translatable="yes" context="colorconfigwin|visitedlinks">Visited links</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="visitedlinks_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="visitedlinks_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="visitedlinks"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="visitedlinks_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|visitedlinks_lb">Visited links color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="autospellcheck">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|autospellcheck">AutoSpellcheck</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">autospellcheck_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="autospellcheck_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="smarttags">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|smarttags">Smart Tags</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">smarttags_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="smarttags_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="shadows">
+ <property name="label" translatable="yes" context="colorconfigwin|shadows">Shadows</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="shadows_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="shadows_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="shadows"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="shadows_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|shadows_lb">Shadows color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">10</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="general">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|general">General</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmWriter">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=8 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="writergrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|writergrid">Grid</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">writergrid_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="writergrid_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="field">
+ <property name="label" translatable="yes" context="colorconfigwin|field">Field shadings</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="field_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="field_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="field"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="field_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|field_lb">Field shadings color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="index">
+ <property name="label" translatable="yes" context="colorconfigwin|index">Index and table shadings</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="index_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="index_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="index"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="index_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|index_lb">Index and table shadings color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="script">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|script">Script Indicator</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">script_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="script_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="section">
+ <property name="label" translatable="yes" context="colorconfigwin|section">Section boundaries</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="section_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="section_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="section"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="section_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|section_lb">Section boundaries color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="hdft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|hdft">Headers and Footer delimiter</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">hdft_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="hdft_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="pagebreak">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|pagebreak">Page and column breaks</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">pagebreak_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="pagebreak_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="direct">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|direct">Direct Cursor</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">direct_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="direct_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="writer">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|writer">Text Document</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmCalc">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=13 -->
+ <object class="GtkGrid" id="gdCalc">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="calcgrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|calcgrid">Grid lines</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">calcgrid_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="calcgrid_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="brk">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|brk">Page breaks</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">brk_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="brk_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="brkmanual">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|brkmanual">Manual page breaks</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">brkmanual_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="brkmanual_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="brkauto">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|brkauto">Automatic page breaks</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">brkauto_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="brkauto_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="det">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|det">Detective</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">det_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="det_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="deterror_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="deterror">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|deterror">Detective error</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">deterror_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="ref_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="ref">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|ref">References</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">ref_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="notes_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="notes">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|notes">Notes background</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">notes_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="values_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="values">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|values">Values</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">values_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="formulas_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="formulas">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|formulas">Formulas</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">formulas_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="text_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="text">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|text">Text</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">text_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="protectedcells_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="protectedcells">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|protectedcells">Protected cells background</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">protectedcells_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="hiddencolrow">
+ <property name="label" translatable="yes" context="colorconfigwin|hiddencolrow">Hidden columns/rows</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="hiddencolrow_lb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="hiddencolrow_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="hiddencolrow"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hiddencolrow_lb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorconfigwin|hiddencolrow_lb">Hidden row/column color</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="calc">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|calc">Spreadsheet</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmDrawImpress">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="gdDraw">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkMenuButton" id="drawgrid_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="drawgrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|drawgrid">Grid</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">drawgrid_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="draw">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|draw">Drawing / Presentation</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmBasic">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=7 -->
+ <object class="GtkGrid" id="gdBasic">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkMenuButton" id="basicid_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="basicid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basicid">Identifier</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">basicid_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="basiccomment_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="basiccomment">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basiccomment">Comment</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">basiccomment_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="basicnumber_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="basicnumber">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basicnumber">Number</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">basicnumber_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="basicstring_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="basicstring">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basicstring">String</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">basicstring_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="basicop_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="basicop">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">end</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basicop">Operator</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">basicop_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="basickeyword_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="basickeyword">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basickeyword">Reserved expression</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">basickeyword_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="error_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="error">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|error">Error</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">error_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="basic">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|basic">Basic Syntax Highlighting</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmSQL">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=7 -->
+ <object class="GtkGrid" id="gdSQL">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkMenuButton" id="sqlid_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlid">Identifier</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlid_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="sqlnumber_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlnumber">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlnumber">Number</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlnumber_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="sqlstring_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlstring">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlstring">String</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlstring_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="sqlop_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlop">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlop">Operator</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlop_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="sqlkeyword_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlkeyword">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlkeyword">Keyword</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlkeyword_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="sqlparam_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlparam">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlparam">Parameter</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlparam_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="sqlcomment_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sqlcomment">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sqlcomment">Comment</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sqlcomment_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="sql">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sql">SQL Syntax Highlighting</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmHTML">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="gdHTML">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkMenuButton" id="sgml_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sgml">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|sgml">SGML syntax highlighting</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sgml_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="htmlcomment">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|htmlcomment">Comment highlighting</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">htmlcomment_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="htmlcomment_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="htmlkeyword">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|htmlkeyword">Keyword highlighting</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">htmlkeyword_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="htmlkeyword_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="unknown">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorconfigwin|unknown">Text</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">unknown_lb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="unknown_lb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="html">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorconfigwin|html">HTML Document</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/colorfragment.ui b/cui/uiconfig/ui/colorfragment.ui
new file mode 100644
index 000000000..75fec68c8
--- /dev/null
+++ b/cui/uiconfig/ui/colorfragment.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="ColorFragment">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ <property name="column-spacing">6</property>
+ <property name="row-homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">button</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="button">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/colorpage.ui b/cui/uiconfig/ui/colorpage.ui
new file mode 100644
index 000000000..ac680de34
--- /dev/null
+++ b/cui/uiconfig/ui/colorpage.ui
@@ -0,0 +1,994 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">255</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="upper">255</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment7">
+ <property name="upper">255</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">res/sc10350.png</property>
+ </object>
+ <object class="GtkBox" id="ColorPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=4 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="colorpage|label21">Palette:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">paletteselector</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="paletteselector">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnMoreColors">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="colorpage|btnMoreColors">Add color palettes via extension</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label20">Recent Colors</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">recentcolorset</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="recentcolorset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">6</property>
+ <property name="column-spacing">3</property>
+ <property name="column-homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RGB">
+ <property name="label" translatable="yes" context="colorpage|RGB">RGB</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="CMYK">
+ <property name="label" translatable="yes" context="colorpage|CMYK">CMYK</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">RGB</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="colorpage|delete">Delete</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="colorpage|extended_tip|delete">Deletes the selected element or elements without requiring confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-bottom">3</property>
+ <property name="label" translatable="yes" context="colorpage|label22">Custom Palette</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">colorset</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="colorsetwin">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="colorset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label1">Colors</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="oldpreview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="oldpreview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorpage|oldpreview-atkobject">Old Color</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="rgbpreset">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label7">B</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">B_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label8">G</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">G_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label9">R</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">R_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label18">Hex</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">hex_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="hex_preset">
+ <property name="width-request">6</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="R_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="G_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="B_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="cmykpreset">
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label10">_C</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">C_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label16">_K</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">K_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label17">_Y</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">Y_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="C_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="M_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="Y_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="K_preset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="editable">False</property>
+ <property name="width-chars">3</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label15">_M</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">M_preset</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label5">Active</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="newpreview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newpreview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="colorpage|newpreview-atkobject">New Color</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="rgbcustom">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="B_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="tooltip-text" translatable="yes" context="colorpage|B_custom">Blue</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment7</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="R_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="tooltip-text" translatable="yes" context="colorpage|R_custom">Red</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label4">_B</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">B_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label3">_G</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">G_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label2">_R</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">R_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="G_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="tooltip-text" translatable="yes" context="colorpage|G_custom">Green</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment6</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label19">_Hex</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">hex_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="hex_custom">
+ <property name="width-request">6</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="overwrite-mode">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="cmykcustom">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label11">_C</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">C_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label12">_M</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">M_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label13">_K</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">K_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="C_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="K_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment5</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label14">_Y</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">Y_custom</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="Y_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment4</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="M_custom">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment3</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="colorpage|edit">Pick</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="valign">start</property>
+ <property name="image">image3</property>
+ <property name="image-position">right</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpage|label6">New</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="R_custom"/>
+ <widget name="hex_custom"/>
+ <widget name="C_custom"/>
+ <widget name="C_preset"/>
+ <widget name="hex_preset"/>
+ <widget name="R_preset"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/colorpickerdialog.ui b/cui/uiconfig/ui/colorpickerdialog.ui
new file mode 100644
index 000000000..6b8485666
--- /dev/null
+++ b/cui/uiconfig/ui/colorpickerdialog.ui
@@ -0,0 +1,831 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentblue">
+ <property name="upper">255</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentbright">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentcyan">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentgreen">
+ <property name="upper">255</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmenthue">
+ <property name="upper">360</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentkey">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentmag">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentred">
+ <property name="upper">255</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentsat">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentyellow">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkDialog" id="ColorPicker">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="colorpickerdialog|ColorPicker">Pick a Color</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=4 n-rows=2 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">2</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | preview">In the left part of the bottom bar, the current result of your work in this dialog is visible.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="previous">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="previous-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | previous">In the right part of the bottom bar, you will see the original color from the parent tab, Colors.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="colorField">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colorField-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | colorField">Click in the big color area on the left to select a new color. Using this selector area you can modify two components of the color as represented in the RGB or HSB color models. Note that these are the two components not selected with the radio buttons on the right side of the dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="colorSlider">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colorSlider-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | colorSlider">With the vertical color component slider you can modify the value of each component of the color.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="rightImage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="icon-name">res/colorsliderright.png</property>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="leftImage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="icon-name">res/colorsliderleft.png</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="redRadiobutton">
+ <property name="label" translatable="yes" context="colorpickerdialog|redRadiobutton">_Red:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">hueRadiobutton</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="redRadiobutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | redRadiobutton">Sets the Red component modifiable on the vertical color slider, and the Green and Blue components in the two-dimensional color picker field. Allowed values are 0 to 255.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="greenRadiobutton">
+ <property name="label" translatable="yes" context="colorpickerdialog|greenRadiobutton">_Green:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">hueRadiobutton</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="greenRadiobutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | greenRadiobutton">Sets the Green component modifiable on the vertical color slider, and the Red and Blue components in the two-dimensional color picker field. Allowed values are 0 to 255.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="blueRadiobutton">
+ <property name="label" translatable="yes" context="colorpickerdialog|blueRadiobutton">_Blue:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">hueRadiobutton</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="blueRadiobutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | blueRadiobutton">Sets the Blue component modifiable on the vertical color slider, and the Green and Red components in the two-dimensional color picker field. Allowed values are 0 to 255.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="redSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentred</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="redSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | redSpinbutton">Set the Red color value directly. Allowed values are 0 to 255.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="greenSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentgreen</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="greenSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | greenSpinbutton">Set the Green color value directly. Allowed values are 0 to 255.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="blueSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentblue</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="blueSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | blueSpinbutton">Set the Blue color value directly. Allowed values are 0 to 255.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label2">Hex _#:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">hexEntry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="hexEntry">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hexEntry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | hexEntry">Displays and sets the color value in the RGB color model expressed as a hexadecimal number.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label1">RGB</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="hueRadiobutton">
+ <property name="label" translatable="yes" context="colorpickerdialog|hueRadiobutton">H_ue:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hueRadiobutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | hueRadiobutton">Sets the Hue component modifiable on the vertical color slider, and the Saturation and Brightness components in the two-dimensional color picker field. Values are expressed in degrees from 0 to 359.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="satRadiobutton">
+ <property name="label" translatable="yes" context="colorpickerdialog|satRadiobutton">_Saturation:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">hueRadiobutton</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="satRadiobutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | satRadiobutton">Sets the Saturation component modifiable on the vertical color slider, and the Hue and Brightness components in the two-dimensional color picker field. Values are expressed in percent (0 to 100).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="brightRadiobutton">
+ <property name="label" translatable="yes" context="colorpickerdialog|brightRadiobutton">Bright_ness:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">hueRadiobutton</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="brightRadiobutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | brightRadiobutton">Sets the Brightness component modifiable on the vertical color slider, and the Hue and Saturation components in the two-dimensional color picker field. Values are expressed in percent (0 to 100).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="hueSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmenthue</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hueSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | hueSpinbutton">Set the Hue directly in the HSB color model. Values are expressed in degrees from 0 to 359.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="satSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentsat</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="satSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | satSpinbutton">Set the Saturation directly in the HSB color model. Values are expressed in percent (0 to 100).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="brightSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentbright</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="brightSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | brightSpinbutton">Set the Brightness directly in the HSB color model. Values are expressed in percent (0 to 100).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label3">HSB</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label5" comments="This is the C of the CMYK color model: https://en.wikipedia.org/wiki/CMYK_color_model">_Cyan:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">cyanSpinbutton</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label6" comments="This is the M of the CMYK color model: https://en.wikipedia.org/wiki/CMYK_color_model">_Magenta:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">magSpinbutton</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label7" comments="This is the Y of the CMYK color model: https://en.wikipedia.org/wiki/CMYK_color_model">_Yellow:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">yellowSpinbutton</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label8" comments="This is the K of the CMYK color model: https://en.wikipedia.org/wiki/CMYK_color_model">_Key:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">keySpinbutton</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="cyanSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentcyan</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cyanSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | cyanSpinbutton">Set the Cyan color value as expressed in the CMYK color model.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="magSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentmag</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="magSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | magSpinbutton">Set the Magenta color value as expressed in the CMYK color model.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="yellowSpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentyellow</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="yellowSpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | yellowSpinbutton">Set the Yellow color value as expressed in the CMYK color model.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="keySpinbutton">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentkey</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="keySpinbutton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | keySpinbutton">Set the Black color value or key (black) as expressed in the CMYK color model.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="colorpickerdialog|label4">CMYK</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ColorPicker-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | ColorPicker">Define custom colors using a two-dimensional graphic and numerical gradient chart of the Pick a Color dialog.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="redRadiobutton"/>
+ <widget name="greenRadiobutton"/>
+ <widget name="blueRadiobutton"/>
+ <widget name="label2"/>
+ <widget name="hueRadiobutton"/>
+ <widget name="satRadiobutton"/>
+ <widget name="brightRadiobutton"/>
+ <widget name="label5"/>
+ <widget name="label6"/>
+ <widget name="label7"/>
+ <widget name="label8"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/comment.ui b/cui/uiconfig/ui/comment.ui
new file mode 100644
index 000000000..185a94dc8
--- /dev/null
+++ b/cui/uiconfig/ui/comment.ui
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-previous</property>
+ </object>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-next</property>
+ </object>
+ <object class="GtkDialog" id="CommentDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="comment|CommentDialog">Insert Comment</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="row_homogeneous">True</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="previous">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="next">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="image">image3</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="comment|label2">Author</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lastedit">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="comment|label4">_Text</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="edit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="wrap_mode">char</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="comment|extended_tip|edit">Enter a comment for the recorded change.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="insertauthor">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="comment|label5">_Insert</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">author</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="author">
+ <property name="label" translatable="yes" context="comment|author">Author</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="alttitle">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="comment|alttitle">Edit Comment</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="comment|label1">Contents</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CommentDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="comment|extended_tip|CommentDialog">Enter a comment for the recorded change.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/connectortabpage.ui b/cui/uiconfig/ui/connectortabpage.ui
new file mode 100644
index 000000000..a2f6aadf3
--- /dev/null
+++ b/cui/uiconfig/ui/connectortabpage.ui
@@ -0,0 +1,470 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment7">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="ConnectorTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_TYPE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_TYPE">_Type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_TYPE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_TYPE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_TYPE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|LB_TYPE">Lists the types of connectors that are available.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_DELTA">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_LINE_1">Line _1:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_LINE_1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_LINE_2">Line _2:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_LINE_2</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_LINE_3">Line _3:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_LINE_3</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LINE_1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_LINE_1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_LINE_1">Enter a skew value for Line 1.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LINE_2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_LINE_2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_LINE_2">Enter a skew value for Line 2.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LINE_3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_LINE_3-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_LINE_3">Enter a skew value for Line 3.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|label2">Line Skew</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_DISTANCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_HORZ_1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_HORZ_1">_Begin horizontal:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HORZ_1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_HORZ_2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_HORZ_2">End _horizontal:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HORZ_2</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_VERT_1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_VERT_1">Begin _vertical:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_VERT_1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_VERT_2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|FT_VERT_2">_End vertical:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_VERT_2</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HORZ_1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HORZ_1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_HORZ_1">Enter the amount of horizontal space you want at the beginning of the connector.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HORZ_2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment5</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HORZ_2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_HORZ_2">Enter the amount of horizontal space you want at the end of the connector.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_VERT_1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_VERT_1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_VERT_1">Enter the amount of vertical space you want at the beginning of the connector.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_VERT_2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment7</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_VERT_2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|MTR_FLD_VERT_2">Enter the amount of vertical space you want at the end of the connector.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connectortabpage|label3">Line Spacing</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="tooltip_text" translatable="yes" context="connectortabpage|CTL_PREVIEW|tooltip_text">Preview</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="connectortabpage|CTL_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ConnectorTabPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="connectortabpage|extended_tip|ConnectorTabPage">Sets the properties of a connector.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="FT_TYPE"/>
+ <widget name="FT_LINE_1"/>
+ <widget name="FT_LINE_2"/>
+ <widget name="FT_LINE_3"/>
+ <widget name="FT_HORZ_1"/>
+ <widget name="FT_HORZ_2"/>
+ <widget name="FT_VERT_1"/>
+ <widget name="FT_VERT_2"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupWidget">
+ <widgets>
+ <widget name="MTR_FLD_LINE_1"/>
+ <widget name="MTR_FLD_LINE_2"/>
+ <widget name="MTR_FLD_LINE_3"/>
+ <widget name="MTR_FLD_HORZ_1"/>
+ <widget name="MTR_FLD_HORZ_2"/>
+ <widget name="MTR_FLD_VERT_1"/>
+ <widget name="MTR_FLD_VERT_2"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/connpooloptions.ui b/cui/uiconfig/ui/connpooloptions.ui
new file mode 100644
index 000000000..83487e9c9
--- /dev/null
+++ b/cui/uiconfig/ui/connpooloptions.ui
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">30</property>
+ <property name="upper">600</property>
+ <property name="value">60</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text1 -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="ConnPoolPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="connectionpooling">
+ <property name="label" translatable="yes" context="connpooloptions|connectionpooling">Connection pooling enabled</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="connectionpooling-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|connectionpooling">Specifies whether the chosen connections are pooled.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="driverslabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connpooloptions|driverslabel">Drivers known in %PRODUCTNAME</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">driverlist</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="driverlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connpooloptions|driverlabel">Current driver:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="driver">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="enablepooling">
+ <property name="label" translatable="yes" context="connpooloptions|enablepooling">Enable pooling for this driver</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="enablepooling-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|enablepooling">Select a driver from the list and mark the Enable pooling for this driver checkbox in order to pool its connection.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="timeoutlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connpooloptions|timeoutlabel">_Timeout (seconds):</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">timeout</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="timeout">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="text">60</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="value">60</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="timeout-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|timeout">Defines the time in seconds after which a pooled connection is freed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="driverlistscroll">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="driverlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="connpooloptions|drivername">Driver name</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn9">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="connpooloptions|pool">Pool</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer9"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn7">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="connpooloptions|timeout">Timeout</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer7"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="connpooloptions|label1">Connection Pool</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/croppage.ui b/cui/uiconfig/ui/croppage.ui
new file mode 100644
index 000000000..b7fe3d822
--- /dev/null
+++ b/cui/uiconfig/ui/croppage.ui
@@ -0,0 +1,545 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">-99.989999999999995</property>
+ <property name="upper">99.989999999999995</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">1</property>
+ <property name="upper">9999</property>
+ <property name="value">100</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">100</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">0.050000000000000003</property>
+ <property name="upper">200</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">0.050000000000000003</property>
+ <property name="upper">200</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="lower">1</property>
+ <property name="upper">9999</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">100</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="lower">-99.989999999999995</property>
+ <property name="upper">99.989999999999995</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment7">
+ <property name="lower">-99.989999999999995</property>
+ <property name="upper">99.989999999999995</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment8">
+ <property name="lower">-99.989999999999995</property>
+ <property name="upper">99.989999999999995</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="CropPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+ <child>
+ <object class="GtkFrame" id="cropframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">18</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="keepscale">
+ <property name="label" translatable="yes" context="croppage|keepscale">Keep _scale</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="keepsize">
+ <property name="label" translatable="yes" context="croppage|keepsize">Keep image si_ze</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">keepscale</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label2">_Left:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">left</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="left">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label3">_Right:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">right</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="right">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment7</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label4">_Top:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">top</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label5">_Bottom:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bottom</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="top">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="bottom">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment8</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="height">4</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="origsizegrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="origsizeft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">origsize</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="origsize">
+ <property name="label" translatable="yes" context="croppage|origsize">_Original Size</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label1">Crop</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="scaleframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label6">_Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">widthzoom</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="widthzoom">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label7">_Height:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">heightzoom</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="heightzoom">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment5</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label10">Scale</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="sizeframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label8">_Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">width</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="width">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label9">_Height:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">height</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="height">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="croppage|label11">Image Size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="label2"/>
+ <widget name="label3"/>
+ <widget name="label4"/>
+ <widget name="label5"/>
+ <widget name="label6"/>
+ <widget name="label7"/>
+ <widget name="label8"/>
+ <widget name="label9"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="left"/>
+ <widget name="right"/>
+ <widget name="top"/>
+ <widget name="bottom"/>
+ <widget name="widthzoom"/>
+ <widget name="heightzoom"/>
+ <widget name="width"/>
+ <widget name="height"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/cuiimapdlg.ui b/cui/uiconfig/ui/cuiimapdlg.ui
new file mode 100644
index 000000000..5618564cb
--- /dev/null
+++ b/cui/uiconfig/ui/cuiimapdlg.ui
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="IMapDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="cuiimapdlg|IMapDialog">Properties</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="cuiimapdlg|label1">_URL:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">urlentry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="urlentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="urlentry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cuiimapdlg|extended_tip|urlentry">Enter the URL for the file that you want to open when you click the selected hotspot.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="cuiimapdlg|label2">F_rame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">frameCB</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="frameCB">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="combobox-entry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="frameCB-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cuiimapdlg|extended_tip|frameCB">Enter the name of the target frame that you want to open the URL in. You can also select a standard frame name that is recognized by all browsers from the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="cuiimapdlg|label3">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">nameentry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="nameentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="nameentry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cuiimapdlg|extended_tip|nameentry">Enter a name for the image.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="cuiimapdlg|label4">_Text Alternative:</property>
+ <property name="tooltip_text" translatable="yes" context="cuiimapdlg|label4">Enter a short description of essential features of the image map for persons who do not see the image.</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">textentry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="textentry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="textentry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cuiimapdlg|extended_tip|textentry">Enter the text that you want to display when the mouse rests on the hotspot in a browser. This text can also be used by assistive technologies.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="cuiimapdlg|label5">_Description:</property>
+ <property name="tooltip_text" translatable="yes" context="cuiimapdlg|label5">Give a longer explanation of the image map if it is too complex to be described briefly in “Text Alternative.”</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">descTV</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="descTV">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscroll_policy">natural</property>
+ <property name="vscroll_policy">natural</property>
+ <property name="wrap_mode">word</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="descTV-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cuiimapdlg|extended_tip|descTV">Enter a description for the hotspot.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="IMapDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cuiimapdlg|extended_tip|IMapDialog">Lists the properties for the selected hotspot.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/customizedialog.ui b/cui/uiconfig/ui/customizedialog.ui
new file mode 100644
index 000000000..6efe09636
--- /dev/null
+++ b/cui/uiconfig/ui/customizedialog.ui
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="CustomizeDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="customizedialog|CustomizeDialog">Customize</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="menus">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customizedialog|menus">Menus</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="toolbars">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customizedialog|toolbars">Toolbars</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="notebookbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customizedialog|notebookbar">Notebookbar</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="contextmenus">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customizedialog|contextmenus">Context Menus</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="keyboard">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customizedialog|keyboard">Keyboard</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="events">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="customizedialog|events">Events</property>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">reset</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/databaselinkdialog.ui b/cui/uiconfig/ui/databaselinkdialog.ui
new file mode 100644
index 000000000..e307b2ea3
--- /dev/null
+++ b/cui/uiconfig/ui/databaselinkdialog.ui
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="DatabaseLinkDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="databaselinkdialog|DatabaseLinkDialog">Create Database Link</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="browse">
+ <property name="label" translatable="yes" context="databaselinkdialog|browse">Browse...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="browse-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|browse">Opens a file dialog where you can select the database file.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="databaselinkdialog|label1">_Database file:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">url</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="url">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="URLBox-entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="databaselinkdialog|label4">Registered _name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">52</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|name">Enter a name for the database. The office suite uses this name to access the database.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="alttitle">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="databaselinkdialog|alttitle">Edit Database Link</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="DatabaseLinkDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|DatabaseLinkDialog">Creates or edits an entry in the Databases tab page.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/dbregisterpage.ui b/cui/uiconfig/ui/dbregisterpage.ui
new file mode 100644
index 000000000..c6d6000d3
--- /dev/null
+++ b/cui/uiconfig/ui/dbregisterpage.ui
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="DbRegisterPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="pathctrl">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="dbregisterpage|type">Registered name</property>
+ <property name="clickable">True</property>
+ <property name="reorderable">True</property>
+ <property name="sort_indicator">True</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="dbregisterpage|path">Database file</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="spacing">3</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="new">
+ <property name="label" translatable="yes" context="dbregisterpage|new">_New...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="new-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|new">Opens the Database Link dialog to create a new entry.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="dbregisterpage|delete">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|delete">Removes the selected entry from the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="dbregisterpage|edit">_Edit...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|edit">Opens the Database Link dialog to edit the selected entry.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dbregisterpage|label1">Registered Databases</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/diagramdialog.ui b/cui/uiconfig/ui/diagramdialog.ui
new file mode 100644
index 000000000..43b181f3d
--- /dev/null
+++ b/cui/uiconfig/ui/diagramdialog.ui
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="DiagramDialog">
+ <property name="can_focus">False</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="btnOk">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeDiagram">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkTextView" id="textAdd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnAdd">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnRemove">
+ <property name="label" translatable="yes" context="stock">_Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">btnOk</action-widget>
+ <action-widget response="-6">btnCancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/dimensionlinestabpage.ui b/cui/uiconfig/ui/dimensionlinestabpage.ui
new file mode 100644
index 000000000..f3c1de0ab
--- /dev/null
+++ b/cui/uiconfig/ui/dimensionlinestabpage.ui
@@ -0,0 +1,557 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">-10</property>
+ <property name="upper">10</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">-10</property>
+ <property name="upper">10</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">-10</property>
+ <property name="upper">10</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="lower">-10</property>
+ <property name="upper">10</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="lower">-10</property>
+ <property name="upper">10</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkBox" id="DimensionLinesTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="FL_LINE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_DIST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_LINE_DIST">Line _distance:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_LINE_DIST</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_HELPLINE_OVERHANG">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_HELPLINE_OVERHANG">Guide _overhang:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HELPLINE_OVERHANG</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_HELPLINE_DIST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_HELPLINE_DIST">_Guide distance:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HELPLINE_DIST</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_HELPLINE1_LEN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_HELPLINE1_LEN">_Left guide:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HELPLINE1_LEN</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_HELPLINE2_LEN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_HELPLINE2_LEN">_Right guide:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HELPLINE2_LEN</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_DECIMALPLACES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_DECIMALPLACES">Decimal _places:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_DECIMALPLACES</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_BELOW_REF_EDGE">
+ <property name="label" translatable="yes" context="dimensionlinestabpage|TSB_BELOW_REF_EDGE">Measure _below object</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">12</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_BELOW_REF_EDGE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|TSB_BELOW_REF_EDGE">Reverses the properties set in the Line area.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_LINE_DIST">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_LINE_DIST-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|MTR_LINE_DIST">Specifies the distance between the dimension line and the baseline (line distance = 0).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HELPLINE_OVERHANG">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HELPLINE_OVERHANG-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|MTR_FLD_HELPLINE_OVERHANG">Specifies the length of the left and right guides starting at the baseline (line distance = 0). Positive values extend the guides above the baseline and negative values extend the guides below the baseline.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HELPLINE_DIST">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HELPLINE_DIST-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|MTR_FLD_HELPLINE_DIST">Specifies the length of the right and left guides starting at the dimension line. Positive values extend the guides above the dimension line and negative values extend the guides below the dimension line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HELPLINE1_LEN">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment5</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HELPLINE1_LEN-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|MTR_FLD_HELPLINE1_LEN">Specifies the length of the left guide starting at the dimension line. Positive values extend the guide below the dimension line and negative values extend the guide above the dimension line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HELPLINE2_LEN">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HELPLINE2_LEN-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|MTR_FLD_HELPLINE2_LEN">Specifies the length of the right guide starting at the dimension line. Positive values extend the guide below the dimension line and negative values extend the guide above the dimension line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_DECIMALPLACES">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_DECIMALPLACES-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|MTR_FLD_DECIMALPLACES">Specifies the number of decimal places used for the display of line properties.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|label1">Line</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_LABEL">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|FT_POSITION">_Text position</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="frameselwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_POSITION-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|CTL_POSITION">Determines the position of the dimension text with respect to the dimension line and the guides.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOPOSV">
+ <property name="label" translatable="yes" context="dimensionlinestabpage|TSB_AUTOPOSV">_AutoVertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOPOSV-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|TSB_AUTOPOSV">Determines the optimal vertical position for the dimension text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOPOSH">
+ <property name="label" translatable="yes" context="dimensionlinestabpage|TSB_AUTOPOSH">A_utoHorizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOPOSH-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|TSB_AUTOPOSH">Determines the optimal horizontal position for the dimension text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_PARALLEL">
+ <property name="label" translatable="yes" context="dimensionlinestabpage|TSB_PARALLEL">_Parallel to line</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_PARALLEL-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|TSB_PARALLEL">If enabled, displays the text parallel to the dimension line. If disabled, the text is shown at 90 degrees to the dimension line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_SHOW_UNIT">
+ <property name="label" translatable="yes" context="dimensionlinestabpage|TSB_SHOW_UNIT">Show _measurement units</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_SHOW_UNIT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|TSB_SHOW_UNIT">Shows or hides the dimension measurement unit. You can select a measurement unit you want to display from the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_UNIT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_UNIT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="dimensionlinestabpage|extended_tip|LB_UNIT">Shows or hides the dimension measurement units. You can also select a measurement unit you want to display from the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|label2">Legend</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="STR_MEASURE_AUTOMATIC">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="dimensionlinestabpage|STR_MEASURE_AUTOMATIC">Automatic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-end">12</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/editdictionarydialog.ui b/cui/uiconfig/ui/editdictionarydialog.ui
new file mode 100644
index 000000000..6d4fe3493
--- /dev/null
+++ b/cui/uiconfig/ui/editdictionarydialog.ui
@@ -0,0 +1,419 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="EditDictionaryDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="editdictionarydialog|EditDictionaryDialog">Edit Custom Dictionary</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkComboBoxText" id="book">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="book-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="book">Specifies the book to be edited.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="lang">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lang-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lang">Assigns a new language to the current custom dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="book_label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="editdictionarydialog|book_label">_Book:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">book</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lang_label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="editdictionarydialog|lang_label">_Language:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">lang</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=3 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkEntry" id="replace">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="replace">This input field is only available if you are editing an exception dictionary or a language-dependent custom dictionary. In exception dictionaries, the field shows the alternative suggestion for the current word in the "Word" text box. In language-dependent custom dictionaries, the field contains a known root word, as a model of affixation of the new word or its usage in compound words. For example, in a German custom dictionary, the new word “Litschi” (lychee) with the model word “Gummi” (gum) will result recognition of “Litschis” (lychees), “Litschibaum” (lychee tree), “Litschifrucht” (lychee fruit) etc.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="word">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="word-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="word">You can type a new word for inclusion in the dictionary. In the list below you will see the contents of the current custom dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="word_label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="editdictionarydialog|word_label">_Word</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">word</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="replace_label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="editdictionarydialog|replace_label">_Replace By</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">replace</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="replaces">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="versions-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="words">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer3"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">25</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout-style">start</property>
+ <child>
+ <object class="GtkButton" id="newreplace">
+ <property name="label" translatable="yes" context="editdictionarydialog|newreplace">_New</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newreplace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="newreplace">Adds the word in the Word text field to your current custom dictionary. The word in the Suggestion field is also added when working with exception dictionaries.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="editdictionarydialog|delete">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="delete">Removes the marked word from the current custom dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-7">close</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="EditDictionaryDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="EditDictionaryDialog">In the Edit Custom Dictionary dialog you have the option to enter new terms or edit existing entries.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/editmodulesdialog.ui b/cui/uiconfig/ui/editmodulesdialog.ui
new file mode 100644
index 000000000..10353d4f0
--- /dev/null
+++ b/cui/uiconfig/ui/editmodulesdialog.ui
@@ -0,0 +1,353 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name weight1 -->
+ <column type="gint"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore6">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="EditModulesDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="editmodulesdialog|EditModulesDialog">Edit Modules</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkLinkButton" id="moredictslink">
+ <property name="label" translatable="yes" context="editmodulesdialog|moredictslink">Get more dictionaries online...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ <property name="uri">https://extensions.libreoffice.org/dictionaries/</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="editmodulesdialog|label2">Language:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">language</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="language">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">liststore6</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext9"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="language-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="language">Specifies the language of the module.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="up">
+ <property name="label" translatable="yes" context="editmodulesdialog|up">Move Up</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="up-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="up">Increases the priority of the module selected in the list box by one level.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="down">
+ <property name="label" translatable="yes" context="editmodulesdialog|down">Move Down</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="down-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="down">Decreases the priority of the module selected in the list box by one level.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="back">
+ <property name="label" translatable="yes" context="editmodulesdialog|back">_Back</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="back-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="back">Click here to undo the current changes in the list box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="lingudicts">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0,50000000000000000000</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0,50000000000000000000</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ <attribute name="weight">5</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingudicts-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingudicts">Specifies the language and the available spelling, hyphenation and Thesaurus sub-modules for the selected module.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="editmodulesdialog|label1">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">close</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/effectspage.ui b/cui/uiconfig/ui/effectspage.ui
new file mode 100644
index 000000000..527d8d8e5
--- /dev/null
+++ b/cui/uiconfig/ui/effectspage.ui
@@ -0,0 +1,716 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentPercent">
+ <property name="upper">100</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=4 -->
+ <object class="GtkGrid" id="EffectsPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">end</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="effectspage|preview-atkobject">Preview</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="Effects">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=4 n-rows=4 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="effectsft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|effectsft">_Case:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">effectslb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="reliefft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|reliefft">R_elief:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">relieflb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="effectslb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="effectspage|liststore1">(Without)</item>
+ <item translatable="yes" context="effectspage|liststore1">UPPERCASE</item>
+ <item translatable="yes" context="effectspage|liststore1">lowercase</item>
+ <item translatable="yes" context="effectspage|liststore1">Capitalize Every Word</item>
+ <item translatable="yes" context="effectspage|liststore1">Small capitals</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="effectslb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|effectslb">Select the font effects that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="relieflb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="effectspage|liststore2">(Without)</item>
+ <item translatable="yes" context="effectspage|liststore2">Embossed</item>
+ <item translatable="yes" context="effectspage|liststore2">Engraved</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relieflb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|relieflb">Select a relief effect to apply to the selected text. The embossed relief makes the characters appear as if they are raised above the page. The engraved relief makes the characters appear as if they are pressed into the page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="emphasislb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="effectspage|liststore3">(Without)</item>
+ <item translatable="yes" context="effectspage|liststore3">Dot</item>
+ <item translatable="yes" context="effectspage|liststore3">Circle</item>
+ <item translatable="yes" context="effectspage|liststore3">Disc</item>
+ <item translatable="yes" context="effectspage|liststore3">Accent</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="emphasislb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|emphasislb">Select a character to display over or below the entire length of the selected text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="positionlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="effectspage|liststore4">Above text</item>
+ <item id="1" translatable="yes" context="effectspage|liststore4">Below text</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="positionlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|positionlb">Specify where to display the emphasis marks.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="positionft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|positionft">_Position:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">positionlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="emphasisft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|emphasisft">Emphasis _mark:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">emphasislb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="outlinecb">
+ <property name="label" translatable="yes" context="effectspage|outlinecb">Outli_ne</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="outlinecb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|outlinecb">Displays the outline of the selected characters. This effect does not work with every font.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="shadowcb">
+ <property name="label" translatable="yes" context="effectspage|shadowcb">Shado_w</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="shadowcb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|shadowcb">Adds a shadow that casts below and to the right of the selected characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="hiddencb">
+ <property name="label" translatable="yes" context="effectspage|hiddencb">Hi_dden</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hiddencb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|hiddencb">Hides the selected characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="effectsft2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|effectsft2">Effects</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="TextDecoration">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=3 n-rows=4 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|label46">O_verlining:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">overlinelb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|label47">Stri_kethrough:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">strikeoutlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|label48">_Underlining:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">underlinelb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="overlinelb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="effectspage|liststore6">(Without)</item>
+ <item id="1" translatable="yes" context="effectspage|liststore6">Single</item>
+ <item id="2" translatable="yes" context="effectspage|liststore6">Double</item>
+ <item id="12" translatable="yes" context="effectspage|liststore6">Bold</item>
+ <item id="3" translatable="yes" context="effectspage|liststore6">Dotted</item>
+ <item id="13" translatable="yes" context="effectspage|liststore6">Dotted (Bold)</item>
+ <item id="5" translatable="yes" context="effectspage|liststore6">Dash</item>
+ <item id="14" translatable="yes" context="effectspage|liststore6">Dash (Bold)</item>
+ <item id="6" translatable="yes" context="effectspage|liststore6">Long Dash</item>
+ <item id="15" translatable="yes" context="effectspage|liststore6">Long Dash (Bold)</item>
+ <item id="7" translatable="yes" context="effectspage|liststore6">Dot Dash</item>
+ <item id="16" translatable="yes" context="effectspage|liststore6">Dot Dash (Bold)</item>
+ <item id="8" translatable="yes" context="effectspage|liststore6">Dot Dot Dash</item>
+ <item id="17" translatable="yes" context="effectspage|liststore6">Dot Dot Dash (Bold)</item>
+ <item id="10" translatable="yes" context="effectspage|liststore6">Wave</item>
+ <item id="18" translatable="yes" context="effectspage|liststore6">Wave (Bold)</item>
+ <item id="11" translatable="yes" context="effectspage|liststore6">Double Wave</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="overlinelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|overlinelb">Select the overlining style that you want to apply. To apply the overlining to words only, select the Individual Words box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="underlinelb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="effectspage|liststore6">(Without)</item>
+ <item id="1" translatable="yes" context="effectspage|liststore6">Single</item>
+ <item id="2" translatable="yes" context="effectspage|liststore6">Double</item>
+ <item id="12" translatable="yes" context="effectspage|liststore6">Bold</item>
+ <item id="3" translatable="yes" context="effectspage|liststore6">Dotted</item>
+ <item id="13" translatable="yes" context="effectspage|liststore6">Dotted (Bold)</item>
+ <item id="5" translatable="yes" context="effectspage|liststore6">Dash</item>
+ <item id="14" translatable="yes" context="effectspage|liststore6">Dash (Bold)</item>
+ <item id="6" translatable="yes" context="effectspage|liststore6">Long Dash</item>
+ <item id="15" translatable="yes" context="effectspage|liststore6">Long Dash (Bold)</item>
+ <item id="7" translatable="yes" context="effectspage|liststore6">Dot Dash</item>
+ <item id="16" translatable="yes" context="effectspage|liststore6">Dot Dash (Bold)</item>
+ <item id="8" translatable="yes" context="effectspage|liststore6">Dot Dot Dash</item>
+ <item id="17" translatable="yes" context="effectspage|liststore6">Dot Dot Dash (Bold)</item>
+ <item id="10" translatable="yes" context="effectspage|liststore6">Wave</item>
+ <item id="18" translatable="yes" context="effectspage|liststore6">Wave (Bold)</item>
+ <item id="11" translatable="yes" context="effectspage|liststore6">Double Wave</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="underlinelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|underlinelb">Select the underlining style that you want to apply. To apply the underlining to words only, select the Individual Words box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="strikeoutlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="effectspage|liststore5">(Without)</item>
+ <item id="1" translatable="yes" context="effectspage|liststore5">Single</item>
+ <item id="2" translatable="yes" context="effectspage|liststore5">Double</item>
+ <item id="4" translatable="yes" context="effectspage|liststore5">Bold</item>
+ <item id="5" translatable="yes" context="effectspage|liststore5">With /</item>
+ <item id="6" translatable="yes" context="effectspage|liststore5">With X</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="strikeoutlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|strikeoutlb">Select a strikethrough style for the selected text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="underlinecolorlb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="underlinecolorlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|underlinecolorlb">Select the color for the underlining.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="overlinecolorlb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="overlinecolorlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|overlinecolorlb">Select the color for the overlining.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="individualwordscb">
+ <property name="label" translatable="yes" context="effectspage|individualwordscb">_Individual words</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="individualwordscb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|individualwordscb">Applies the selected effect only to words and ignores spaces.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="overlinecolorft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">overlinecolorlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="underlinecolorft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">underlinecolorlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="textdecoration">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|textdecoration">Text Decoration</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FontColor">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=4 n-rows=2 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="fontcolorft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|fontcolorft">_Font color:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">fontcolorlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="fontcolorlb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw-indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fontcolorlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|fontcolorlb">Sets the color for the selected text. If you select Automatic, the text color is set to black for light backgrounds and to white for dark backgrounds.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="a11ywarning">
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|a11ywarning">Accessibility option "Use automatic font color for screen display" is active. Font color attributes are not currently used to display text.</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">50</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="fonttransparencyft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|fonttransparencyft">_Transparency:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">fonttransparencymtr</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="fonttransparencymtr">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentPercent</property>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="fontcolorft3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="effectspage|fontcolorft3">Font Color</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="EffectsPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="effectspage|extended_tip|EffectsPage">Specify the font effects that you want to use.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="effectsft"/>
+ <widget name="reliefft"/>
+ <widget name="positionft"/>
+ <widget name="emphasisft"/>
+ <widget name="label3"/>
+ <widget name="label4"/>
+ <widget name="label5"/>
+ <widget name="fontcolorft"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="effectslb"/>
+ <widget name="relieflb"/>
+ <widget name="emphasislb"/>
+ <widget name="positionlb"/>
+ <widget name="overlinelb"/>
+ <widget name="underlinelb"/>
+ <widget name="strikeoutlb"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/embossdialog.ui b/cui/uiconfig/ui/embossdialog.ui
new file mode 100644
index 000000000..5184d2b77
--- /dev/null
+++ b/cui/uiconfig/ui/embossdialog.ui
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="EmbossDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="embossdialog|EmbossDialog">Emboss</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="embossdialog|label2">_Light source:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">lightsource</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="frameselwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="lightsource">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="embossdialog|label1">Parameters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="EmbossDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="embossdialog|extended_tip|EmbossDialog">Displays a dialog for creating reliefs.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/entrycontextmenu.ui b/cui/uiconfig/ui/entrycontextmenu.ui
new file mode 100644
index 000000000..21295d6fd
--- /dev/null
+++ b/cui/uiconfig/ui/entrycontextmenu.ui
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMenu" id="menu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="remove">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="entrycontextmenu|remove">_Remove</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="rename">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="entrycontextmenu|rename">R_ename...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="add">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="entrycontextmenu|add">_Add</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="changeIcon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="entrycontextmenu|changeIcon">_Change Icon...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="resetIcon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="entrycontextmenu|resetIcon">Re_set Icon</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="restoreDefault">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="entrycontextmenu|restoreDefault">Restore _Default Command</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/eventassigndialog.ui b/cui/uiconfig/ui/eventassigndialog.ui
new file mode 100644
index 000000000..2ce22196d
--- /dev/null
+++ b/cui/uiconfig/ui/eventassigndialog.ui
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="EventAssignDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="eventassigndialog|EventAssignDialog">Assign Macro</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/eventassignpage.ui b/cui/uiconfig/ui/eventassignpage.ui
new file mode 100644
index 000000000..78bf01cc4
--- /dev/null
+++ b/cui/uiconfig/ui/eventassignpage.ui
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="EventAssignPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <property name="row_homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="assignments">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="eventassignpage|eventft">Event</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="eventassignpage|assignft">Assigned Action</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="assignments-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventassignpage|extended_tip|assignments">Lists the events that can trigger a macro.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="libraryft1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="eventassignpage|libraryft1">Assignments</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="assign">
+ <property name="label" translatable="yes" context="eventassignpage|assign">Assign</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="assign-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventassignpage|extended_tip|assign">Assigns the selected macro to the selected event.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="eventassignpage|delete">Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventassignpage|extended_tip|delete">Removes the macro assignment from the selected entry.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">6</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="groupframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="libraries">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="libraries-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventassignpage|extended_tip|libraries">Lists the office suite program and any open documents.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="macrotoft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="eventassignpage|macrotoft">Macro From</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="macroframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="macros">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="macros-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventassignpage|extended_tip|macros">Lists the available macros. Select the macro that you want to assign to the selected event, and then click Assign.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="existingmacrosft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="eventassignpage|existingmacrosft">Existing Macros</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="EventAssignPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventassignpage|extended_tip|EventAssignPage">Specifies the macro to run when you click an image, frame, or an OLE object.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/eventsconfigpage.ui b/cui/uiconfig/ui/eventsconfigpage.ui
new file mode 100644
index 000000000..b1309fc40
--- /dev/null
+++ b/cui/uiconfig/ui/eventsconfigpage.ui
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="EventsConfigPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="eventsconfigpage|label1">Assign:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="macro">
+ <property name="label" translatable="yes" context="eventsconfigpage|macro">M_acro...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="macro-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventsconfigpage|extended_tip|macro">Opens the Macro Selector to assign a macro to the selected event.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="eventsconfigpage|delete">_Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventsconfigpage|extended_tip|delete">Deletes the macro or component assignment for the selected event.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="eventsconfigpage|label2">Save in:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">savein</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="savein">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="savein-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventsconfigpage|extended_tip|savein">Select first where to save the event binding, in the current document or in the office suite.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="events">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="eventsconfigpage|eventft">Event</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="eventsconfigpage|actionft">Assigned Action</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="events-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventsconfigpage|extended_tip|events">The big list box lists the events and the assigned macros. After you selected the location in the Save In list box, select an event in the big list box. Then click Assign Macro.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="EventsConfigPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="eventsconfigpage|extended_tip|EventsConfigPage">Assigns macros to program events. The assigned macro runs automatically every time the selected event occurs.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/fileextcheckdialog.ui b/cui/uiconfig/ui/fileextcheckdialog.ui
new file mode 100644
index 000000000..da0c3b8da
--- /dev/null
+++ b/cui/uiconfig/ui/fileextcheckdialog.ui
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="FileExtCheckDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkCheckButton" id="cbPerformCheck">
+ <property name="label" translatable="yes" context="FileExtCheck|Checkbox">_Perform check on startup</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="tooltip-text" translatable="yes" context="FileExtCheck|Checkbox_Tooltip">Enable the dialog again at Tools &gt; Options &gt; General</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnOk">
+ <property name="label" translatable="yes" context="FileExtCheckDialog|Ok_Button">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="has-focus">True</property>
+ <property name="is-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbText">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="wrap">True</property>
+ <property name="width-chars">50</property>
+ <property name="max-width-chars">50</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">btnCancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/fmsearchdialog.ui b/cui/uiconfig/ui/fmsearchdialog.ui
new file mode 100644
index 000000000..57f15b115
--- /dev/null
+++ b/cui/uiconfig/ui/fmsearchdialog.ui
@@ -0,0 +1,889 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="RecordSearchDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="fmsearchdialog|RecordSearchDialog">Record Search</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox3">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="pbSearchAgain">
+ <property name="label" translatable="yes" context="fmsearchdialog|pbSearchAgain">S_earch</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="pbSearchAgain-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|pbSearchAgain">Starts or cancels the search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="close-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|close">Closes the dialog. The settings of the last search will be saved until you quit the office suite.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="searchframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkComboBoxText" id="cmbSearchText">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="combobox-entry2">
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cmbSearchText-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cmbSearchText">Enter the search term in the box or select it from the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbSearchForText">
+ <property name="label" translatable="yes" context="fmsearchdialog|rbSearchForText">_Text:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rbSearchForText-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|rbSearchForText">Enter the search term in the box or select it from the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbSearchForNull">
+ <property name="label" translatable="yes" context="fmsearchdialog|rbSearchForNull">Field content is _NULL</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbSearchForText</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rbSearchForNull-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|rbSearchForNull">Specifies that fields will be found that contain no data.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbSearchForNotNull">
+ <property name="label" translatable="yes" context="fmsearchdialog|rbSearchForNotNull">Field content is not NU_LL</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbSearchForText</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rbSearchForNotNull-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|rbSearchForNotNull">Specifies that fields will be found that contain data.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="flSearchFor">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|flSearchFor">_Search for</property>
+ <property name="use-underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="wheretosearchframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=3 -->
+ <object class="GtkGrid" id="grid11">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="rbSingleField">
+ <property name="label" translatable="yes" context="fmsearchdialog|rbSingleField">_Single field:</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rbSingleField-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|rbSingleField">Searches through a specified data field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="lbField">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lbField-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|lbField">Searches through a specified data field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbAllFields">
+ <property name="label" translatable="yes" context="fmsearchdialog|rbAllFields">_All fields</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbSingleField</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rbAllFields-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|rbAllFields">Searches through all fields.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="ftForm">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|ftForm">Form:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">lbForm</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="lbForm">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lbForm-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|lbForm">Specifies the logical form in which you want the search to take place.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="replacedesc">
+ <property name="width-request">1</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|label2">Where to Search</property>
+ <property name="use-underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="settingsframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="ftPosition">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|ftPosition">_Position:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">lbPosition</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="lbPosition">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lbPosition-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|lbPosition">Specifies the relationship of the search term and the field contents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=3 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="HalfFullFormsCJK">
+ <property name="label" translatable="yes" context="fmsearchdialog|HalfFullFormsCJK">Match character wi_dth</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HalfFullFormsCJK-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|HalfFullFormsCJK">Distinguishes between half-width and full-width character forms.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="SoundsLikeCJK">
+ <property name="label" translatable="yes" context="fmsearchdialog|SoundsLikeCJK">Sounds like (_Japanese)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SoundsLikeCJK-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|SoundsLikeCJK">Lets you specify the search options for similar notation used in Japanese text. Select this checkbox, and then click the Sounds button to specify the search options.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="SoundsLikeCJKSettings">
+ <property name="label" translatable="yes" context="fmsearchdialog|SoundsLikeCJKSettings">Similarities...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SoundsLikeCJKSettings-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|SoundsLikeCJKSettings">Sets the search options for similar notation used in Japanese text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="cbApprox">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbApprox">S_imilarity search</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbApprox-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbApprox">Find terms that are similar to the Find text. Select this checkbox, and then click the Similarities button to define the similarity options.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="pbApproxSettings">
+ <property name="label" translatable="yes" context="fmsearchdialog|pbApproxSettings">Similarities...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="pbApproxSettings-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|pbApproxSettings">Find terms that are similar to the Find text. Select this checkbox, and then click the Similarities button to define the similarity options.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbCase">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbCase">_Match case</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbCase-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbCase">Specifies that upper and lower case are taken into consideration during the search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbStartOver">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbStartOver">Fr_om top</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbStartOver-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbStartOver">Restarts the search. A forward search restarts with the first record. A backwards search restarts with the last record.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbRegular">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbRegular">_Regular expression</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbRegular-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbRegular">Searches with regular expressions.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbUseFormat">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbUseFormat">Appl_y field format</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbUseFormat-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbUseFormat">Specifies that all field formats are considered when searching in the current document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbBackwards">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbBackwards">Search _backwards</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbBackwards-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbBackwards">Specifies that the search process will run in reverse direction, from the last to the first record.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbWildCard">
+ <property name="label" translatable="yes" context="fmsearchdialog|cbWildCard">_Wildcard expression</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cbWildCard-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|cbWildCard">Allows a search with a * or ? wildcard.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="flOptions">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|flOptions">Settings</property>
+ <property name="use-underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="stateframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=3 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="ftRecordLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|ftRecordLabel">Record:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="ftRecord">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|ftRecord">record count</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="ftHint">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="flState">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="fmsearchdialog|flState">State</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">close</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="RecordSearchDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fmsearchdialog|extended_tip|RecordSearchDialog">Searches database tables and forms.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="rbSearchForText"/>
+ <widget name="rbSingleField"/>
+ <widget name="rbAllFields"/>
+ <widget name="ftForm"/>
+ <widget name="ftPosition"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="lbField"/>
+ <widget name="lbForm"/>
+ <widget name="lbPosition"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/fontfeaturesdialog.ui b/cui/uiconfig/ui/fontfeaturesdialog.ui
new file mode 100644
index 000000000..f33f2f779
--- /dev/null
+++ b/cui/uiconfig/ui/fontfeaturesdialog.ui
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="FontFeaturesDialog">
+ <property name="width_request">-1</property>
+ <property name="height_request">-1</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="fontfeaturesdialog|FontFeaturesDialog">Font Features</property>
+ <property name="modal">True</property>
+ <property name="default_width">1</property>
+ <property name="default_height">1</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="contentWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="contentGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="row-homogeneous">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="previewwin">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-end">12</property>
+ <property name="valign">end</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="fontfeaturesdialog|preview-atkobject">Preview</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="FontFeaturesDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="fontfeaturesdialog|extended_tip|FontFeaturesDialog">Select and apply font typographical features to characters.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/fontfragment.ui b/cui/uiconfig/ui/fontfragment.ui
new file mode 100644
index 000000000..e66cd71b7
--- /dev/null
+++ b/cui/uiconfig/ui/fontfragment.ui
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="fontentry">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">combo</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="check">
+ <property name="label" translatable="no">placeholder</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="combo">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/formatcellsdialog.ui b/cui/uiconfig/ui/formatcellsdialog.ui
new file mode 100644
index 000000000..9df8d7b34
--- /dev/null
+++ b/cui/uiconfig/ui/formatcellsdialog.ui
@@ -0,0 +1,352 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="FormatCellsDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="formatcellsdialog|FormatCellsDialog">Table Properties</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="formatcellsdialog|name">Font</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="effects">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="formatcellsdialog|effects">Font Effects</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="border">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="formatcellsdialog|border">Borders</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="area">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="formatcellsdialog|area">Background</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="shadow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="formatcellsdialog|shadow">Shadow</property>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/formatnumberdialog.ui b/cui/uiconfig/ui/formatnumberdialog.ui
new file mode 100644
index 000000000..1a686ca49
--- /dev/null
+++ b/cui/uiconfig/ui/formatnumberdialog.ui
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="FormatNumberDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="formatnumberdialog|FormatNumberDialog">Format Number</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/galleryapplyprogress.ui b/cui/uiconfig/ui/galleryapplyprogress.ui
new file mode 100644
index 000000000..614810c3e
--- /dev/null
+++ b/cui/uiconfig/ui/galleryapplyprogress.ui
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GalleryApplyProgress">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="galleryapplyprogress|GalleryApplyProgress">Apply</property>
+ <property name="modal">True</property>
+ <property name="type_hint">normal</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkLabel" id="file">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">40</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="galleryapplyprogress|label2">File</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/galleryfilespage.ui b/cui/uiconfig/ui/galleryfilespage.ui
new file mode 100644
index 000000000..559037348
--- /dev/null
+++ b/cui/uiconfig/ui/galleryfilespage.ui
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="GalleryFilesPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="galleryfilespage|label1">_File type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">filetype</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="filetype">
+ <property name="width_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="comboboxtext-entry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="filetype-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryfilespage|extended_tip|filetype">Select the type of file that you want to add.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="files">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="files-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="galleryfilespage|files-atkobject">Files Found</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryfilespage|extended_tip|files">Lists the available files. Select the file(s) that you want to add, and then click Add. To add all of the files in the list, click Add All.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">24</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="preview">
+ <property name="label" translatable="yes" context="galleryfilespage|preview">Pr_eview</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryfilespage|extended_tip|preview">Displays or hides a preview of the selected file.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="image-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="galleryfilespage|image-atkobject">Preview</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="findfiles">
+ <property name="label" translatable="yes" context="galleryfilespage|findfiles">_Find Files...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="findfiles-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryfilespage|extended_tip|findfiles">Locate the directory containing the files that you want to add, and then click OK.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryfilespage|extended_tip|add">Adds the selected file(s) to the current theme.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="addall">
+ <property name="label" translatable="yes" context="galleryfilespage|addall">A_dd All</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="addall-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryfilespage|extended_tip|addall">Adds all of the files in the list to the current theme.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/gallerygeneralpage.ui b/cui/uiconfig/ui/gallerygeneralpage.ui
new file mode 100644
index 000000000..2a5f93f7d
--- /dev/null
+++ b/cui/uiconfig/ui/gallerygeneralpage.ui
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="GalleryGeneralPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">24</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerygeneralpage|label1">Modified:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="modified">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerygeneralpage|label2">Type:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="type">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerygeneralpage|label3">Location:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerygeneralpage|label4">Contents:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="location">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="contents">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkBox" id="imagecontainer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <accessibility>
+ <relation type="label-for" target="name"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="image-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="gallerygeneralpage|image-atkobject">Theme Name</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="image"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="label1"/>
+ <widget name="label2"/>
+ <widget name="label3"/>
+ <widget name="label4"/>
+ <widget name="imagecontainer"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/gallerysearchprogress.ui b/cui/uiconfig/ui/gallerysearchprogress.ui
new file mode 100644
index 000000000..888d959e1
--- /dev/null
+++ b/cui/uiconfig/ui/gallerysearchprogress.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GallerySearchProgress">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="gallerysearchprogress|GallerySearchProgress">Find</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkLabel" id="file">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="ellipsize">end</property>
+ <property name="width_chars">40</property>
+ <property name="single_line_mode">True</property>
+ <property name="max_width_chars">40</property>
+ <property name="xalign">0</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerysearchprogress|label1">File Type</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkLabel" id="dir">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">40</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerysearchprogress|label2">Directory</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/gallerythemedialog.ui b/cui/uiconfig/ui/gallerythemedialog.ui
new file mode 100644
index 000000000..2c8bd4be3
--- /dev/null
+++ b/cui/uiconfig/ui/gallerythemedialog.ui
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GalleryThemeDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="gallerythemedialog|GalleryThemeDialog" comments="%1 will be replaced by a gallery theme name">Properties of %1</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="general">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerythemedialog|general">General</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="files">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerythemedialog|files">Files</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/gallerythemeiddialog.ui b/cui/uiconfig/ui/gallerythemeiddialog.ui
new file mode 100644
index 000000000..38f654cee
--- /dev/null
+++ b/cui/uiconfig/ui/gallerythemeiddialog.ui
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GalleryThemeIDDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="gallerythemeiddialog|GalleryThemeIDDialog">Theme ID</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerythemeiddialog|label2">ID:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/gallerytitledialog.ui b/cui/uiconfig/ui/gallerytitledialog.ui
new file mode 100644
index 000000000..6da25e70d
--- /dev/null
+++ b/cui/uiconfig/ui/gallerytitledialog.ui
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GalleryTitleDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="gallerytitledialog|GalleryTitleDialog">Enter Title</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gallerytitledialog|label2">Title:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="width_chars">32</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">500</property>
+ <property name="value">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/galleryupdateprogress.ui b/cui/uiconfig/ui/galleryupdateprogress.ui
new file mode 100644
index 000000000..8729cdcc4
--- /dev/null
+++ b/cui/uiconfig/ui/galleryupdateprogress.ui
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GalleryUpdateProgress">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="galleryupdateprogress|GalleryUpdateProgress">Update</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkLabel" id="file">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="width_chars">40</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="galleryupdateprogress|label2">File</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="GalleryUpdateProgress-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="galleryupdateprogress|extended_tip|GalleryUpdateProgress">Updates the view in the window or in the selected object.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/gradientpage.ui b/cui/uiconfig/ui/gradientpage.ui
new file mode 100644
index 000000000..6a66dad09
--- /dev/null
+++ b/cui/uiconfig/ui/gradientpage.ui
@@ -0,0 +1,754 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">3</property>
+ <property name="upper">256</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">3</property>
+ <property name="upper">256</property>
+ <property name="value">3</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="angleadjustment">
+ <property name="upper">359</property>
+ <property name="step_increment">15</property>
+ </object>
+ <object class="GtkAdjustment" id="angleadjustmentslider">
+ <property name="upper">359</property>
+ <property name="step_increment">15</property>
+ <property name="page_increment">15</property>
+ </object>
+ <object class="GtkAdjustment" id="percentadjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ </object>
+ <object class="GtkAdjustment" id="percentadjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ </object>
+ <object class="GtkAdjustment" id="percentadjustment2">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ </object>
+ <object class="GtkAdjustment" id="percentadjustment3">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ </object>
+ <object class="GtkAdjustment" id="percentadjustment4">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ </object>
+ <object class="GtkBox" id="GradientPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="gradientpresetlistwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="gradientpresetlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|add">Adds a custom gradient to the current list. Specify the properties of your gradient, and then click this button</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="modify">
+ <property name="label" translatable="yes" context="gradientpage|modify">_Modify</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="modify-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|modify">Applies the current gradient properties to the selected gradient. If you want, you can save the gradient under a different name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|label1">Gradient</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="typeft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|typeft">_Type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">gradienttypelb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="gradienttypelb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="gradientpage|gradienttypelb">Linear</item>
+ <item translatable="yes" context="gradientpage|gradienttypelb">Axial</item>
+ <item translatable="yes" context="gradientpage|gradienttypelb">Radial</item>
+ <item translatable="yes" context="gradientpage|gradienttypelb">Ellipsoid</item>
+ <item translatable="yes" context="gradientpage|gradienttypelb">Quadratic</item>
+ <item translatable="yes" context="gradientpage|gradienttypelb">Square</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="gradienttypelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|gradienttypelb">Select the gradient that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="incrementft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|incrementft">Increment:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">incrementmtr</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="incrementmtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">end</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autoincrement">
+ <property name="label" translatable="yes" context="gradientpage|autoincrement">A_utomatic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="centerft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|centerft">Center ( X / Y ):</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="centerxmtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">percentadjustment3</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="centerxmtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|centerxmtr">Enter the horizontal offset for the gradient, where 0% corresponds to the current horizontal location of the endpoint color in the gradient. The endpoint color is the color that is selected in the To Color box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="centerymtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">percentadjustment4</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="centerymtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|centerymtr">Enter the vertical offset for the gradient, where 0% corresponds to the current vertical location of the endpoint color in the gradient. The endpoint color is the color that is selected in the To Color box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="borderft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|borderft">_Border:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bordermtr</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScale" id="borderslider">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="round_digits">1</property>
+ <property name="draw_value">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="bordermtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">end</property>
+ <property name="adjustment">percentadjustment</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="bordermtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|bordermtr">Enter the amount by which you want to adjust the area of the endpoint color on the gradient. The endpoint color is the color that is selected in the To Color box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="anglemtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">angleadjustment</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="anglemtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|anglemtr">Enter a rotation angle for the selected gradient.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="angleft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="gradientpage|angleft">A_ngle:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">anglemtr</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="colortomtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">percentadjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colortomtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|colortomtr">Enter the intensity for the color in the To Color box, where 0% corresponds to black, and 100 % to the selected color.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="colortolb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colortolb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|colortolb">Select a color for the endpoint of the gradient.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="colortoft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|colortoft">_To Color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">colortolb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="colorfromlb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colorfromlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|colorfromlb">Select a color for the beginning point of the gradient.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="colorfrommtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">percentadjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colorfrommtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|colorfrommtr">Enter the intensity for the color in the From Color box, where 0% corresponds to black, and 100 % to the selected color.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="colorfromft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|colorfromft">_From Color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">colorfromlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScale" id="angleslider">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">angleadjustmentslider</property>
+ <property name="draw_value">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|a11y_center_x">Center X</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">centerxmtr</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|a11y_center_y">Center Y</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">centerymtr</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|a11y_percentage_from">From color percentage</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">colorfrommtr</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|a11y_percentage_to">To color percentage</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">colortomtr</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="propfl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|propfl">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="previewctl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="previewctl-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="gradientpage|previewctl-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="gradientpage|label2">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="GradientPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="gradientpage|extended_tip|GradientPage">Select a gradient, modify the properties of a gradient, or save a new gradient.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/graphictestdlg.ui b/cui/uiconfig/ui/graphictestdlg.ui
new file mode 100644
index 000000000..3c6b14d0a
--- /dev/null
+++ b/cui/uiconfig/ui/graphictestdlg.ui
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="GraphicTestsDialog">
+ <property name="can-focus">False</property>
+ <property name="title" translatable="yes" context="graphictestdlg|GraphicTestsDialog">Run Graphics Tests</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default-width">550</property>
+ <property name="default-height">550</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="gptest-main">
+ <property name="can-focus">False</property>
+ <property name="margin-top">4</property>
+ <property name="margin-bottom">4</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="gptestbtnrun">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="gptest_downld">
+ <property name="label" translatable="yes" context="graphictestdlg|gptest_downld">Download Results</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-start">20</property>
+ <property name="margin-end">20</property>
+ <property name="margin-top">5</property>
+ <property name="margin-bottom">5</property>
+ <accelerator key="c" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="gptest_label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="tooltip-text" translatable="yes" context="graphictestdlg|gptest_label">Helps to determine the efficiency of %PRODUCTNAME’s graphics rendering by running some tests under the hood and providing their results in the log.</property>
+ <property name="margin-start">400</property>
+ <property name="margin-top">10</property>
+ <property name="label" translatable="yes" context="graphictestdlg|gptest_label">What's this?</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkTextView" id="gptest_txtVW">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="pixels-above-lines">2</property>
+ <property name="pixels-below-lines">2</property>
+ <property name="editable">False</property>
+ <property name="left-margin">2</property>
+ <property name="right-margin">2</property>
+ <property name="top-margin">2</property>
+ <property name="bottom-margin">2</property>
+ <accessibility>
+ <relation type="labelled-by" target="gptest_log"/>
+ </accessibility>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="gptest_log">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">5</property>
+ <property name="label" translatable="yes" context="graphictestdlg|gptest_log">Result Log:</property>
+ <accessibility>
+ <relation type="label-for" target="gptest_txtVW"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="gptest_detail">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">20</property>
+ <property name="margin-bottom">10</property>
+ <property name="label" translatable="yes" context="graphictestdlg|gptest_detail">Test Details</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="gptest_scrollwindow1">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox" id="gptest_box">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">5</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/graphictestentry.ui b/cui/uiconfig/ui/graphictestentry.ui
new file mode 100644
index 000000000..2248b433f
--- /dev/null
+++ b/cui/uiconfig/ui/graphictestentry.ui
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="gptestbox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">3</property>
+ <child>
+ <object class="GtkLabel" id="gptestlabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">4</property>
+ <property name="hexpand">True</property>
+ <property name="selectable">True</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="gptestlabel-atkobject">
+ <property name="AtkObject::accessible-role">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="gptestbutton">
+ <property name="label" translatable="yes" context="graphictestentry|gptestbutton">button</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hangulhanjaadddialog.ui b/cui/uiconfig/ui/hangulhanjaadddialog.ui
new file mode 100644
index 000000000..da47cc3da
--- /dev/null
+++ b/cui/uiconfig/ui/hangulhanjaadddialog.ui
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="HangulHanjaAddDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="hangulhanjaadddialog|HangulHanjaAddDialog">New Dictionary</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaadddialog|label2">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="max_length">32</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaadddialog|extended_tip|entry">Enter a name for the dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaadddialog|label1">Dictionary</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hangulhanjaconversiondialog.ui b/cui/uiconfig/ui/hangulhanjaconversiondialog.ui
new file mode 100644
index 000000000..07dc8eea3
--- /dev/null
+++ b/cui/uiconfig/ui/hangulhanjaconversiondialog.ui
@@ -0,0 +1,791 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="HangulHanjaConversionDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="hangulhanjaconversiondialog|HangulHanjaConversionDialog">Hangul/Hanja Conversion</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=2 n-rows=5 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">12</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|label1">Original</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">originalword</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="originalword">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="originalword-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|originalword">Displays the current selection.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|label3">Word</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">wordinput</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="wordinput">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="wordinput-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|wordinput">Displays the first replacement suggestion from the dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="find">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|find">_Find</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="find-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|find">Finds your Hangul input in the dictionary and replaces it with the corresponding Hanja.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|label4">Suggestions</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrollwin">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkDrawingArea" id="valueset">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="listbox">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="search-column">0</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|label5">Format</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=2 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">12</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="simpleconversion">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|simpleconversion">_Hangul/Hanja</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="simpleconversion-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|simpleconversion">The original characters are replaced by the suggested characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="hangulbracket">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hangulbracket">Hanja (Han_gul)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">simpleconversion</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hangulbracket-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hangulbracket">The Hangul part will be displayed in brackets after the Hanja part.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="hanjabracket">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hanjabracket">Hang_ul (Hanja)</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">simpleconversion</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hanjabracket-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hanjabracket">The Hanja part will be displayed in brackets after the Hangul part.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">12</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkImage" id="hanja_above_img">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="hanja_above">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hanja_above">Hanja above</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">simpleconversion</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hanja_above-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hanja_above">The Hangul part will be displayed as ruby text above the Hanja part.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkImage" id="hanja_below_img">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="hanja_below">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hanja_below">Hanja below</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">simpleconversion</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hanja_below-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hanja_below">The Hangul part will be displayed as ruby text below the Hanja part.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkImage" id="hangul_above_img">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="hangul_above">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hangul_above">Hangul above</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">simpleconversion</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hangul_above-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hangul_above">The Hanja part will be displayed as ruby text above the Hangul part.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkImage" id="hangul_below_img">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="hangul_below">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hangul_below">Hangul below</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">simpleconversion</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hangul_below-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hangul_below">The Hanja part will be displayed as ruby text below the Hangul part.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|label6">Conversion</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="hangulonly">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hangulonly">Hangul _only</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hangulonly-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hangulonly">Check to convert only Hangul. Do not convert Hanja.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="hanjaonly">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|hanjaonly">Hanja onl_y</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="hanjaonly-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|hanjaonly">Check to convert only Hanja. Do not convert Hangul.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="ignore">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|ignore">_Ignore</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignore-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|ignore">No changes will be made to the current selection. The next word or character will be selected for conversion.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ignoreall">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|ignoreall">Always I_gnore</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignoreall-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|ignoreall">No changes will be made to the current selection, and every time the same selection is detected it will be skipped automatically.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replace">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|replace">_Replace</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|replace">Replaces the selection with the suggested characters or word according to the format options.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="replaceall">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|replaceall">Always R_eplace</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replaceall-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|replaceall">Replaces the selection with the suggested characters or word according to the format options. Every time the same selection is detected it will be replaced automatically.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="replacebychar">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|replacebychar">Replace b_y character</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replacebychar-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|replacebychar">Check to move character-by-character through the selected text. If not checked, full words are replaced.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="options">
+ <property name="label" translatable="yes" context="hangulhanjaconversiondialog|options">Options...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="options-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|options">Opens the Hangul/Hanja Options dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HangulHanjaConversionDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaconversiondialog|extended_tip|HangulHanjaConversionDialog">Converts the selected Korean text from Hangul to Hanja or from Hanja to Hangul.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hangulhanjaeditdictdialog.ui b/cui/uiconfig/ui/hangulhanjaeditdictdialog.ui
new file mode 100644
index 000000000..50dcad7bc
--- /dev/null
+++ b/cui/uiconfig/ui/hangulhanjaeditdictdialog.ui
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="HangulHanjaEditDictDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="hangulhanjaeditdictdialog|HangulHanjaEditDictDialog">Edit Custom Dictionary</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="book">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="book-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|book">Select the user-defined dictionary that you want to edit.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaeditdictdialog|label4">Book</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">book</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="original">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="combobox-entry">
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="original-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|original">Select the entry in the current dictionary that you want to edit. If you want, you can also type a new entry in this box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="new">
+ <property name="label" translatable="yes" context="stock">_New</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="new-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|new">Adds the current replacement definition to the dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|delete">Deletes the selected entry.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaeditdictdialog|label2">Original</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrollbar">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">start</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">always</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">3</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="edit1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">40</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|edit1">Type a suggested replacement for the entry that is selected in the Original text box. The replacement word can contain a maximum of eight characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edit2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|edit2">Type a suggested replacement for the entry that is selected in the Original text box. The replacement word can contain a maximum of eight characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edit3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit3-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|edit3">Type a suggested replacement for the entry that is selected in the Original text box. The replacement word can contain a maximum of eight characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edit4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit4-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaeditdictdialog|extended_tip|edit4">Type a suggested replacement for the entry that is selected in the Original text box. The replacement word can contain a maximum of eight characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaeditdictdialog|label3">Suggestions</property>
+ <property name="use_underline">True</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">close</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hangulhanjaoptdialog.ui b/cui/uiconfig/ui/hangulhanjaoptdialog.ui
new file mode 100644
index 000000000..36e1dddb6
--- /dev/null
+++ b/cui/uiconfig/ui/hangulhanjaoptdialog.ui
@@ -0,0 +1,367 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="HangulHanjaOptDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="hangulhanjaoptdialog|HangulHanjaOptDialog">Hangul/Hanja Options</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="new">
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|new">New...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="new-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|new">Opens the New dictionary dialog box, where you can create a new dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|edit">Edit...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|edit">Opens the Edit Custom Dictionary dialog where you can edit any user-defined dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|delete">Deletes the selected user-defined dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="dicts">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="dicts-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|dicts">Lists all user-defined dictionaries. Select the check box next to the dictionaries that you want to use. Clear the check box next to the dictionaries that you do not want to use.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|label1">User-defined Dictionaries</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="ignorepost">
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|ignorepost">Ignore post-positional word</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignorepost-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|ignorepost">Ignores positional characters at the end of Korean words when you search a dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="showrecentfirst">
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|showrecentfirst">Show recently used entries first</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="showrecentfirst-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|showrecentfirst">Shows the replacement suggestion that you selected the last time as the first entry on the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autoreplaceunique">
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|autoreplaceunique">Replace all unique entries automatically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autoreplaceunique-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hangulhanjaoptdialog|extended_tip|autoreplaceunique">Automatically replaces words that only have one suggested word replacement.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hangulhanjaoptdialog|label2">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hatchpage.ui b/cui/uiconfig/ui/hatchpage.ui
new file mode 100644
index 000000000..1fc21ef8c
--- /dev/null
+++ b/cui/uiconfig/ui/hatchpage.ui
@@ -0,0 +1,458 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">359</property>
+ <property name="step_increment">15</property>
+ <property name="page_increment">15</property>
+ </object>
+ <object class="GtkAdjustment" id="angleadjustment">
+ <property name="upper">359</property>
+ <property name="step_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="distanceadjustment">
+ <property name="lower">0.3</property>
+ <property name="upper">99</property>
+ <property name="step_increment">100</property>
+ </object>
+ <object class="GtkBox" id="HatchPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="hatchpresetlistwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="hatchpresetlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|add">Adds a custom hatching pattern to the current list. Specify the properties of your hatching pattern, and then click this button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="modify">
+ <property name="label" translatable="yes" context="hatchpage|modify">_Modify</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="modify-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|modify">Applies the current hatching properties to the selected hatching pattern. If you want, you can save the pattern under a different name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|label2">Hatch</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="distanceft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|distanceft">_Spacing:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">distancemtr</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="distancemtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">distanceadjustment</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="distancemtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|distancemtr">Enter the amount of space that you want to have between the hatch lines.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="angleft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|angleft">A_ngle:</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScale" id="angleslider">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="round_digits">1</property>
+ <property name="draw_value">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="anglemtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">angleadjustment</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="anglemtr-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|anglemtr">Enter the rotation angle for the hatch lines, or click a position in the angle grid.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="linetypeft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|linetypeft">_Line type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">linetypelb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="linetypelb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="hatchpage|linetypelb">Single</item>
+ <item translatable="yes" context="hatchpage|linetypelb">Crossed</item>
+ <item translatable="yes" context="hatchpage|linetypelb">Triple</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linetypelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|linetypelb">Select the type of hatch lines that you want to use.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="linecolorft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|linecolorft">Line _color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">linecolorlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="linecolorlb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="valign">center</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linecolorlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|linecolorlb">Select the color of the hatch lines.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="backgroundcolor">
+ <property name="label" translatable="yes" context="hatchpage|backgroundcolor">Background Color</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="backgroundcolorlb"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="backgroundcolorlb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="valign">center</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="backgroundcolor"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="propfl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|propfl">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="previewctl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="previewctl-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="hatchpage|previewctl-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hatchpage|label1">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HatchPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hatchpage|extended_tip|HatchPage">Set the properties of a hatching pattern, or save a new hatching pattern.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyperlinkdialog.ui b/cui/uiconfig/ui/hyperlinkdialog.ui
new file mode 100644
index 000000000..57b9f665f
--- /dev/null
+++ b/cui/uiconfig/ui/hyperlinkdialog.ui
@@ -0,0 +1,446 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="HyperlinkDialog">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="hyperlinkdialog|HyperlinkDialog">Hyperlink</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="hyperlinkdialog|reset">Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="reset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdialog|extended_tip|reset">Resets the entries in the dialog to their original state.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="apply">
+ <property name="label" translatable="yes" context="hyperlinkdialog|apply">Apply</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="apply-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdialog|extended_tip|apply">Applies the data to your document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cancel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdialog|extended_tip|cancel">Closes the dialog without saving.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="tab_pos">left</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkBox" id="internet">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLINETTP_HELP">This is where you create a hyperlink to a Web page or FTP server connection.</property>
+ <property name="icon_name">res/hlinettp.png</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RID_SVXSTR_HYPERDLG_HLINETTP">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLINETTP">_Internet</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">internet</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkBox" id="mail">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLMAILTP_HELP">This is where you create a hyperlink to an email address.</property>
+ <property name="icon_name">res/hlmailtp.png</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RID_SVXSTR_HYPERDLG_HLMAILTP">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLMAILTP">_Mail</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">mail</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkBox" id="document">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLDOCTP_HELP">This is where you create a hyperlink to an existing document or a target within a document.</property>
+ <property name="icon_name">res/hldoctp.png</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RID_SVXSTR_HYPERDLG_HLDOCTP">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLDOCTP">_Document</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">document</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkBox" id="newdocument">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLDOCNTP_HELP">This is where you create a new document to which the new link points.</property>
+ <property name="icon_name">res/hldocntp.png</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="RID_SVXSTR_HYPERDLG_HLDOCNTP">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdialog|RID_SVXSTR_HYPERDLG_HLDOCNTP">_New Document</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">newdocument</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="102">apply</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyperlinkdocpage.ui b/cui/uiconfig/ui/hyperlinkdocpage.ui
new file mode 100644
index 000000000..1e769d508
--- /dev/null
+++ b/cui/uiconfig/ui/hyperlinkdocpage.ui
@@ -0,0 +1,438 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">res/target.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">res/fileopen.png</property>
+ </object>
+ <object class="GtkBox" id="HyperlinkDocPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="path_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|path_label">_Path:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">path</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="fileopen">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdocpage|fileopen|tooltip_text">Open File</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fileopen-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|fileopen">Opens the Open dialog, where you can select a file.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="path">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="path-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|path">Enter a URL for the file that you want to open when you click the hyperlink. If you do not specify a target frame, the file opens in the current document or frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|label2">Document</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="target_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|target_label">Targ_et:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">target</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="url_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|url_label">URL:</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="browse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdocpage|browse|tooltip_text">Target in Document</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="browse-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|browse">Opens the Target in Document dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="target">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="target-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|target">Enter a URL for the file that you want to open when you click the hyperlink. If you do not specify a target frame, the file opens in the current document or frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="url">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|url">Test text</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|label3">Target in Document</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="frame_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|frame_label">F_rame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">frame</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="indication_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|indication_label">Te_xt:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">indication</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|name_label">N_ame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="indication">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indication-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|indication">Specifies the visible text or button caption for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|name">Enter a name for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="form_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|form_label">F_orm:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">form</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="form">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="form-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|form">Specifies whether the hyperlink is inserted as text or as a button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="script">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkdocpage|script|tooltip_text">Events</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="script-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|script">Opens the Assign Macro dialog, in which you can give events such as "mouse over object" or "trigger hyperlink" their own program codes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="frame-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|frame">Enter the name of the frame that you want the linked file to open in, or select a predefined frame from the list. If you leave this box blank, the linked file opens in the current browser window.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkdocpage|label1">Further Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HyperlinkDocPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkdocpage|extended_tip|HyperlinkDocPage">Hyperlinks to any document or targets in documents can be edited using the Document tab from the Hyperlink dialog.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="path_label"/>
+ <widget name="target_label"/>
+ <widget name="url_label"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyperlinkinternetpage.ui b/cui/uiconfig/ui/hyperlinkinternetpage.ui
new file mode 100644
index 000000000..63978b8d0
--- /dev/null
+++ b/cui/uiconfig/ui/hyperlinkinternetpage.ui
@@ -0,0 +1,452 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="HyperlinkInternetPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="linktyp_internet">
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|linktyp_internet">_Web</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linktyp_internet-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|linktyp_internet">Creates an "http://" hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="linktyp_ftp">
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|linktyp_ftp">_FTP</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">linktyp_internet</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linktyp_ftp-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|linktyp_ftp">Creates an "FTP://" hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="target_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|target_label">_URL:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">target</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="login_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|login_label">_Login name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">login</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="password_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|password_label">_Password:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">password</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="login">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="login-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|login">Specifies your login name, if you are working with FTP addresses.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="password">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="password-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|password">Specifies your password, if you are working with FTP addresses.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="anonymous">
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|anonymous">Anonymous _user</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="anonymous-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|anonymous">Allows you to log in to the FTP address as an anonymous user.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="target">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="target-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|target">Enter a URL for the file that you want to open when you click the hyperlink. If you do not specify a target frame, the file opens in the current document or frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="indication_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|indication_label">Te_xt:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">indication</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="indication">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indication-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|indication">Specifies the visible text or button caption for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbProtocol">
+ <property name="name">lbProtocol</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|protocol_label">Proto_col:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">linktyp_internet</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|label2">Hyperlink Type</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="frame_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|frame_label">F_rame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">frame</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|name_label">N_ame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|name">Enter a name for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="form_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|form_label">F_orm:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">form</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="form">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="form-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|form">Specifies whether the hyperlink is inserted as text or as a button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="script">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkinternetpage|script|tooltip_text">Events</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="script-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|script">Opens the Assign Macro dialog, in which you can give events such as "mouse over object" or "trigger hyperlink" their own program codes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="frame-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|frame">Enter the name of the frame that you want the linked file to open in, or select a predefined frame from the list. If you leave this box blank, the linked file opens in the current browser window.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkinternetpage|label1">Further Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HyperlinkInternetPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkinternetpage|extended_tip|HyperlinkInternetPage">Use the Internet page of the Hyperlink dialog to edit hyperlinks with WWW or FTP addresses.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="target_label"/>
+ <widget name="login_label"/>
+ <widget name="password_label"/>
+ <widget name="frame_label"/>
+ <widget name="indication_label"/>
+ <widget name="name_label"/>
+ <widget name="lbProtocol"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyperlinkmailpage.ui b/cui/uiconfig/ui/hyperlinkmailpage.ui
new file mode 100644
index 000000000..f76d74aaf
--- /dev/null
+++ b/cui/uiconfig/ui/hyperlinkmailpage.ui
@@ -0,0 +1,362 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">res/adrbook.png</property>
+ </object>
+ <object class="GtkBox" id="HyperlinkMailPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="receiver_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|receiver_label">Re_cipient:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">receiver</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="addressbook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkmailpage|addressbook|tooltip_text">Data Sources...</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="addressbook-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|addressbook">Hides or shows the data source browser.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subject_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|subject_label">_Subject:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">subject</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="subject">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="subject-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|subject">Specifies the subject that is inserted in the subject line of the new message document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="receiver">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="receiver-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|receiver">Assigns the specified email address to the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|label2">Mail</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="frame_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|frame_label">F_rame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">frame</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="indication_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|indication_label">Te_xt:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">indication</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|name_label">N_ame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="indication">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indication-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|indication">Specifies the visible text or button caption for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|name">Enter a name for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="form_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|form_label">F_orm:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">form</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="form">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="form-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|form">Specifies whether the hyperlink is inserted as text or as a button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="script">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinkmailpage|script|tooltip_text">Events</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="script-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|script">Opens the Assign Macro dialog, in which you can give events such as "mouse over object" or "trigger hyperlink" their own program codes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="frame-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|frame">Enter the name of the frame that you want the linked file to open in, or select a predefined frame from the list. If you leave this box blank, the linked file opens in the current browser window.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinkmailpage|label1">Further Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HyperlinkMailPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmailpage|extended_tip|HyperlinkMailPage">On the Mail page in the Hyperlink dialog you can edit hyperlinks for email addresses.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="receiver_label"/>
+ <widget name="subject_label"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyperlinkmarkdialog.ui b/cui/uiconfig/ui/hyperlinkmarkdialog.ui
new file mode 100644
index 000000000..007dcd5ca
--- /dev/null
+++ b/cui/uiconfig/ui/hyperlinkmarkdialog.ui
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="HyperlinkMark">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="hyperlinkmarkdialog|HyperlinkMark">Target in Document</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="hyperlinkmarkdialog|apply">_Apply</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="hyperlinkmarkdialog|close">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="close-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmarkdialog|extended_tip|close">Once the hyperlink has been completely entered, click on Close to set the link and leave the dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="TreeListBox">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TreeListBox-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="hyperlinkmarkdialog|TreeListBox-atkobject">Mark Tree</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinkmarkdialog|extended_tip|TreeListBox">Specifies the position in the target document where you wish to jump to.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="error">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">ok</action-widget>
+ <action-widget response="-6">close</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyperlinknewdocpage.ui b/cui/uiconfig/ui/hyperlinknewdocpage.ui
new file mode 100644
index 000000000..a087c403b
--- /dev/null
+++ b/cui/uiconfig/ui/hyperlinknewdocpage.ui
@@ -0,0 +1,446 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">cmd/sc_adddirect.png</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="HyperlinkNewDocPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="editnow">
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|editnow">Edit _now</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="editnow-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|editnow">Specifies that the new document is created and immediately opened for editing.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="editlater">
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|editlater">Edit _later</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">editnow</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="editlater-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|editlater">Specifies that the document is created but it is not immediately opened.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="file_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|file_label">_File:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">path</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="create">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinknewdocpage|create|tooltip_text">Select Path</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="create-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|create">Opens the Select Path dialog, where you can select a path.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="types_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|types_label">File _type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">types</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="path">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="path-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|path">Enter a URL for the file that you want to open when you click the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">False</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="types">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="types-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|types">Specifies the file type for the new document.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|label2">New Document</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="frame_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|frame_label">F_rame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">frame</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="indication_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|indication_label">Te_xt:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">indication</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|name_label">N_ame:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">name</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="indication">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indication-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|indication">Specifies the visible text or button caption for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|name">Enter a name for the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="form_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|form_label">F_orm:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">form</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="form">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="form-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|form">Specifies whether the hyperlink is inserted as text or as a button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="script">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="hyperlinknewdocpage|script|tooltip_text">Events</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="script-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|script">Opens the Assign Macro dialog, in which you can give events such as "mouse over object" or "trigger hyperlink" their own program codes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="frame-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|frame">Enter the name of the frame that you want the linked file to open in, or select a predefined frame from the list. If you leave this box blank, the linked file opens in the current browser window.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyperlinknewdocpage|label1">Further Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HyperlinkNewDocPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyperlinknewdocpage|extended_tip|HyperlinkNewDocPage">Use the New Document tab from the Hyperlink dialog to set up a hyperlink to a new document and create the new document simultaneously.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="file_label"/>
+ <widget name="types_label"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/hyphenate.ui b/cui/uiconfig/ui/hyphenate.ui
new file mode 100644
index 000000000..386e5a98d
--- /dev/null
+++ b/cui/uiconfig/ui/hyphenate.ui
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-previous</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-next</property>
+ </object>
+ <object class="GtkDialog" id="HyphenateDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="hyphenate|HyphenateDialog">Hyphenation</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="hyphall">
+ <property name="label" translatable="yes" context="hyphenate|hyphall">Hyphenate All</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="hyphenate|ok">Hyphenate</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ok-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|ok">Inserts the hyphen at the indicated position.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="continue">
+ <property name="label" translatable="yes" context="hyphenate|continue">Skip</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="continue-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|continue">Ignores the hyphenation suggestion and finds the next word to hyphenate.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|delete">Removes the current hyphenation point from the displayed word.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="hyphenate|label1">Word:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">worded</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkEntry" id="worded">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="editable">False</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">32</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="worded-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|worded">Displays the hyphenation suggestion(s) for the selected word.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="left">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="left-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|left">Set the position of the hyphen. This option is only available if more than one hyphenation suggestion is displayed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="right">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="right-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|right">Set the position of the hyphen. This option is only available if more than one hyphenation suggestion is displayed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">hyphall</action-widget>
+ <action-widget response="-7">close</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="HyphenateDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="hyphenate|extended_tip|HyphenateDialog">Inserts hyphens in words that are too long to fit at the end of a line.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/iconchangedialog.ui b/cui/uiconfig/ui/iconchangedialog.ui
new file mode 100644
index 000000000..e615ab01b
--- /dev/null
+++ b/cui/uiconfig/ui/iconchangedialog.ui
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="IconChange">
+ <property name="can_focus">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="buttons">ok</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="homogeneous">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="addrTextview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="editable">False</property>
+ <property name="wrap_mode">word</property>
+ <property name="cursor_visible">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="iconchangedialog|label1">The files listed below could not be imported.
+The file format could not be interpreted.</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/iconselectordialog.ui b/cui/uiconfig/ui/iconselectordialog.ui
new file mode 100644
index 000000000..f9672c740
--- /dev/null
+++ b/cui/uiconfig/ui/iconselectordialog.ui
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="IconSelector">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="iconselectordialog|IconSelector">Change Icon</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="symbolswin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="symbolsToolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="margin-start">3</property>
+ <property name="margin-end">3</property>
+ <property name="margin_top">3</property>
+ <property name="margin_bottom">3</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="iconselectordialog|label1">_Icons</property>
+ <property name="use_underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="importButton">
+ <property name="label" translatable="yes" context="iconselectordialog|importButton">I_mport...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="importButton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="iconselectordialog|extended_tip|importButton">Adds new icons to the list of icons. You see a file open dialog that imports the selected icon or icons into the internal icon directory of the office suite.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="deleteButton">
+ <property name="label" translatable="yes" context="iconselectordialog|deleteButton">_Delete...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="deleteButton-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="iconselectordialog|extended_tip|deleteButton">Click to remove the selected icon from the list. Only user-defined icons can be removed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="noteLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="iconselectordialog|noteLabel">Note:
+The size of an icon should be 16x16 pixel to achieve best quality.
+Different sized icons will be scaled automatically.</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/imagetabpage.ui b/cui/uiconfig/ui/imagetabpage.ui
new file mode 100644
index 000000000..f4574f298
--- /dev/null
+++ b/cui/uiconfig/ui/imagetabpage.ui
@@ -0,0 +1,608 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="ImageTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="Fill Frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="imagewin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="IMAGE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_IMPORT">
+ <property name="label" translatable="yes" context="imagetabpage|BTN_IMPORT">Add / Import</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_IMPORT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="imagetabpage|extended_tip|BTN_IMPORT">Locate the image that you want to import, and then click Open. The image is added to the end of the list of available images.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label1">Image</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label3">Style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">imagestyle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="imagestyle">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="imagetabpage|imagestyle">Custom position/size</item>
+ <item translatable="yes" context="imagetabpage|imagestyle">Tiled</item>
+ <item translatable="yes" context="imagetabpage|imagestyle">Stretched</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="sizebox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label4">Size:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label5">Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">width</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="width">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label6">Height:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">height</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="height">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="scaletsb">
+ <property name="label" translatable="yes" context="imagetabpage|scaletsb">Scale</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="posbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label7">Position:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">positionlb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="positionlb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="imagetabpage|positionlb">Top Left</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Top Center</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Top Right</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Center Left</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Center</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Center Right</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Bottom Left</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Bottom Center</item>
+ <item translatable="yes" context="imagetabpage|positionlb">Bottom Right</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="posoffbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label9">Tiling Position:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label10">X-Offset:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">posoffx</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="posoffx">
+ <property name="visible">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label11">Y-Offset:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">posoffy</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="posoffy">
+ <property name="visible">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="tileoffbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label15">Tiling Offset:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">tileofflb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box13">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="tileofflb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="active">0</property>
+ <items>
+ <item translatable="yes" context="imagetabpage|tileofflb">Row</item>
+ <item translatable="yes" context="imagetabpage|tileofflb">Column</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="tileoffmtr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label2">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_IMAGE_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_IMAGE_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="imagetabpage|CTL_IMAGE_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="imagetabpage|label8">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ImageTabPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="imagetabpage|extended_tip|ImageTabPage">Select a image that you want to use as a fill image, or add your own image/pattern.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup">
+ <widgets>
+ <widget name="label10"/>
+ <widget name="label11"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup">
+ <widgets>
+ <widget name="label5"/>
+ <widget name="label6"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/imageviewer.ui b/cui/uiconfig/ui/imageviewer.ui
new file mode 100644
index 000000000..6008137ad
--- /dev/null
+++ b/cui/uiconfig/ui/imageviewer.ui
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="ImageViewerDialog">
+ <property name="can-focus">False</property>
+ <property name="resizable">False</property>
+ <property name="default-width">350</property>
+ <property name="default-height">350</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="imgVW_bx">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="imgVW_btngrid">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="ImgVW_mainImage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/insertfloatingframe.ui b/cui/uiconfig/ui/insertfloatingframe.ui
new file mode 100644
index 000000000..4727dacf7
--- /dev/null
+++ b/cui/uiconfig/ui/insertfloatingframe.ui
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="InsertFloatingFrameDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="insertfloatingframe|InsertFloatingFrameDialog">Floating Frame Properties</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkEntry" id="edname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edname-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|edname">Enter a name for the floating frame. The name cannot contain spaces, special characters, or begin with an underscore (_).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edurl">
+ <property name="width_request">400</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin-end">12</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edurl-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|edurl">Enter the path and the name of the file that you want to display in the floating frame. You can also click the Browse button and locate the file that you want to display.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-end">12</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|label6">Name:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-end">12</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|label7">Contents:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="buttonbrowse">
+ <property name="label" translatable="yes" context="insertfloatingframe|buttonbrowse">Browse...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="buttonbrowse-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|buttonbrowse">Locate the file that you want to display in the selected floating frame, and then click Open.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="scrollbaron">
+ <property name="label" translatable="yes" context="insertfloatingframe|scrollbaron">On</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="scrollbaron-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|scrollbaron">Displays the scrollbar for the floating frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="scrollbaroff">
+ <property name="label" translatable="yes" context="insertfloatingframe|scrollbaroff">Off</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">scrollbaron</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="scrollbaroff-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|scrollbaroff">Hides the scrollbar for the floating frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="scrollbarauto">
+ <property name="label" translatable="yes" context="insertfloatingframe|scrollbarauto">Automatic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">scrollbaron</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="scrollbarauto-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|scrollbarauto">Mark this option if the currently active floating frame can have a scrollbar when needed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|label1">Scroll Bar</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="borderon">
+ <property name="label" translatable="yes" context="insertfloatingframe|borderon">On</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="borderon-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|borderon">Displays the border of the floating frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="borderoff">
+ <property name="label" translatable="yes" context="insertfloatingframe|borderoff">Off</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">borderon</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="borderoff-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|borderoff">Hides the border of the floating frame.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|label2">Border</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="widthlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-end">12</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|widthlabel">Width:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="heightlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-end">12</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|heightlabel">Height:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="width">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin-end">12</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="width-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|width">Enter the amount of horizontal space that you want to leave between the right and the left edges of the floating frame and the contents of the frame. Both documents inside and outside the floating frame must be HTML documents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="height">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin-end">12</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="height-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|height">Enter the amount of vertical space that you want to leave between the top and bottom edges of the floating frame and the contents of the frame. Both documents inside and outside the floating frame must be HTML documents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="defaultwidth">
+ <property name="label" translatable="yes" context="insertfloatingframe|defaultwidth">Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="defaultwidth-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|defaultwidth">Applies the default horizontal spacing.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="defaultheight">
+ <property name="label" translatable="yes" context="insertfloatingframe|defaultheight">Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="defaultheight-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|defaultheight">Applies the default vertical spacing.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="insertfloatingframe|label3">Padding</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">12</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="InsertFloatingFrameDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertfloatingframe|extended_tip|InsertFloatingFrameDialog">Changes the properties of the selected floating frame. Floating frames work best when they contain an html document, and when they are inserted in another html document.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/insertoleobject.ui b/cui/uiconfig/ui/insertoleobject.ui
new file mode 100644
index 000000000..799799626
--- /dev/null
+++ b/cui/uiconfig/ui/insertoleobject.ui
@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="InsertOLEObjectDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="insertoleobject|InsertOLEObjectDialog">Insert OLE Object</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkRadioButton" id="createnew">
+ <property name="label" translatable="yes" context="insertoleobject|createnew">Create new</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="createfromfile">
+ <property name="label" translatable="yes" context="insertoleobject|createfromfile">Create from file</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">createnew</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="objecttypeframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="types">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="insertoleobject|label1">Object Type</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="fileframe">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkEntry" id="urled">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="urlbtn">
+ <property name="label" translatable="yes" context="insertoleobject|urlbtn">Search…</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="linktofile">
+ <property name="label" translatable="yes" context="insertoleobject|linktofile">Link to file</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linktofile-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertoleobject|extended_tip|linktofile">Enable this checkbox to insert the OLE object as a link to the original file. If this checkbox is not enabled, the OLE object will be embedded into your document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="asicon">
+ <property name="label" translatable="yes" context="insertoleobject|asicon">Display as icon</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="insertoleobject|label2">File</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">6</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="InsertOLEObjectDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertoleobject|extended_tip|InsertOLEObjectDialog">Inserts an OLE object into the current document. The OLE object is inserted as a link or an embedded object.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/insertrowcolumn.ui b/cui/uiconfig/ui/insertrowcolumn.ui
new file mode 100644
index 000000000..374667e83
--- /dev/null
+++ b/cui/uiconfig/ui/insertrowcolumn.ui
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">200</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="InsertRowColumnDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="insertrowcolumn|InsertRowColumnDialog">Insert Row</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="insertrowcolumn|label3">_Number:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">insert_number</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="insert_number">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="numeric">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="insert_number-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertrowcolumn|extended_tip|insert_number">Enter the number of columns or rows that you want.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="insertrowcolumn|label1">Insert</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="insert_before">
+ <property name="label" translatable="yes" context="insertrowcolumn|insert_before">_Before</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="insert_before-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertrowcolumn|extended_tip|insert_before">Adds new columns to the left of the current column, or adds new rows above the current row.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="insert_after">
+ <property name="label" translatable="yes" context="insertrowcolumn|insert_after">A_fter</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">insert_before</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="insert_after-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="insertrowcolumn|extended_tip|insert_after">Adds new columns to the right of the current column, or adds new rows below the current row.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="insertrowcolumn|label2">Position</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/javaclasspathdialog.ui b/cui/uiconfig/ui/javaclasspathdialog.ui
new file mode 100644
index 000000000..3616764dc
--- /dev/null
+++ b/cui/uiconfig/ui/javaclasspathdialog.ui
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="JavaClassPath">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="javaclasspathdialog|JavaClassPath">Class Path</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="javaclasspathdialog|label1">A_ssigned folders and archives</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">paths</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="paths">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="paths-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|paths">Specifies the location of Java classes or Java class libraries.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkButton" id="archive">
+ <property name="label" translatable="yes" context="javaclasspathdialog|archive">_Add Archive...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="archive-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|archive">Select an archive file in jar or zip format and add the file to the class path.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="folder">
+ <property name="label" translatable="yes" context="javaclasspathdialog|folder">Add _Folder</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="folder-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|folder">Select a folder and add the folder to the class path.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="remove">
+ <property name="label" translatable="yes" context="javaclasspathdialog|remove">_Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="remove-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|remove">Select an archive or a folder in the list and click Remove to remove the object from the class path.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="JavaClassPath-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|JavaClassPath">Specifies the location of Java classes or Java class libraries.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/javastartparametersdialog.ui b/cui/uiconfig/ui/javastartparametersdialog.ui
new file mode 100644
index 000000000..303e67624
--- /dev/null
+++ b/cui/uiconfig/ui/javastartparametersdialog.ui
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="JavaStartParameters">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="javastartparametersdialog|JavaStartParameters">Java Start Parameters</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="javastartparametersdialog|label4">Java start _parameter</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">parameterfield</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="parameterfield">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="parameterfield-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|parameterfield">Enter a start parameter for a JRE as you would on a command line. Click Add to include the parameter to the list of available start parameters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="javastartparametersdialog|label5">Assig_ned start parameters</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">assignlist</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="assignlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="assignlist-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|assignlist">Lists the assigned JRE start parameters. To remove a start parameter, select the parameter, and then click Remove.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="javastartparametersdialog|label6">For example: -Dmyprop=c:\\program files\\java</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="assignbtn">
+ <property name="label" translatable="yes" context="javastartparametersdialog|assignbtn">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="assignbtn-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|assignbtn">Adds the current JRE start parameter to the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="editbtn">
+ <property name="label" translatable="yes" context="javastartparametersdialog|editbtn">_Edit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">start</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="editbtn-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|editbtn">Opens a dialog where the selected JRE start parameter can be edited.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="removebtn">
+ <property name="label" translatable="yes" context="javastartparametersdialog|removebtn">_Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">start</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="removebtn-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|removebtn">Deletes the selected JRE start parameter.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/langtoolconfigpage.ui b/cui/uiconfig/ui/langtoolconfigpage.ui
new file mode 100644
index 000000000..846961baa
--- /dev/null
+++ b/cui/uiconfig/ui/langtoolconfigpage.ui
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptLangToolPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkGrid" id="grid0">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkLabel" id="disclaimer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">4</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|disclaimer">If you enable this, the data will be sent to an external server.</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="policy">
+ <property name="label" translatable="yes" context="langtoolconfigpage|policy">Please read the privacy policy</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="relief">none</property>
+ <property name="uri">https://languagetool.org/legal/privacy</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="activate">
+ <property name="label" translatable="yes" context="langtoolconfigpage|activate">Enable LanguageTool</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">9</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="apisettings">
+ <property name="can_focus">False</property>
+ <property name="margin_top">10</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">5</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="base">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|base">Base URL:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">baseurl</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="baseurl">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="usernamelbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|usernamelbl">Username:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">username</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="apikeylbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|apikeylbl">API key:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">apikey</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="username">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="apikey">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="urldesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|urldesc">Please use the base URL, i.e., without “/check”, at the end.</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="usernamedesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|usernamedesc">Your LanguageTool account’s username for premium usage.</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="apikeydesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|apikeydesc">Your LanguageTool account’s API key for premium usage.</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="apisettingsheader">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">10</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|apisettingsheader">API Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="langtoolsettings">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">4</property>
+ <property name="label" translatable="yes" context="langtoolconfigpage|langtoolsettings">LanguageTool API Options</property>
+ <attributes>
+ <attribute name="style" value="normal"/>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/linedialog.ui b/cui/uiconfig/ui/linedialog.ui
new file mode 100644
index 000000000..cb4648e8c
--- /dev/null
+++ b/cui/uiconfig/ui/linedialog.ui
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="LineDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="linedialog|LineDialog">Line</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_LINE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linedialog|RID_SVXPAGE_LINE">Line</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_SHADOW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linedialog|RID_SVXPAGE_SHADOW">Shadow</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_LINE_DEF">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linedialog|RID_SVXPAGE_LINE_DEF">Line Styles</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_LINEEND_DEF">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linedialog|RID_SVXPAGE_LINEEND_DEF">Arrow Styles</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/lineendstabpage.ui b/cui/uiconfig/ui/lineendstabpage.ui
new file mode 100644
index 000000000..292159657
--- /dev/null
+++ b/cui/uiconfig/ui/lineendstabpage.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">res/sc05501.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">res/sc05502.png</property>
+ </object>
+ <object class="GtkListStore" id="liststore4">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name surface -->
+ <column type="CairoSurface"/>
+ </columns>
+ </object>
+ <object class="GtkFrame" id="LineEndPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_TITLE">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="lineendstabpage|FT_TITLE">Style _name:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">EDT_NAME</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_END_STYLE">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="lineendstabpage|FT_LINE_END_STYLE">Arrow _style:</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="EDT_NAME">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">start</property>
+ <property name="width-chars">30</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="LB_LINEENDS">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="model">liststore4</property>
+ <property name="entry-text-column">0</property>
+ <property name="id-column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext3"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="surface">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout-style">start</property>
+ <child>
+ <object class="GtkButton" id="BTN_ADD">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="lineendstabpage|BTN_ADD|tooltip_text">Adds selected shape as Arrow Style.</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_ADD-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lineendstabpage|extended_tip|BTN_ADD">To add a new Arrow Style, first select the shape in the document to be added, then open this dialog and press Add. If the selected shape is not permitted as an Arrow Style, then the Add button is not active.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_MODIFY">
+ <property name="label" translatable="yes" context="lineendstabpage|BTN_MODIFY">_Rename</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="lineendstabpage|BTN_MODIFY|tooltip_text">Applies changes to the Style name.</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_DELETE">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_DELETE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lineendstabpage|extended_tip|BTN_DELETE">Deletes the selected element or elements after confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="column-homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="BTN_LOAD">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="lineendstabpage|BTN_LOAD|tooltip_text">Load arrow styles</property>
+ <property name="halign">center</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_SAVE">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="lineendstabpage|BTN_SAVE|tooltip_text">Save arrow styles</property>
+ <property name="halign">center</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">end</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="lineendstabpage|label1">Manage Arrow Styles</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/linestyletabpage.ui b/cui/uiconfig/ui/linestyletabpage.ui
new file mode 100644
index 000000000..3c1ca1da7
--- /dev/null
+++ b/cui/uiconfig/ui/linestyletabpage.ui
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentDIST">
+ <property name="upper">5</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentDIST1">
+ <property name="upper">5</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentDIST2">
+ <property name="upper">5</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentNUM">
+ <property name="upper">99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentNUM1">
+ <property name="upper">99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">res/sc05501.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">res/sc05502.png</property>
+ </object>
+ <object class="GtkListStore" id="liststore4">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name surface -->
+ <column type="CairoSurface"/>
+ </columns>
+ </object>
+ <object class="GtkFrame" id="LineStylePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-end">12</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_TYPE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linestyletabpage|FT_TYPE">_Type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_TYPE_1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_NUMBER">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linestyletabpage|FT_NUMBER">_Number:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">NUM_FLD_1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_LENGTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linestyletabpage|FT_LENGTH">_Length:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_LENGTH_1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_DISTANCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linestyletabpage|FT_DISTANCE">_Spacing:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_DISTANCE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_TYPE_1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">1</property>
+ <items>
+ <item translatable="yes" context="linestyletabpage|liststoreTYPE">Dots</item>
+ <item translatable="yes" context="linestyletabpage|liststoreTYPE">Dash</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_TYPE_2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">1</property>
+ <items>
+ <item translatable="yes" context="linestyletabpage|liststoreTYPE">Dots</item>
+ <item translatable="yes" context="linestyletabpage|liststoreTYPE">Dash</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="NUM_FLD_1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentNUM</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="NUM_FLD_2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentNUM1</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LENGTH_1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentDIST</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LENGTH_2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentDIST1</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_DISTANCE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentDIST2</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="CBX_SYNCHRONIZE">
+ <property name="label" translatable="yes" context="linestyletabpage|CBX_SYNCHRONIZE">_Fit to line width</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_LINESTYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linestyletabpage|FT_LINESTYLE">Line _style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_LINESTYLES</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="LB_LINESTYLES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore4</property>
+ <property name="active">0</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext3"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="BTN_ADD">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_MODIFY">
+ <property name="label" translatable="yes" context="linestyletabpage|BTN_MODIFY">_Modify</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_DELETE">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_DELETE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="linestyletabpage|extended_tip|BTN_DELETE">Deletes the selected element or elements after confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="BTN_LOAD">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="linestyletabpage|BTN_LOAD|tooltip_text">Load Line Styles</property>
+ <property name="halign">center</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_SAVE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="linestyletabpage|BTN_SAVE|tooltip_text">Save Line Styles</property>
+ <property name="halign">center</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linestyletabpage|label1">Properties</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1"/>
+</interface>
diff --git a/cui/uiconfig/ui/linetabpage.ui b/cui/uiconfig/ui/linetabpage.ui
new file mode 100644
index 000000000..a5f9b178f
--- /dev/null
+++ b/cui/uiconfig/ui/linetabpage.ui
@@ -0,0 +1,953 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentHEIGHT_SYMBOL">
+ <property name="upper">20</property>
+ <property name="step_increment">0.05</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPERCENT">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentWIDTH">
+ <property name="upper">5</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentWIDTH1">
+ <property name="upper">5</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentWIDTH2">
+ <property name="upper">5</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentWIDTH_SYMBOL">
+ <property name="upper">20</property>
+ <property name="step_increment">0.05</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkListStore" id="liststore4">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name surface -->
+ <column type="CairoSurface"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore5">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name surface -->
+ <column type="CairoSurface"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore6">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name surface -->
+ <column type="CairoSurface"/>
+ </columns>
+ </object>
+ <object class="GtkMenu" id="menuSELECT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="none">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|menuitem1">_No Symbol</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="automatic">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|menuitem2">_Automatic</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="file">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|menuitem3">_From file...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="gallery">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|menuitem4">_Gallery</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="gallerysubmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="symbols">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|menuitem5">_Symbols</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="symbolssubmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkBox" id="LineTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+ <child>
+ <object class="GtkFrame" id="FL_LINE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_LINE_STYLE">_Style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_LINE_STYLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="LB_LINE_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">liststore5</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext7"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext11"/>
+ <attributes>
+ <attribute name="surface">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxCOLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_COLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_COLOR">Colo_r:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_COLOR</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="LB_COLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxWIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_LINE_WIDTH">_Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_LINE_WIDTH</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LINE_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="adjustment">adjustmentWIDTH</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxTRANSPARENCY">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_TRANSPARENT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_TRANSPARENT">_Transparency:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_LINE_TRANSPARENT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_LINE_TRANSPARENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentPERCENT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|label1">Line Properties</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_LINE_ENDS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="boxARROW_STYLES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">36</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_ENDS_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_LINE_ENDS_STYLE">Start st_yle:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_START_STYLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="LB_START_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">liststore4</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="surface">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="boxSTART">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_CENTER_START">
+ <property name="label" translatable="yes" context="linetabpage|TSB_CENTER_START">Ce_nter</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="halign">start</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_START_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_LINE_START_WIDTH">Wi_dth:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_START_WIDTH</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_START_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="adjustment">adjustmentWIDTH1</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="CBX_SYNCHRONIZE">
+ <property name="label" translatable="yes" context="linetabpage|CBX_SYNCHRONIZE">Synchroni_ze ends</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="halign">start</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkComboBox" id="LB_END_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="model">liststore6</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="surface">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|label5">End sty_le:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_END_STYLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="boxEND">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_LINE_END_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_LINE_END_WIDTH">W_idth:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_END_WIDTH</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_END_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="adjustment">adjustmentWIDTH2</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_CENTER_END">
+ <property name="label" translatable="yes" context="linetabpage|TSB_CENTER_END">C_enter</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="halign">start</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|label2">Arrow Styles</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_EDGE_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="gridEDGE_CAPS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_EDGE_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_EDGE_STYLE">_Corner style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_EDGE_STYLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_CAP_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_CAP_STYLE">Ca_p style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_CAP_STYLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_EDGE_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="linetabpage|liststoreEDGE_STYLE">Rounded</item>
+ <item id="1" translatable="yes" context="linetabpage|liststoreEDGE_STYLE">- none -</item>
+ <item id="2" translatable="yes" context="linetabpage|liststoreEDGE_STYLE">Mitered</item>
+ <item id="3" translatable="yes" context="linetabpage|liststoreEDGE_STYLE">Beveled</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_CAP_STYLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="linetabpage|liststoreCAP_STYLE">Flat</item>
+ <item id="1" translatable="yes" context="linetabpage|liststoreCAP_STYLE">Round</item>
+ <item id="2" translatable="yes" context="linetabpage|liststoreCAP_STYLE">Square</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|label3">Corner and Cap Styles</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_SYMBOL_FORMAT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkMenuButton" id="MB_SYMBOL_BITMAP">
+ <property name="label" translatable="yes" context="linetabpage|MB_SYMBOL_BITMAP">Select...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="popup">menuSELECT</property>
+ <property name="use_popover">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="gridICON_SIZE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_SYMBOL_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_SYMBOL_WIDTH">Widt_h:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MF_SYMBOL_WIDTH</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MF_SYMBOL_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustmentWIDTH_SYMBOL</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="CB_SYMBOL_RATIO">
+ <property name="label" translatable="yes" context="linetabpage|CB_SYMBOL_RATIO">_Keep ratio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="halign">start</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_SYMBOL_HEIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|FT_SYMBOL_HEIGHT">Hei_ght:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MF_SYMBOL_HEIGHT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MF_SYMBOL_HEIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustmentHEIGHT_SYMBOL</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="linetabpage|label4">Icon</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="linetabpage|CTL_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel1">
+ <widgets>
+ <widget name="FT_LINE_STYLE"/>
+ <widget name="FT_COLOR"/>
+ <widget name="FT_LINE_WIDTH"/>
+ <widget name="FT_TRANSPARENT"/>
+ <widget name="FT_LINE_ENDS_STYLE"/>
+ <widget name="FT_LINE_START_WIDTH"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel2">
+ <widgets>
+ <widget name="FT_EDGE_STYLE"/>
+ <widget name="FT_CAP_STYLE"/>
+ <widget name="FT_SYMBOL_WIDTH"/>
+ <widget name="FT_SYMBOL_HEIGHT"/>
+ <widget name="label5"/>
+ <widget name="FT_LINE_END_WIDTH"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupSpin">
+ <widgets>
+ <widget name="MTR_FLD_LINE_WIDTH"/>
+ <widget name="MTR_LINE_TRANSPARENT"/>
+ <widget name="MTR_FLD_START_WIDTH"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupWidget1">
+ <widgets>
+ <widget name="LB_LINE_STYLE"/>
+ <widget name="LB_COLOR"/>
+ <widget name="LB_START_STYLE"/>
+ <widget name="LB_EDGE_STYLE"/>
+ <widget name="LB_CAP_STYLE"/>
+ <widget name="LB_END_STYLE"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/macroassigndialog.ui b/cui/uiconfig/ui/macroassigndialog.ui
new file mode 100644
index 000000000..781ba2ec7
--- /dev/null
+++ b/cui/uiconfig/ui/macroassigndialog.ui
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="MacroAssignDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="macroassigndialog|MacroAssignDialog">Assign Action</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MacroAssignDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="macroassigndialog|extended_tip|MacroAssignDialog">Assigns macros to program events. The assigned macro runs automatically every time the selected event occurs.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/macroassignpage.ui b/cui/uiconfig/ui/macroassignpage.ui
new file mode 100644
index 000000000..3ecd4ce3d
--- /dev/null
+++ b/cui/uiconfig/ui/macroassignpage.ui
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="MacroAssignPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="assignments">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="macroassignpage|eventft">Event</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="macroassignpage|assignft">Assigned Action</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="assignments-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="macroassignpage|extended_tip|assignments">The big list box lists the events and the assigned macros. After you selected the location in the Save In list box, select an event in the big list box. Then click Assign Macro.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="libraryft1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="macroassignpage|libraryft1">Assignments</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkButton" id="assign">
+ <property name="label" translatable="yes" context="macroassignpage|assign">M_acro...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="assign-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="macroassignpage|extended_tip|assign">Opens the Macro Selector to assign a macro to the selected event.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="component">
+ <property name="label" translatable="yes" context="macroassignpage|component">Com_ponent...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="macroassignpage|delete">Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="macroassignpage|extended_tip|delete">Deletes the macro or component assignment for the selected event.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="macroassignpage|label1">Assign</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MacroAssignPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="macroassignpage|extended_tip|MacroAssignPage">Assigns macros to program events. The assigned macro runs automatically every time the selected event occurs.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/macroselectordialog.ui b/cui/uiconfig/ui/macroselectordialog.ui
new file mode 100644
index 000000000..329c25940
--- /dev/null
+++ b/cui/uiconfig/ui/macroselectordialog.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="MacroSelectorDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="macroselectordialog|MacroSelectorDialog">Macro Selector</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="helpmacro">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label" translatable="yes" context="macroselectordialog|helpmacro">Select the library that contains the macro you want. Then select the macro under 'Macro name'.</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">60</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="categories">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">1</property>
+ <property name="enable-tree-lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="libraryft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-bottom">6</property>
+ <property name="label" translatable="yes" context="macroselectordialog|libraryft">Library</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="commands">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Tree List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="macronameft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-bottom">6</property>
+ <property name="label" translatable="yes" context="macroselectordialog|macronameft">Macro Name</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="descriptionframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="height-request">100</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <child>
+ <object class="GtkTextView" id="description">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="editable">False</property>
+ <property name="wrap-mode">word</property>
+ <property name="cursor-visible">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-bottom">6</property>
+ <property name="label" translatable="yes" context="macroselectordialog|label1">_Description</property>
+ <property name="use-underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/menuassignpage.ui b/cui/uiconfig/ui/menuassignpage.ui
new file mode 100644
index 000000000..64c9efc4d
--- /dev/null
+++ b/cui/uiconfig/ui/menuassignpage.ui
@@ -0,0 +1,1012 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-up</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-down</property>
+ </object>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-next</property>
+ <property name="icon_size">3</property>
+ </object>
+ <object class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-previous</property>
+ <property name="icon_size">3</property>
+ </object>
+ <object class="GtkImage" id="image7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ <property name="icon_size">2</property>
+ </object>
+ <object class="GtkImage" id="image8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ <property name="icon_size">2</property>
+ </object>
+ <object class="GtkMenu" id="insertmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="insertseparator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|insertseparator">Insert Separator</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="insertsubmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|insertsubmenu">Insert Submenu</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name image1 -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkMenu" id="menugearmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="menu_gear_add">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_add">_Add...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menu_gear_delete">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_delete">_Delete</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menu_gear_rename">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_rename">_Rename...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="menu_gear_move">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_move">_Move...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkMenu" id="modifymenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="renameItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|renameItem">Rename...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="changeIcon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|changeIcon">Change Icon...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="resetIcon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|resetIcon">Reset Icon</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="restoreItem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|restoreItem">Restore Default Command</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkMenu" id="toolbargearmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="toolbar_gear_add">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_add">_Add...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="toolbar_gear_delete">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_delete">_Delete</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="toolbar_gear_rename">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_rename">_Rename...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="toolbar_gear_move">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_move">_Move...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorMenuItem" id="toolbar_gear_separator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="toolbar_gear_iconAndText">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_iconAndText">_Icon and text</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">toolbar_gear_iconOnly</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="toolbar_gear_iconOnly">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_iconOnly">Icon _only</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_as_radio">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRadioMenuItem" id="toolbar_gear_textOnly">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="menuassignpage|gear_textOnly">_Text only</property>
+ <property name="use_underline">True</property>
+ <property name="draw_as_radio">True</property>
+ <property name="group">toolbar_gear_iconOnly</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkBox" id="MenuAssignPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">4</property>
+ <property name="column_spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="searchlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="menuassignpage|contentslabel">_Search</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="desc">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes" context="menuassignpage|desc">Description of the currently selected function.</property>
+ <property name="editable">False</property>
+ <property name="wrap_mode">word</property>
+ <property name="cursor_visible">False</property>
+ <property name="accepts_tab">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="desc-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|desc">The text box contains a short description of the selected command.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="descriptionlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="label" translatable="yes" context="menuassignpage|label33">D_escription</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">desc</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="functions">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="functions-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|functions">Displays the results of the combination of the search string and category of the desired function.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="leftfunctionlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="label" translatable="yes" context="menuassignpage|contentslabel">_Available Commands</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="commandcategorylist">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">4</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="commandcategorylist-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|commandcategorylist">Select the menu command category in the drop-down list to restrict the search of commands or scroll the list below. Macros and styles commands are in the bottom of the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="categorylabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="menuassignpage|contentslabel">Categor_y</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">commandcategorylist</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="searchEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_bottom">4</property>
+ <property name="placeholder_text" translatable="yes" context="menuassignpage|searchEntry">Type to search</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="searchEntry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|searchEntry">Enter a string in the text box to narrow the search of commands.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">4</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkComboBoxText" id="savein">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-end">5</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="savein-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|savein">Select the location where the menu is to be attached. If attached to an office suite module, the menu is available for all files opened in that module. If attached to the file, the menu will be available only when that file is opened and active.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="functionbtn">
+ <property name="label" translatable="yes" context="menuassignpage|functionbtn">_Function</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="image_position">right</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">4</property>
+ <child>
+ <object class="GtkComboBoxText" id="toplevellist">
+ <property name="width_request">1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="toplevellist-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|toplevellist">Select the menu where the customization is to be applied. The current set of functions is displayed in the box below.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="menugearbtn">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="margin-start">1</property>
+ <property name="image">image7</property>
+ <property name="always_show_image">True</property>
+ <property name="popup">menugearmenu</property>
+ <property name="use_popover">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="menugearbtn-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="menuassignpage|menugearbtn">Gear Menu</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|menugearbtn">Contains commands to modify or delete the selected top level menu, and the command to add new top level menus.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="toolbargearbtn">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="margin-start">1</property>
+ <property name="image">image8</property>
+ <property name="always_show_image">True</property>
+ <property name="popup">toolbargearmenu</property>
+ <property name="use_popover">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="toolbargearbtn-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="menuassignpage|toolbargearbtn">Gear Menu</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|toolbargearbtn">Contains commands to modify or delete the selected toolbar, and the command to add new toolbars.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="entries">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_bottom">4</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="toolcontents">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="reorderable">True</property>
+ <property name="search_column">1</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">4</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext9"/>
+ <attributes>
+ <attribute name="pixbuf">1</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext10"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="menucontents">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="headers_visible">False</property>
+ <property name="reorderable">True</property>
+ <property name="search_column">1</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn22">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext44"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext22"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn44">
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext55"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="hexpand">True</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkMenuButton" id="insert">
+ <property name="label" translatable="yes" context="menuassignpage|insert">_Insert</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="popup">insertmenu</property>
+ <property name="use_popover">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="modify">
+ <property name="label" translatable="yes" context="menuassignpage|modify">_Modify</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="popup">modifymenu</property>
+ <property name="use_popover">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="defaultsbtn">
+ <property name="label" translatable="yes" context="menuassignpage|defaultsbtn">_Defaults</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="margin-start">5</property>
+ <property name="margin-end">5</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="defaultsbtn-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|defaultsbtn">Resets the selected toolbar, menu, or context menu to its default state.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">5</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="menuassignpage|add">Add item</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="margin_bottom">5</property>
+ <property name="image">image3</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|add">Click on the right arrow button to select a function on the left display box and copy to the right display box. This will add the function to the selected menu.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">5</property>
+ <child>
+ <object class="GtkButton" id="remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="menuassignpage|remove">Remove item</property>
+ <property name="halign">center</property>
+ <property name="valign">end</property>
+ <property name="margin_bottom">5</property>
+ <property name="image">image4</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="remove-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|remove">Click on the left arrow button to remove the selected command from the current menu.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkButton" id="up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="menuassignpage|moveupbtn">Move up</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="up-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|up">Click on the Up or Down arrows on the right to move the selected command upward or downward in the list of displayed menu commands.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="menuassignpage|movedownbtn">Move down</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="down-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|down">Click on the Up or Down arrows on the right to move the selected command upward or downward in the list of displayed menu commands.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="scopelabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="menuassignpage|scopelabel">S_cope</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="targetlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="menuassignpage|targetlabel">_Target</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="rightfunctionlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="menuassignpage|functionlabel">Assi_gned Commands</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="customizelabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="menuassignpage|customizelabel">_Customize</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MenuAssignPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="menuassignpage|extended_tip|MenuAssignPage">Lets you customize the office suite menus for all modules.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegrp2">
+ <property name="mode">vertical</property>
+ <widgets>
+ <widget name="commandcategorylist"/>
+ <widget name="toplevellist"/>
+ <widget name="searchEntry"/>
+ <widget name="savein"/>
+ <widget name="functionbtn"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/mosaicdialog.ui b/cui/uiconfig/ui/mosaicdialog.ui
new file mode 100644
index 000000000..ef89f0b6c
--- /dev/null
+++ b/cui/uiconfig/ui/mosaicdialog.ui
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">999</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">1</property>
+ <property name="upper">999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="MosaicDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="mosaicdialog|MosaicDialog">Mosaic</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="width">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="text">2</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="value">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="width-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="mosaicdialog|extended_tip|width">Defines the width of the individual tiles.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="mosaicdialog|label2">_Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">width</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="height">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="text" translatable="yes" context="mosaicdialog|height">2</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="value">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="height-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="mosaicdialog|extended_tip|height">Defines the height of the individual tiles.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="mosaicdialog|label3">_Height:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">height</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="edges">
+ <property name="label" translatable="yes" context="mosaicdialog|edges">E_nhance edges</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edges-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="mosaicdialog|extended_tip|edges">Enhances, or sharpens, the edges of the object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="mosaicdialog|label1">Parameters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MosaicDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="mosaicdialog|extended_tip|MosaicDialog">Joins small groups of pixels into rectangular areas of the same color.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/movemenu.ui b/cui/uiconfig/ui/movemenu.ui
new file mode 100644
index 000000000..43b582625
--- /dev/null
+++ b/cui/uiconfig/ui/movemenu.ui
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-up</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-down</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="MoveMenuDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="movemenu|MoveMenuDialog">New Menu</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="namebox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="menunameft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="movemenu|menunameft">Menu name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">menuname</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="menuname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="menuname-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="movemenu|extended_tip|menuname">Enter a name for the menu. To specify a letter in the name as an accelerator key, enter a tilde (~) before the letter.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="movemenu|label1">Menu _position:</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="menulist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">image1</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="up-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="movemenu|up-atkobject">Up</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">image2</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="down-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="movemenu|down-atkobject">Down</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MoveMenuDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="movemenu|extended_tip|MoveMenuDialog">Moves the selected menu entry up one position or down one position in the menu when you click an arrow button.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/multipathdialog.ui b/cui/uiconfig/ui/multipathdialog.ui
new file mode 100644
index 000000000..969b365ec
--- /dev/null
+++ b/cui/uiconfig/ui/multipathdialog.ui
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="MultiPathDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="multipathdialog|MultiPathDialog">Select Paths</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ok-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="multipathdialog|extended_tip|ok">Saves all changes and closes dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cancel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="multipathdialog|extended_tip|cancel">Closes dialog and discards all changes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="multipathdialog|add">_Add...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cui/ui/multipathdialog/add">Opens the Select Path dialog to select another folder or the Open dialog to select another file.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="multipathdialog|extended_tip|delete">Deletes the selected element or elements without requiring confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="paths">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="multipathdialog|pathlist">Path list</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5">
+ <property name="radio">True</property>
+ </object>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="paths-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cui/ui/multipathdialog/paths">Contains a list of the paths that have already been added. Mark the default path for new files.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="multipathdialog|label1">Mark the Default Path for New Files</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/namedialog.ui b/cui/uiconfig/ui/namedialog.ui
new file mode 100644
index 000000000..2936179e4
--- /dev/null
+++ b/cui/uiconfig/ui/namedialog.ui
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="NameDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="namedialog|NameDialog">Name</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="description_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <property name="wrap">True</property>
+ <property name="mnemonic_widget">name_entry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="width_chars">40</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/newlibdialog.ui b/cui/uiconfig/ui/newlibdialog.ui
new file mode 100644
index 000000000..51fed37d0
--- /dev/null
+++ b/cui/uiconfig/ui/newlibdialog.ui
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="NewLibDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="newlibdialog|NewLibDialog">Create Library</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="newlibft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="newlibdialog|newlibft">Enter the name for the new library.</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="newmacroft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="newlibdialog|newmacroft">Enter the name for the new macro.</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="renameft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="newlibdialog|renameft">Enter the new name for the selected object.</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="altmacrotitle">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="newlibdialog|altmacrotitle">Create Macro</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="altrenametitle">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="newlibdialog|altrenametitle">Rename</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/newtabledialog.ui b/cui/uiconfig/ui/newtabledialog.ui
new file mode 100644
index 000000000..8b3d12aef
--- /dev/null
+++ b/cui/uiconfig/ui/newtabledialog.ui
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.4 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="columns_value">
+ <property name="lower">1</property>
+ <property name="upper">75</property>
+ <property name="value">5</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="rows_value">
+ <property name="lower">1</property>
+ <property name="upper">75</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="NewTableDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="newtabledialog|NewTableDialog">Insert Table</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="columns_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="newtabledialog|columns_label">_Number of columns:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">columns</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="rows_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="newtabledialog|rows_label">_Number of rows:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">rows</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="columns">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">columns_value</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="rows">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">rows_value</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="numeric">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/newtoolbardialog.ui b/cui/uiconfig/ui/newtoolbardialog.ui
new file mode 100644
index 000000000..ec9e76c35
--- /dev/null
+++ b/cui/uiconfig/ui/newtoolbardialog.ui
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="NewToolbarDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="newtoolbardialog|NewToolbarDialog">Name</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <property name="image_position">right</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ <property name="non_homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="newtoolbardialog|label1">_Toolbar name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="width_chars">26</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="newtoolbardialog|label2">_Save in:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">savein</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="savein">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/numberingformatpage.ui b/cui/uiconfig/ui/numberingformatpage.ui
new file mode 100644
index 000000000..2954e7f4b
--- /dev/null
+++ b/cui/uiconfig/ui/numberingformatpage.ui
@@ -0,0 +1,724 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">20</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">8</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">20</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">svx/res/nu02.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">svx/res/nu01.png</property>
+ </object>
+ <object class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">svx/res/nu03.png</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name textcolor -->
+ <column type="GdkRGBA"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="NumberingFormatPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="formatcode">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkEntry" id="formatted">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="formatted-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|formatted">Displays the number format code for the selected format. You can also enter a custom format.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="numberingformatpage|add|tooltip_text">Add</property>
+ <property name="valign">center</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|add">Adds the number format code that you entered to the user-defined category.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="numberingformatpage|edit|tooltip_text">Edit Comment</property>
+ <property name="valign">center</property>
+ <property name="image">image3</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|edit">Enter a comment for the selected number format, and then click outside this box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="numberingformatpage|delete|tooltip_text">Remove</property>
+ <property name="valign">center</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|delete">Deletes the selected number format.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="commentft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="commented">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="tooltip_text" translatable="yes" context="numberingformatpage|commented|tooltip_text">Comment</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="commented-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|commented">Adds a comment to the selected number format.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="formatf">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|formatf">_Format Code</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">formatted</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="options">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">0</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="decimalsed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="decimalsed-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|decimalsed">Enter the number of decimal places that you want to display.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="denominatored">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="denominatored-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|denominatored">With fraction format, enter the number of places for the denominator that you want to display.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="leadzerosed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="leadzerosed-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|leadzerosed">Enter the maximum number of zeroes to display in front of the decimal point.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="border_width">0</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="decimalsft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|decimalsft">_Decimal places:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">decimalsed</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="denominatorft">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|denominatorft">Den_ominator places:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">denominatored</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="leadzerosft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|leadzerosft">Leading _zeroes:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">leadzerosed</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="negnumred">
+ <property name="label" translatable="yes" context="numberingformatpage|negnumred">_Negative numbers red</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="negnumred-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|negnumred">Changes the font color of negative numbers to red.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">0</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="engineering">
+ <property name="label" translatable="yes" context="numberingformatpage|engineering">_Engineering notation</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="engineering-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|engineering">With scientific format, Engineering notation ensures that exponent is a multiple of 3.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="thousands">
+ <property name="label" translatable="yes" context="numberingformatpage|thousands">_Thousands separator</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="thousands-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|thousands">Inserts a separator between thousands. The type of separator that is used depends on your language settings.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="optionsft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|optionsft">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="categoryframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="categorylb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="categorylb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|categorylb">Select a category from the list, and then select a formatting style in the Format box.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="categoryft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|categoryft">C_ategory</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">categorylb</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="formatframe">
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="currencylb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="numberingformatpage|liststore2">Automatically</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="currencylb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|currencylb">Select a currency, and then scroll to the top of the Format list to view the formatting options for the currency.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="formatlb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ <attribute name="foreground-rgba">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="formatlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|formatlb">Select how you want the contents of the selected field to be displayed.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="formatft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|formatft">Fo_rmat</property>
+ <property name="use_underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="languageframe">
+ <property name="height_request">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="languagelb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="languagelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|languagelb">Specifies the language setting for the selected field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="sourceformat">
+ <property name="label" translatable="yes" context="numberingformatpage|sourceformat">So_urce format</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="sourceformat-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|sourceformat">Uses the same number format as the cells containing the data for the chart.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">end</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="languageft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingformatpage|languageft">_Language</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">languagelb</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="NumberingFormatPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingformatpage|extended_tip|NumberingFormatPage">Specify the formatting options for the selected cell(s).</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <property name="mode">both</property>
+ <property name="ignore_hidden">True</property>
+ <widgets>
+ <widget name="categoryframe"/>
+ <widget name="formatframe"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/numberingoptionspage.ui b/cui/uiconfig/ui/numberingoptionspage.ui
new file mode 100644
index 000000000..adb0ea9cc
--- /dev/null
+++ b/cui/uiconfig/ui/numberingoptionspage.ui
@@ -0,0 +1,760 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">19.99</property>
+ <property name="step_increment">0.05</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">65535</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">1</property>
+ <property name="upper">10</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">1</property>
+ <property name="upper">400</property>
+ <property name="value">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="upper">19.99</property>
+ <property name="step_increment">0.05</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkMenu" id="bitmapmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuItem" id="fromfile">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|fromfile">From file...</property>
+ <property name="use_underline">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuItem" id="gallery">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|gallery">Gallery</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="gallerysubmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="NumberingOptionsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="levellb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="levellb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|levellb">Select the level(s) that you want to define the formatting options for.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|label1">Level</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|label4">Number:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">numfmtlb</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="charstyle">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="charstyle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|charstyle">Select the Character Style that you want to use in the numbered list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="sublevels">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="sublevels-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|sublevels">Enter the number of previous levels to include in the numbering scheme. For example, if you enter "2" and the previous level uses the "A, B, C..." numbering, the numbering scheme for the current level becomes: "A.1".</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="startat">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="startat-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|startat">Enter a new starting number for the current level.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="startatft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|startatft">Start at:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">startat</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="numfmtlb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numfmtlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|numfmtlb">Select a numbering scheme for the selected levels.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bitmapft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|bitmapft">Graphics:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bitmap</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="widthft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|widthft">Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">widthmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="widthmf">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="widthmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|widthmf">Enter a width for the graphic.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="heightft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|heightft">Height:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">heightmf</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">13</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="heightmf">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment5</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="heightmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|heightmf">Enter a height for the graphic.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">13</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="keepratio">
+ <property name="label" translatable="yes" context="numberingoptionspage|keepratio">Keep ratio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="keepratio-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|keepratio">Maintains the size proportions of the graphic.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">14</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="orientft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|orientft">Alignment:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">orientlb</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">15</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="orientlb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">0</property>
+ <items>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Top of baseline</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Center of baseline</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Bottom of baseline</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Top of character</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Center of character</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Bottom of character</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Top of line</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Center of line</item>
+ <item translatable="yes" context="numberingoptionspage|orientlb">Bottom of line</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="orientlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|orientlb">Select the alignment option for the graphic.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">15</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="bitmap">
+ <property name="label" translatable="yes" context="numberingoptionspage|bitmap">Select...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="popup">bitmapmenu</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="bitmap-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|bitmap">Select the graphic, or locate the graphic file that you want to use as a bullet.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="color">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="color-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|color">Select a color for the current numbering scheme.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="relsize">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relsize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|relsize">Enter the amount by which you want to resize the bullet character with respect to the font height of the current paragraph.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="bullet">
+ <property name="label" translatable="yes" context="numberingoptionspage|bullet">Select...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="bullet-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|bullet">Select the graphic, or locate the graphic file that you want to use as a bullet.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="prefixft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|prefixft">Before:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">prefix</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">20</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="separator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|separator">Separator</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">20</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="suffix">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="suffix-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|suffix">Enter a character or the text to display behind the number in the list. To create the numbering scheme "1.)", enter ".)" in this box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="prefix">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="prefix-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|prefix">Enter a character or the text to display in front of the number in the list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="suffixft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|suffixft">After:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">suffix</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="sublevelsft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|sublevelsft">Show sublevels:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">sublevels</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="bulletft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|bulletft">Character:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">bullet</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="relsizeft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|relsizeft">_Relative size:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">relsize</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="colorft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|colorft">Color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">color</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="charstyleft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|charstyleft">Character style:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">charstyle</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|label2">Numbering</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="levelsframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkCheckButton" id="allsame">
+ <property name="label" translatable="yes" context="numberingoptionspage|allsame">_Consecutive numbering</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="allsame-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingoptionspage|extended_tip|allsame">Increases the numbering by one as you go down each level in the list hierarchy.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|label3">All Levels</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="previewframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="width_request">150</property>
+ <property name="height_request">300</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="previewlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="numberingoptionspage|previewlabel">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/numberingpositionpage.ui b/cui/uiconfig/ui/numberingpositionpage.ui
new file mode 100644
index 000000000..fce23a35b
--- /dev/null
+++ b/cui/uiconfig/ui/numberingpositionpage.ui
@@ -0,0 +1,569 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">19.99</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">-19.99</property>
+ <property name="upper">19.99</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">19.99</property>
+ <property name="step-increment">0.05</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="upper">19.99</property>
+ <property name="step-increment">0.01</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="upper">19.99</property>
+ <property name="step-increment">0.01</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="upper">19.99</property>
+ <property name="step-increment">0.01</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="NumberingPositionPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="levellb">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="levellb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|levellb">Select the level(s) that you want to modify.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|1">Level</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="numberingframe">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=10 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="numfollowedby">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|numfollowedby">Numbering followed by:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">numfollowedbylb</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="num2align">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|num2align">N_umbering alignment:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">num2alignlb</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="alignedat">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|alignedat">Aligned at:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">alignedatmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="indentat">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|indentat">Indent at:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">indentatmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="indentatmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indentatmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|indentatmf">Enter the distance from the left page margin to the start of all lines in the numbered paragraph that follow the first line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="at">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|at">Tab stop at:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">atmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="atmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment5</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="atmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|atmf">If you select a tab stop to follow the numbering, you can enter a non-negative value as the tab stop position.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="alignedatmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="alignedatmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|alignedatmf">Enter the distance from the left page margin at which the numbering symbol will be aligned.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="numfollowedbylb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="numberingpositionpage|liststore2">Tab stop</item>
+ <item translatable="yes" context="numberingpositionpage|liststore2">Space</item>
+ <item translatable="yes" context="numberingpositionpage|liststore2">Nothing</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numfollowedbylb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|numfollowedbylb">Enter the distance from the left page margin at which the numbering symbol will be aligned.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="indent">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|indent">Indent:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">indentmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="indentmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="indentmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|indentmf">Enter the amount of space to leave between the left page margin (or the left edge of the text object) and the left edge of the numbering area. If the current paragraph style uses an indent, the amount you enter here is added to the indent.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="relative">
+ <property name="label" translatable="yes" context="numberingpositionpage|relative">Relati_ve</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">end</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relative-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|relative">Indents the current level relative to the previous level in the list hierarchy.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">6</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="numberingwidth">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|numberingwidth">Width of numbering:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">numberingwidthmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="numberingwidthmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numberingwidthmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|numberingwidthmf">Enter the width of the numbering area. The numbering symbol can be left, center or right in this area.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="numdistmf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numdistmf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|numdistmf">The alignment of the numbering symbol is adjusted to get the desired minimum space. If it is not possible because the numbering area is not wide enough, then the start of the text is adjusted.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="numdist">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|numdist">Minimum space between
+numbering and text:</property>
+ <property name="use-underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic-widget">numdistmf</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="numalign">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|numalign">N_umbering alignment:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">numalignlb</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="numalignlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="numberingpositionpage|liststore1">Left</item>
+ <item translatable="yes" context="numberingpositionpage|liststore1">Centered</item>
+ <item translatable="yes" context="numberingpositionpage|liststore1">Right</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numalignlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|numalignlb">Set the alignment of the numbering symbols. Select "Left" to align the numbering symbol to start directly at the "Aligned at" position. Select "Right" to align the symbol to end directly before the "Aligned at" position. Select "Centered" to center the symbol around the "Aligned at" position.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="num2alignlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="num2alignlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|num2alignlb">Set the alignment of the numbering symbols. Select "Left" to align the numbering symbol to start directly at the "Aligned at" position. Select "Right" to align the symbol to end directly before the "Aligned at" position. Select "Centered" to center the symbol around the "Aligned at" position.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|label10">Position and Spacing</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkButton" id="standard">
+ <property name="label" translatable="yes" context="numberingpositionpage|standard">Default</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="valign">end</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="standard-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="numberingpositionpage|extended_tip|standard">Resets the indent and the spacing values to the default values.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="previewwin">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="width-request">300</property>
+ <property name="height-request">150</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="numberingpositionpage|previewframe">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/objectnamedialog.ui b/cui/uiconfig/ui/objectnamedialog.ui
new file mode 100644
index 000000000..886a01643
--- /dev/null
+++ b/cui/uiconfig/ui/objectnamedialog.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="ObjectNameDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="objectnamedialog|ObjectNameDialog">Name</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox3">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area3">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="object_name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="objectnamedialog|object_name_label">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">object_name_entry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="object_name_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="width_chars">55</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ObjectNameDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="objectnamedialog|extended_tip|ObjectNameDialog">Enter a name for the selected object. The name will be visible in the Navigator.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/objecttitledescdialog.ui b/cui/uiconfig/ui/objecttitledescdialog.ui
new file mode 100644
index 000000000..bcd206758
--- /dev/null
+++ b/cui/uiconfig/ui/objecttitledescdialog.ui
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTextBuffer" id="textbuffer1">
+ <property name="text">
+
+
+
+</property>
+ </object>
+ <object class="GtkDialog" id="ObjectTitleDescDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="objecttitledescdialog|ObjectTitleDescDialog">Description</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox5">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area5">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="object_title_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="objecttitledescdialog|object_title_label">_Text Alternative:</property>
+ <property name="use_underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="objecttitledescdialog|object_title_label|tooltip_text">Give a short description of non-text content for users who do not see this object.</property>
+ <property name="mnemonic_widget">object_title_entry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="object_title_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">55</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="object_title_entry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="objecttitledescdialog|extended_tip|object_title_entry">Enter a title text. This short name is visible as an alternative tag in HTML format. Accessibility tools can read this text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="desc_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="objecttitledescdialog|desc_label">_Description:</property>
+ <property name="use_underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="objecttitledescdialog|desc_label|tooltip_text">Give longer explanation of non-text content that is too complex to be described briefly in “Text Alternative”</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="desc_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="wrap_mode">word</property>
+ <property name="buffer">textbuffer1</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="desc_entry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="objecttitledescdialog|extended_tip|desc_entry">Enter a description text. The long description text can be entered to describe a complex object or group of objects to users with screen reader software. The description is visible as an alternative tag for accessibility tools.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ObjectTitleDescDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="objecttitledescdialog|extended_tip|ObjectTitleDescDialog">Assigns a title and a description to the selected object. These are accessible for accessibility tools and as alternative tags when you export the document.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optaccessibilitypage.ui b/cui/uiconfig/ui/optaccessibilitypage.ui
new file mode 100644
index 000000000..3f1dbeaf0
--- /dev/null
+++ b/cui/uiconfig/ui/optaccessibilitypage.ui
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptAccessibilityPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="acctool">
+ <property name="label" translatable="yes" context="optaccessibilitypage|acctool">Support _assistive technology tools (program restart required)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="acctool-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|acctool">Allows you to use assistive tools, such as external screen readers, Braille devices or speech recognition input devices. The Java Runtime Environment must be installed on your computer before you can enable assistive support.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="textselinreadonly">
+ <property name="label" translatable="yes" context="optaccessibilitypage|textselinreadonly">Use te_xt selection cursor in read-only text documents</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="textselinreadonly-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|textselinreadonly">Displays cursor in read-only documents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="animatedgraphics">
+ <property name="label" translatable="yes" context="optaccessibilitypage|animatedgraphics">Allow animated _images</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="animatedgraphics-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|animatedgraphics">Previews animated graphics, such as GIF images.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="animatedtext">
+ <property name="label" translatable="yes" context="optaccessibilitypage|animatedtext">Allow animated _text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="animatedtext-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|animatedtext">Previews animated text, such as blinking and scrolling.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optaccessibilitypage|label1">Miscellaneous Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="autodetecthc">
+ <property name="label" translatable="yes" context="optaccessibilitypage|autodetecthc">Automatically _detect high contrast mode of operating system</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autodetecthc-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autodetecthc">Switches the office suite into high contrast mode when the system background color is very dark.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autofontcolor">
+ <property name="label" translatable="yes" context="optaccessibilitypage|autofontcolor">Use automatic font _color for screen display</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autofontcolor-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autofontcolor">Displays fonts in the office suite using the system color settings. This option only affects the screen display.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="systempagepreviewcolor">
+ <property name="label" translatable="yes" context="optaccessibilitypage|systempagepreviewcolor">_Use system colors for page previews</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="systempagepreviewcolor-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|systempagepreviewcolor">Applies the high contrast settings of the operating system to page previews.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optaccessibilitypage|label2">Options for High Contrast Appearance</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptAccessibilityPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptAccessibilityPage">Sets options that make the office suite programs more accessible for users with reduced sight, limited dexterity or other disabilities.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">99</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optadvancedpage.ui b/cui/uiconfig/ui/optadvancedpage.ui
new file mode 100644
index 000000000..f05045bed
--- /dev/null
+++ b/cui/uiconfig/ui/optadvancedpage.ui
@@ -0,0 +1,442 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name check2 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis2 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri2 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="OptAdvancedPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkFrame" id="javaframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="javaenabled">
+ <property name="label" translatable="yes" context="optadvancedpage|javaenabled">_Use a Java runtime environment</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="javaenabled-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|javaenabled">Allows you to run extensions written with Java.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="javabox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="row_spacing">12</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optadvancedpage|label2">_Java runtime environments (JRE) already installed:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">javas</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="optadvancedpage|add">_Add...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|add">Add a path to the root folder of a JRE on your computer.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="parameters">
+ <property name="label" translatable="yes" context="optadvancedpage|parameters">_Parameters...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="parameters-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|parameters">Opens the Java Start Parameters dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="classpath">
+ <property name="label" translatable="yes" context="optadvancedpage|classpath">_Class Path...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="classpath-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|classpath">Opens the Class Path dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="javasscroll">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="javas">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5">
+ <property name="radio">True</property>
+ </object>
+ <attributes>
+ <attribute name="visible">5</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer9">
+ <property name="radio">True</property>
+ </object>
+ <attributes>
+ <attribute name="visible">6</attribute>
+ <attribute name="active">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optadvancedpage|vendor">Vendor</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optadvancedpage|version">Version</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="javas-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|javas">Select the JRE that you want to use. On some systems, you must wait a minute until the list gets populated. On some systems, you must restart the office suite to use your changed setting.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="javapath">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optadvancedpage|javapath">Location: </property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="selectruntime">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optadvancedpage|selectruntime">Select a Java Runtime Environment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optadvancedpage|label1">Java Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="experimental">
+ <property name="label" translatable="yes" context="optadvancedpage|experimental">Enable experimental features (may be unstable)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="experimental-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|experimental">Enable experimental features</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="macrorecording">
+ <property name="label" translatable="yes" context="optadvancedpage|macrorecording">Enable macro recording (may be limited)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="macrorecording-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|macrorecording">Enable macro recording</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="expertconfig">
+ <property name="label" translatable="yes" context="optadvancedpage|expertconfig">Open Expert Configuration</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="expertconfig-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|expertconfig">Opens the Expert Configuration dialog for advanced settings and configuration.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optadvancedpage|label12">Optional Features</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optappearancepage.ui b/cui/uiconfig/ui/optappearancepage.ui
new file mode 100644
index 000000000..64c338ba9
--- /dev/null
+++ b/cui/uiconfig/ui/optappearancepage.ui
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptAppearancePage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=4 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optappearancepage|label3">_Scheme:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">colorschemelb</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="save">
+ <property name="label" translatable="yes" context="optappearancepage|save">_Save</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="save-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|save">Saves the current settings as a color scheme that you can reload later.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|delete">Deletes the color scheme shown in the Scheme box. You cannot delete the Default scheme.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="colorschemelb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colorschemelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|colorschemelb">Selects the color scheme you want to use.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optappearancepage|label1">Color Scheme</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid" id="table">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scroll">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">always</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="colorconfig">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colorconfig-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|colorconfig">Select the colors for the user interface elements.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="uielements">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optappearancepage|uielements">User interface elements</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="colorsetting">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label" translatable="yes" context="optappearancepage|colorsetting">Color setting</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="on">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optappearancepage|label2">Custom Colors</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptAppearancePage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptAppearancePage">Sets the colors for the user interface.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optasianpage.ui b/cui/uiconfig/ui/optasianpage.ui
new file mode 100644
index 000000000..1183559f1
--- /dev/null
+++ b/cui/uiconfig/ui/optasianpage.ui
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptAsianPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="charkerning">
+ <property name="label" translatable="yes" context="optasianpage|charkerning">_Western text only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="charkerning-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|charkerning">Specifies that kerning is only applied to western text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="charpunctkerning">
+ <property name="label" translatable="yes" context="optasianpage|charpunctkerning">Western _text and Asian punctuation</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">charkerning</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="charpunctkerning-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|charpunctkerning">Specifies that kerning is applied to both western text and Asian punctuation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|label1">Kerning</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="nocompression">
+ <property name="label" translatable="yes" context="optasianpage|nocompression">_No compression</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="nocompression-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|nocompression">Specifies that no compression at all will occur.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="punctcompression">
+ <property name="label" translatable="yes" context="optasianpage|punctcompression">_Compress punctuation only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">nocompression</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="punctcompression-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|punctcompression">Specifies that only the punctuation is compressed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="punctkanacompression">
+ <property name="label" translatable="yes" context="optasianpage|punctkanacompression">Compress punctuation and Japanese Kana</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">nocompression</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="punctkanacompression-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|punctkanacompression">Specifies that punctuation and Japanese Kana are compressed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|label2">Character Spacing</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkComboBoxText" id="language">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="language-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|language">Specifies the language for which you want to define first and last characters.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="standard">
+ <property name="label" translatable="yes" context="optasianpage|standard">_Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="standard-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|standard">When you mark Default, the following two text boxes are filled with the default characters for the selected language:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="languageft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|languageft">_Language:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">language</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="startft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|startft">Not _at start of line:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">start</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="endft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|endft">Not at _end of line:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">end</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="start">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="start-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|start">Specifies the characters that should not appear alone at the beginning of a line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="end">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="end-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|end">Specifies the characters that should not appear alone at the end of a line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="hintft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|hintft">Without user-defined line break symbols</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optasianpage|label3">First and Last Characters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optbasicidepage.ui b/cui/uiconfig/ui/optbasicidepage.ui
new file mode 100644
index 000000000..f4311747f
--- /dev/null
+++ b/cui/uiconfig/ui/optbasicidepage.ui
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptBasicIDEPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="codecomplete_enable">
+ <property name="label" translatable="yes" context="optbasicidepage|codecomplete_enable">Enable code completion</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="codecomplete_enable-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|codecomplete_enable">Display methods of a Basic object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optbasicidepage|label1">Code Completion</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="autoclose_proc">
+ <property name="label" translatable="yes" context="optbasicidepage|autoclose_proc">Autoclose procedures</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autoclose_proc-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autoclose_proc">Automatically insert closing statements for procedures.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autoclose_paren">
+ <property name="label" translatable="yes" context="optbasicidepage|autoclose_paren">Autoclose parenthesis</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autoclose_paren-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autoclose_paren">Automatically close open parenthesis.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autoclose_quotes">
+ <property name="label" translatable="yes" context="optbasicidepage|autoclose_quotes">Autoclose quotes</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autoclose_quotes-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autoclose_quotes">Automatically close open quotes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="autocorrect">
+ <property name="label" translatable="yes" context="optbasicidepage|autocorrect">Autocorrection</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autocorrect-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autocorrect">Correct cases of Basic variables and keywords while typing.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optbasicidepage|label2">Code Suggestion</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="extendedtypes_enable">
+ <property name="label" translatable="yes" context="optbasicidepage|extendedtypes_enable">Use extended types</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="extendedtypes_enable-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|extendedtypes_enable">Allow UNO object types as valid Basic types.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optbasicidepage|label3">Language Features</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optchartcolorspage.ui b/cui/uiconfig/ui/optchartcolorspage.ui
new file mode 100644
index 000000000..0359dcf5f
--- /dev/null
+++ b/cui/uiconfig/ui/optchartcolorspage.ui
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name image -->
+ <column type="CairoSurface"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="OptChartColorsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="colorswin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="colors">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="surface">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="colors-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|colors">Displays all the colors available for the data series.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optchartcolorspage|label20">Chart Colors</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="column_spacing">12</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="default">
+ <property name="label" translatable="yes" context="optchartcolorspage|default">_Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="default-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|default">Restores the color settings that were defined when the program was installed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="paletteselector">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="tablewin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="table">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optchartcolorspage|label1">Color Table</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptChartColorsPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptChartColorsPage">Displays all the colors available for the data series.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1"/>
+</interface>
diff --git a/cui/uiconfig/ui/optctlpage.ui b/cui/uiconfig/ui/optctlpage.ui
new file mode 100644
index 000000000..c12c2982d
--- /dev/null
+++ b/cui/uiconfig/ui/optctlpage.ui
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptCTLPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="sequencechecking">
+ <property name="label" translatable="yes" context="optctlpage|sequencechecking">Use se_quence checking</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="sequencechecking-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|sequencechecking">Enables sequence input checking for languages such as Thai.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkCheckButton" id="restricted">
+ <property name="label" translatable="yes" context="optctlpage|restricted">Restricted</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="restricted-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|restricted">Prevents the use as well as the printing of illegal character combinations.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="typeandreplace">
+ <property name="label" translatable="yes" context="optctlpage|typeandreplace">_Type and replace</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optctlpage|label1">Sequence Checking</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optctlpage|label3">Movement:</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="movementlogical">
+ <property name="label" translatable="yes" context="optctlpage|movementlogical">Lo_gical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="movementlogical-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|movementlogical">Pressing the Right Arrow key moves the text cursor toward the end of the current text. Pressing the Left Arrow key moves the text cursor toward the beginning of the current text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="movementvisual">
+ <property name="label" translatable="yes" context="optctlpage|movementvisual">_Visual</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">movementlogical</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="movementvisual-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|movementvisual">Pressing the Right Arrow key moves the text cursor in the right-hand direction. Pressing the Left Arrow key moves the text cursor in the left-hand direction.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optctlpage|label2">Cursor Control</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optctlpage|label5">_Numerals:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">numerals</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="numerals">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="optctlpage|numerals">Arabic (1, 2, 3…)</item>
+ <item translatable="yes" context="optctlpage|numerals">Eastern Arabic (٣ ,٢ ,١…)</item>
+ <item translatable="yes" context="optctlpage|numerals">System</item>
+ <item translatable="yes" context="optctlpage|numerals">Context</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numerals-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|numerals">Selects the type of numerals used within text, text in objects, fields, and controls, in all office suite modules. Only cell contents of Calc are not affected.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optctlpage|label4">General Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptCTLPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptCTLPage">Defines the options for documents with complex text layouts.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="label3"/>
+ <widget name="label5"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optemailpage.ui b/cui/uiconfig/ui/optemailpage.ui
new file mode 100644
index 000000000..24ff34756
--- /dev/null
+++ b/cui/uiconfig/ui/optemailpage.ui
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="OptEmailPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="program">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optemailpage|label2">_Email program:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">url</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="url">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">32</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="url-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|url">Enter the email program path and name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="browse">
+ <property name="label" translatable="yes" context="optemailpage|browse">Browse...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="browse-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|browse">Opens a file dialog to select the email program.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockemail">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="browsetitle">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="optemailpage|browsetitle">All files</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="suppressHiddenCont">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="suppress">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optemailpage|suppress">Suppress hidden elements of documents</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="suppressHidden">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockSuppressHidden">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optemailpage|label1">Sending Documents as Email Attachments</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptEmailPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptEmailPage">Enter the email program path and name.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optfltrembedpage.ui b/cui/uiconfig/ui/optfltrembedpage.ui
new file mode 100644
index 000000000..1cf4e6a76
--- /dev/null
+++ b/cui/uiconfig/ui/optfltrembedpage.ui
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name check2 -->
+ <column type="gboolean"/>
+ <!-- column-name check3 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis2 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis3 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri2 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri3 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptFilterPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="checklbcontainerscroll">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="checklbcontainer">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optfltrembedpage|column1" comments="A column title, short for Load. This string is repeated as a prefix to an explanatory note under the widget">[L]</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">5</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer8"/>
+ <attributes>
+ <attribute name="visible">6</attribute>
+ <attribute name="active">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn7">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optfltrembedpage|column2" comments="A column title, short for Save. This string is repeated as a prefix to an explanatory note under the widget">[S]</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer7"/>
+ <attributes>
+ <attribute name="visible">7</attribute>
+ <attribute name="active">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checklbcontainer-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|checklbcontainer">The [L] and [S] checkbox displays the entries for the pair of OLE objects that can be converted when loaded from a Microsoft format [L] and/or when saved to to a Microsoft format [S]. </property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrembedpage|label2" comments="The [L] here is repeated as the column title for the &quot;Load&quot; column of this options page">[L]: Load and convert the object</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrembedpage|label3" comments="The [S] here is repeated as the column title for the &quot;Save&quot; column of this options page">[S]: Convert and save the object</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrembedpage|label1">Embedded Objects</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">18</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrembedpage|label5">Export as:</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkRadioButton" id="highlighting">
+ <property name="label" translatable="yes" context="optfltrembedpage|highlighting">Highlighting</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="highlighting-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|highlighting">Microsoft Office has two character attributes similar to Writer character background. Select the appropriate attribute (highlighting or shading) which you would like to use during export to Microsoft Office file formats.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="shading">
+ <property name="label" translatable="yes" context="optfltrembedpage|shading">Shading</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">highlighting</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="shading-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|shading">Microsoft Office has two character attributes similar to Writer character background. Select the appropriate attribute (highlighting or shading) which you would like to use during export to Microsoft Office file formats.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrembedpage|label4">Character Highlighting</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">start</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="mso_lockfile">
+ <property name="label" translatable="yes" context="optfltrembedpage|mso_lockfile">Create MSO lock file</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="mso_lockfile-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|mso_lockfile">Mark this checkbox to generate a Microsoft Office lock file in addition to this office suite's own lock file.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrembedpage|label5">Lock Files</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptFilterPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptFilterPage">Specifies the settings for importing and exporting Microsoft Office and other documents.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optfltrpage.ui b/cui/uiconfig/ui/optfltrpage.ui
new file mode 100644
index 000000000..1057a30bc
--- /dev/null
+++ b/cui/uiconfig/ui/optfltrpage.ui
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptFltrPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="wo_basic">
+ <property name="label" translatable="yes" context="optfltrpage|wo_basic">Load Basic _code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="wo_basic-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|wo_basic">Loads and saves the Basic code from a Microsoft document as a special Basic module with the document. The disabled Microsoft Basic code is visible in the Basic IDE between Sub and End Sub.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="wo_exec">
+ <property name="label" translatable="yes" context="optfltrpage|wo_exec">E_xecutable code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">18</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="wo_exec-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|wo_exec">The VBA (Visual Basic for Applications) code will be loaded ready to be executed. If this checkbox is not checked, the VBA code will be commented out so it can be inspected, but will not run.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="wo_saveorig">
+ <property name="label" translatable="yes" context="optfltrpage|wo_saveorig">Save _original Basic code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="wo_saveorig-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|wo_saveorig">Specifies that the original Microsoft Basic code contained in the document is held in a special internal memory for as long as the document remains loaded in the office suite. When saving the document in Microsoft format the Microsoft Basic is saved again with the code in an unchanged form.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrpage|label1">Microsoft Word</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="ex_basic">
+ <property name="label" translatable="yes" context="optfltrpage|ex_basic">Lo_ad Basic code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ex_basic-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ex_basic">Loads and saves the Basic code from a Microsoft document as a special Basic module with the document. The disabled Microsoft Basic code is visible in the Basic IDE between Sub and End Sub.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ex_exec">
+ <property name="label" translatable="yes" context="optfltrpage|ex_exec">E_xecutable code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">18</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ex_exec-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ex_exec">The VBA (Visual Basic for Applications) code will be loaded ready to be executed. If this checkbox is not checked, the VBA code will be commented out so it can be inspected, but will not run.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ex_saveorig">
+ <property name="label" translatable="yes" context="optfltrpage|ex_saveorig">Sa_ve original Basic code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ex_saveorig-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ex_saveorig">Specifies that the original Microsoft Basic code contained in the document is held in a special internal memory for as long as the document remains loaded in the office suite. When saving the document in Microsoft format the Microsoft Basic is saved again with the code in an unchanged form.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrpage|label2">Microsoft Excel</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="pp_basic">
+ <property name="label" translatable="yes" context="optfltrpage|pp_basic">Load Ba_sic code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="pp_basic-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|pp_basic">Loads and saves the Basic code from a Microsoft document as a special Basic module with the document. The disabled Microsoft Basic code is visible in the Basic IDE between Sub and End Sub.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="pp_saveorig">
+ <property name="label" translatable="yes" context="optfltrpage|pp_saveorig">Sav_e original Basic code</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="pp_saveorig-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|pp_saveorig">Specifies that the original Microsoft Basic code contained in the document is held in a special internal memory for as long as the document remains loaded in the office suite. When saving the document in Microsoft format the Microsoft Basic is saved again with the code in an unchanged form.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfltrpage|label3">Microsoft PowerPoint</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptFltrPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptFltrPage">Specifies the general properties for loading and saving Microsoft Office documents with VBA (Visual Basic for Applications) code.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optfontspage.ui b/cui/uiconfig/ui/optfontspage.ui
new file mode 100644
index 000000000..30bb49d92
--- /dev/null
+++ b/cui/uiconfig/ui/optfontspage.ui
@@ -0,0 +1,480 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">svx/res/nu01.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">svx/res/nu02.png</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name check2 -->
+ <column type="gboolean"/>
+ <!-- column-name check3 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text1 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis2 -->
+ <column type="gboolean"/>
+ <!-- column-name checkvis3 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri2 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri3 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="OptFontsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="replacements">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfontspage|label2">_Font:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">font1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfontspage|label3">Re_place with:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">font2</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="checklbscroll">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="checklb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optfontspage|always">Always</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="visible">6</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">7</attribute>
+ <attribute name="active">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn7">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optfontspage|screenonly">Screen only</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer7"/>
+ <attributes>
+ <attribute name="visible">8</attribute>
+ <attribute name="active">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optfontspage|font">Font</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn9">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optfontspage|replacewith">Replace with</property>
+ <property name="clickable">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer9"/>
+ <attributes>
+ <attribute name="text">4</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checklb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | checklb">Lists the original font and the font that will replace it. Select Always to replace the font, even if the original font is installed on your system. Select Screen only to replace the screen font only and never replace the font for printing.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="apply">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="apply-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | apply">Applies the selected font replacement.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | delete">Deletes the selected font replacement.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="font2">
+ <property name="sensitive">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="font2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | font2">Enter or select the name of the replacement font.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="font1">
+ <property name="sensitive">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="font1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | font1">Enter or select the name of the font that you want to replace.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replacements-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | replacements">Substitutes a font with a font of your choice. The substitution replaces a font only when it is displayed on screen, or on screen and when printing. The replacement does not change the font settings that are saved in the document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="usetable">
+ <property name="label" translatable="yes" context="optfontspage|usetable">_Apply replacement table</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="usetable-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | usetable">Enables the font replacement settings that you define.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfontspage|label4">Replacement Table</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_top">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optfontspage|label8">Fon_ts:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">fontname</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optfontspage|label9">_Size:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">fontheight</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="fontname">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="optfontspage|fontname">Automatic</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fontname-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | fontname">Select the font for the display of HTML and Basic source code.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="nonpropfontonly">
+ <property name="label" translatable="yes" context="optfontspage|nonpropfontonly">_Non-proportional fonts only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="nonpropfontonly-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | nonpropfontonly">Check to display only non-proportional fonts in the Fonts list box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="fontheight">
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fontheight-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | fontheight">Select a font size for the display of HTML and Basic source code.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optfontspage|label1">Font Settings for HTML, Basic and SQL Sources</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optgeneralpage.ui b/cui/uiconfig/ui/optgeneralpage.ui
new file mode 100644
index 000000000..dfd8e7bd9
--- /dev/null
+++ b/cui/uiconfig/ui/optgeneralpage.ui
@@ -0,0 +1,441 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1583</property>
+ <property name="upper">9857</property>
+ <property name="value">1930</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptGeneralPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="exthelp">
+ <property name="label" translatable="yes" context="optgeneralpage|exthelp">_Extended tips</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="exthelp-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | exthelp">Displays a help text when you rest the mouse pointer on an icon, a menu command, or a control on a dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="popupnohelp">
+ <property name="label" translatable="yes" context="optgeneralpage|popupnohelp">Warn if local help is not installed</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbShowTipOfTheDay">
+ <property name="label" translatable="yes" context="optgeneralpage|TipOfTheDayCheckbox">Show "Tip of the Day" dialog on start-up</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label1">Help</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="filedlgframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="filedlg">
+ <property name="label" translatable="yes" context="optgeneralpage|filedlg">_Use %PRODUCTNAME dialogs</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockimage">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label2">Open/Save Dialogs</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkCheckButton" id="docstatus">
+ <property name="label" translatable="yes" context="optgeneralpage|docstatus">_Printing sets "document modified" status</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="docstatus-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | docstatus">Specifies whether the printing of the document counts as a modification.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label4">Document Status</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="yearframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label6">_Interpret as years between </property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">year</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="year">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="year-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | year">Defines a date range, within which the system recognizes a two-digit year.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="toyear">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|toyear">and </property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label5">Year (Two Digits)</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="privacyframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="crashreport">
+ <property name="label" translatable="yes" context="optgeneralpage|crashreport">Sen_d crash reports to The Document Foundation</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label7">Help Improve %PRODUCTNAME</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="quickstarter">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="quicklaunch">
+ <property name="label" translatable="yes" context="optgeneralpage|quicklaunch">Load %PRODUCTNAME during system start-up</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="systray">
+ <property name="label" translatable="yes" context="optgeneralpage|systray">Enable systray Quickstarter</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|label8">%PRODUCTNAME Quickstarter</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="fileassoc">
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkButton" id="assocfiles">
+ <property name="label" translatable="yes" context="optgeneralpage|fileassoc">Windows Default apps</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="cbPerformFileExtCheck">
+ <property name="label" translatable="yes" context="optgeneralpage|FileExtCheckCheckbox">Perform check for default file associations on start-up</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optgeneralpage|fileassoc">%PRODUCTNAME File Associations</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptGeneralPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | OptGeneralPage">Specifies the general settings for the office suite.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/opthtmlpage.ui b/cui/uiconfig/ui/opthtmlpage.ui
new file mode 100644
index 000000000..85eed35d5
--- /dev/null
+++ b/cui/uiconfig/ui/opthtmlpage.ui
@@ -0,0 +1,550 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustsize1">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">7</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustsize2">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustsize3">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">12</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustsize4">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">14</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustsize5">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">18</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustsize6">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">24</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustsize7">
+ <property name="lower">1</property>
+ <property name="upper">50</property>
+ <property name="value">36</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="OptHtmlPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkLabel" id="size7FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size7FT">Size _7:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size7</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size7">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize7</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size7-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size7">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size6FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size6FT">Size _6:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size6</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size6">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize6</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size6-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size6">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size5FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size5FT">Size _5:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size5</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size5">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize5</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size5-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size5">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size4FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size4FT">Size _4:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size4</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize4</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size4-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size4">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size3FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size3FT">Size _3:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size3</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize3</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size3-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size3">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size2FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size2FT">Size _2:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size2</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size2">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="size1FT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|size1FT">Size _1:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">size1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="size1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustsize1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="size1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|size1">Use the spin buttons Size 1 to Size 7 to define the respective font sizes for the HTML &lt;font size=1&gt; to &lt;font size=7&gt; tags.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|label1">Font Sizes</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="ignorefontnames">
+ <property name="label" translatable="yes" context="opthtmlpage|ignorefontnames">Ignore _font settings</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignorefontnames-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ignorefontnames">Mark this check box to ignore all font settings when importing. The fonts that were defined in the HTML Page Style will be the fonts that will be used. </property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="unknowntag">
+ <property name="label" translatable="yes" context="opthtmlpage|unknowntag">_Import unknown HTML tags as fields</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="unknowntag-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|unknowntag">Mark this check box if you want tags that are not recognized by Writer/Web to be imported as fields.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="numbersenglishus">
+ <property name="label" translatable="yes" context="opthtmlpage|numbersenglishus">_Use '%ENGLISHUSLOCALE' locale for numbers</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="numbersenglishus-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|numbersenglishus">If not checked, numbers will be interpreted according to the setting in Language Settings - Language of - Locale setting in the Options dialog box. If checked, numbers will be interpreted as 'English (USA)' locale.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|label2">Import</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="savegrflocal">
+ <property name="label" translatable="yes" context="opthtmlpage|savegrflocal">_Copy local images to Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="savegrflocal-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|savegrflocal">Mark this check box to automatically upload the embedded pictures to the Internet server when uploading using FTP. Use the Save As dialog to save the document and enter a complete FTP URL as the file name in the Internet.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="printextension">
+ <property name="label" translatable="yes" context="opthtmlpage|printextension">_Print layout</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="printextension-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|printextension">If you mark this field, the print layout of the current document (for example, table of contents with justified page numbers and dot leaders) is exported as well.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="starbasicwarning">
+ <property name="label" translatable="yes" context="opthtmlpage|starbasicwarning">Display _warning</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">12</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="starbasicwarning-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|starbasicwarning">If this field is marked, when exporting to HTML a warning is shown that Basic macros will be lost.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="starbasic">
+ <property name="label" translatable="yes" context="opthtmlpage|starbasic">LibreOffice _Basic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="starbasic-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|starbasic">Check this box to include the BASIC instructions when exporting to HTML format.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="opthtmlpage|label3">Export</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptHtmlPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptHtmlPage">Defines settings for HTML pages.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1"/>
+</interface>
diff --git a/cui/uiconfig/ui/optionsdialog.ui b/cui/uiconfig/ui/optionsdialog.ui
new file mode 100644
index 000000000..85acd3198
--- /dev/null
+++ b/cui/uiconfig/ui/optionsdialog.ui
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="OptionsDialog">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="optionsdialog|OptionsDialog">Options</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="revert">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="optionsdialog|revert">Unsaved modifications to this tab are reverted.</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="revert-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="optionsdialog|extended_tip|revert">Resets changes made to the current tab to those applicable when this dialog was opened.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="apply">
+ <property name="label" translatable="yes" context="stock">_Apply</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="optionsdialog|apply">Save all modifications without closing dialog. Cannot be reverted with Reset.</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="optionsdialog|ok">Save all changes and close dialog.</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ok-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="optionsdialog|extended_tip|ok">Saves all changes and closes dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <property name="tooltip_text" translatable="yes" context="optionsdialog|cancel">Discard all unsaved changes and close dialog.</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cancel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="optionsdialog|extended_tip|cancel">Closes dialog and discards all unsaved changes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="pages">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">revert</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optjsearchpage.ui b/cui/uiconfig/ui/optjsearchpage.ui
new file mode 100644
index 000000000..e4f96549e
--- /dev/null
+++ b/cui/uiconfig/ui/optjsearchpage.ui
@@ -0,0 +1,448 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptJSearchPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="column_homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="matchcase">
+ <property name="label" translatable="yes" context="optjsearchpage|matchcase">_uppercase/lowercase</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchcase-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchcase">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchfullhalfwidth">
+ <property name="label" translatable="yes" context="optjsearchpage|matchfullhalfwidth">_full-width/half-width forms</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchfullhalfwidth-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchfullhalfwidth">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchhiraganakatakana">
+ <property name="label" translatable="yes" context="optjsearchpage|matchhiraganakatakana">_hiragana/katakana</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchhiraganakatakana-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchhiraganakatakana">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchcontractions">
+ <property name="label" translatable="yes" context="optjsearchpage|matchcontractions">_contractions (yo-on, sokuon)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchcontractions-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchcontractions">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchminusdashchoon">
+ <property name="label" translatable="yes" context="optjsearchpage|matchminusdashchoon">_minus/dash/cho-on</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchminusdashchoon-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchminusdashchoon">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchrepeatcharmarks">
+ <property name="label" translatable="yes" context="optjsearchpage|matchrepeatcharmarks">It_eration marks</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchrepeatcharmarks-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchrepeatcharmarks">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchvariantformkanji">
+ <property name="label" translatable="yes" context="optjsearchpage|matchvariantformkanji">_variant-form kanji (itaiji)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchvariantformkanji-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchvariantformkanji">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matcholdkanaforms">
+ <property name="label" translatable="yes" context="optjsearchpage|matcholdkanaforms">_old Kana forms</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matcholdkanaforms-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matcholdkanaforms">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchdiziduzu">
+ <property name="label" translatable="yes" context="optjsearchpage|matchdiziduzu">_di/zi, du/zu</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchdiziduzu-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchdiziduzu">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchbavahafa">
+ <property name="label" translatable="yes" context="optjsearchpage|matchbavahafa">_ba/va, ha/fa</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchbavahafa-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchbavahafa">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchtsithichidhizi">
+ <property name="label" translatable="yes" context="optjsearchpage|matchtsithichidhizi">_tsi/thi/chi, dhi/zi</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchtsithichidhizi-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchtsithichidhizi">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchhyuiyubyuvyu">
+ <property name="label" translatable="yes" context="optjsearchpage|matchhyuiyubyuvyu">h_yu/fyu, byu/vyu</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchhyuiyubyuvyu-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchhyuiyubyuvyu">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchseshezeje">
+ <property name="label" translatable="yes" context="optjsearchpage|matchseshezeje">_se/she, ze/je</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchseshezeje-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchseshezeje">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchiaiya">
+ <property name="label" translatable="yes" context="optjsearchpage|matchiaiya">_ia/iya (piano/piyano)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchiaiya-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchiaiya">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchkiku">
+ <property name="label" translatable="yes" context="optjsearchpage|matchkiku">_ki/ku (tekisuto/tekusuto)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchkiku-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchkiku">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="matchprolongedsoundmark">
+ <property name="label" translatable="yes" context="optjsearchpage|matchprolongedsoundmark">Prolon_ged vowels (ka-/kaa)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="matchprolongedsoundmark-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|matchprolongedsoundmark">Specifies the options to be treated as equal in a search.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optjsearchpage|label1">Treat as Equal</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="column_homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="ignorepunctuation">
+ <property name="label" translatable="yes" context="optjsearchpage|ignorepunctuation">Pu_nctuation characters</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignorepunctuation-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ignorepunctuation">Specifies the characters to be ignored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ignorewhitespace">
+ <property name="label" translatable="yes" context="optjsearchpage|ignorewhitespace">_Whitespace characters</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignorewhitespace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ignorewhitespace">Specifies the characters to be ignored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ignoremiddledot">
+ <property name="label" translatable="yes" context="optjsearchpage|ignoremiddledot">Midd_le dots</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignoremiddledot-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ignoremiddledot">Specifies the characters to be ignored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optjsearchpage|label2">Ignore</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optlanguagespage.ui b/cui/uiconfig/ui/optlanguagespage.ui
new file mode 100644
index 000000000..b33c2e0a1
--- /dev/null
+++ b/cui/uiconfig/ui/optlanguagespage.ui
@@ -0,0 +1,557 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkListStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptLanguagesPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|label4">_User interface:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">userinterface</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="userinterface">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="userinterface-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|userinterface">Select the language used for the user interface, for example menus, dialogs, help files. You must have installed at least one additional language pack.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|label1">Language Of</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkComboBox" id="westernlanguage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="westernlanguage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|westernlanguage">Specifies the language used for the spellcheck function in western alphabets.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="asianlanguage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext3"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="asianlanguage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|asianlanguage">Specifies the language used for the spellcheck function in Asian alphabets.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="complexlanguage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext5"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="complexlanguage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|complexlanguage">Specifies the language for the complex text layout spellcheck.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="currentdoc">
+ <property name="label" translatable="yes" context="optlanguagespage|currentdoc">For the current document only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="currentdoc-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|currentdoc">Specifies that the settings for default languages are valid only for the current document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ctlsupport">
+ <property name="label" translatable="yes" context="optlanguagespage|ctlsupport">Complex _text layout:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ctlsupport-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ctlsupport">Activates complex text layout support. You can now modify the settings corresponding to complex text layout.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="asiansupport">
+ <property name="label" translatable="yes" context="optlanguagespage|asiansupport">Asian:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="asiansupport-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|asiansupport">Activates Asian languages support. You can now modify the corresponding Asian language settings.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="western">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|western">Western:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">westernlanguage</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|label2">Default Languages for Documents</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="ignorelanguagechange">
+ <property name="label" translatable="yes" context="optlanguagespage|ignorelanguagechange">Ignore s_ystem input language</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignorelanguagechange-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ignorelanguagechange">Indicates whether changes to the system input language/keyboard will be ignored. If ignored, when new text is typed that text will follow the language of the document or current paragraph, not the current system language.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|label3">Enhanced Language Support</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="localesettingFT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|localesettingFT">Locale setting:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">localesetting</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|label6">Decimal separator key:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">decimalseparator</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="defaultcurrency">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|defaultcurrency">_Default currency:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">currencylb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="dataaccpatterns">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|dataaccpatterns">Date acceptance _patterns:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">datepatterns</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="localesetting">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="localesetting-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|localesetting">Specifies the locale setting of the country setting. This influences settings for numbering, currency and units of measure.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="currencylb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="currencylb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|currencylb">Specifies the default currency that is used for the currency format and the currency fields.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="datepatterns">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="datepatterns-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|datepatterns">Specifies the date acceptance patterns for the current locale. Calc spreadsheet and Writer table cell input needs to match locale dependent date acceptance patterns before it is recognized as a valid date.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="decimalseparator">
+ <property name="label" translatable="yes" context="optlanguagespage|decimalseparator">_Same as locale setting ( %1 )</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="decimalseparator-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|decimalseparator">Specifies to use the decimal separator key that is set in your system when you press the respective key on the number pad.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optlanguagespage|label7">Formats</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptLanguagesPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptLanguagesPage">Defines the default languages and some other locale settings for documents.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="label4"/>
+ <widget name="localesettingFT"/>
+ <widget name="label6"/>
+ <widget name="defaultcurrency"/>
+ <widget name="dataaccpatterns"/>
+ <widget name="ctlsupport"/>
+ <widget name="asiansupport"/>
+ <widget name="western"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="userinterface"/>
+ <widget name="localesetting"/>
+ <widget name="currencylb"/>
+ <widget name="datepatterns"/>
+ <widget name="decimalseparator"/>
+ <widget name="westernlanguage"/>
+ <widget name="asianlanguage"/>
+ <widget name="complexlanguage"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optlingupage.ui b/cui/uiconfig/ui/optlingupage.ui
new file mode 100644
index 000000000..5ae94f81c
--- /dev/null
+++ b/cui/uiconfig/ui/optlingupage.ui
@@ -0,0 +1,623 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore4">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptLinguPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="row-spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column-spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="lingumodules">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">1</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingumodules-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingumodules">Contains the installed language modules.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="lingumodulesedit">
+ <property name="label" translatable="yes" context="optlingupage|lingumodulesedit">_Edit...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="valign">start</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingumodulesedit-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="optlingupage|lingumodulesedit-atkobject">Edit Available language modules</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingumodulesedit">To edit a language module, select it and click Edit.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="lingumodulesft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optlingupage|lingumodulesft">_Available Language Modules</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">lingumodules</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column-spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="lingudicts">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="hexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">1</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn44">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer55"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn55">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer44"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingudicts-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingudicts">Lists the available user dictionaries.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout-style">start</property>
+ <child>
+ <object class="GtkButton" id="lingudictsnew">
+ <property name="label" translatable="yes" context="optlingupage|lingudictsnew">_New...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingudictsnew-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingudictsnew">Opens the New Dictionary dialog, in which you can name a new user-defined dictionary or dictionary of exceptions and specify the language.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="lingudictsedit">
+ <property name="label" translatable="yes" context="optlingupage|lingudictsedit">Ed_it...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingudictsedit-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="optlingupage|lingudictsedit-atkobject">Edit User-defined dictionaries</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingudictsedit">Opens the Edit custom dictionary dialog, in which you can add to your custom dictionary or edit existing entries.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="lingudictsdelete">
+ <property name="label" translatable="yes" context="optlingupage|lingudictsdelete">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lingudictsdelete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="lingudictsdelete">Deletes the selected dictionary after a confirmation, provided it is not write-protected.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="lingudictsft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optlingupage|lingudictsft">_User-defined Dictionaries</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">lingudicts</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="linguoptions">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore4</property>
+ <property name="headers-visible">False</property>
+ <property name="search-column">1</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection3"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn444">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer555"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn555">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer444"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linguoptions-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="linguoptions">Defines the options for the spellcheck and hyphenation.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="linguoptionsedit">
+ <property name="label" translatable="yes" context="optlingupage|linguoptionsedit">Edi_t...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="valign">start</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="linguoptionsedit-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="optlingupage|linguoptionsedit-atkobject">Edit Options</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="linguoptionsedit">If you want to change a value, select the entry and then click Edit.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">cmd/sc_additionsdialog.png</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="moredictslink">
+ <property name="label" translatable="yes" context="optlingupage|moredictslink">Get more dictionaries online...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optlingupage|label4">_Options</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">linguoptions</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptLinguPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="OptLinguPage">Specifies the properties of the spelling, thesaurus and hyphenation.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="lingumodulesedit"/>
+ <widget name="buttonbox1"/>
+ <widget name="linguoptionsedit"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optnewdictionarydialog.ui b/cui/uiconfig/ui/optnewdictionarydialog.ui
new file mode 100644
index 000000000..0566ea9d6
--- /dev/null
+++ b/cui/uiconfig/ui/optnewdictionarydialog.ui
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="OptNewDictionaryDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="optnewdictionarydialog|OptNewDictionaryDialog">New Dictionary</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkEntry" id="nameedit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">32</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">32</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="nameedit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="nameedit">Specifies the name of the new custom dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optnewdictionarydialog|name_label">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">nameedit</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="language_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optnewdictionarydialog|language_label">_Language:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">language</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="except">
+ <property name="label" translatable="yes" context="optnewdictionarydialog|except">_Exception (-)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="except-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="except">Specifies whether you wish to avoid certain words in your documents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="language">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="language-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="language">By selecting a certain language you can limit the use of the custom dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optnewdictionarydialog|label1">Dictionary</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptNewDictionaryDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="OptNewDictionaryDialog">In the Dictionary section you can name a new user-defined dictionary or dictionary of exceptions and specify the language.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optonlineupdatepage.ui b/cui/uiconfig/ui/optonlineupdatepage.ui
new file mode 100644
index 000000000..7788baecc
--- /dev/null
+++ b/cui/uiconfig/ui/optonlineupdatepage.ui
@@ -0,0 +1,469 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="OptOnlineUpdatePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="autocheck">
+ <property name="label" translatable="yes" context="optonlineupdatepage|autocheck">_Check for updates automatically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autocheck-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autocheck">Mark to check for online updates periodically, then select the time interval how often to automatically check for online updates.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkRadioButton" id="everyday">
+ <property name="label" translatable="yes" context="optonlineupdatepage|everyday">Every da_y</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="everyday-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|everyday">A check will be performed once a day.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="everyweek">
+ <property name="label" translatable="yes" context="optonlineupdatepage|everyweek">Every _week</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">everyday</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="everyweek-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|everyweek">A check will be performed once a week. This is the default setting.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="everymonth">
+ <property name="label" translatable="yes" context="optonlineupdatepage|everymonth">Every _month</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">everyday</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="everymonth-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|everymonth">A check will be performed once a month.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="checknow">
+ <property name="label" translatable="yes" context="optonlineupdatepage|checknow">Check _Now</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checknow-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|checknow">A check will be performed now.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkLabel" id="lastchecked">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|lastchecked">Last checked: %DATE%, %TIME%</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="neverchecked">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|neverchecked">Last checked: Not yet</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="autodownload">
+ <property name="label" translatable="yes" context="optonlineupdatepage|autodownload">_Download updates automatically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autodownload-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|autodownload">Enable the automatic download of updates to the specified folder.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkButton" id="changepath">
+ <property name="label" translatable="yes" context="optonlineupdatepage|changepath">Ch_ange...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="changepath-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|changepath">Click to select the destination folder for downloaded files.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="destpathlabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|destpathlabel">Download destination:</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="destpathlabel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|destpathlabel">Click to select the destination folder for downloaded files.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="destpath">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labeldest">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|labeldest">Download Destination</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="extrabits">
+ <property name="label" translatable="yes" context="optonlineupdatepage|extrabits">_Send OS version and basic hardware information</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes" context="optonlineupdatepage|extrabits|tooltip_text">This information lets us make optimizations for your hardware and operating system.</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="hbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkLabel" id="useragent_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|useragent_label">User Agent:</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="useragent_changed">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|useragent_changed">Hit apply to update</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="useragent">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelagent">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|labelagent">User Agent</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="btnPrivacyPolicy">
+ <property name="label" translatable="yes" context="optonlineupdatepage|privacy">Privacy Policy</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optonlineupdatepage|label1">Online Update Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptOnlineUpdatePage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptOnlineUpdatePage">Specifies some options for the automatic notification and downloading of online updates to the office suite.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupButtons">
+ <widgets>
+ <widget name="checknow"/>
+ <widget name="changepath"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel">
+ <widgets>
+ <widget name="box2"/>
+ <widget name="box1"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optopenclpage.ui b/cui/uiconfig/ui/optopenclpage.ui
new file mode 100644
index 000000000..ac5cac268
--- /dev/null
+++ b/cui/uiconfig/ui/optopenclpage.ui
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="OptOpenCLPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="denylistbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="useopencl">
+ <property name="label" translatable="yes" context="optopenclpage|useopencl">Allow use of OpenCL</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="openclused">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optopenclpage|openclused">OpenCL is available for use.</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="openclnotused">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optopenclpage|openclnotused">OpenCL is not used.</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optopenclpage|label1">OpenCL Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1"/>
+</interface>
diff --git a/cui/uiconfig/ui/optpathspage.ui b/cui/uiconfig/ui/optpathspage.ui
new file mode 100644
index 000000000..3b4b1d14e
--- /dev/null
+++ b/cui/uiconfig/ui/optpathspage.ui
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text1 -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name weight1 -->
+ <column type="gint"/>
+ <!-- column-name weight2 -->
+ <column type="gint"/>
+ <!-- column-name weight3 -->
+ <column type="gint"/>
+ <!-- column-name sensitive1 -->
+ <column type="gboolean"/>
+ <!-- column-name sensitive2 -->
+ <column type="gboolean"/>
+ <!-- column-name sensitive3 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="OptPathsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="pathscroll">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="paths">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optpathspage|type">Type</property>
+ <property name="clickable">True</property>
+ <property name="sort-indicator">True</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="sensitive">8</attribute>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn9">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optpathspage|user_paths">User Paths</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer9"/>
+ <attributes>
+ <attribute name="sensitive">9</attribute>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="optpathspage|internal_paths">Internal Paths</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="sensitive">10</attribute>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="paths-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="paths">To modify an entry in this list, click the entry and click Edit. You can also double click the entry.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optpathspage|label1">Paths used by %PRODUCTNAME</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="default">
+ <property name="label" translatable="yes" context="optpathspage|default">_Default</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="default-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="default">The Default button resets the predefined paths for all selected entries.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="optpathspage|edit">_Edit...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="edit">Click to display the Select Path or Edit Paths dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptPathsPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="OptPathsPage">This section contains the default paths to important folders of the office suite. These paths can be edited by the user.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optproxypage.ui b/cui/uiconfig/ui/optproxypage.ui
new file mode 100644
index 000000000..663937620
--- /dev/null
+++ b/cui/uiconfig/ui/optproxypage.ui
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="OptProxyPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|label2">Proxy s_erver:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">proxymode</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="http">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="http-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|http">Type the name of the proxy server for HTTP.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="https">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="https-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|https">Type the name of the proxy server for HTTPS. Type the port in the right-hand field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ftp">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ftp-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ftp">Type the name of the proxy server for FTP.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="noproxy">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="noproxy-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|noproxy">Specifies the names of the servers that do not require any proxy servers, separated by semicolons.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="httpport">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="max_length">5</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">5</property>
+ <property name="input_purpose">digits</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="httpport-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|httpport">Type the port for the corresponding proxy server.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="httpsport">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="max_length">5</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">5</property>
+ <property name="input_purpose">digits</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="httpsport-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|httpsport">Type the port for the corresponding proxy server.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ftpport">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="max_length">5</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">5</property>
+ <property name="input_purpose">digits</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ftpport-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ftpport">Type the port for the corresponding proxy server.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="proxymode">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="optproxypage|proxymode">None</item>
+ <item translatable="yes" context="optproxypage|proxymode">System</item>
+ <item translatable="yes" context="optproxypage|proxymode">Manual</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="proxymode-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|proxymode">Specifies the type of proxy definition.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="httpft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|httpft">HT_TP proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">http</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="httpportft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|httpportft">_Port:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">httpport</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="httpsft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|httpsft">HTTP_S proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">https</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="ftpft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|ftpft">_FTP proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">ftp</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="noproxyft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|noproxyft">_No proxy for:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">noproxy</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="httpsportft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|httpsportft">P_ort:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">httpsport</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="ftpportft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|ftpportft">P_ort:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">ftpport</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="noproxydesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|noproxydesc">Separator ;</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optproxypage|label1">Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptProxyPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptProxyPage">Specifies the type of proxy definition.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optsavepage.ui b/cui/uiconfig/ui/optsavepage.ui
new file mode 100644
index 000000000..d9c1ce123
--- /dev/null
+++ b/cui/uiconfig/ui/optsavepage.ui
@@ -0,0 +1,475 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">60</property>
+ <property name="value">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptSavePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="load_docprinter">
+ <property name="label" translatable="yes" context="optsavepage|load_docprinter">Load printer settings with the document</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="load_docprinter-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="load_docprinter">If enabled, the printer settings will be loaded with the document. This can cause a document to be printed on a distant printer, if you do not change the printer manually in the Print dialog. If disabled, your standard printer will be used to print this document. The current printer settings will be stored with the document whether or not this option is checked.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="load_settings">
+ <property name="label" translatable="yes" context="optsavepage|load_settings">Load user-specific settings with the document</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="load_settings-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="load_settings">Loads the user-specific settings saved in a document with the document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|label1">Load</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="autosave">
+ <property name="label" translatable="yes" context="optsavepage|autosave">Save _AutoRecovery information every:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autosave-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="autosave">Specifies that the office suite saves the information needed to restore all open documents in case of a crash. You can specify the saving time interval.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="autosave_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autosave_spin-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="autosave_spin">Specifies the time interval in minutes for the automatic recovery option.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="autosave_mins">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|autosave_mins">minutes</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="userautosave">
+ <property name="label" translatable="yes" context="optsavepage|userautosave">Automatically save the document too</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">12</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="userautosave-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="userautosave">Specifies that the office suite saves all open documents when saving auto recovery information. Uses the same time interval as AutoRecovery does.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="relative_fsys">
+ <property name="label" translatable="yes" context="optsavepage|relative_fsys">Save URLs relative to file system</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relative_fsys-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="relative_fsys">Select this box for relative saving of URLs in the file system.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="docinfo">
+ <property name="label" translatable="yes" context="optsavepage|docinfo">_Edit document properties before saving</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="docinfo-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="docinfo">Specifies that the Properties dialog will appear every time you select the Save As command.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="relative_inet">
+ <property name="label" translatable="yes" context="optsavepage|relative_inet">Save URLs relative to internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relative_inet-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="relative_inet">Select this box for relative saving of URLs to the Internet.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="backup">
+ <property name="label" translatable="yes" context="optsavepage|backup">Al_ways create backup copy</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="backup-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="backup">Saves the previous version of a document as a backup copy whenever you save a document. Every time the office suite creates a backup copy, the previous backup copy is replaced. The backup copy gets the extension .BAK.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|label2">Save</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="warnalienformat">
+ <property name="label" translatable="yes" context="optsavepage|warnalienformat">Warn when not saving in ODF or default format</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="warnalienformat-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="warnalienformat">You can choose to get a warning message when you save a document in a format that is not OpenDocument or which you did not set as default format in Load/Save - General in the Options dialog box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="odfwarning_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|odfwarning_label" comments="EN-US, the term 'extended' must not be translated.">Not using ODF 1.3 Extended may cause information to be lost.</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="odfwarning_image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">svx/res/caution_11x16.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="odfversion">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="optsavepage|odfversion">1.0/1.1</item>
+ <item translatable="yes" context="optsavepage|odfversion">1.2</item>
+ <item translatable="yes" context="optsavepage|odfversion">1.2 Extended (compatibility mode)</item>
+ <item translatable="yes" context="optsavepage|odfversion">1.2 Extended</item>
+ <item translatable="yes" context="optsavepage|odfversion">1.3</item>
+ <item translatable="yes" context="optsavepage|odfversion">1.3 Extended (recommended)</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="odfversion-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="odfversion">Some companies or organizations may require ODF documents in the ODF 1.0/1.1, or ODF 1.2 format. You can select these format to save in the listbox. These older formats cannot store all new features, so the new format ODF 1.3 (Extended) is recommended where possible.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|label5">ODF format version:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">odfversion</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="saveas_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|saveas_label">Always sa_ve as:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">saveas</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="doctype">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="optsavepage|doctype">Text document</item>
+ <item translatable="yes" context="optsavepage|doctype">HTML document</item>
+ <item translatable="yes" context="optsavepage|doctype">Master document</item>
+ <item translatable="yes" context="optsavepage|doctype">Spreadsheet</item>
+ <item translatable="yes" context="optsavepage|doctype">Presentation</item>
+ <item translatable="yes" context="optsavepage|doctype">Drawing</item>
+ <item translatable="yes" context="optsavepage|doctype">Formula</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="doctype-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="doctype">Specifies the document type for which you want to define the default file format.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="saveas">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="saveas-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="saveas">Specifies how documents of the type selected on the left will always be saved as this file type. You may select another file type for the current document in the Save as dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|label6">D_ocument type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">doctype</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsavepage|label3">Default File Format and ODF Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptSavePage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="OptSavePage">In the General section, you can select default settings for saving documents, and can select default file formats.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optsecuritypage.ui b/cui/uiconfig/ui/optsecuritypage.ui
new file mode 100644
index 000000000..c72825933
--- /dev/null
+++ b/cui/uiconfig/ui/optsecuritypage.ui
@@ -0,0 +1,506 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="OptSecurityPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="tsaurls">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label9">Maintain a list of Time Stamping Authority (TSA) URLs to be used for digital signatures in PDF export.</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">56</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="tsas">
+ <property name="label" translatable="yes" context="optsecuritypage|tsas">_TSAs...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="tsas-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|tsas">Opens the Time Stamping Authority URLs dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label10">TSAs</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="certificatepath">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label7">Select the Network Security Services certificate directory to use for digital signatures.</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">56</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cert">
+ <property name="label" translatable="yes" context="optsecuritypage|cert">_Certificate...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cert-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|cert">Opens the Certificate Path dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label8">Certificate Path</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="macrosecurity">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label5">Adjust the security level for executing macros and specify trusted macro developers.</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">56</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="macro">
+ <property name="label" translatable="yes" context="optsecuritypage|macro">Macro Securit_y...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="macro-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|macro">Opens the Macro Security dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label3">Macro Security</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="savepassword">
+ <property name="label" translatable="yes" context="optsecuritypage|savepassword">Persistently _save passwords for web connections</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="savepassword-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|savepassword">If enabled, all passwords that you use to access files from web servers will be securely stored. You can retrieve the passwords from the list after you enter the master password.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <child>
+ <object class="GtkCheckButton" id="usemasterpassword">
+ <property name="label" translatable="yes" context="optsecuritypage|usemasterpassword">Protected _by a master password (recommended)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="masterpasswordtext">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optsecuritypage|masterpasswordtext">Passwords are protected by a master password. You will be asked to enter it once per session, if %PRODUCTNAME retrieves a password from the protected password list.</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">56</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="nopasswordsave">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optsecuritypage|nopasswordsave">Disabling the function to persistently store passwords deletes the list of passwords stored and resets the master password.
+
+Do you want to delete password list and reset master password?</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">56</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_homogeneous">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton" id="connections">
+ <property name="label" translatable="yes" context="optsecuritypage|connections">Connect_ions...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="connections-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|connections">Asks for the master password. If master password is correct, shows the Stored Web Connection Information dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton" id="masterpassword">
+ <property name="label" translatable="yes" context="optsecuritypage|masterpassword">_Master Password...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="masterpassword-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|masterpassword">Opens the Enter Master Password dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label2">Passwords for Web Connections</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label4">Adjust security related options and define warnings for hidden information in documents. </property>
+ <property name="wrap">True</property>
+ <property name="width_chars">56</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="options">
+ <property name="label" translatable="yes" context="optsecuritypage|options">O_ptions...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="options-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|options">Opens the "Security Options and Warnings" dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optsecuritypage|label1">Security Options and Warnings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptSecurityPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptSecurityPage">Defines the security options for saving documents, for web connections, and for opening documents that contain macros.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="tsas"/>
+ <widget name="cert"/>
+ <widget name="macro"/>
+ <widget name="connections"/>
+ <widget name="masterpassword"/>
+ <widget name="options"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optuserpage.ui b/cui/uiconfig/ui/optuserpage.ui
new file mode 100644
index 000000000..25c6438f2
--- /dev/null
+++ b/cui/uiconfig/ui/optuserpage.ui
@@ -0,0 +1,1058 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="OptUserPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="companyft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|companyft">_Company:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">company</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="nameft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|nameft">First/last _name/initials:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">firstname</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="streetft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|streetft">_Street:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">street</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="cityft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|cityft">City/state/_zip:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">city</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="countryft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|countryft">Country/re_gion:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">country</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="titleft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|titleft">_Title/position:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">title</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="phoneft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|phoneft">Telephone (home/_work):</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">home</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="phoneft-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="phoneft-atkobject">Home telephone number</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="faxft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|faxft">Fa_x/email:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">fax</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="firstname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="firstname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="optuserpage|firstname-atkobject">First name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | firstname">Type your first name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="lastname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="lastname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="lastname-atkobject">Last name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | lastname">Type your last name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="shortname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">7</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="shortname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="shortname-atkobject">Initials</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | shortname">Type your initials.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="city">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="city-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="city-atkobject">City</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | city">Type the city where you live.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="state">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="state-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="state-atkobject">State</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | state">Type your state.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="zip">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">15</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="zip-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="zip-atkobject">Zip code</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | zip">Type your ZIP in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="title">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="title-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="title-atkobject">Title</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | title">Type your title in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="position">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="position-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="position-atkobject">Position</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | position">Type your position in the company in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="home">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="home-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="home-atkobject">Home telephone number</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | home">Type your private telephone number in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="work">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="work-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="work-atkobject">Work telephone number</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | work">Type your work number in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="fax">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fax-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="fax-atkobject">Fax number</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | fax">Type your fax number in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="email">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="email-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="email-atkobject">email address</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | email">Type your email address.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="usefordocprop">
+ <property name="label" translatable="yes" context="optuserpage|usefordocprop">Use data for document properties</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="usefordocprop-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tips | usefordoprop">Mark to use the data in document properties</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">12</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="rusnameft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|rusnameft">Last/first/father’s _name/initials:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">ruslastname</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="ruslastname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ruslastname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="ruslastname-atkobject">Last name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | ruslastname">Type your last name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="rusfathersname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rusfathersname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="rusfathersname-atkobject">Father's name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tips | rusfathersname">Type your father's name</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="russhortname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">7</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="russhortname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="russhortname-atkobject">Initials</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | russhortname">Type your initials.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="rusfirstname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rusfirstname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="rusfirstname-atkobject">First name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | rusfirstname">Type your first name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="eastnameft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|eastnameft">Last/first _name/initials:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">eastlastname</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="eastlastname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="eastlastname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="eastlastname-atkobject">Last name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | eastlastname">Type your last name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="eastfirstname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="eastfirstname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="eastfirstname-atkobject">First name</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | eastfirstname">Type your first name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="eastshortname">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">7</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="eastshortname-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="eastshortname-atkobject">Initials</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | eastshortname">Type your initials.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="russtreetft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|russtreetft">_Street/apartment number:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">russtreet</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="russtreet">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="russtreet-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="russtreet-atkobject">Street</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tips | russrteet">Type the name of your street in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="apartnum">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">15</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="apartnum-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="ruslastname-atkobject">Apartment number</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tips | apartnum">Type your apartment number</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="icityft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optuserpage|icityft">_Zip/city:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">izip</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid11">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="icity">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="icity-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="icity-atkobject">City</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | icity">Type the city where you live.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="izip">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="activates_default">True</property>
+ <property name="width_chars">15</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="izip-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="izip-atkobject">Zip code</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | izip">Type your ZIP in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkEntry" id="street">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="street-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | street">Type the name of your street in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid12">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkEntry" id="country">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="country-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tips | country">Type your country and region</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid13">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkEntry" id="company">
+ <property name="can_focus">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="company-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | company">Type the name of your company in this field.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optuserpage|label1">Address</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="cryptography">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid14">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="signingkeylabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optuserpage|signingkeylabel">OpenPGP signing key:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">signingkey</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="encryptionkeylabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optuserpage|encryptionkeylabel">OpenPGP encryption key:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">encryptionkey</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="encryptionkey">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optuserpage|liststore1">No key</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="encryptionkey-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | encryptionkey">Select your OpenPGP key from the drop-down list for encrypting ODF documents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="signingkey">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optuserpage|liststore1">No key</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="signingkey-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | signingkey">Select your OpenPGP key from the drop-down list for signing ODF documents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="encrypttoself">
+ <property name="label" translatable="yes" context="optuserpage|encrypttoself">When encrypting documents, always encrypt to self</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="encrypttoself-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | encrypttoself">Mark this checkbox to also encrypt the file with your public key, so you can open the document with your private key.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="cryptographylabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="optuserpage|cryptographylabel">Cryptography</property>
+ <property name="use_underline">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="OptUserPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended tip | OptUserPage">Use this tab page to enter or edit user data.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel">
+ <widgets>
+ <widget name="companyft"/>
+ <widget name="nameft"/>
+ <widget name="streetft"/>
+ <widget name="cityft"/>
+ <widget name="countryft"/>
+ <widget name="titleft"/>
+ <widget name="phoneft"/>
+ <widget name="faxft"/>
+ <widget name="rusnameft"/>
+ <widget name="eastnameft"/>
+ <widget name="russtreetft"/>
+ <widget name="icityft"/>
+ <widget name="signingkeylabel"/>
+ <widget name="encryptionkeylabel"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/optviewpage.ui b/cui/uiconfig/ui/optviewpage.ui
new file mode 100644
index 000000000..ac6b7fcde
--- /dev/null
+++ b/cui/uiconfig/ui/optviewpage.ui
@@ -0,0 +1,782 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">1</property>
+ <property name="upper">10000</property>
+ <property name="value">8</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="OptViewPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="border-width">6</property>
+ <property name="column-spacing">24</property>
+ <child>
+ <!-- n-columns=1 n-rows=4 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label11">_Positioning:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">mousepos</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label12">Middle _button:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">mousemiddle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="mousepos">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|mousepos">Default button</item>
+ <item translatable="yes" context="optviewpage|mousepos">Dialog center</item>
+ <item translatable="yes" context="optviewpage|mousepos">No automatic positioning</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="mousepos-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | mousepos">Specifies if and how the mouse pointer will be positioned in newly opened dialogs.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="mousemiddle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|mousemiddle">No function</item>
+ <item translatable="yes" context="optviewpage|mousemiddle">Automatic scrolling</item>
+ <item translatable="yes" context="optviewpage|mousemiddle">Paste clipboard</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="mousemiddle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | mousemiddle">Defines the function of the middle mouse button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label4">Mouse</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=2 -->
+ <object class="GtkGrid" id="grid8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="menuiconsbox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label13">Menu icons:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">menuicons</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="menuicons">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|menuicons">Automatic</item>
+ <item translatable="yes" context="optviewpage|menuicons">Hide</item>
+ <item translatable="yes" context="optviewpage|menuicons">Show</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="menuicons-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | menuicons">Displays icons next to the corresponding menu items. Select from "Automatic", "Hide" and "Show". "Automatic" displays icons according to system settings and themes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="menushortcutsbpx">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="contextmenushortcuts">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|contextmenushortcuts">Automatic</item>
+ <item translatable="yes" context="optviewpage|contextmenushortcuts">Hide</item>
+ <item translatable="yes" context="optviewpage|contextmenushortcuts">Show</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label10">Shortcuts:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">contextmenushortcuts</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label3">Visibility</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="refgrid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="notebookbariconsize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|notebookbariconsize">Automatic</item>
+ <item translatable="yes" context="optviewpage|notebookbariconsize">Small</item>
+ <item translatable="yes" context="optviewpage|notebookbariconsize">Large</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="notebookbariconsize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | notebookbariconsize">Specifies the display size of notebook bar icons.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label7">_Notebookbar:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">notebookbariconsize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="sidebariconsize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|sidebariconsize">Automatic</item>
+ <item translatable="yes" context="optviewpage|sidebariconsize">Small</item>
+ <item translatable="yes" context="optviewpage|sidebariconsize">Large</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="sidebariconsize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | sidebariconsize">Specifies the display size of sidebar icons.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label9">Sidebar:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">sidebariconsize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="iconsize">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|iconsize">Automatic</item>
+ <item translatable="yes" context="optviewpage|iconsize">Small</item>
+ <item translatable="yes" context="optviewpage|iconsize">Large</item>
+ <item translatable="yes" context="optviewpage|iconsize">Extra Large</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="iconsize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | iconsize">Specifies the display size of toolbar icons.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label8">Toolbar:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">iconsize</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label1">Icon Size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=3 n-rows=1 -->
+ <object class="GtkGrid" id="refgrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="iconstyle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <items>
+ <item translatable="yes" context="optviewpage|iconstyle">Automatic</item>
+ <item translatable="yes" context="optviewpage|iconstyle">Sifr</item>
+ <item translatable="yes" context="optviewpage|iconstyle">Breeze</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="iconstyle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | iconstyle">Specifies the icon style for icons in toolbars and dialogs.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label6">_Theme:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">iconstyle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnMoreIcons">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="optviewpage|btnMoreIcons">Add more icon themes via extension</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label1">Icon Theme</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=3 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=6 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="tooltip-text" translatable="yes" context="optviewpage|grid3|tooltip_text">Requires restart</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <child>
+ <object class="GtkCheckButton" id="useaccel">
+ <property name="label" translatable="yes" context="optviewpage|useaccel">Use hard_ware acceleration</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="useaccel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | useaccel">Directly accesses hardware features of the graphical display adapter to improve the screen display.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="useaa">
+ <property name="label" translatable="yes" context="optviewpage|useaa">Use anti-a_liasing</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="useaa-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | useaa">When supported, you can enable and disable anti-aliasing of graphics. With anti-aliasing enabled, the display of most graphical objects looks smoother and with less artifacts.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="useskia">
+ <property name="label" translatable="yes" context="optviewpage|useskia">Use Skia for all rendering</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="forceskiaraster">
+ <property name="label" translatable="yes" context="optviewpage|forceskiaraster">Force Skia software rendering</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="tooltip-text" translatable="yes" context="optviewpage|forceskia|tooltip_text">Requires restart. Enabling this will prevent the use of graphics drivers.</property>
+ <property name="margin-start">12</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="skiaenabled">
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="label" translatable="yes" context="optviewpage|skiaenabled">Skia is currently enabled.</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="skiadisabled">
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="label" translatable="yes" context="optviewpage|skiadisabled">Skia is currently disabled.</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label2">Graphics Output</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=3 -->
+ <object class="GtkGrid" id="grid9">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">3</property>
+ <child>
+ <object class="GtkCheckButton" id="showfontpreview">
+ <property name="label" translatable="yes" context="optviewpage|showfontpreview">Show p_review of fonts</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="showfontpreview-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | showfontpreview">Displays the names of selectable fonts in the corresponding font, for example, fonts in the Font box on the Formatting bar.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="aafont">
+ <property name="label" translatable="yes" context="optviewpage|aafont">Screen font antialiasin_g</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="aafont-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | aafont">Select to smooth the screen appearance of text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">18</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="aafrom">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="optviewpage|aafrom">fro_m:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">aanf</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="aanf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="aanf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip | aanf">Enter the smallest font size to apply antialiasing to.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="optviewpage|label5">Font Lists</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btn_rungptest">
+ <property name="label" translatable="yes" context="optviewpage|btn_rungptest">Run Graphics Tests</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="margin-start">10</property>
+ <property name="margin-end">10</property>
+ <property name="margin-top">10</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel">
+ <widgets>
+ <widget name="label6"/>
+ <widget name="label14"/>
+ <widget name="label8"/>
+ <widget name="label9"/>
+ <widget name="label13"/>
+ <widget name="label10"/>
+ <widget name="label11"/>
+ <widget name="label12"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupWidget">
+ <widgets>
+ <widget name="iconstyle"/>
+ <widget name="iconsize"/>
+ <widget name="notebookbariconsize"/>
+ <widget name="sidebariconsize"/>
+ <widget name="menuicons"/>
+ <widget name="contextmenushortcuts"/>
+ <widget name="mousepos"/>
+ <widget name="mousemiddle"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/pageformatpage.ui b/cui/uiconfig/ui/pageformatpage.ui
new file mode 100644
index 000000000..e96e063f4
--- /dev/null
+++ b/cui/uiconfig/ui/pageformatpage.ui
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=1 n-rows=3 -->
+ <object class="GtkGrid" id="PageFormatPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="border-width">6</property>
+ <property name="row-spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <!-- n-columns=2 n-rows=6 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="labelFormat">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelFormat">_Format:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboPageFormat</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboPageFormat">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelWidth">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelWidth">_Width:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinWidth</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinWidth">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelHeight">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelHeight">_Height:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinHeight</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinHeight">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelOrientation">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelOrientation">_Orientation:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">radiobuttonPortrait</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="radiobuttonPortrait"/>
+ <relation type="label-for" target="radiobuttonLandscape"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonPortrait">
+ <property name="label" translatable="yes" context="pageformatpage|radiobuttonPortrait">_Portrait</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="labelOrientation"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonLandscape">
+ <property name="label" translatable="yes" context="pageformatpage|radiobuttonLandscape">L_andscape</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">radiobuttonPortrait</property>
+ <accessibility>
+ <relation type="labelled-by" target="labelOrientation"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelTextFlow">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelTextFlow">_Text direction:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboTextFlowBox</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboTextFlowBox">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaPageDirection">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="vexpand">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelPaperTray">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelPaperTray">Paper _tray:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboPaperTray</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboPaperTray">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelPaperFormat">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelPaperFormat">Paper Format</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=5 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="labelLeftMargin">
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelLeftMargin">Left:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargLeft</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelInner">
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelInner">I_nner:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargLeft</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMargLeft">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="labelRightMargin">
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelRightMargin">Right:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargRight</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelOuter">
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelOuter">O_uter:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargRight</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMargRight">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelTopMargin">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelTopMargin">Top:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargTop</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMargTop">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelBottomMargin">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelBottomMargin">Bottom:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargBot</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMargBot">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelGutterMargin">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelGutterMargin">Gutter:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">spinMargGut</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMargGut">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelMargins">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelMargins">Margins</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=10 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="labelPageLayout">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelPageLayout">_Page layout:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboPageLayout</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelPageNumbers">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelPageNumbers">Page numbers:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboLayoutFormat</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkRegisterTrue">
+ <property name="label" translatable="yes" context="pageformatpage|checkRegisterTrue">Use page li_ne-spacing</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="tooltip-text" translatable="yes" context="pageformatpage|checkRegisterTrue" comments="xdds">Enables page line-spacing (register-true) using the selected Reference Style</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkRegisterTrue-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|checkRegisterTrue">If enabled, then all paragraph styles with the option page line-spacing activated will be affected, assuming the line spacing of the Reference Style. This will align them to an invisible vertical page grid, regardless of their font size, so that each line is the same height.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboPageLayout">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="pageformatpage|liststorePageLayout">Right and left</item>
+ <item translatable="yes" context="pageformatpage|liststorePageLayout">Mirrored</item>
+ <item translatable="yes" context="pageformatpage|liststorePageLayout">Only right</item>
+ <item translatable="yes" context="pageformatpage|liststorePageLayout">Only left</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboLayoutFormat">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelTblAlign">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelTblAlign">Table alignment:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">checkbuttonHorz</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbuttonHorz">
+ <property name="label" translatable="yes" context="pageformatpage|checkbuttonHorz">Hori_zontal</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbuttonVert">
+ <property name="label" translatable="yes" context="pageformatpage|checkbuttonVert">_Vertical</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkAdaptBox">
+ <property name="label" translatable="yes" context="pageformatpage|checkAdaptBox">_Fit object to paper format</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelRegisterStyle">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelRegisterStyle">Reference _Style:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboRegisterStyle</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboRegisterStyle">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelGutterPosition">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelGutterPosition">Gutter position:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">comboGutterPosition</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboGutterPosition">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <items>
+ <item translatable="yes" context="pageformatpage|liststoreGutterPosition">Left</item>
+ <item translatable="yes" context="pageformatpage|liststoreGutterPosition">Top</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkRtlGutter">
+ <property name="label" translatable="yes" context="pageformatpage|checkRtlGutter">Gutter on right side of page</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkBackgroundFullSize">
+ <property name="label" translatable="yes" context="pageformatpage|checkBackgroundFullSize">Background covers margins</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="no-show-all">True</property>
+ <property name="tooltip-text" translatable="yes" context="pageformatpage|checkBackgroundFullSize" comments="xdds">Any background will cover margins of the page as well</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkBackgroundFullSize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|checkBackgroundFullSize">If enabled, then any background will cover the entire page, including margins. If disabled, any background will cover the page only inside the margins.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|label5">Layout Settings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelMsg">
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="pageformatpage|labelMsg">The margin settings are out of print range.
+
+Do you still want to apply these settings?</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="grid3"/>
+ <widget name="grid6"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="grid4"/>
+ <widget name="grid7"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel1">
+ <widgets>
+ <widget name="labelFormat"/>
+ <widget name="labelWidth"/>
+ <widget name="labelHeight"/>
+ <widget name="labelOrientation"/>
+ <widget name="labelTextFlow"/>
+ <widget name="box3"/>
+ <widget name="box2"/>
+ <widget name="labelTopMargin"/>
+ <widget name="labelBottomMargin"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupLabel2">
+ <widgets>
+ <widget name="labelPaperTray"/>
+ <widget name="labelPageLayout"/>
+ <widget name="labelPageNumbers"/>
+ <widget name="labelRegisterStyle"/>
+ <widget name="labelTblAlign"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroupWidget2">
+ <property name="ignore-hidden">True</property>
+ <widgets>
+ <widget name="comboPaperTray"/>
+ <widget name="comboPageLayout"/>
+ <widget name="comboLayoutFormat"/>
+ <widget name="comboRegisterStyle"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/paragalignpage.ui b/cui/uiconfig/ui/paragalignpage.ui
new file mode 100644
index 000000000..70fab84cc
--- /dev/null
+++ b/cui/uiconfig/ui/paragalignpage.ui
@@ -0,0 +1,403 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="ParaAlignPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-top">24</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaWN_EXAMPLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="drawingareaWN_EXAMPLE-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="paragalignpage|drawingareaWN_EXAMPLE-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="maingrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="radioBTN_LEFTALIGN">
+ <property name="label" translatable="yes" context="paragalignpage|radioBTN_LEFTALIGN">_Left</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radioBTN_RIGHTALIGN">
+ <property name="label" translatable="yes" context="paragalignpage|radioBTN_RIGHTALIGN">_Right</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radioBTN_LEFTALIGN</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radioBTN_CENTERALIGN">
+ <property name="label" translatable="yes" context="paragalignpage|radioBTN_CENTERALIGN">_Center</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radioBTN_LEFTALIGN</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radioBTN_JUSTIFYALIGN">
+ <property name="label" translatable="yes" context="paragalignpage|radioBTN_JUSTIFYALIGN">_Justified</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radioBTN_LEFTALIGN</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkCB_EXPAND">
+ <property name="label" translatable="yes" context="paragalignpage|checkCB_EXPAND">_Expand single word</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">22</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkCB_SNAP">
+ <property name="label" translatable="yes" context="paragalignpage|checkCB_SNAP">_Snap to text grid (if active)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">22</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="labelST_RIGHTALIGN_ASIAN">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|labelST_RIGHTALIGN_ASIAN">Righ_t/Bottom</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelST_LEFTALIGN_ASIAN">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|labelST_LEFTALIGN_ASIAN">_Left/Top</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkLabel" id="labelLB_LASTLINE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|labelLB_LASTLINE">_Last line:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboLB_LASTLINE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboLB_LASTLINE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">0</property>
+ <items>
+ <item id="0" translatable="yes" context="paragalignpage|liststoreLB_LASTLINE">Start</item>
+ <item id="1" translatable="yes" context="paragalignpage|liststoreLB_LASTLINE">Start</item>
+ <item id="2" translatable="yes" context="paragalignpage|liststoreLB_LASTLINE">Centered</item>
+ <item id="3" translatable="yes" context="paragalignpage|liststoreLB_LASTLINE">Justified</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|label1">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frameFL_VERTALIGN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="labelFT_VERTALIGN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|labelFT_VERTALIGN">_Alignment:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboLB_VERTALIGN</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboLB_VERTALIGN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="active">0</property>
+ <items>
+ <item id="0" translatable="yes" context="paragalignpage|liststoreLB_VERTALIGN">Automatic</item>
+ <item id="1" translatable="yes" context="paragalignpage|liststoreLB_VERTALIGN">Base line</item>
+ <item id="2" translatable="yes" context="paragalignpage|liststoreLB_VERTALIGN">Top</item>
+ <item id="3" translatable="yes" context="paragalignpage|liststoreLB_VERTALIGN">Middle</item>
+ <item id="4" translatable="yes" context="paragalignpage|liststoreLB_VERTALIGN">Bottom</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelFL_VERTALIGN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|labelFL_VERTALIGN">Text-to-text</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="framePROPERTIES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|label2">_Text direction:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboLB_TEXTDIRECTION</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboLB_TEXTDIRECTION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelFL_PROPERTIES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paragalignpage|labelFL_PROPERTIES">Properties</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="labelFT_VERTALIGN"/>
+ <widget name="label2"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="comboLB_VERTALIGN"/>
+ <widget name="comboLB_TEXTDIRECTION"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/paraindentspacing.ui b/cui/uiconfig/ui/paraindentspacing.ui
new file mode 100644
index 000000000..8a37b7d86
--- /dev/null
+++ b/cui/uiconfig/ui/paraindentspacing.ui
@@ -0,0 +1,525 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentED_DIST">
+ <property name="upper">9999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentED_DIST1">
+ <property name="upper">9999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentED_LINEDISTMETRIC">
+ <property name="upper">9999</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentLINEDISTPERCENT">
+ <property name="lower">6</property>
+ <property name="upper">65535</property>
+ <property name="value">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentspinED_INDENT">
+ <property name="upper">9999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentspinED_INDENT1">
+ <property name="upper">9999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentspinED_INDENT2">
+ <property name="upper">9999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="ParaIndentSpacing">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="margin_start">24</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaWN_EXAMPLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="drawingareaWN_EXAMPLE-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="paraindentspacing|drawingareaWN_EXAMPLE-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="maingrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">12</property>
+ <property name="margin_top">6</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="labelFT_LEFTINDENT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFT_LEFTINDENT">_Before text:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinED_LEFTINDENT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelFT_RIGHTINDENT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFT_RIGHTINDENT">After _text:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinED_RIGHTINDENT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelFT_FLINEINDENT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFT_FLINEINDENT">_First line:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinED_FLINEINDENT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkCB_AUTO">
+ <property name="label" translatable="yes" context="paraindentspacing|checkCB_AUTO">_Automatic</property>
+ <property name="visible">True</property>
+ <property name="tooltip_text" translatable="yes" context="paraindentspacing|checkCB_AUTO|tooltip_text">Indent paragraph automatically according to font size and line spacing.</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinED_LEFTINDENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentspinED_INDENT</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinED_RIGHTINDENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentspinED_INDENT1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinED_FLINEINDENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentspinED_INDENT2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelST_LINEDIST_ABS">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelST_LINEDIST_ABS">Fixed</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|label1">Indent</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">12</property>
+ <property name="margin_top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="labelFT_TOPDIST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFT_TOPDIST">Ab_ove paragraph:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinED_TOPDIST</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelFT_BOTTOMDIST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFT_BOTTOMDIST">Below _paragraph:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinED_BOTTOMDIST</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinED_TOPDIST">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentED_DIST</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinED_BOTTOMDIST">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentED_DIST1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkCB_CONTEXTUALSPACING">
+ <property name="label" translatable="yes" context="paraindentspacing|checkCB_CONTEXTUALSPACING">Do not add space between paragraphs of the same style</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelFL_VERTALIGN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFL_VERTALIGN">Spacing</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="framePROPERTIES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">12</property>
+ <property name="margin_top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="comboLB_LINEDIST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item id="0" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">Single</item>
+ <item id="1" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">1.15 Lines</item>
+ <item id="2" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">1.5 Lines</item>
+ <item id="3" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">Double</item>
+ <item id="4" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">Proportional</item>
+ <item id="5" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">At least</item>
+ <item id="6" translatable="yes" context="paraindentspacing|liststoreLB_LINEDIST">Leading</item>
+ </items>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelFT_LINEDIST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFT_LINEDIST">of</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkSpinButton" id="spinED_LINEDISTPERCENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentLINEDISTPERCENT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinED_LINEDISTMETRIC">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustmentED_LINEDISTMETRIC</property>
+ <property name="digits">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkCB_REGISTER">
+ <property name="label" translatable="yes" context="paraindentspacing|checkCB_REGISTER">Activate page li_ne-spacing</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes" context="paraindentspacing|checkCB_REGISTER|tooltip_text" comments="xdds">Applies page line-spacing (register-true) if set for the Page Style.</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkCB_REGISTER-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="paraindentspacing|extended_tip|checkCB_REGISTER">If page line-spacing is activated and the Page style uses page line-spacing, then this paragraph will align to an invisible vertical page grid, regardless of their font size, so that each line is the same height.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelFL_PROPERTIES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paraindentspacing|labelFL_PROPERTIES">Line Spacing</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup_label">
+ <widgets>
+ <widget name="labelFT_LEFTINDENT"/>
+ <widget name="labelFT_RIGHTINDENT"/>
+ <widget name="labelFT_FLINEINDENT"/>
+ <widget name="labelFT_TOPDIST"/>
+ <widget name="labelFT_BOTTOMDIST"/>
+ <widget name="box3"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup_widget">
+ <widgets>
+ <widget name="spinED_LEFTINDENT"/>
+ <widget name="spinED_RIGHTINDENT"/>
+ <widget name="spinED_FLINEINDENT"/>
+ <widget name="spinED_TOPDIST"/>
+ <widget name="spinED_BOTTOMDIST"/>
+ <widget name="spinED_LINEDISTPERCENT"/>
+ <widget name="spinED_LINEDISTMETRIC"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/paratabspage.ui b/cui/uiconfig/ui/paratabspage.ui
new file mode 100644
index 000000000..79d01a5d5
--- /dev/null
+++ b/cui/uiconfig/ui/paratabspage.ui
@@ -0,0 +1,599 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">-56</property>
+ <property name="upper">56</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="ParagraphTabsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="tabgrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="height_request">42</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="LB_TABPOS">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="ED_TABPOS">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="SP_TABPOS">
+ <property name="can_focus">False</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paratabspage|label1">Position</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frameFL_TABTYPE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_TABTYPE_DECIMAL">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonBTN_TABTYPE_DECIMAL">Deci_mal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_TABTYPE_LEFT</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entryED_TABTYPE_DECCHAR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="width_chars">3</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaWIN_TABLEFT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaWIN_TABRIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaWIN_TABCENTER">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="drawingareaWIN_TABDECIMAL">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_TABTYPE_LEFT">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonBTN_TABTYPE_LEFT">_Left</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonST_LEFTTAB_ASIAN">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonST_LEFTTAB_ASIAN">_Left/Top</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_TABTYPE_LEFT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_TABTYPE_RIGHT">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonBTN_TABTYPE_RIGHT">Righ_t</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_TABTYPE_LEFT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonST_RIGHTTAB_ASIAN">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonST_RIGHTTAB_ASIAN">Righ_t/Bottom</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_TABTYPE_LEFT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_TABTYPE_CENTER">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonBTN_TABTYPE_CENTER">C_entered</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_TABTYPE_LEFT</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelFT_TABTYPE_DECCHAR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes" context="paratabspage|labelFT_TABTYPE_DECCHAR">_Character</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entryED_TABTYPE_DECCHAR</property>
+ <property name="xalign">0</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paratabspage|label2">Type</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frameFL_FILLCHAR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_FILLCHAR_NO">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonBTN_FILLCHAR_NO">N_one</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_FILLCHAR_POINTS">
+ <property name="label" context="paratabspage|radiobuttonBTN_FILLCHAR_POINTS">_........</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_FILLCHAR_NO</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_FILLCHAR_DASHLINE">
+ <property name="label" context="paratabspage|radiobuttonBTN_FILLCHAR_DASHLINE">_--------</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_FILLCHAR_NO</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_FILLCHAR_UNDERSCORE">
+ <property name="label" context="paratabspage|radiobuttonBTN_FILLCHAR_UNDERSCORE">______</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_FILLCHAR_NO</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobuttonBTN_FILLCHAR_OTHER">
+ <property name="label" translatable="yes" context="paratabspage|radiobuttonBTN_FILLCHAR_OTHER">C_haracter</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobuttonBTN_FILLCHAR_NO</property>
+ <accessibility>
+ <relation type="label-for" target="entryED_FILLCHAR_OTHER"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entryED_FILLCHAR_OTHER">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="width_chars">3</property>
+ <property name="truncate-multiline">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="radiobuttonBTN_FILLCHAR_OTHER"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paratabspage|label3">Fill Character</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="buttonBTN_NEW">
+ <property name="label" translatable="yes" context="stock">_New</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="buttonBTN_DELALL">
+ <property name="label" translatable="yes" context="paratabspage|buttonBTN_DELALL">Delete _all</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="buttonBTN_DEL">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="buttonBTN_DEL-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="paratabspage|extended_tip|buttonBTN_DEL">Deletes the selected element or elements after confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paratabspage|label4">points</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">radiobuttonBTN_FILLCHAR_POINTS</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paratabspage|label5">dashes</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">radiobuttonBTN_FILLCHAR_DASHLINE</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="paratabspage|label6">underscores</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">radiobuttonBTN_FILLCHAR_UNDERSCORE</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <property name="mode">vertical</property>
+ <widgets>
+ <widget name="entryED_TABTYPE_DECCHAR"/>
+ <widget name="entryED_FILLCHAR_OTHER"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup3">
+ <widgets>
+ <widget name="radiobuttonBTN_TABTYPE_DECIMAL"/>
+ <widget name="box3"/>
+ <widget name="box4"/>
+ <widget name="radiobuttonBTN_TABTYPE_CENTER"/>
+ <widget name="labelFT_TABTYPE_DECCHAR"/>
+ <widget name="radiobuttonBTN_FILLCHAR_NO"/>
+ <widget name="radiobuttonBTN_FILLCHAR_POINTS"/>
+ <widget name="radiobuttonBTN_FILLCHAR_DASHLINE"/>
+ <widget name="radiobuttonBTN_FILLCHAR_UNDERSCORE"/>
+ <widget name="radiobuttonBTN_FILLCHAR_OTHER"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/password.ui b/cui/uiconfig/ui/password.ui
new file mode 100644
index 000000000..447968f7f
--- /dev/null
+++ b/cui/uiconfig/ui/password.ui
@@ -0,0 +1,443 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="PasswordDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="password|PasswordDialog">Set Password</property>
+ <property name="modal">True</property>
+ <property name="window-position">center</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=6 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkEntry" id="newpassEntry">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="activates-default">True</property>
+ <property name="width-chars">50</property>
+ <property name="truncate-multiline">True</property>
+ <property name="input-purpose">password</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newpassEntry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="password|extended_tip|newpassEntry">Type a password. A password is case sensitive.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="confirmpassEntry">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="input-purpose">password</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="confirmpassEntry-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="password|extended_tip|confirmpassEntry">Re-enter the password.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label1">Note: After a password has been set, the document will only open with the password. Should you lose the password, there will be no way to recover the document. Please also note that this password is case-sensitive.</property>
+ <property name="wrap">True</property>
+ <property name="max-width-chars">60</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkExpander" id="expander">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="resize-toplevel">True</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">12</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=5 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="readonly">
+ <property name="label" translatable="yes" context="password|readonly">Open file read-only</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="newpassroEntry">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="input-purpose">password</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="confirmropassEntry">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="input-purpose">password</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label7">Enter password to allow editing</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">newpassroEntry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="newpassroIndicator">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newpassroIndicator-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label8">Confirm password</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">confirmropassEntry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="confirmropassIndicator">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="confirmropassIndicator-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label6">File Sharing Password</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label3">_Options</property>
+ <property name="use-underline">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="expander-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="password|extended_tip|expander">Click to show or hide the file sharing password options.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label4">_Enter password to open</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">newpassEntry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="newpassIndicator">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="newpassIndicator-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label5">Confirm password</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">confirmpassEntry</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="confirmpassIndicator">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="confirmpassIndicator-atkobject">
+ <property name="AtkObject::accessible-role" translatable="no">static</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="password|label2">File Encryption Password</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1"/>
+</interface>
diff --git a/cui/uiconfig/ui/pastespecial.ui b/cui/uiconfig/ui/pastespecial.ui
new file mode 100644
index 000000000..436e77f8d
--- /dev/null
+++ b/cui/uiconfig/ui/pastespecial.ui
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="PasteSpecialDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="pastespecial|PasteSpecialDialog">Paste Special</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox3">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area3">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="pastespecial|label2">Source:</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="source">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="wrap">True</property>
+ <property name="max_width_chars">72</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="source-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pastespecial|extended_tip|source">Displays the source of the clipboard contents.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkTreeView" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="list-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pastespecial|extended_tip|list">Select a format for the clipboard contents that you want to paste. The available format depends on the copied or cut source format.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="pastespecial|label1">Selection</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PasteSpecialDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pastespecial|extended_tip|PasteSpecialDialog">Inserts the contents of the clipboard into the current file in a format that you can specify.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/patterntabpage.ui b/cui/uiconfig/ui/patterntabpage.ui
new file mode 100644
index 000000000..cd9c44120
--- /dev/null
+++ b/cui/uiconfig/ui/patterntabpage.ui
@@ -0,0 +1,401 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="PatternTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="patternpresetlistwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkDrawingArea" id="patternpresetlist">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="BTN_ADD">
+ <property name="label" translatable="yes" context="stock">_Add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_ADD-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="patterntabpage|extended_tip|BTN_ADD">Adds a custom pattern to the current list. Specify the properties of your pattern, and then click this button.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="BTN_MODIFY">
+ <property name="label" translatable="yes" context="patterntabpage|BTN_MODIFY">_Modify</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_MODIFY-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="patterntabpage|extended_tip|BTN_MODIFY">Applies the current pattern properties to the selected pattern. If you want, you can save the pattern under a different name.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="patterntabpage|label3">Pattern</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="patterntabpage|label4">Pattern Editor:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PIXEL">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_PIXEL-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="patterntabpage|CTL_PIXEL-atkobject">Pattern Editor</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="patterntabpage|extended_tip|CTL_PIXEL">Draw the pattern in the 8 x 8 pixel board. Click on a pattern pixel to activate it, click again to deactivate it.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="patterntabpage|label5">Foreground Color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_COLOR</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="LB_COLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_COLOR-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="patterntabpage|extended_tip|LB_COLOR">Set the color of the activated pattern pixels.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="patterntabpage|label6">Background Color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_BACKGROUND_COLOR</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="LB_BACKGROUND_COLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_BACKGROUND_COLOR-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="patterntabpage|extended_tip|LB_BACKGROUND_COLOR">Set the color of the deactivated pattern pixels.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="patterntabpage|label1">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="patterntabpage|CTL_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="patterntabpage|label2">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PatternTabPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="patterntabpage|extended_tip|PatternTabPage">Fills the object with a simple two color pattern selected on this page.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/percentdialog.ui b/cui/uiconfig/ui/percentdialog.ui
new file mode 100644
index 000000000..99903516d
--- /dev/null
+++ b/cui/uiconfig/ui/percentdialog.ui
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="value">77</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="PercentDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="percentdialog|PercentDialog">Combine</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkSpinButton" id="margin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="margin-start">12</property>
+ <property name="truncate-multiline">True</property>
+ <property name="margin-top">6</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="percentdialog|label1">Minimum Size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PercentDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="percentdialog|extended_tip|PercentDialog">Enter the minimum length for combining single-lined paragraphs as a percentage of the page width.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/personalization_tab.ui b/cui/uiconfig/ui/personalization_tab.ui
new file mode 100644
index 000000000..9e483780b
--- /dev/null
+++ b/cui/uiconfig/ui/personalization_tab.ui
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="PersonalizationTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="margin-end">6</property>
+ <child>
+ <object class="GtkRadioButton" id="no_persona">
+ <property name="label" translatable="yes" context="personalization_tab|no_persona">Default look, do not use Themes</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="default_persona">
+ <property name="label" translatable="yes" context="personalization_tab|default_persona">Preinstalled Theme</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">no_persona</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="margin-start">24</property>
+ <property name="margin-end">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkToggleButton" id="default1">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default0">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default2">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default3">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default4">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default5">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default6">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default7">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="default8">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="personas_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="personalization_tab|personas_label">LibreOffice Themes</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/pickbulletpage.ui b/cui/uiconfig/ui/pickbulletpage.ui
new file mode 100644
index 000000000..b9749dda5
--- /dev/null
+++ b/cui/uiconfig/ui/pickbulletpage.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="PickBulletPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="valuesetwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="valueset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="valueset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pickbulletpage|extended_tip|valueset">Click the bullet style that you want to use.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="pickbulletpage|label25">Selection</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PickBulletPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pickbulletpage|extended_tip|PickBulletPage">Displays the different bullet styles that you can apply.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/pickgraphicpage.ui b/cui/uiconfig/ui/pickgraphicpage.ui
new file mode 100644
index 000000000..fd7b9922e
--- /dev/null
+++ b/cui/uiconfig/ui/pickgraphicpage.ui
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="PickGraphicPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="valuesetwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="valueset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="valueset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pickgraphicpage|extended_tip|valueset">Click the graphics that you want to use as bullets.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="errorft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="pickgraphicpage|errorft">The Gallery theme 'Bullets' is empty (no images).</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="browseBtn">
+ <property name="label" translatable="yes" context="pickgraphicpage|browseBtn">Add and Resize</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="pickgraphicpage|label25">Selection</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PickGraphicPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pickgraphicpage|extended_tip|PickGraphicPage">Displays the different graphics that you can use as bullets in a bulleted list.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/picknumberingpage.ui b/cui/uiconfig/ui/picknumberingpage.ui
new file mode 100644
index 000000000..ef410711a
--- /dev/null
+++ b/cui/uiconfig/ui/picknumberingpage.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="PickNumberingPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="valuesetwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="valueset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="valueset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="picknumberingpage|extended_tip|valueset">Click the numbering scheme that you want to use.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="picknumberingpage|label25">Selection</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PickNumberingPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="picknumberingpage|extended_tip|PickNumberingPage">Displays the different numbering schemes that you can apply.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/pickoutlinepage.ui b/cui/uiconfig/ui/pickoutlinepage.ui
new file mode 100644
index 000000000..c1050b48e
--- /dev/null
+++ b/cui/uiconfig/ui/pickoutlinepage.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkFrame" id="PickOutlinePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkScrolledWindow" id="valuesetwin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="valueset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="valueset-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pickoutlinepage|extended_tip|valueset">Click the outline style that you want to use.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label25">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="pickoutlinepage|label25">Selection</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PickOutlinePage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="pickoutlinepage|extended_tip|PickOutlinePage">Displays the different styles that you can apply to a hierarchical list. Up to nine outline levels in a list hierarchy are supported.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/positionpage.ui b/cui/uiconfig/ui/positionpage.ui
new file mode 100644
index 000000000..ad962316a
--- /dev/null
+++ b/cui/uiconfig/ui/positionpage.ui
@@ -0,0 +1,546 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">1</property>
+ <property name="upper">999</property>
+ <property name="value">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">-1000</property>
+ <property name="upper">1000</property>
+ <property name="step_increment">0.1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="PositionPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">4</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkRadioButton" id="normal">
+ <property name="label" translatable="yes" context="positionpage|normal">Normal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="superscript">
+ <property name="label" translatable="yes" context="positionpage|superscript">Superscript</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">normal</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="subscript">
+ <property name="label" translatable="yes" context="positionpage|subscript">Subscript</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">normal</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">end</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="raiselower">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|raiselower">Raise/lower by</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">raiselowersb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="raiselowersb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="fontsizesb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment4</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="automatic">
+ <property name="label" translatable="yes" context="positionpage|automatic">Automatic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="relativefontsize">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|relativefontsize">Relative font size</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">fontsizesb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|label20">Position</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="rotationcontainer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="0deg">
+ <property name="label" translatable="yes" context="positionpage|0deg">0 degrees</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="90deg">
+ <property name="label" translatable="yes" context="positionpage|90deg">90 degrees</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">0deg</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="270deg">
+ <property name="label" translatable="yes" context="positionpage|270deg">270 degrees</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">0deg</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label24">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|label24">Scale width</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">scalewidthsb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="scalewidthsb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment2</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="fittoline">
+ <property name="label" translatable="yes" context="positionpage|fittoline">Fit to line</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="rotateandscale">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|rotateandscale">Rotation / Scaling</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="scale">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="positionpage|scale">Scaling</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|label7">Character spacing</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">kerningsb</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="kerningsb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="pairkerning">
+ <property name="label" translatable="yes" context="positionpage|pairkerning">Pair kerning</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionpage|label22">Spacing</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="valign">end</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-end">12</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="positionpage|preview-atkobject">Preview</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="box3"/>
+ <widget name="rotationcontainer"/>
+ <widget name="label7"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="raiselower"/>
+ <widget name="relativefontsize"/>
+ <widget name="label24"/>
+ <widget name="box6"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup3">
+ <widgets>
+ <widget name="raiselowersb"/>
+ <widget name="fontsizesb"/>
+ <widget name="scalewidthsb"/>
+ <widget name="kerningsb"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/positionsizedialog.ui b/cui/uiconfig/ui/positionsizedialog.ui
new file mode 100644
index 000000000..2fe4f2d7f
--- /dev/null
+++ b/cui/uiconfig/ui/positionsizedialog.ui
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="PositionAndSizeDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="positionsizedialog|PositionAndSizeDialog">Position and Size</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_POSITION_SIZE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionsizedialog|RID_SVXPAGE_POSITION_SIZE">Position and Size</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_SWPOSSIZE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionsizedialog|RID_SVXPAGE_SWPOSSIZE">Position and Size</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionsizedialog|RID_SVXPAGE_ANGLE">Rotation</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_SLANT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="positionsizedialog|RID_SVXPAGE_SLANT">Slant &amp; Corner Radius</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/possizetabpage.ui b/cui/uiconfig/ui/possizetabpage.ui
new file mode 100644
index 000000000..0d807e94a
--- /dev/null
+++ b/cui/uiconfig/ui/possizetabpage.ui
@@ -0,0 +1,594 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentPOS">
+ <property name="lower">-120</property>
+ <property name="upper">240</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPOS1">
+ <property name="lower">-120</property>
+ <property name="upper">240</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentSIZE">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentSIZE1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="PositionAndSize">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="FL_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_POS_X">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|FT_POS_X">Position _X:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_POS_X</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_POS_Y">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|FT_POS_Y">Position _Y:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_POS_Y</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_POS_X">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPOS</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_POS_X-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|MTR_FLD_POS_X">Enter the horizontal distance that you want to move the object relative to the base point selected in the grid.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_POS_Y">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPOS1</property>
+ <property name="digits">4</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_POS_Y-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|MTR_FLD_POS_Y">Enter the vertical distance that you want to move the object relative to the base point selected in the grid.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_POSRECT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_POSRECT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|CTL_POSRECT">Click a base point in the grid, and then enter the amount that you want to shift the object relative to the base point that you selected in the Position Y and Position X boxes. The base points correspond to the selection handles on an object.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_POSREFERENCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|FT_POSREFERENCE">_Base point:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">CTL_POSRECT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|label1">Position</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_SIZE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|FT_WIDTH">Wi_dth:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_WIDTH</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_HEIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|FT_HEIGHT">H_eight:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_HEIGHT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_WIDTH">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentSIZE</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_WIDTH-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|MTR_FLD_WIDTH">Enter a width for the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_HEIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentSIZE1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_HEIGHT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|MTR_FLD_HEIGHT">Enter a height for the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="CBX_SCALE">
+ <property name="label" translatable="yes" context="possizetabpage|CBX_SCALE">_Keep ratio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CBX_SCALE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|CBX_SCALE">Maintains proportions when you resize the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_SIZERECT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_SIZERECT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|CTL_SIZERECT">Click a base point in the grid, and then enter the new size dimensions for the selected object in the Width and Height boxes.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_SIZEREFERENCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|FT_SIZEREFERENCE">Base _point:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">CTL_SIZERECT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|label2">Size</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="FL_PROTECT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_POSPROTECT">
+ <property name="label" translatable="yes" context="possizetabpage|TSB_POSPROTECT">Positio_n</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_POSPROTECT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|TSB_POSPROTECT">Prevents changes to the position or the size of the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_SIZEPROTECT">
+ <property name="label" translatable="yes" context="possizetabpage|TSB_SIZEPROTECT">_Size</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_SIZEPROTECT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|TSB_SIZEPROTECT">Prevents you from resizing the object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|label3">Protect</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_ADJUST">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOGROW_WIDTH">
+ <property name="label" translatable="yes" context="possizetabpage|TSB_AUTOGROW_WIDTH">_Fit width to text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOGROW_WIDTH-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|TSB_AUTOGROW_WIDTH">Expands the width of the object to the width of the text, if the object is smaller than the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOGROW_HEIGHT">
+ <property name="label" translatable="yes" context="possizetabpage|TSB_AUTOGROW_HEIGHT">Fit _height to text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOGROW_HEIGHT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|TSB_AUTOGROW_HEIGHT">Expands the height of the object to the height of the text, if the object is smaller than the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="possizetabpage|label4">Adapt</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PositionAndSize-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="possizetabpage|extended_tip|PositionAndSize">Resizes or moves the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="FT_POS_X"/>
+ <widget name="FT_POS_Y"/>
+ <widget name="FT_WIDTH"/>
+ <widget name="FT_HEIGHT"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="MTR_FLD_POS_X"/>
+ <widget name="MTR_FLD_POS_Y"/>
+ <widget name="MTR_FLD_WIDTH"/>
+ <widget name="MTR_FLD_HEIGHT"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/posterdialog.ui b/cui/uiconfig/ui/posterdialog.ui
new file mode 100644
index 000000000..c45d13c53
--- /dev/null
+++ b/cui/uiconfig/ui/posterdialog.ui
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">2</property>
+ <property name="upper">64</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="PosterDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="posterdialog|PosterDialog">Posterize</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="value">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="value-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="posterdialog|extended_tip|value">Specifies the number of colors to which the image is to be reduced.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="posterdialog|label2">Poster colors:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">value</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="posterdialog|label1">Parameters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="PosterDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="posterdialog|extended_tip|PosterDialog">Opens a dialog to determine the number of poster colors.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/qrcodegen.ui b/cui/uiconfig/ui/qrcodegen.ui
new file mode 100644
index 000000000..7078e3aa4
--- /dev/null
+++ b/cui/uiconfig/ui/qrcodegen.ui
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="margin_value">
+ <property name="upper">75</property>
+ <property name="value">1</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkTextBuffer" id="textbuffer1">
+ <property name="text" translatable="yes" context="qrcodegen|edit_name">www.libreoffice.org</property>
+ </object>
+ <object class="GtkDialog" id="QrCodeGenDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="qrcodegen|QrCodeGenDialog">QR and Barcode</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">6</property>
+ <property name="margin-bottom">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label_text">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="label" translatable="yes" context="qrcodegen|label_text" comments="Text to be stored in the QR">URL/Text:</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_margin">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="qrcodegen|label_margin" comments="Set Margin around QR">Margin:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">edit_margin</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_type">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="qrcodegen|label_type" comments="Select type">Type:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">choose_type</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="choose_type">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="active">0</property>
+ <items>
+ <item translatable="yes" context="qrcodegen|QrCode">QR Code</item>
+ <item translatable="yes" context="qrcodegen|BarCode">Barcode</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="choose_type-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="type">The type of code to generate.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">2</property>
+ <child>
+ <object class="GtkLabel" id="label_ecc">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="qrcodegen|label_ecc" comments="Error Correction Level of QR code">Error correction:</property>
+ <property name="use-underline">True</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="button_low"/>
+ <relation type="label-for" target="button_medium"/>
+ <relation type="label-for" target="button_quartile"/>
+ <relation type="label-for" target="button_high"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="edit_margin">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">margin_value</property>
+ <property name="snap-to-ticks">True</property>
+ <property name="numeric">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_margin-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="edit margin">The margin surrounding the code.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=4 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="row-spacing">2</property>
+ <child>
+ <object class="GtkRadioButton" id="button_low">
+ <property name="label" translatable="yes" context="qrcodegen|ErrorCorrection">Low</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label_ecc"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button_low-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="button_low">7% of codewords can be restored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="button_medium">
+ <property name="label" translatable="yes" context="qrcodegen|ErrorCorrection">Medium</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">button_low</property>
+ <accessibility>
+ <relation type="labelled-by" target="label_ecc"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button_medium-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="button_medium">15% of codewords can be restored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="button_quartile">
+ <property name="label" translatable="yes" context="qrcodegen|ErrorCorrection">Quartile</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">button_low</property>
+ <accessibility>
+ <relation type="labelled-by" target="label_ecc"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button_quartile-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="button_quartile">25% of codewords can be restored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="button_high">
+ <property name="label" translatable="yes" context="qrcodegen|ErrorCorrection">High</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">button_low</property>
+ <accessibility>
+ <relation type="labelled-by" target="label_ecc"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button_high-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="button_high">30% of codewords can be restored.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">always</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTextView" id="edit_text">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="buffer">textbuffer1</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_text-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="qr text">The text from which to generate the code.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="qrcodegen|QR Code Properties">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="QrCodeGenDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="qr code dialog title">Generate linear and matrix codes for any text or URL.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querychangelineenddialog.ui b/cui/uiconfig/ui/querychangelineenddialog.ui
new file mode 100644
index 000000000..5ec156700
--- /dev/null
+++ b/cui/uiconfig/ui/querychangelineenddialog.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskChangeLineEndDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querychangelineenddialog|AskChangeLineEndDialog">Save Arrow Style?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">warning</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querychangelineenddialog|AskChangeLineEndDialog">The arrow style was modified without saving.</property>
+ <property name="secondary_text" translatable="yes" context="querychangelineenddialog|AskChangeLineEndDialog">Would you like to save the arrow style now?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletebitmapdialog.ui b/cui/uiconfig/ui/querydeletebitmapdialog.ui
new file mode 100644
index 000000000..ae0db9528
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletebitmapdialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskDelBitmapDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletebitmapdialog|AskDelBitmapDialog">Delete Bitmap?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletebitmapdialog|AskDelBitmapDialog">Are you sure you want to delete the bitmap?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletechartcolordialog.ui b/cui/uiconfig/ui/querydeletechartcolordialog.ui
new file mode 100644
index 000000000..957f9e48b
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletechartcolordialog.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="QueryDeleteChartColorDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletechartcolordialog|QueryDeleteChartColorDialog">Delete Color?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">warning</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletechartcolordialog|QueryDeleteChartColorDialog">Do you really want to delete the chart color?</property>
+ <property name="secondary_text" translatable="yes" context="querydeletechartcolordialog|QueryDeleteChartColorDialog">This action cannot be undone.</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletecolordialog.ui b/cui/uiconfig/ui/querydeletecolordialog.ui
new file mode 100644
index 000000000..9cf4d0648
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletecolordialog.ui
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskDelColorDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletecolordialog|AskDelColorDialog">Delete color?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletecolordialog|AskDelColorDialog">Do you want to delete the color?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">24</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletedictionarydialog.ui b/cui/uiconfig/ui/querydeletedictionarydialog.ui
new file mode 100644
index 000000000..38185b2eb
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletedictionarydialog.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="QueryDeleteDictionaryDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletedictionarydialog|QueryDeleteDictionaryDialog">Delete Dictionary?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">warning</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletedictionarydialog|QueryDeleteDictionaryDialog">Do you really want to delete the dictionary?</property>
+ <property name="secondary_text" translatable="yes" context="querydeletedictionarydialog|QueryDeleteDictionaryDialog">This action cannot be undone.</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletegradientdialog.ui b/cui/uiconfig/ui/querydeletegradientdialog.ui
new file mode 100644
index 000000000..d80d96ff0
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletegradientdialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskDelGradientDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletegradientdialog|AskDelGradientDialog">Delete gradient?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletegradientdialog|AskDelGradientDialog">Do you want to delete the gradient?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletehatchdialog.ui b/cui/uiconfig/ui/querydeletehatchdialog.ui
new file mode 100644
index 000000000..a0f98efd8
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletehatchdialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskDelHatchDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletehatchdialog|AskDelHatchDialog">Delete Hatching?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletehatchdialog|AskDelHatchDialog">Do you want to delete the hatching?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletelineenddialog.ui b/cui/uiconfig/ui/querydeletelineenddialog.ui
new file mode 100644
index 000000000..6917fc624
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletelineenddialog.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskDelLineEndDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletelineenddialog|AskDelLineEndDialog">Delete Arrow Style?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletelineenddialog|AskDelLineEndDialog">Do you really want to delete the arrow style?</property>
+ <property name="secondary_text" translatable="yes" context="querydeletelineenddialog|AskDelLineEndDialog">This action cannot be undone.</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querydeletelinestyledialog.ui b/cui/uiconfig/ui/querydeletelinestyledialog.ui
new file mode 100644
index 000000000..ae26e8255
--- /dev/null
+++ b/cui/uiconfig/ui/querydeletelinestyledialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskDelLineStyleDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querydeletelinestyledialog|AskDelLineStyleDialog">Delete Line Style?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="querydeletelinestyledialog|AskDelLineStyleDialog">Do you want to delete the line style?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/queryduplicatedialog.ui b/cui/uiconfig/ui/queryduplicatedialog.ui
new file mode 100644
index 000000000..54dd9bde6
--- /dev/null
+++ b/cui/uiconfig/ui/queryduplicatedialog.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="DuplicateNameDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="queryduplicatedialog|DuplicateNameDialog">Duplicate Name</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">warning</property>
+ <property name="buttons">ok</property>
+ <property name="text" translatable="yes" context="queryduplicatedialog|DuplicateNameDialog">The name you have entered already exists.</property>
+ <property name="secondary_text" translatable="yes" context="queryduplicatedialog|DuplicateNameDialog">Please choose another name.</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querynoloadedfiledialog.ui b/cui/uiconfig/ui/querynoloadedfiledialog.ui
new file mode 100644
index 000000000..5959a6c64
--- /dev/null
+++ b/cui/uiconfig/ui/querynoloadedfiledialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="NoLoadedFileDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querynoloadedfiledialog|NoLoadedFileDialog">No Loaded File</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">error</property>
+ <property name="buttons">ok</property>
+ <property name="text" translatable="yes" context="querynoloadedfiledialog|NoLoadedFileDialog">The file could not be loaded!</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querynosavefiledialog.ui b/cui/uiconfig/ui/querynosavefiledialog.ui
new file mode 100644
index 000000000..8961d7477
--- /dev/null
+++ b/cui/uiconfig/ui/querynosavefiledialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="NoSaveFileDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querynosavefiledialog|NoSaveFileDialog">No Saved File</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">error</property>
+ <property name="buttons">ok</property>
+ <property name="text" translatable="yes" context="querynosavefiledialog|NoSaveFileDialog">The file could not be saved!</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/querysavelistdialog.ui b/cui/uiconfig/ui/querysavelistdialog.ui
new file mode 100644
index 000000000..76f407ef3
--- /dev/null
+++ b/cui/uiconfig/ui/querysavelistdialog.ui
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="AskSaveList">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="querysavelistdialog|AskSaveList">Save List?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">warning</property>
+ <property name="buttons">ok-cancel</property>
+ <property name="text" translatable="yes" context="querysavelistdialog|AskSaveList">The list was modified without saving.</property>
+ <property name="secondary_text" translatable="yes" context="querysavelistdialog|AskSaveList">Would you like to save the list now?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/queryupdategalleryfilelistdialog.ui b/cui/uiconfig/ui/queryupdategalleryfilelistdialog.ui
new file mode 100644
index 000000000..2f72d98d5
--- /dev/null
+++ b/cui/uiconfig/ui/queryupdategalleryfilelistdialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMessageDialog" id="QueryUpdateFileListDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes" context="queryupdategalleryfilelistdialog|QueryUpdateFileListDialog">Update File List?</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="message_type">question</property>
+ <property name="buttons">yes-no</property>
+ <property name="text" translatable="yes" context="queryupdategalleryfilelistdialog|QueryUpdateFileListDialog">Do you want to update the file list?</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="messagedialog-vbox4">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="messagedialog-action_area4">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/recordnumberdialog.ui b/cui/uiconfig/ui/recordnumberdialog.ui
new file mode 100644
index 000000000..5713243c7
--- /dev/null
+++ b/cui/uiconfig/ui/recordnumberdialog.ui
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="RecordNumberDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="recordnumberdialog|RecordNumberDialog">Record Number</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="recordnumberdialog|label2">go to record</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/rotationtabpage.ui b/cui/uiconfig/ui/rotationtabpage.ui
new file mode 100644
index 000000000..8fc381928
--- /dev/null
+++ b/cui/uiconfig/ui/rotationtabpage.ui
@@ -0,0 +1,353 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentANGLE">
+ <property name="upper">360</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPOS1">
+ <property name="lower">-500</property>
+ <property name="upper">50000</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPOS2">
+ <property name="lower">-500</property>
+ <property name="upper">50000</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="Rotation">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="FL_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_POS_X">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|FT_POS_X">Position _X:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_POS_X</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_POS_Y">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|FT_POS_Y">Position _Y:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_POS_Y</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_POS_X">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPOS1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_POS_X-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="rotationtabpage|extended_tip|MTR_FLD_POS_X">Enter the horizontal distance from the left edge of the page to the pivot point.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_POS_Y">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPOS2</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_POS_Y-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="rotationtabpage|extended_tip|MTR_FLD_POS_Y">Enter the vertical distance from the top edge of the page to the pivot point.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_RECT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="tooltip_text" translatable="yes" context="rotationtabpage|CTL_RECT|tooltip_text">Rotation point</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_RECT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="rotationtabpage|extended_tip|CTL_RECT">Click where you want to place the pivot point.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_POSPRESETS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|FT_POSPRESETS">_Default settings:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">CTL_RECT</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|label1">Pivot Point</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|FT_ANGLE">_Angle:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">NF_ANGLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="NF_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentANGLE</property>
+ <property name="digits">2</property>
+ <property name="wrap">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="NF_ANGLE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="rotationtabpage|extended_tip|NF_ANGLE">Enter the number of degrees that you want to rotate the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="tooltip_text" translatable="yes" context="rotationtabpage|CTL_ANGLE|tooltip_text">Rotation Angle</property>
+ <property name="halign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_ANGLE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="rotationtabpage|extended_tip|CTL_ANGLE">Click to specify the rotation angle in multiples of 45 degrees.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_ANGLEPRESETS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|FT_ANGLEPRESETS">Default _settings:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">CTL_ANGLE</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="rotationtabpage|label2">Rotation Angle</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="Rotation-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="rotationtabpage|extended_tip|Rotation">Rotates the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="FT_POS_X"/>
+ <widget name="FT_POS_Y"/>
+ <widget name="FT_ANGLE"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="MTR_FLD_POS_X"/>
+ <widget name="MTR_FLD_POS_Y"/>
+ <widget name="NF_ANGLE"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/screenshotannotationdialog.ui b/cui/uiconfig/ui/screenshotannotationdialog.ui
new file mode 100644
index 000000000..346af2f59
--- /dev/null
+++ b/cui/uiconfig/ui/screenshotannotationdialog.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="ScreenshotAnnotationDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="screenshotannotationdialog|ScreenshotAnnotationDialog">Interactive Screenshot Annotation</property>
+ <property name="modal">True</property>
+ <property name="default_width">600</property>
+ <property name="default_height">460</property>
+ <property name="type_hint">normal</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="save">
+ <property name="label" translatable="yes" context="screenshotannotationdialog|save">Save Screenshot...</property>
+ <property name="name">save</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="screenshotannotationdialog|label2">Click the widgets to add annotation:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">picture</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="picture">
+ <property name="name">image</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="screenshotannotationdialog|label1">Paste the following markup into the help file:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">text</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="text">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="101">save</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/scriptorganizer.ui b/cui/uiconfig/ui/scriptorganizer.ui
new file mode 100644
index 000000000..2421ca93f
--- /dev/null
+++ b/cui/uiconfig/ui/scriptorganizer.ui
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name expander -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="ScriptOrganizerDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="scriptorganizer|ScriptOrganizerDialog">%MACROLANG Macros</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="scriptorganizer|run">Run</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="scripts">
+ <property name="width_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">1</property>
+ <property name="enable_tree_lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="create">
+ <property name="label" translatable="yes" context="scriptorganizer|create">Create...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="create-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="scriptorganizer|extended_tip|create">Creates a new script.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="label" translatable="yes" context="stock">_Edit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="scriptorganizer|extended_tip|edit">Opens the default script editor for your operating system.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="rename">
+ <property name="label" translatable="yes" context="scriptorganizer|rename">Rename...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="rename-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="scriptorganizer|extended_tip|rename">Opens a dialog where you can change the name of the selected script.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="scriptorganizer|delete">Delete...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="scriptorganizer|extended_tip|delete">Prompts you to delete the selected script.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="macrosft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="scriptorganizer|macrosft">Macros</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-7">close</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ScriptOrganizerDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="scriptorganizer|extended_tip|ScriptOrganizerDialog">Select a macro or script from My Macros, Application Macros, or an open document. To view the available macros or scripts, double-click an entry.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/searchattrdialog.ui b/cui/uiconfig/ui/searchattrdialog.ui
new file mode 100644
index 000000000..5e94639f3
--- /dev/null
+++ b/cui/uiconfig/ui/searchattrdialog.ui
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="SearchAttrDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="searchattrdialog|SearchAttrDialog">Attributes</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SearchAttrDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="searchattrdialog|extended_tip|SearchAttrDialog">Choose the text attributes that you want to search for. For example, if you search for the Font attribute, all instances of text that do not use the default font are found. All text that has a directly coded font attribute, and all text where a style switches the font attribute, are found.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/searchformatdialog.ui b/cui/uiconfig/ui/searchformatdialog.ui
new file mode 100644
index 000000000..c1b05669f
--- /dev/null
+++ b/cui/uiconfig/ui/searchformatdialog.ui
@@ -0,0 +1,544 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="SearchFormatDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="searchformatdialog|SearchFormatDialog">Text Format </property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="font">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|font">Font</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="fonteffects">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|fonteffects">Font Effects</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="position">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|position">Position</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="asianlayout">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|asianlayout">Asian Layout</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="labelTP_PARA_STD">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|labelTP_PARA_STD">Indents &amp; Spacing</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="labelTP_PARA_ALIGN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|labelTP_PARA_ALIGN">Alignment</property>
+ <property name="xalign">0.5</property>
+ </object>
+ <packing>
+ <property name="position">5</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="labelTP_PARA_EXT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|labelTP_PARA_EXT">Text Flow</property>
+ <property name="xalign">0.5</property>
+ </object>
+ <packing>
+ <property name="position">6</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="labelTP_PARA_ASIAN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|labelTP_PARA_ASIAN">Asian Typography</property>
+ </object>
+ <packing>
+ <property name="position">7</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="background">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="searchformatdialog|background">Highlighting</property>
+ </object>
+ <packing>
+ <property name="position">8</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/securityoptionsdialog.ui b/cui/uiconfig/ui/securityoptionsdialog.ui
new file mode 100644
index 000000000..5ff6c85ec
--- /dev/null
+++ b/cui/uiconfig/ui/securityoptionsdialog.ui
@@ -0,0 +1,457 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="SecurityOptionsDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="securityoptionsdialog|SecurityOptionsDialog">Security Options and Warnings</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="savesenddocs">
+ <property name="label" translatable="yes" context="securityoptionsdialog|savesenddocs">_When saving or sending</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="savesenddocs-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|savesenddocs">Select to see a warning dialog when you try to save or send a document that contains recorded changes, versions, or comments.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="whensigning">
+ <property name="label" translatable="yes" context="securityoptionsdialog|whensigning">When _signing</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="whensigning-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|whensigning">Select to see a warning dialog when you try to sign a document that contains recorded changes, versions, fields, references to other sources (for example linked sections or linked pictures), or comments.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="whenprinting">
+ <property name="label" translatable="yes" context="securityoptionsdialog|whenprinting">When _printing</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="whenprinting-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|whenprinting">Select to see a warning dialog when you try to print a document that contains recorded changes or comments.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="whenpdf">
+ <property name="label" translatable="yes" context="securityoptionsdialog|whenpdf">When creating PDF _files</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="whenpdf-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|whenpdf">Select to see a warning dialog when you try to export a document to PDF format that displays recorded changes in Writer, or that displays comments.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockwhenprinting">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="locksavesenddocs">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockwhensigning">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockwhenpdf">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="securityoptionsdialog|label3">Warn if document contains recorded changes, versions, hidden information or notes:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="securityoptionsdialog|label1">Security Warnings</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="removepersonal">
+ <property name="label" translatable="yes" context="securityoptionsdialog|removepersonal">_Remove personal information on saving</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="removepersonal-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|removepersonal">Select to always remove user data from the file properties. If this option is not selected, you can still remove the personal information for the current document with the Reset Properties button on File - Properties - General.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="password">
+ <property name="label" translatable="yes" context="securityoptionsdialog|password">Recommend password protection on sa_ving</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="password-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|password">Select to always enable the Save with password option in the file save dialogs. Deselect the option to save files by default without password.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ctrlclick">
+ <property name="label" translatable="yes" context="securityoptionsdialog|ctrlclick">Ctrl-click required _to open hyperlinks</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ctrlclick-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|ctrlclick">If enabled, you must hold down the Ctrl key while clicking a hyperlink to follow that link. If not enabled, a click opens the hyperlink.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="blockuntrusted">
+ <property name="label" translatable="yes" context="securityoptionsdialog|blockuntrusted">Block any links from documents not among the trusted locations (see Macro Security)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="blockuntrusted-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|blockuntrusted">Blocks the use of linked images by documents not in the trusted locations defined on the Trusted Sources tab of the Macro Security dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockremovepersonal">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockpassword">
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockctrlclick">
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="lockblockuntrusted">
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="icon_name">res/lock.png</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="securityoptionsdialog|label2">Security Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SecurityOptionsDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|SecurityOptionsDialog">Set security related options and warnings about hidden information in documents.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/selectpathdialog.ui b/cui/uiconfig/ui/selectpathdialog.ui
new file mode 100644
index 000000000..568029411
--- /dev/null
+++ b/cui/uiconfig/ui/selectpathdialog.ui
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="SelectPathDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="selectpathdialog|SelectPathDialog">Select Paths</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">normal</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ok-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="selectpathdialog|extended_tip|ok">Saves all changes and closes dialog.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="cancel-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="selectpathdialog|extended_tip|cancel">Closes dialog and discards all changes.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="selectpathdialog|add">_Add...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cui/ui/selectpathdialog/add">Opens the Select Path dialog to select another folder or the Open dialog to select another file.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="selectpathdialog|extended_tip|delete">Deletes the selected element or elements without requiring confirmation.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="paths">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="paths-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="cui/ui/selectpathdialog/paths">Contains a list of the paths that have already been added. Mark the default path for new files.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="selectpathdialog|label1">Paths</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/shadowtabpage.ui b/cui/uiconfig/ui/shadowtabpage.ui
new file mode 100644
index 000000000..3ce897796
--- /dev/null
+++ b/cui/uiconfig/ui/shadowtabpage.ui
@@ -0,0 +1,344 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentDistance">
+ <property name="upper">999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent">
+ <property name="upper">100</property>
+ <property name="step_increment">5</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPoint">
+ <property name="upper">150</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="ShadowTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="spacing">24</property>
+ <child>
+ <object class="GtkFrame" id="property">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="maingrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_SHOW_SHADOW">
+ <property name="label" translatable="yes" context="shadowtabpage|TSB_SHOW_SHADOW">_Use shadow</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_SHOW_SHADOW-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="shadowtabpage|extended_tip|TSB_SHOW_SHADOW">Adds a shadow to the selected drawing object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="gridSHADOW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">4</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkSpinButton" id="MTR_SHADOW_TRANSPARENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_SHADOW_TRANSPARENT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="shadowtabpage|extended_tip|MTR_SHADOW_TRANSPARENT">Enter a percentage from 0% (opaque) to 100% (transparent) to specify the transparency of the shadow.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="LB_SHADOW_BLUR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentPoint</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_DISTANCE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentDistance</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_DISTANCE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="shadowtabpage|extended_tip|MTR_FLD_DISTANCE">Enter the distance that you want the shadow to be offset from the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_POSITION-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="shadowtabpage|extended_tip|CTL_POSITION">Click where you want to cast the shadow.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="LB_SHADOW_COLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_SHADOW_COLOR-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="shadowtabpage|extended_tip|LB_SHADOW_COLOR">Select a color for the shadow.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_DISTANCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="shadowtabpage|FT_DISTANCE">_Distance:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_DISTANCE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_SHADOW_COLOR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="shadowtabpage|FT_SHADOW_COLOR">_Color:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_SHADOW_COLOR</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_SHADOW_BLUR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="shadowtabpage|FT_SHADOW_BLUR">_Blur:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_SHADOW_BLUR</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRANSPARENT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="shadowtabpage|FT_TRANSPARENT">_Transparency:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_SHADOW_TRANSPARENT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="shadowtabpage|label">Properties</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_COLOR_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_COLOR_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="shadowtabpage|CTL_COLOR_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="shadowtabpage|label">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ShadowTabPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="shadowtabpage|extended_tip|ShadowTabPage">Add a shadow to the selected drawing object, and define the properties of the shadow.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="MTR_SHADOW_TRANSPARENT"/>
+ <widget name="MTR_FLD_DISTANCE"/>
+ <widget name="LB_SHADOW_COLOR"/>
+ <widget name="LB_SHADOW_BLUR"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <property name="mode">vertical</property>
+ <widgets>
+ <widget name="maingrid"/>
+ <widget name="box3"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/showcoldialog.ui b/cui/uiconfig/ui/showcoldialog.ui
new file mode 100644
index 000000000..7928d7383
--- /dev/null
+++ b/cui/uiconfig/ui/showcoldialog.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="ShowColDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="showcoldialog|ShowColDialog">Show Columns</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="showcoldialog|label1">The following columns are currently hidden. Please mark the fields you want to show and choose OK.</property>
+ <property name="use_underline">True</property>
+ <property name="wrap">True</property>
+ <property name="mnemonic_widget">treeview</property>
+ <property name="max_width_chars">56</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/signatureline.ui b/cui/uiconfig/ui/signatureline.ui
new file mode 100644
index 000000000..8cdda4020
--- /dev/null
+++ b/cui/uiconfig/ui/signatureline.ui
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="SignatureLineDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="signatureline|SignatureLineDialog">Signature Line</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkEntry" id="edit_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="placeholder_text" translatable="yes" context="signatureline|edit_name">John Doe</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signatureline|extended_tip|edit_name">Enter your name as signer of the document. Your name will be inserted above the signature horizontal line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edit_title">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="placeholder_text" translatable="yes" context="signatureline|edit_title">Director</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_title-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signatureline|extended_tip|edit_title">Enter the title of the signer. The title is displayed in the signature line graphic box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="edit_email">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="placeholder_text" translatable="yes" context="signatureline|edit_email">john.doe@example.org</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_email-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signatureline|extended_tip|edit_email">Enter the email of the signer. The email is not displayed in the signature line graphic box, but is used for the digital signature.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signatureline|label_name" comments="Suggested Signer Name">Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit_name</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signatureline|label_title" comments="Suggested Signer Title">Title:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit_title</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_email">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signatureline|label_email" comments="Suggested Signer email">Email:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit_email</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="signatureline|label_suggestedsigner">Suggested Signer</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkbox_can_add_comments">
+ <property name="label" translatable="yes" context="signatureline|checkbox_can_add_comments">Signer can add comments</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkbox_can_add_comments-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signatureline|extended_tip|checkbox_can_add_comments">Enable signer to insert comments in the Sign Signature Line dialog at time of signature.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbox_show_sign_date">
+ <property name="label" translatable="yes" context="signatureline|checkbox_show_sign_date">Show sign date in signature line</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkbox_show_sign_date-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signatureline|extended_tip|checkbox_show_sign_date">Mark this checkbox to display the date of the signature, at the time when the document is digitally signed.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_instructions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signatureline|label_instructions">Instructions to the signer:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit_instructions</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="edit_instructions">
+ <property name="height_request">60</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_instructions-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signatureline|extended_tip|edit_instructions">Insert instructions for the signer. The instructions appears in the Sign Signature Line dialog box, at the time of signature.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="signatureline|label_more">More</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/signsignatureline.ui b/cui/uiconfig/ui/signsignatureline.ui
new file mode 100644
index 000000000..ade411ed2
--- /dev/null
+++ b/cui/uiconfig/ui/signsignatureline.ui
@@ -0,0 +1,382 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="SignSignatureLineDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="signsignatureline|SignSignatureLineDialog">Sign Signature Line</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="signsignatureline|ok">Sign</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkEntry" id="edit_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="placeholder_text" translatable="yes" context="signsignatureline|edit_name">Type your name here</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_name-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signsignatureline|extended_tip|edit_name">Enter your name as signer of the document. Your name will be inserted above the signature horizontal line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_name" comments="Name of the signer">Your Name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit_name</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_certificate">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_certificate" comments="Certificate to be used for signing">Certificate:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">btn_select_certificate</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btn_select_certificate">
+ <property name="label" translatable="yes" context="signsignatureline|btn_select_certificate">Select X.509 Certificate</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="btn_select_certificate-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signsignatureline|extended_tip|btn_select_certificate">Click on the Select Certificate button to open the Select Certificate dialog box, where your certificates are listed. Select the certificate suitable for signing the document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_or">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_name" comments="Name of the signer">or</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btn_load_image">
+ <property name="label" translatable="yes" context="signsignatureline|btn_load_image">Use Signature Image</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label_image_dimensions"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btn_clear_image">
+ <property name="label" translatable="yes" context="signsignatureline|btn_clear_image">Clear</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_image_dimensions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_bottom">6</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_image_dimensions">Best image size: 600 x 100 px</property>
+ <attributes>
+ <attribute name="style" value="italic"/>
+ </attributes>
+ <accessibility>
+ <relation type="label-for" target="btn_load_image"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label_sign">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_sign">Sign</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label_add_comment">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_add_comment">Add comment:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">edit_comment</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="edit_comment">
+ <property name="height_request">60</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="edit_comment-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signsignatureline|extended_tip|edit_comment">Enter comments about the signature. The comments are displayed in the Description field of the certificate.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_hint">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_hint">Instructions from the document creator:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">label_hint_text</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_hint_text">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="mnemonic_widget">edit_comment</property>
+ <attributes>
+ <attribute name="style" value="oblique"/>
+ </attributes>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="label_hint_text-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="signsignatureline|extended_tip|label_hint_text">This area displays the instructions entered by the document creator when adding the signature line.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="signsignatureline|label_more">More</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/similaritysearchdialog.ui b/cui/uiconfig/ui/similaritysearchdialog.ui
new file mode 100644
index 000000000..cf9e51c4a
--- /dev/null
+++ b/cui/uiconfig/ui/similaritysearchdialog.ui
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">30</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">30</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">30</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="SimilaritySearchDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="similaritysearchdialog|SimilaritySearchDialog">Similarity Search</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area3">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="margin-end">6</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="similaritysearchdialog|label2">_Exchange characters:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">otherfld</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="similaritysearchdialog|label3">_Add characters:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">longerfld</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="similaritysearchdialog|label4">_Remove characters:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">shorterfld</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="relaxbox">
+ <property name="label" translatable="yes" context="similaritysearchdialog|relaxbox">_Combine</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="relaxbox-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="similaritysearchdialog|extended_tip|relaxbox">Searches for a term that matches any combination of the similarity search settings.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="otherfld">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="otherfld-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="similaritysearchdialog|extended_tip|otherfld">Enter the number of characters in the search term that can be exchanged.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="longerfld">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="longerfld-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="similaritysearchdialog|extended_tip|longerfld">Enter the maximum number of characters by which a word can exceed the number of characters in the search term.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="shorterfld">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="shorterfld-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="similaritysearchdialog|extended_tip|shorterfld">Enter the number of characters by which a word can be shorter than the search term.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SimilaritySearchDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="similaritysearchdialog|extended_tip|SimilaritySearchDialog">Find terms that are similar to the Find text. Select this checkbox, and then click the Similarities button to define the similarity options.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/slantcornertabpage.ui b/cui/uiconfig/ui/slantcornertabpage.ui
new file mode 100644
index 000000000..ca8dca1bd
--- /dev/null
+++ b/cui/uiconfig/ui/slantcornertabpage.ui
@@ -0,0 +1,459 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentRADIUS">
+ <property name="upper">500</property>
+ <property name="step_increment">10</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentSLANT">
+ <property name="lower">-89</property>
+ <property name="upper">89</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="SlantAndCornerRadius">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">24</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="controlgroups1">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="controlgroupx1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label5">_X:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">controlx1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="controlx1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="controlx1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|controlx1">Enter the X coordinate of the control point 1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="controlgroupy1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label6">_Y:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">controly1</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="controly1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="controly1-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|controly1">Enter the Y coordinate of the control point 1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label3">Control Point 1</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_RADIUS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_RADIUS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|FT_RADIUS">_Radius:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_RADIUS</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_RADIUS">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentRADIUS</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_RADIUS-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|MTR_FLD_RADIUS">Enter the radius of the circle that you want to use to round the corners.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label1">Corner Radius</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_SLANT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="FT_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|FT_ANGLE">_Angle:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_ANGLE</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentSLANT</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_ANGLE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|MTR_FLD_ANGLE">Enter the angle of the slant axis.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label2">Slant</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="controlgroups2">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="controlgroupx2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label4">_X:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">controlx2</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="controlx2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="controlx2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|controlx2">Enter the X coordinate of the control point 2</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="controlgroupy2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label7">_Y:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">controly2</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="controly2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="controly2-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|controly2">Enter the Y coordinate of the control point 2</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="slantcornertabpage|label8">Control Point 2</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SlantAndCornerRadius-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="slantcornertabpage|extended_tip|SlantAndCornerRadius">Slants the selected object, or rounds the corners of a rectangular object.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="label5"/>
+ <widget name="label6"/>
+ <widget name="FT_RADIUS"/>
+ <widget name="FT_ANGLE"/>
+ <widget name="label4"/>
+ <widget name="label7"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <widgets>
+ <widget name="MTR_FLD_RADIUS"/>
+ <widget name="MTR_FLD_ANGLE"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup5">
+ <widgets>
+ <widget name="controlx1"/>
+ <widget name="controly1"/>
+ <widget name="controlx2"/>
+ <widget name="controly2"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/smarttagoptionspage.ui b/cui/uiconfig/ui/smarttagoptionspage.ui
new file mode 100644
index 000000000..ad9f9998d
--- /dev/null
+++ b/cui/uiconfig/ui/smarttagoptionspage.ui
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="SmartTagOptionsPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="main">
+ <property name="label" translatable="yes" context="smarttagoptionspage|main">Label text with smart tags</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="main-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="smarttagoptionspage|extended_tip|main">Enables Smart Tags to be evaluated and shown in your text document.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GtkButton" id="properties">
+ <property name="label" translatable="yes" context="smarttagoptionspage|properties">Properties...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">start</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="properties-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="smarttagoptionspage|extended_tip|properties">To configure a Smart Tag, select the name of the Smart Tag, then click Properties. Not all Smart Tags can be configured.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="activatable">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="smarttagoptionspage|label1">Currently Installed Smart Tags</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SmartTagOptionsPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="smarttagoptionspage|extended_tip|SmartTagOptionsPage">When you have installed at least one Smart Tag extension, you see the Smart Tags page.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/smoothdialog.ui b/cui/uiconfig/ui/smoothdialog.ui
new file mode 100644
index 000000000..cd36ba2ef
--- /dev/null
+++ b/cui/uiconfig/ui/smoothdialog.ui
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">0.1</property>
+ <property name="upper">100</property>
+ <property name="value">0.6</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="SmoothDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="smoothdialog|SmoothDialog">Smooth</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="radius">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <property name="digits">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="smoothdialog|label2">_Smooth radius:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">radius</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="smoothdialog|label1">Parameters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SmoothDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="smoothdialog|extended_tip|SmoothDialog">Softens or blurs the image by applying a low pass filter.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/solarizedialog.ui b/cui/uiconfig/ui/solarizedialog.ui
new file mode 100644
index 000000000..88f36d9a0
--- /dev/null
+++ b/cui/uiconfig/ui/solarizedialog.ui
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="SolarizeDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="solarizedialog|SolarizeDialog">Solarization</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">24</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="value">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="value-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="solarizedialog|extended_tip|value">Specifies the number of colors to which the image is to be reduced.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="solarizedialog|label2">Threshold _value:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">value</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="invert">
+ <property name="label" translatable="yes" context="solarizedialog|invert">_Invert</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="invert-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="solarizedialog|extended_tip|invert">Specifies to also invert all pixels.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="solarizedialog|label1">Parameters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SolarizeDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="solarizedialog|extended_tip|SolarizeDialog">Opens a dialog for defining solarization. Solarization refers to an effect that looks like what can happen when there is too much light during photo development. The colors become partly inverted.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/specialcharacters.ui b/cui/uiconfig/ui/specialcharacters.ui
new file mode 100644
index 000000000..ff541b7e0
--- /dev/null
+++ b/cui/uiconfig/ui/specialcharacters.ui
@@ -0,0 +1,915 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="SpecialCharactersDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="specialcharacters|SpecialCharactersDialog">Special Characters</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="insert">
+ <property name="label" translatable="yes" context="specialcharacters|insert">_Insert</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=4 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">12</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <!-- n-columns=3 n-rows=2 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="subsetft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="specialcharacters|subsetft">Character block:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">subsetlb</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="fontft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="specialcharacters|fontft">Font:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">fontlb</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="srchft">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="specialcharacters|srchft">Search:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">search</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="search">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="subsetlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="subsetlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="specialcharacters|extended_tip|subsetlb">Select a Unicode block for the current font.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="fontlb">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="has-entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fontlb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="specialcharacters|extended_tip|fontlb">Select a font to display the special characters that are associated with it.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=3 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="row-spacing">6</property>
+ <child>
+ <object class="GtkDrawingArea" id="showchar">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="vexpand">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="row-spacing">3</property>
+ <property name="column-spacing">6</property>
+ <property name="row-homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="hexlabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="specialcharacters|hexlabel">Hexadecimal:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">hexvalue</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="hexulabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="no">U+</property>
+ <property name="width-chars">3</property>
+ <property name="single-line-mode">True</property>
+ <property name="max-width-chars">3</property>
+ <property name="lines">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="hexvalue">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="width-chars">8</property>
+ <property name="text">A2</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="decimallabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="specialcharacters|decimallabel">Decimal:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">decimalvalue</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="decimalvalue">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="width-chars">8</property>
+ <property name="text">162</property>
+ <property name="truncate-multiline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="favbtn">
+ <property name="label" translatable="yes" context="specialcharacters|favbtn">Add to Favorites</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="specialcharacters|favbtn|tooltip_text">Maximum Limit: 16 Characters</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="charname">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="use-underline">True</property>
+ <property name="wrap">True</property>
+ <property name="mnemonic-widget">showchar</property>
+ <property name="yalign">0</property>
+ <attributes>
+ <attribute name="scale" value="0.9"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="symboltext1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="label" translatable="yes" context="specialcharacters|symboltext1">Recent Characters:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">viewchar1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="viewgrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar1">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar2">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar3">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar4">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar5">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar6">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar7">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar8">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar9">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar10">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar11">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar12">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar13">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar14">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">13</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar15">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">14</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="viewchar16">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">15</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">4</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="symboltext2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="label" translatable="yes" context="specialcharacters|favbtn|symboltext2">Favorite Characters:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">favchar1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=16 n-rows=1 -->
+ <object class="GtkGrid" id="favgrid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="column-spacing">2</property>
+ <child>
+ <object class="GtkDrawingArea" id="favchar1">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar2">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar4">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar3">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar5">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">4</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar6">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">5</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar7">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">6</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar8">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">7</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar16">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">15</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar15">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">14</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar14">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">13</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar13">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">12</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar12">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">11</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar11">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">10</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar10">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">9</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="favchar9">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ </object>
+ <packing>
+ <property name="left-attach">8</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">3</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="showscroll">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">always</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="showcharset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="searchscroll">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">always</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="searchcharset">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SpecialCharactersDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="specialcharacters|extended_tip|SpecialCharactersDialog">Allows a user to insert characters from the range of symbols found in the installed fonts.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">80</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">7</property>
+ <property name="page-size">8</property>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/spellingdialog.ui b/cui/uiconfig/ui/spellingdialog.ui
new file mode 100644
index 000000000..8010ae92f
--- /dev/null
+++ b/cui/uiconfig/ui/spellingdialog.ui
@@ -0,0 +1,669 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkMenu" id="addmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="liststore6">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name image -->
+ <column type="GdkPixbuf"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="SpellingDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="spellingdialog|SpellingDialog">Spelling: $LANGUAGE ($LOCATION)</property>
+ <property name="resizable">False</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="options">
+ <property name="label" translatable="yes" context="spellingdialog|options">_Options...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="options-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|options">Opens a dialog, where you can select the user-defined dictionaries, and set the rules for the spellchecking.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="undo">
+ <property name="label" translatable="yes" context="spellingdialog|undo">_Undo</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="undo-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|undo">Click to undo the last change in the current sentence. Click again to undo the previous change in the same sentence.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="explain">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="use_underline">True</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="explainlink">
+ <property name="label" translatable="yes" context="spellingdialog|explainlink">More...</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="relief">none</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">0</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="sentence">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="sentence-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|sentence">Displays the sentence with the misspelled word highlighted. Edit the word or the sentence, or click one of the suggestions in the text box below.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="suggestionsft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="spellingdialog|suggestionsft">_Suggestions</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">suggestionslb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="suggestionslb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="suggestionslb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|suggestionslb">Lists suggested words to replace the misspelled word. Select the word that you want to use, and then click Correct or Correct All.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkgrammar">
+ <property name="label" translatable="yes" context="spellingdialog|checkgrammar">Chec_k grammar</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkgrammar-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|checkgrammar">Enable Check grammar to work first on all spelling errors, then on all grammar errors.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="notindictft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|notindictft">_Not in Dictionary</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">sentence</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolbar" id="toolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">end</property>
+ <property name="toolbar_style">icons</property>
+ <child>
+ <object class="GtkToolButton" id="paste">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|paste">Paste</property>
+ <property name="use_underline">True</property>
+ <property name="icon-name">edit-paste</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="insert">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|insert">Special Character</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">cmd/sc_insertsymbol.png</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="languageft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|languageft">Text languag_e:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">languagelb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="languagelb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="model">liststore6</property>
+ <property name="entry_text_column">0</property>
+ <property name="id_column">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext9"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext6"/>
+ <attributes>
+ <attribute name="pixbuf">2</attribute>
+ </attributes>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="languagelb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|languagelb">Specifies the language to use to check the spelling.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="resumeft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|resumeft">Res_ume</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="nosuggestionsft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|nosuggestionsft">(no suggestions)</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="alttitleft">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes" context="spellingdialog|alttitleft">Spelling: $LANGUAGE ($LOCATION)</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkButton" id="change">
+ <property name="label" translatable="yes" context="spellingdialog|change">Co_rrect</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="change-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|change">Replaces the unknown word with the current suggestion. If you changed more than just the misspelled word, the entire sentence is replaced.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="changeall">
+ <property name="label" translatable="yes" context="spellingdialog|changeall">Correct A_ll</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="changeall-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|changeall">Replaces all occurrences of the unknown word with the current suggestion.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="autocorrect">
+ <property name="label" translatable="yes" context="spellingdialog|autocorrect">Add to _AutoCorrect</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="spellingdialog|autocorrect|tooltip_text">Add selected suggestion as replacement for incorrect word in AutoCorrect replacement table.</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="autocorrect-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|autocorrect">Adds the current combination of the incorrect word and the replacement word to the AutoCorrect replacement table.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkButton" id="ignore">
+ <property name="label" translatable="yes" context="spellingdialog|ignore">_Ignore Once</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignore-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|ignore">Skips the unknown word and continues with the spellcheck.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ignoreall">
+ <property name="label" translatable="yes" context="spellingdialog|ignoreall">I_gnore All</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignoreall-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|ignoreall">Skips all occurrences of the unknown word until the end of the current office suite session and continues with the spellcheck.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ignorerule">
+ <property name="label" translatable="yes" context="spellingdialog|ignorerule">I_gnore Rule</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ignorerule-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|ignorerule">While performing a grammar check, click Ignore Rule to ignore the rule that is currently flagged as a grammar error.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="spellingdialog|add">Add to _Dictionary</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="add-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|add">Adds the unknown word to a user-defined dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="addmb">
+ <property name="label" translatable="yes" context="spellingdialog|addmb">Add to _Dictionary</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <property name="popup">addmenu</property>
+ <property name="use_popover">False</property>
+ <property name="draw-indicator">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="addmb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|addmb">Adds the unknown word to a user-defined dictionary.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">options</action-widget>
+ <action-widget response="102">undo</action-widget>
+ <action-widget response="-7">close</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SpellingDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="spellingdialog|extended_tip|SpellingDialog">Checks the document or the current selection for spelling errors. If a grammar checking extension is installed, the dialog also checks for grammar errors.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup">
+ <widgets>
+ <widget name="change"/>
+ <widget name="changeall"/>
+ <widget name="autocorrect"/>
+ <widget name="ignore"/>
+ <widget name="ignoreall"/>
+ <widget name="ignorerule"/>
+ <widget name="add"/>
+ <widget name="addmb"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/spelloptionsdialog.ui b/cui/uiconfig/ui/spelloptionsdialog.ui
new file mode 100644
index 000000000..ef690fd7d
--- /dev/null
+++ b/cui/uiconfig/ui/spelloptionsdialog.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="SpellOptionsDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="spelloptionsdialog|SpellOptionsDialog">Options</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/spinbox.ui b/cui/uiconfig/ui/spinbox.ui
new file mode 100644
index 000000000..15bdbf2d4
--- /dev/null
+++ b/cui/uiconfig/ui/spinbox.ui
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">100000</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="SpinDialog">
+ <property name="can_focus">False</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="SpinBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/splitcellsdialog.ui b/cui/uiconfig/ui/splitcellsdialog.ui
new file mode 100644
index 000000000..a95e0613d
--- /dev/null
+++ b/cui/uiconfig/ui/splitcellsdialog.ui
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">2</property>
+ <property name="upper">20</property>
+ <property name="value">2</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">5</property>
+ </object>
+ <object class="GtkDialog" id="SplitCellsDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="splitcellsdialog|SplitCellsDialog">Split Cells</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default-width">0</property>
+ <property name="default-height">0</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="splitcellsdialog|label3">_Split cell into:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">countnf</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="countnf">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="splitcellsdialog|label1">Split</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <!-- n-columns=2 n-rows=3 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">3</property>
+ <child>
+ <object class="GtkRadioButton" id="hori">
+ <property name="label" translatable="yes" context="splitcellsdialog|hori">H_orizontally</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="vert">
+ <property name="label" translatable="yes" context="splitcellsdialog|vert">_Vertically</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">hori</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="prop">
+ <property name="label" translatable="yes" context="splitcellsdialog|prop">_Into equal proportions</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="margin-start">12</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">svx/res/zetlhor2.png</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">svx/res/zetlver2.png</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="splitcellsdialog|label2">Direction</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SplitCellsDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="splitcellsdialog|extended_tip|SplitCellsDialog">Splits the cell or group of cells horizontally or vertically into the number of cells that you enter.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/storedwebconnectiondialog.ui b/cui/uiconfig/ui/storedwebconnectiondialog.ui
new file mode 100644
index 000000000..59dc80b4d
--- /dev/null
+++ b/cui/uiconfig/ui/storedwebconnectiondialog.ui
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name text2 -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="StoredWebConnectionDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="storedwebconnectiondialog|StoredWebConnectionDialog">Stored Web Connection Information</property>
+ <property name="resizable">False</property>
+ <property name="type_hint">dialog</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="storedwebconnectiondialog|label1">Web login information (passwords are never shown)</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="logins">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="storedwebconnectiondialog|website">Website</property>
+ <property name="clickable">True</property>
+ <property name="sort_indicator">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="title" translatable="yes" context="storedwebconnectiondialog|username">User name</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="remove">
+ <property name="label" translatable="yes" context="stock">_Remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="removeall">
+ <property name="label" translatable="yes" context="storedwebconnectiondialog|removeall">Remove _All</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="change">
+ <property name="label" translatable="yes" context="storedwebconnectiondialog|change">_Change Password...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">close</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/swpossizepage.ui b/cui/uiconfig/ui/swpossizepage.ui
new file mode 100644
index 000000000..17ab225bf
--- /dev/null
+++ b/cui/uiconfig/ui/swpossizepage.ui
@@ -0,0 +1,679 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">0.05</property>
+ <property name="upper">99.99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">-99.99</property>
+ <property name="upper">99.99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">-99.99</property>
+ <property name="upper">99.99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">0.05</property>
+ <property name="upper">99.99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="SwPosSizePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkSpinButton" id="width">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="width-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|width">Enter the width that you want for the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="widthft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|widthft">_Width:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">width</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkSpinButton" id="height">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="height-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|height">Enter the height that you want for the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="heightft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|heightft">H_eight:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">height</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="ratio">
+ <property name="label" translatable="yes" context="swpossizepage|ratio">_Keep ratio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ratio-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|ratio">Maintains the height and width ratio when you change the width or the height setting.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|label2">Size</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="anchorframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="topage">
+ <property name="label" translatable="yes" context="swpossizepage|topage">To _page</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="topage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|topage">Anchors the selection to the current page.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="topara">
+ <property name="label" translatable="yes" context="swpossizepage|topara">To paragrap_h</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">topage</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="topara-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|topara">Anchors the selection to the current paragraph.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="tochar">
+ <property name="label" translatable="yes" context="swpossizepage|tochar">To cha_racter</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">topage</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="tochar-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|tochar">Anchors the selection to a character.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="aschar">
+ <property name="label" translatable="yes" context="swpossizepage|aschar">_As character</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">topage</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="aschar-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|aschar">Anchors the selection as character. The height of the current line is resized to match the height of the selection.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="toframe">
+ <property name="label" translatable="yes" context="swpossizepage|toframe">To _frame</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">topage</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|label1">Anchor</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="posframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="horiposft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|horiposft">Hori_zontal:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">horipos</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="horibyft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|horibyft">b_y:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">byhori</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="vertbyft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|vertbyft">_by:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">byvert</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="horitoft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|horitoft">_to:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">horianchor</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="byhori">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="byhori-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|byhori">Enter the amount of space to leave between the left edge of the selected object and the reference point that you select in the To box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="horianchor">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="horianchor-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|horianchor">Select the reference point for the selected horizontal alignment option.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">5</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="horipos">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="horipos-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|horipos">Select the horizontal alignment option for the object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="vertposft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|vertposft">_Vertical:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">vertpos</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="vertpos">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="vertpos-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|vertpos">Select the vertical alignment option for the object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="byvert">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="byvert-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|byvert">Enter the amount of space to leave between the top edge of the selected object and the reference point that you select in the To box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="verttoft">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|verttoft">t_o:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">vertanchor</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="vertanchor">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="vertanchor-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|vertanchor">Select the reference point for the selected vertical alignment option.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">5</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="mirror">
+ <property name="label" translatable="yes" context="swpossizepage|mirror">_Mirror on even pages</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">12</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="mirror-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|mirror">Reverses the current horizontal alignment settings on even pages.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="followtextflow">
+ <property name="label" translatable="yes" context="swpossizepage|followtextflow">Keep inside te_xt boundaries</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="margin-start">12</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="followtextflow-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|followtextflow">Keeps the selected object within the layout boundaries of the text that the object is anchored to. To place the selected object anywhere in your document, do not select this option.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">6</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|label11">Position</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">18</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="pos">
+ <property name="label" translatable="yes" context="swpossizepage|pos">Positio_n</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="size">
+ <property name="label" translatable="yes" context="swpossizepage|size">_Size</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="swpossizepage|label3">Protect</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="SwPosSizePage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="swpossizepage|extended_tip|SwPosSizePage">Specifies the size and the position of the selected object or frame on a page.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="widthft"/>
+ <widget name="heightft"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/textanimtabpage.ui b/cui/uiconfig/ui/textanimtabpage.ui
new file mode 100644
index 000000000..01e449dfc
--- /dev/null
+++ b/cui/uiconfig/ui/textanimtabpage.ui
@@ -0,0 +1,561 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentAMOUNT">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentCOUNT">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentDELAY">
+ <property name="upper">30000</property>
+ <property name="step-increment">50</property>
+ <property name="page-increment">500</property>
+ </object>
+ <object class="GtkImage" id="imageDOWN">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-down</property>
+ </object>
+ <object class="GtkImage" id="imageLEFT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-previous</property>
+ </object>
+ <object class="GtkImage" id="imageRIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-next</property>
+ </object>
+ <object class="GtkImage" id="imageUP">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-up</property>
+ </object>
+ <object class="GtkBox" id="TextAnimation">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkComboBoxText" id="LB_EFFECT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <items>
+ <item id="0" translatable="yes" context="textanimtabpage|liststoreEFFECT">No Effect</item>
+ <item id="1" translatable="yes" context="textanimtabpage|liststoreEFFECT">Blink</item>
+ <item id="2" translatable="yes" context="textanimtabpage|liststoreEFFECT">Scroll Through</item>
+ <item id="3" translatable="yes" context="textanimtabpage|liststoreEFFECT">Scroll Back and Forth</item>
+ <item id="4" translatable="yes" context="textanimtabpage|liststoreEFFECT">Scroll In</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_EFFECT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|LB_EFFECT">Select the animation effect that you want to apply to the text in the selected drawing object. To remove an animation effect, select No Effect.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxDIRECTION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="FT_DIRECTION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textanimtabpage|FT_DIRECTION">Direction:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">grid1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkToggleButton" id="BTN_UP">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="textanimtabpage|BTN_UP|tooltip_text">To top</property>
+ <property name="halign">center</property>
+ <property name="hexpand">True</property>
+ <property name="image">imageUP</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_UP-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="textanimtabpage|BTN_UP-atkobject">Up</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|BTN_UP">Scrolls text from bottom to top.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="BTN_RIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="textanimtabpage|BTN_RIGHT|tooltip_text">To right</property>
+ <property name="halign">center</property>
+ <property name="hexpand">True</property>
+ <property name="image">imageRIGHT</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_RIGHT-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="textanimtabpage|BTN_RIGHT-atkobject">Right</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|BTN_RIGHT">Scrolls text from left to right.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="BTN_LEFT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="textanimtabpage|BTN_LEFT|tooltip_text">To left</property>
+ <property name="halign">center</property>
+ <property name="hexpand">True</property>
+ <property name="image">imageLEFT</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_LEFT-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="textanimtabpage|BTN_LEFT-atkobject">Left</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|BTN_LEFT">Scrolls text from right to left.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="BTN_DOWN">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="tooltip_text" translatable="yes" context="textanimtabpage|BTN_DOWN|tooltip_text">To bottom</property>
+ <property name="halign">center</property>
+ <property name="hexpand">True</property>
+ <property name="image">imageDOWN</property>
+ <property name="always_show_image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="BTN_DOWN-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="textanimtabpage|BTN_DOWN-atkobject">Down</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|BTN_DOWN">Scrolls text from top to bottom.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="FT_EFFECTS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textanimtabpage|FT_EFFECTS">E_ffect</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_EFFECT</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_PROPERTIES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_START_INSIDE">
+ <property name="label" translatable="yes" context="textanimtabpage|TSB_START_INSIDE">S_tart inside</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_START_INSIDE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|TSB_START_INSIDE">Text is visible and inside the drawing object when the effect is applied.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_STOP_INSIDE">
+ <property name="label" translatable="yes" context="textanimtabpage|TSB_STOP_INSIDE">Text _visible when exiting</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_STOP_INSIDE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|TSB_STOP_INSIDE">Text remains visible after the effect is applied.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_COUNT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textanimtabpage|FT_COUNT">Animation cycles:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxCOUNT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_ENDLESS">
+ <property name="label" translatable="yes" context="textanimtabpage|TSB_ENDLESS">_Continuous</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="NUM_FLD_COUNT"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_ENDLESS-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|TSB_ENDLESS">Plays the animation effect continuously. To specify the number of times to play the effect, clear this checkbox, and enter a number in the Continuous box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="NUM_FLD_COUNT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentCOUNT</property>
+ <accessibility>
+ <relation type="labelled-by" target="TSB_ENDLESS"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="NUM_FLD_COUNT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|NUM_FLD_COUNT">Enter the number of times that you want the animation effect to repeat.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_AMOUNT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textanimtabpage|FT_AMOUNT">Increment:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxAMOUNT">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_PIXEL">
+ <property name="label" translatable="yes" context="textanimtabpage|TSB_PIXEL">_Pixels</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="MTR_FLD_AMOUNT"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_PIXEL-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|TSB_PIXEL">Measures increment value in pixels.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_AMOUNT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentAMOUNT</property>
+ <accessibility>
+ <relation type="labelled-by" target="TSB_PIXEL"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_AMOUNT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|MTR_FLD_AMOUNT">Enter the number of increments by which to scroll the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_DELAY">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textanimtabpage|FT_DELAY">Delay:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxDELAY">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin-start">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTO">
+ <property name="label" translatable="yes" context="textanimtabpage|TSB_AUTO">_Automatic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="MTR_FLD_DELAY"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTO-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|TSB_AUTO">Automatically determine the amount of time to wait before repeating the effect. To manually assign the delay period, clear this checkbox, and then enter a value in the Automatic box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_DELAY">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentDELAY</property>
+ <accessibility>
+ <relation type="labelled-by" target="TSB_AUTO"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_DELAY-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|MTR_FLD_DELAY">Enter the amount of time to wait before repeating the effect.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textanimtabpage|label2">Properties</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TextAnimation-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textanimtabpage|extended_tip|TextAnimation">Adds an animation effect to the text in the selected drawing object.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup">
+ <widgets>
+ <widget name="NUM_FLD_COUNT"/>
+ <widget name="MTR_FLD_AMOUNT"/>
+ <widget name="MTR_FLD_DELAY"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="TSB_ENDLESS"/>
+ <widget name="TSB_PIXEL"/>
+ <widget name="TSB_AUTO"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/textattrtabpage.ui b/cui/uiconfig/ui/textattrtabpage.ui
new file mode 100644
index 000000000..610a59c72
--- /dev/null
+++ b/cui/uiconfig/ui/textattrtabpage.ui
@@ -0,0 +1,509 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">-100</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">-100</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="lower">-100</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">-100</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkBox" id="TextAttributesPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkFrame" id="drawingtext">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOGROW_WIDTH">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_AUTOGROW_WIDTH">Fit wi_dth to text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOGROW_WIDTH-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_AUTOGROW_WIDTH">Expands the width of the object to the width of the text, if the object is smaller than the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOGROW_HEIGHT">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_AUTOGROW_HEIGHT">Fit h_eight to text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOGROW_HEIGHT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_AUTOGROW_HEIGHT">Expands the height of the object to the height of the text, if the object is smaller than the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_FIT_TO_SIZE">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_FIT_TO_SIZE">_Fit to frame</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_FIT_TO_SIZE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_FIT_TO_SIZE">Resizes the text to fit the entire area of the drawing or text object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_CONTOUR">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_CONTOUR">_Adjust to contour</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_CONTOUR-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_CONTOUR">Adapts the text flow so that it matches the contours of the selected drawing object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label1">Drawing Object Text</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="customshapetext">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="TSB_WORDWRAP_TEXT">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_WORDWRAP_TEXT">_Word wrap text in shape</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_WORDWRAP_TEXT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_WORDWRAP_TEXT">Wraps the text that you add after double-clicking a custom shape to fit inside the shape.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_AUTOGROW_SIZE">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_AUTOGROW_SIZE">_Resize shape to fit text</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_AUTOGROW_SIZE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_AUTOGROW_SIZE">Resizes a custom shape to fit the text that you enter after double-clicking the shape.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label8">Custom Shape Text</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkFrame" id="FL_DISTANCE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label4">_Left:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_LEFT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label5">_Right:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_RIGHT</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label6">_Top:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_TOP</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label7">_Bottom:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_FLD_BOTTOM</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_LEFT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_LEFT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|MTR_FLD_LEFT">Enter the amount of space to leave between the left edge of the drawing or text object and the left border of the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_RIGHT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_RIGHT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|MTR_FLD_RIGHT">Enter the amount of space to leave between the right edge of the drawing or text object and the right border of the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_TOP">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_TOP-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|MTR_FLD_TOP">Enter the amount of space to leave between the top edge of the drawing or text object and the upper border of the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_BOTTOM">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="digits">2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_BOTTOM-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|MTR_FLD_BOTTOM">Enter the amount of space to leave between the bottom edge of the drawing or text object and the lower border of the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label2">Spacing to Borders</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FL_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_POSITION">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_POSITION-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|CTL_POSITION">Click where you want to place the anchor for the text.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="TSB_FULL_WIDTH">
+ <property name="label" translatable="yes" context="textattrtabpage|TSB_FULL_WIDTH">Full _width</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TSB_FULL_WIDTH-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TSB_FULL_WIDTH">Anchors the text to the full width of the drawing object or text object.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textattrtabpage|label3">Text Anchor</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TextAttributesPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textattrtabpage|extended_tip|TextAttributesPage">Sets the layout and anchoring properties for text in the selected drawing or text object.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/textcolumnstabpage.ui b/cui/uiconfig/ui/textcolumnstabpage.ui
new file mode 100644
index 000000000..6fae67f9a
--- /dev/null
+++ b/cui/uiconfig/ui/textcolumnstabpage.ui
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentColNumber">
+ <property name="lower">1</property>
+ <!-- MSO has an upper limit of 16 in UI -->
+ <property name="upper">16</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentColSpacing">
+ <property name="lower">0</property>
+ <property name="upper">2147483647</property>
+ <property name="step-increment">1</property>
+ <property name="page-increment">10</property>
+ </object>
+ <object class="GtkBox" id="TextColumnsPage">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <!-- n-columns=2 n-rows=2 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="labelColNumber">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="textcolumnstabpage|labelColNumber">_Number of columns:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">FLD_COL_NUMBER</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelColSpacing">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="textcolumnstabpage|labelColSpacing">_Spacing:</property>
+ <property name="use-underline">True</property>
+ <property name="mnemonic-widget">MTR_FLD_COL_SPACING</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="FLD_COL_NUMBER">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentColNumber</property>
+ <property name="value">1</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="FLD_COL_NUMBER-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textcolumnstabpage|extended_tip|FLD_COL_NUMBER">Enter the number of columns to use for the text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_FLD_COL_SPACING">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="adjustment">adjustmentColSpacing</property>
+ <property name="digits">2</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_FLD_COL_SPACING-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textcolumnstabpage|extended_tip|MTR_FLD_COL_SPACING">Enter the amount of space to leave between the columns.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TextColumnsPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textcolumnstabpage|extended_tip|TextColumnsPage">Sets the columns’ layout properties for text in the selected drawing or text object.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/textdialog.ui b/cui/uiconfig/ui/textdialog.ui
new file mode 100644
index 000000000..6cde38354
--- /dev/null
+++ b/cui/uiconfig/ui/textdialog.ui
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.4 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="TextDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="textdialog|TextDialog">Text</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="reset">
+ <property name="label" translatable="yes" context="stock">_Reset</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="tabcontrol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="scrollable">True</property>
+ <property name="enable_popup">True</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_TEXTATTR">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textdialog|RID_SVXPAGE_TEXTATTR">Text</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_TEXTANIMATION">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textdialog|RID_SVXPAGE_TEXTANIMATION">Text Animation</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="RID_SVXPAGE_TEXTCOLUMNS">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textdialog|RID_SVXPAGE_TEXTCOLUMNS">Text Columns</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="101">reset</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/textflowpage.ui b/cui/uiconfig/ui/textflowpage.ui
new file mode 100644
index 000000000..1be6c0422
--- /dev/null
+++ b/cui/uiconfig/ui/textflowpage.ui
@@ -0,0 +1,728 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">9</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">99</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">55535</property>
+ <property name="value">1</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment4">
+ <property name="lower">1</property>
+ <property name="upper">9</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment5">
+ <property name="lower">2</property>
+ <property name="upper">9</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment6">
+ <property name="lower">2</property>
+ <property name="upper">9</property>
+ <property name="value">2</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment7">
+ <property name="lower">4</property>
+ <property name="upper">99</property>
+ <property name="value">4</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment8">
+ <property name="upper">55.88</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="TextFlowPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="FrameHyphenation">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_EXPOSURE_MASK</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkAuto">
+ <property name="label" translatable="yes" context="textflowpage|checkAuto">A_utomatically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkAuto-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkAuto">Automatically inserts hyphens where they are needed in a paragraph.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMinLen">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="margin-start">25</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment7</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinMinLen-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinMinLen">Enter the minimum word length in characters that can be hyphenated.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinMaxNum">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="margin-start">25</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinMaxNum-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinMaxNum">Enter the maximum number of consecutive lines that can be hyphenated.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinLineBegin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="margin-start">25</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment4</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinLineBegin-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinLineBegin">Enter the minimum number of characters that must appear at the beginning of the line after the hyphen.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinLineEnd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="margin-start">25</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinLineEnd-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinLineEnd">Enter the minimum number of characters to leave at the end of the line before a hyphen is inserted.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelLineEnd">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="textflowpage|labelLineEnd">C_haracters at line end</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinLineEnd</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelLineBegin">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="textflowpage|labelLineBegin">Cha_racters at line begin</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinLineBegin</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelMaxNum">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="textflowpage|labelMaxNum">_Maximum consecutive hyphenated lines</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinMaxNum</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelMinLen">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes" context="textflowpage|labelMinLen">_Minimum word length in characters</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinMinLen</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkNoCaps">
+ <property name="label" translatable="yes" context="textflowpage|checkNoCaps">Don't hyphenate words in _CAPS</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkNoLastWord">
+ <property name="label" translatable="yes" context="textflowpage|checkNoLastWord">Don't hyphenate the last word</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="gridHyphenZone">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkSpinButton" id="spinHyphenZone">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="adjustment">adjustment8</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelHyphenZone">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|labelHyphenZone">Hyphenation _zone:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinHyphenZone</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="LabelHyphenation">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|LabelHyphenation">Hyphenation</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frameBreaks">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">3</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkInsert">
+ <property name="label" translatable="yes" context="textflowpage|checkInsert">_Insert</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkInsert-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkInsert">Select this check box, and then select the break type that you want to use.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkPageStyle">
+ <property name="label" translatable="yes" context="textflowpage|checkPageStyle">With page st_yle:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="comboPageStyle"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkPageStyle-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkPageStyle">Select this check box, and then select the page style that you want to use for the first page after the break.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelType">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|labelType">_Type:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">comboBreakType</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinPageNumber">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment3</property>
+ <accessibility>
+ <relation type="labelled-by" target="labelPageNum"/>
+ </accessibility>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinPageNumber-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinPageNumber">Enter the page number for the first page that follows the break. If you want to continue the current page numbering, leave the checkbox unchecked.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="labelPageNum">
+ <property name="label" translatable="yes" context="textflowpage|labelPageNum">Page _number:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="spinPageNumber"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelPosition">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|labelPosition">Position:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">comboBreakPosition</property>
+ <property name="xalign">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboPageStyle">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <accessibility>
+ <relation type="labelled-by" target="checkPageStyle"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="comboPageStyle-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="textflowpage|comboPageStyle-atkobject">Page Style</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|comboPageStyle">Select the formatting style to use for the first page after the break.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboBreakType">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="textflowpage|comboBreakType">Page</item>
+ <item translatable="yes" context="textflowpage|comboBreakType">Column</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="comboBreakType-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|comboBreakType">Select the break type that you want to insert.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="comboBreakPosition">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="textflowpage|comboBreakPosition">Before</item>
+ <item translatable="yes" context="textflowpage|comboBreakPosition">After</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="comboBreakPosition-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|comboBreakPosition">Select where you want to insert the break.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|label3">Breaks</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="FrameOptions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="gridOptions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkSplitPara">
+ <property name="label" translatable="yes" context="textflowpage|checkSplitPara">_Do not split paragraph</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkSplitPara-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkSplitPara">Shifts the entire paragraph to the next page or column after a break is inserted.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkKeepPara">
+ <property name="label" translatable="yes" context="textflowpage|checkKeepPara">_Keep with next paragraph</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkKeepPara-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkKeepPara">Keeps the current paragraph and the following paragraph together when a break or column break is inserted.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkOrphan">
+ <property name="label" translatable="yes" context="textflowpage|checkOrphan">_Orphan control</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="spinOrphan"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkOrphan-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkOrphan">Specifies the minimum number of lines in a paragraph before a page break. Select this check box, and then enter a number in the Lines box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkWidow">
+ <property name="label" translatable="yes" context="textflowpage|checkWidow">_Widow control</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="inconsistent">True</property>
+ <property name="draw_indicator">True</property>
+ <accessibility>
+ <relation type="label-for" target="spinWidow"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="checkWidow-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|checkWidow">Specifies the minimum number of lines in a paragraph in the first page after the break. Select this check box, and then enter a number in the Lines box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinOrphan">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment5</property>
+ <accessibility>
+ <relation type="labelled-by" target="checkOrphan"/>
+ </accessibility>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinOrphan-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinOrphan">Specifies the minimum number of lines in a paragraph before a page break. Select this check box, and then enter a number in the Lines box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spinWidow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment6</property>
+ <property name="numeric">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="checkWidow"/>
+ </accessibility>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="spinWidow-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|spinWidow">Specifies the minimum number of lines in a paragraph in the first page after the break. Select this check box, and then enter a number in the Lines box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelOrphan">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|labelOrphan">lines</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labelWidow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|labelWidow">lines</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="labelOptions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="textflowpage|labelOptions">Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TextFlowPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="textflowpage|extended_tip|TextFlowPage">Specify hyphenation and pagination options.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/themetabpage.ui b/cui/uiconfig/ui/themetabpage.ui
new file mode 100644
index 000000000..67888c47c
--- /dev/null
+++ b/cui/uiconfig/ui/themetabpage.ui
@@ -0,0 +1,557 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkBox" id="ThemePage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frmGeneral">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkGrid" id="gdGeneral">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="lbThemeName">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbThemeName">Name:</property>
+ <accessibility>
+ <relation type="label-for" target="themeName"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="themeName">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbThemeName"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="general">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|general">General</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frmColors">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkGrid" id="gdColors">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="lbColorSetName">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbColorSetName">Name:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="colorSetName"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="colorSetName">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="lbColorSetName"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbDk1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbDk1">Background - Dark 1:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnDk1"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbLt1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbLt1">Text - Light 1:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnLt1"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbDk2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbDk2">Background - Dark 2:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnDk2"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbLt2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbLt2">Text - Light 2:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnLt2"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAccent1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbAccent1">Accent 1:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnAccent1"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAccent2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbAccent2">Accent 2:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnAccent2"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAccent3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbAccent3">Accent 3:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnAccent3"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAccent4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbAccent4">Accent 4:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnAccent4"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAccent5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbAccent5">Accent 5:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnAccent5"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbAccent6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbAccent6">Accent 6:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnAccent6"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbHlink">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbHlink">Hyperlink:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnHlink"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbFolHlink">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|lbFolHlink">Followed Hyperlink:</property>
+ <property name="xalign">0</property>
+ <accessibility>
+ <relation type="label-for" target="btnFolHlink"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnDk1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbDk1"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnLt1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbLt1"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnDk2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbDk2"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnLt2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbLt2"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnAccent1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbAccent1"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnAccent2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbAccent2"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnAccent3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbAccent3"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnAccent4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbAccent4"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnAccent5">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbAccent5"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnAccent6">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbAccent6"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnHlink">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbHlink"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="btnFolHlink">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="no"></property>
+ <child>
+ <placeholder/>
+ </child>
+ <accessibility>
+ <relation type="labelled-by" target="lbFolHlink"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">12</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="colorSet">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="themetabpage|colorSet">Color Set</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/thesaurus.ui b/cui/uiconfig/ui/thesaurus.ui
new file mode 100644
index 000000000..fbd890635
--- /dev/null
+++ b/cui/uiconfig/ui/thesaurus.ui
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-previous</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore3">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name weight1 -->
+ <column type="gint"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="ThesaurusDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="thesaurus|ThesaurusDialog">Thesaurus</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="thesaurus|replace">_Replace</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="thesaurus|label1">Current word:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">wordcb</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="thesaurus|label2">Alternatives:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">alternatives</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="thesaurus|label3">Replace with:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">replaceed</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="replaceed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="replaceed-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="thesaurus|extended_tip|replaceed">The word or words in the "Replace with" text box will replace the original word in the document when you click the Replace button. You can also type text directly in this box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="left">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="left-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="thesaurus|extended_tip|left">Recalls the previous contents of the "Current word" text box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="langcb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="langcb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="thesaurus|extended_tip|langcb">Select a language for the thesaurus.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="wordcb">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="has_entry">True</property>
+ <child internal-child="entry">
+ <object class="GtkEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="activates_default">True</property>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="wordcb-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="thesaurus|extended_tip|wordcb">Displays the current word, or the related term that you selected by double-clicking a line in the Alternatives list. You can also type text directly in this box to look up your text.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="width_request">450</property>
+ <property name="height_request">250</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="alternatives">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore3</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ <attribute name="weight">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="alternatives-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="thesaurus|extended_tip|alternatives">Click an entry in the Alternatives list to copy the related term to the "Replace with" text box. Double-click an entry to copy the related term to the "Current word" text box and to look up that term.</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="notfound">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label" translatable="yes" context="thesaurus|RID_SVXSTR_ERR_TEXTNOTFOUND">No alternatives found.</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ThesaurusDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="thesaurus|extended_tip|ThesaurusDialog">Opens a dialog box to replace the current word with a synonym, or a related term.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/tipofthedaydialog.ui b/cui/uiconfig/ui/tipofthedaydialog.ui
new file mode 100644
index 000000000..2ea58ad3b
--- /dev/null
+++ b/cui/uiconfig/ui/tipofthedaydialog.ui
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="TipOfTheDayDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="TipOfTheDayDialog|Name">Tip of the Day</property>
+ <property name="resizable">False</property>
+ <property name="modal">False</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkCheckButton" id="cbShowTip">
+ <property name="label" translatable="yes" context="TipOfTheDay|Checkbox">_Show tips on startup</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="tooltip-text" translatable="yes" context="TipOfTheDay|Checkbox_Tooltip">Enable the dialog again at Tools ▸ Options ▸ General, or Help ▸ Show Tip of the Day</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnNext">
+ <property name="label" translatable="yes" context="TipOfTheDayDialog|Next_Button">_Next Tip</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnOk">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="has-focus">True</property>
+ <property name="is-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="imPreview">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">12</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="lbTitle">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-top">12</property>
+ <property name="label" translatable="yes" context="TipOfTheDayDialog|Title">Did you know?</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.5"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lbText">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="wrap">True</property>
+ <property name="width-chars">50</property>
+ <property name="max-width-chars">50</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="btnLink">
+ <property name="label" translatable="yes" context="TipOfTheDayDialog|Link_Button">Link</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">btnOk</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/toolbarmodedialog.ui b/cui/uiconfig/ui/toolbarmodedialog.ui
new file mode 100644
index 000000000..d401f75ed
--- /dev/null
+++ b/cui/uiconfig/ui/toolbarmodedialog.ui
@@ -0,0 +1,391 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkImage" id="imgApply">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="icon-name">sw/res/sc20558.png</property>
+ </object>
+ <object class="GtkDialog" id="ToolbarmodeDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="ToolbarmodeDialog|Name">Select Your Preferred User Interface</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area">
+ <property name="can-focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="btnApplyAll">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|applyall">A_pply to All</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnApply">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|applymodule">A_pply to %MODULE</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="image">imgApply</property>
+ <property name="use-underline">True</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="has-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack-type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkRadioButton" id="rbButton1">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton1">Standard Toolbar</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton2">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton2">Tabbed</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton3">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton3">Single Toolbar</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton4">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton4">Sidebar</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton5">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton5">Tabbed Compact</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton6">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton6">Groupedbar</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton7">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton7">Groupedbar Compact</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton8">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton8">Contextual Single</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbButton9">
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|radiobutton9">Contextual Groups</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="draw-indicator">True</property>
+ <property name="group">rbButton1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">9</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|leftframe">UI variants</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <property name="label-xalign">0</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="baseline-position">top</property>
+ <child>
+ <object class="GtkImage" id="imImage">
+ <property name="height-request">125</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="icon-name">missing-image</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="width-request">436</property>
+ <property name="height-request">100</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkLabel" id="lbInfo">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="valign">start</property>
+ <property name="vexpand">True</property>
+ <property name="label">Information:</property>
+ <property name="wrap">True</property>
+ <property name="wrap-mode">word-char</property>
+ <property name="max-width-chars">50</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes" context="ToolbarmodeDialog|rightframe">Preview</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">btnApplyAll</action-widget>
+ <action-widget response="-5">btnApply</action-widget>
+ <action-widget response="-7">close</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/transparencytabpage.ui b/cui/uiconfig/ui/transparencytabpage.ui
new file mode 100644
index 000000000..c5c9a014c
--- /dev/null
+++ b/cui/uiconfig/ui/transparencytabpage.ui
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustmentDegrees">
+ <property name="upper">359</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent1">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent2">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent3">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent4">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustmentPercent5">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkFrame" id="TransparencyTabPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">18</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="RBT_TRANS_OFF">
+ <property name="label" translatable="yes" context="transparencytabpage|RBT_TRANS_OFF">_No transparency</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="RBT_TRANS_OFF-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|RBT_TRANS_OFF">Turns off color transparency.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RBT_TRANS_LINEAR">
+ <property name="label" translatable="yes" context="transparencytabpage|RBT_TRANS_LINEAR">_Transparency:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">RBT_TRANS_OFF</property>
+ <accessibility>
+ <relation type="label-for" target="MTR_TRANSPARENT"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="RBT_TRANS_LINEAR-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|RBT_TRANS_LINEAR">Turns on color transparency. Select this option, and then enter a number in the box, where 0% is fully opaque and 100% is fully transparent.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="RBT_TRANS_GRADIENT">
+ <property name="label" translatable="yes" context="transparencytabpage|RBT_TRANS_GRADIENT">_Gradient</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">RBT_TRANS_OFF</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="RBT_TRANS_GRADIENT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|RBT_TRANS_GRADIENT">Applies a transparency gradient to the current fill color. Select this option, and then set the gradient properties.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRANSPARENT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent</property>
+ <accessibility>
+ <relation type="labelled-by" target="RBT_TRANS_LINEAR"/>
+ </accessibility>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRANSPARENT-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRANSPARENT">Adjusts the transparency of the current fill color. Enter a number between 0% (opaque) and 100% (transparent).</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="gridGradient">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRGR_END_VALUE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent5</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRGR_END_VALUE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRGR_END_VALUE">Enter a transparency value for the endpoint of the gradient, where 0% is fully opaque and 100% is fully transparent.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRGR_START_VALUE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent4</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRGR_START_VALUE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRGR_START_VALUE">Enter a transparency value for the beginning point of the gradient, where 0% is fully opaque and 100% is fully transparent.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRGR_BORDER">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent3</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRGR_BORDER-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRGR_BORDER">Enter the amount by which you want to adjust the transparent area of the gradient. The default value is 0%.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRGR_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentDegrees</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRGR_ANGLE-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRGR_ANGLE">Enter a rotation angle for the gradient.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRGR_CENTER_Y">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent2</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRGR_CENTER_Y-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRGR_CENTER_Y">Enter the vertical offset for the gradient.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="MTR_TRGR_CENTER_X">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustmentPercent1</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="MTR_TRGR_CENTER_X-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|MTR_TRGR_CENTER_X">Enter the horizontal offset for the gradient.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="LB_TRGR_GRADIENT_TYPES">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <items>
+ <item translatable="yes" context="transparencytabpage|liststoreTYPE">Linear</item>
+ <item translatable="yes" context="transparencytabpage|liststoreTYPE">Axial</item>
+ <item translatable="yes" context="transparencytabpage|liststoreTYPE">Radial</item>
+ <item translatable="yes" context="transparencytabpage|liststoreTYPE">Ellipsoid</item>
+ <item translatable="yes" context="transparencytabpage|liststoreTYPE">Quadratic</item>
+ <item translatable="yes" context="transparencytabpage|liststoreTYPE">Square</item>
+ </items>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="LB_TRGR_GRADIENT_TYPES-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|LB_TRGR_GRADIENT_TYPES">Select the type of transparency gradient that you want to apply.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_TYPE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_TYPE">Ty_pe:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">LB_TRGR_GRADIENT_TYPES</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_CENTER_X">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_CENTER_X">Center _X:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_TRGR_CENTER_X</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_CENTER_Y">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_CENTER_Y">Center _Y:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_TRGR_CENTER_Y</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_ANGLE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_ANGLE">_Angle:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_TRGR_ANGLE</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_BORDER">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_BORDER">_Border:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_TRGR_BORDER</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_START_VALUE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_START_VALUE">_Start value:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_TRGR_START_VALUE</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="FT_TRGR_END_VALUE">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FT_TRGR_END_VALUE">_End value:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">MTR_TRGR_END_VALUE</property>
+ <property name="xalign">1</property>
+ <property name="margin-start">12</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin-end">12</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="bitmap_border">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_IMAGE_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_IMAGE_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="transparencytabpage|CTL_IMAGE_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="trans_border">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="CTL_TRANS_PREVIEW">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="CTL_TRANS_PREVIEW-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="transparencytabpage|CTL_TRANS_PREVIEW-atkobject">Example</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="FL_PROP">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="transparencytabpage|FL_PROP">Area Transparency Mode</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="TransparencyTabPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="transparencytabpage|extended_tip|TransparencyTabPage">Set the transparency options for the fill that you apply to the selected object.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup2">
+ <property name="mode">both</property>
+ <property name="ignore_hidden">True</property>
+ <widgets>
+ <widget name="MTR_TRANSPARENT"/>
+ <widget name="MTR_TRGR_END_VALUE"/>
+ <widget name="MTR_TRGR_START_VALUE"/>
+ <widget name="MTR_TRGR_BORDER"/>
+ <widget name="MTR_TRGR_ANGLE"/>
+ <widget name="MTR_TRGR_CENTER_Y"/>
+ <widget name="MTR_TRGR_CENTER_X"/>
+ <widget name="LB_TRGR_GRADIENT_TYPES"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup3">
+ <property name="mode">both</property>
+ <property name="ignore_hidden">True</property>
+ <widgets>
+ <widget name="box1"/>
+ <widget name="box3"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup4">
+ <widgets>
+ <widget name="RBT_TRANS_OFF"/>
+ <widget name="RBT_TRANS_LINEAR"/>
+ <widget name="RBT_TRANS_GRADIENT"/>
+ <widget name="FT_TRGR_TYPE"/>
+ <widget name="FT_TRGR_CENTER_X"/>
+ <widget name="FT_TRGR_CENTER_Y"/>
+ <widget name="FT_TRGR_ANGLE"/>
+ <widget name="FT_TRGR_BORDER"/>
+ <widget name="FT_TRGR_START_VALUE"/>
+ <widget name="FT_TRGR_END_VALUE"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/tsaurldialog.ui b/cui/uiconfig/ui/tsaurldialog.ui
new file mode 100644
index 000000000..26f4aad0e
--- /dev/null
+++ b/cui/uiconfig/ui/tsaurldialog.ui
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkDialog" id="TSAURLDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="tsaurldialog|TSAURLDialog">Time Stamping Authority URLs</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">normal</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="stock">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="label" translatable="yes" context="tsaurldialog|add">_Add...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">6</property>
+ <property name="label" translatable="yes" context="tsaurldialog|label2">Add or delete Time Stamp Authority URLs</property>
+ <property name="use_underline">True</property>
+ <property name="wrap">True</property>
+ <property name="max_width_chars">60</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="urls">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <child>
+ <object class="GtkLabel" id="enteraurl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes" context="tsaurldialog|enteraurl">Enter a Time Stamp Authority URL</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="tsaurldialog|label1">TSA URL</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">help</action-widget>
+ <action-widget response="101">delete</action-widget>
+ <action-widget response="102">add</action-widget>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/twolinespage.ui b/cui/uiconfig/ui/twolinespage.ui
new file mode 100644
index 000000000..79602dc71
--- /dev/null
+++ b/cui/uiconfig/ui/twolinespage.ui
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="TwoLinesPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkCheckButton" id="twolines">
+ <property name="label" translatable="yes" context="twolinespage|twolines">Write in double lines</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="twolinespage|label2">Double-lined</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="enclosing">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="column_spacing">6</property>
+ <property name="column_homogeneous">True</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkLabel" id="label29">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="twolinespage|label29">Initial character</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label30">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="twolinespage|label30">Final character</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="startbracket">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection1"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="endbracket">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection2"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label28">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="twolinespage|label28">Enclosing Characters</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <property name="margin-end">12</property>
+ <property name="valign">end</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="preview">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="preview-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="twolinespage|preview-atkobject">Preview</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/wordcompletionpage.ui b/cui/uiconfig/ui/wordcompletionpage.ui
new file mode 100644
index 000000000..d77e2c4f8
--- /dev/null
+++ b/cui/uiconfig/ui/wordcompletionpage.ui
@@ -0,0 +1,429 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">50</property>
+ <property name="upper">65535</property>
+ <property name="value">500</property>
+ <property name="step_increment">25</property>
+ <property name="page_increment">100</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="lower">5</property>
+ <property name="upper">100</property>
+ <property name="value">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="WordCompletionPage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="wordcompletion">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="wordcompletionpage|wordcompletion">Word Completion</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="enablewordcomplete">
+ <property name="label" translatable="yes" context="wordcompletionpage|enablewordcomplete">Enable word _completion</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="enablewordcomplete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|enablewordcomplete">Stores frequently used words, and automatically completes a word after you type three letters that match the first three letters of a stored word.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid41">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkCheckButton" id="appendspace">
+ <property name="label" translatable="yes" context="wordcompletionpage|appendspace">_Append space</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="appendspace-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|appendspace">If you do not add punctuation after the word then a space is added automatically.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="showastip">
+ <property name="label" translatable="yes" context="wordcompletionpage|showastip">_Show as tip</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="showastip-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|showastip">Displays the completed word as a Help Tip.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="margin-start">18</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="wordcompletionpage|label2">Mi_n. word length:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">maxentries</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="minwordlen">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="text">100</property>
+ <property name="adjustment">adjustment2</property>
+ <property name="value">100</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="minwordlen-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|minwordlen">Enter the minimum word length for a word to become eligible for the word completion feature.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="wordcompletionpage|label1">_Max. entries:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">maxentries</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="maxentries">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="text">500</property>
+ <property name="adjustment">adjustment1</property>
+ <property name="value">500</property>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="maxentries-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|maxentries">Enter the maximum number of words that you want to store in the Word Completion list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="wordcompletionpage|label3">Acc_ept with:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">acceptwith</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="acceptwith">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="acceptwith-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|acceptwith">Select the key that you want to use to accept the automatic word completion.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=1 n-rows=1 -->
+ <object class="GtkGrid" id="grid3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="collectedwords">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="acorreplacepage|collectedwords">Collected Words</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="entries">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entries-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|entries">Lists the collected words. The list is valid until you close the current document. To make the list available to other documents in the current session, disable "When closing a document, remove the words collected from it from the list".</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="whenclosing">
+ <property name="label" translatable="yes" context="wordcompletionpage|whenclosing">_When closing a document, remove the words collected from it from the list</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="whenclosing-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|whenclosing">When enabled, the list gets cleared when closing the current document. When disabled, makes the current Word Completion list available to other documents after you close the current document. The list remains available until you exit office suite.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkCheckButton" id="collectwords">
+ <property name="label" translatable="yes" context="wordcompletionpage|collectwords">C_ollect words</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="collectwords-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|collectwords">Adds the frequently used words to a list. To remove a word from the Word Completion list, select the word, and then click Delete Entry.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="label" translatable="yes" context="wordcompletionpage|delete">_Delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="delete-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|delete">Removes the selected word or words from the Word Completion list.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="WordCompletionPage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="wordcompletionpage|extended_tip|WordCompletionPage">Stores frequently used words, and automatically completes a word after you type three letters that match the first three letters of a stored word.</property>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <widgets>
+ <widget name="minwordlen"/>
+ <widget name="maxentries"/>
+ <widget name="acceptwith"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/cui/uiconfig/ui/zoomdialog.ui b/cui/uiconfig/ui/zoomdialog.ui
new file mode 100644
index 000000000..b9ca90236
--- /dev/null
+++ b/cui/uiconfig/ui/zoomdialog.ui
@@ -0,0 +1,450 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.36.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="lower">1</property>
+ <property name="upper">999</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkDialog" id="ZoomDialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="zoomdialog|ZoomDialog">Zoom &amp; View Layout</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="default_width">0</property>
+ <property name="default_height">0</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help">
+ <property name="label" translatable="yes" context="stock">_Help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="optimal">
+ <property name="label" translatable="yes" context="zoomdialog|optimal">Optimal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="optimal-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|optimal">Resizes the display to fit the width of the text in the document at the moment the command is started.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="fitwandh">
+ <property name="label" translatable="yes" context="zoomdialog|fitwandh">Fit width and height</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">optimal</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fitwandh-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|fitwandh">Displays the entire page on your screen.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="fitw">
+ <property name="label" translatable="yes" context="zoomdialog|fitw">Fit width</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">optimal</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="fitw-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|fitw">Displays the complete width of the document page. The top and bottom edges of the page may not be visible.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="100pc">
+ <property name="label" translatable="yes" context="zoomdialog|100pc">100%</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">optimal</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="100pc-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|100pc">Displays the document at its actual size.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="variable">
+ <property name="label" translatable="yes" context="zoomdialog|variable">Variable:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">optimal</property>
+ <accessibility>
+ <relation type="label-for" target="zoomsb"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="variable-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|variable">Enter the zoom factor at which you want to display the document. Enter a percentage in the box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="zoomsb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment2</property>
+ <accessibility>
+ <relation type="labelled-by" target="variable"/>
+ </accessibility>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="zoomsb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="zoomdialog|zoomsb-atkobject">Variable</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|zoomsb">Enter the zoom factor at which you want to display the document. Enter a percentage in the box.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="zoomdialog|label2">Zoom Factor</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="viewframe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">6</property>
+ <child>
+ <object class="GtkRadioButton" id="automatic">
+ <property name="label" translatable="yes" context="zoomdialog|automatic">Automatic</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="automatic-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|automatic">The automatic view layout displays pages side by side, as many as the zoom factor allows.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="singlepage">
+ <property name="label" translatable="yes" context="zoomdialog|singlepage">Single page</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">automatic</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="singlepage-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|singlepage">The single page view layout displays pages beneath each other, but never side by side.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkRadioButton" id="columns">
+ <property name="label" translatable="yes" context="zoomdialog|columns">Columns:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">automatic</property>
+ <accessibility>
+ <relation type="label-for" target="columnssb"/>
+ <relation type="label-for" target="bookmode"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="columns-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|columns">In columns view layout you see pages in a given number of columns side by side. Enter the number of columns.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="columnssb">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="adjustment">adjustment1</property>
+ <accessibility>
+ <relation type="labelled-by" target="columns"/>
+ </accessibility>
+ <property name="truncate-multiline">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="columnssb-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" context="zoomdialog|columnssb-atkobject">Columns</property>
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|columnssb">In columns view layout you see pages in a given number of columns side by side. Enter the number of columns.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="bookmode">
+ <property name="label" translatable="yes" context="zoomdialog|bookmode">Book mode</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="margin-start">12</property>
+ <accessibility>
+ <relation type="labelled-by" target="columns"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="bookmode-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|bookmode">In book mode view layout you see two pages side by side as in an open book. The first page is a right page with an odd page number.</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" context="zoomdialog|label1">View Layout</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">ok</action-widget>
+ <action-widget response="-6">cancel</action-widget>
+ <action-widget response="-11">help</action-widget>
+ </action-widgets>
+ <child type="titlebar">
+ <placeholder/>
+ </child>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="ZoomDialog-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="zoomdialog|extended_tip|ZoomDialog">Reduces or enlarges the screen display.</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/cui/util/cui.component b/cui/util/cui.component
new file mode 100644
index 000000000..1be360dcd
--- /dev/null
+++ b/cui/util/cui.component
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.cui.ColorPicker"
+ constructor="com_sun_star_cui_ColorPicker_get_implementation">
+ <service name="com.sun.star.ui.dialogs.ColorPicker"/>
+ </implementation>
+ <implementation name="com.sun.star.cui.AsynchronousColorPicker"
+ constructor="com_sun_star_cui_ColorPicker_get_implementation">
+ <service name="com.sun.star.ui.dialogs.AsynchronousColorPicker"/>
+ </implementation>
+</component>