summaryrefslogtreecommitdiffstats
path: root/sw/source/ui
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/ui')
-rw-r--r--sw/source/ui/chrdlg/break.cxx213
-rw-r--r--sw/source/ui/chrdlg/chardlg.cxx316
-rw-r--r--sw/source/ui/chrdlg/drpcps.cxx760
-rw-r--r--sw/source/ui/chrdlg/numpara.cxx418
-rw-r--r--sw/source/ui/chrdlg/pardlg.cxx245
-rw-r--r--sw/source/ui/chrdlg/swuiccoll.cxx247
-rw-r--r--sw/source/ui/chrdlg/tblnumfm.cxx46
-rw-r--r--sw/source/ui/config/mailconfigpage.cxx578
-rw-r--r--sw/source/ui/config/optcomp.cxx481
-rw-r--r--sw/source/ui/config/optload.cxx1508
-rw-r--r--sw/source/ui/config/optpage.cxx2848
-rw-r--r--sw/source/ui/dbui/addresslistdialog.cxx641
-rw-r--r--sw/source/ui/dbui/addresslistdialog.hxx101
-rw-r--r--sw/source/ui/dbui/createaddresslistdialog.cxx590
-rw-r--r--sw/source/ui/dbui/createaddresslistdialog.hxx108
-rw-r--r--sw/source/ui/dbui/customizeaddresslistdialog.cxx181
-rw-r--r--sw/source/ui/dbui/customizeaddresslistdialog.hxx91
-rw-r--r--sw/source/ui/dbui/dbinsdlg.cxx1750
-rw-r--r--sw/source/ui/dbui/dbtablepreviewdialog.cxx119
-rw-r--r--sw/source/ui/dbui/dbtablepreviewdialog.hxx46
-rw-r--r--sw/source/ui/dbui/mailmergewizard.cxx268
-rw-r--r--sw/source/ui/dbui/mmaddressblockpage.cxx1582
-rw-r--r--sw/source/ui/dbui/mmaddressblockpage.hxx280
-rw-r--r--sw/source/ui/dbui/mmdocselectpage.cxx226
-rw-r--r--sw/source/ui/dbui/mmdocselectpage.hxx58
-rw-r--r--sw/source/ui/dbui/mmgreetingspage.cxx421
-rw-r--r--sw/source/ui/dbui/mmgreetingspage.hxx130
-rw-r--r--sw/source/ui/dbui/mmlayoutpage.cxx692
-rw-r--r--sw/source/ui/dbui/mmlayoutpage.hxx87
-rw-r--r--sw/source/ui/dbui/mmoutputtypepage.cxx532
-rw-r--r--sw/source/ui/dbui/mmoutputtypepage.hxx43
-rw-r--r--sw/source/ui/dbui/mmresultdialogs.cxx1296
-rw-r--r--sw/source/ui/dbui/selectdbtabledialog.cxx144
-rw-r--r--sw/source/ui/dbui/selectdbtabledialog.hxx44
-rw-r--r--sw/source/ui/dialog/abstract.cxx41
-rw-r--r--sw/source/ui/dialog/addrdlg.cxx36
-rw-r--r--sw/source/ui/dialog/ascfldlg.cxx448
-rw-r--r--sw/source/ui/dialog/docstdlg.cxx131
-rw-r--r--sw/source/ui/dialog/macassgn.cxx132
-rw-r--r--sw/source/ui/dialog/swdlgfact.cxx1430
-rw-r--r--sw/source/ui/dialog/swdlgfact.hxx881
-rw-r--r--sw/source/ui/dialog/swmessdialog.cxx20
-rw-r--r--sw/source/ui/dialog/swuiexp.cxx40
-rw-r--r--sw/source/ui/dialog/uiregionsw.cxx2145
-rw-r--r--sw/source/ui/dialog/wordcountdialog.cxx161
-rw-r--r--sw/source/ui/dochdl/selglos.cxx42
-rw-r--r--sw/source/ui/envelp/envfmt.cxx425
-rw-r--r--sw/source/ui/envelp/envfmt.hxx76
-rw-r--r--sw/source/ui/envelp/envlop1.cxx340
-rw-r--r--sw/source/ui/envelp/envprt.cxx190
-rw-r--r--sw/source/ui/envelp/envprt.hxx71
-rw-r--r--sw/source/ui/envelp/label1.cxx717
-rw-r--r--sw/source/ui/envelp/labelexp.cxx104
-rw-r--r--sw/source/ui/envelp/labfmt.cxx609
-rw-r--r--sw/source/ui/envelp/labfmt.hxx140
-rw-r--r--sw/source/ui/envelp/labprt.cxx155
-rw-r--r--sw/source/ui/envelp/labprt.hxx63
-rw-r--r--sw/source/ui/envelp/mailmrge.cxx617
-rw-r--r--sw/source/ui/envelp/swuilabimp.hxx145
-rw-r--r--sw/source/ui/fldui/DateFormFieldDialog.cxx126
-rw-r--r--sw/source/ui/fldui/DropDownFieldDialog.cxx142
-rw-r--r--sw/source/ui/fldui/DropDownFormFieldDialog.cxx200
-rw-r--r--sw/source/ui/fldui/changedb.cxx258
-rw-r--r--sw/source/ui/fldui/flddb.cxx541
-rw-r--r--sw/source/ui/fldui/flddb.hxx83
-rw-r--r--sw/source/ui/fldui/flddinf.cxx511
-rw-r--r--sw/source/ui/fldui/flddinf.hxx70
-rw-r--r--sw/source/ui/fldui/flddok.cxx644
-rw-r--r--sw/source/ui/fldui/flddok.hxx72
-rw-r--r--sw/source/ui/fldui/fldedt.cxx336
-rw-r--r--sw/source/ui/fldui/fldfunc.cxx611
-rw-r--r--sw/source/ui/fldui/fldfunc.hxx92
-rw-r--r--sw/source/ui/fldui/fldpage.cxx350
-rw-r--r--sw/source/ui/fldui/fldpage.hxx89
-rw-r--r--sw/source/ui/fldui/fldref.cxx1239
-rw-r--r--sw/source/ui/fldui/fldref.hxx99
-rw-r--r--sw/source/ui/fldui/fldtdlg.cxx313
-rw-r--r--sw/source/ui/fldui/fldvar.cxx1277
-rw-r--r--sw/source/ui/fldui/fldvar.hxx84
-rw-r--r--sw/source/ui/fldui/inpdlg.cxx176
-rw-r--r--sw/source/ui/fldui/javaedit.cxx253
-rw-r--r--sw/source/ui/fmtui/tmpdlg.cxx542
-rw-r--r--sw/source/ui/frmdlg/column.cxx1381
-rw-r--r--sw/source/ui/frmdlg/cption.cxx537
-rw-r--r--sw/source/ui/frmdlg/frmdlg.cxx201
-rw-r--r--sw/source/ui/frmdlg/frmpage.cxx3285
-rw-r--r--sw/source/ui/frmdlg/pattern.cxx42
-rw-r--r--sw/source/ui/frmdlg/uiborder.cxx54
-rw-r--r--sw/source/ui/frmdlg/wrap.cxx631
-rw-r--r--sw/source/ui/inc/mmresultdialogs.hxx189
-rw-r--r--sw/source/ui/inc/swuiexp.hxx29
-rw-r--r--sw/source/ui/index/cntex.cxx395
-rw-r--r--sw/source/ui/index/cnttab.cxx4136
-rw-r--r--sw/source/ui/index/multmrk.cxx65
-rw-r--r--sw/source/ui/index/swuiidxmrk.cxx1965
-rw-r--r--sw/source/ui/misc/bookmark.cxx590
-rw-r--r--sw/source/ui/misc/contentcontroldlg.cxx477
-rw-r--r--sw/source/ui/misc/contentcontrollistitemdlg.cxx48
-rw-r--r--sw/source/ui/misc/docfnote.cxx393
-rw-r--r--sw/source/ui/misc/glosbib.cxx405
-rw-r--r--sw/source/ui/misc/glossary.cxx1100
-rw-r--r--sw/source/ui/misc/impfnote.hxx82
-rw-r--r--sw/source/ui/misc/insfnote.cxx249
-rw-r--r--sw/source/ui/misc/linenum.cxx260
-rw-r--r--sw/source/ui/misc/num.cxx949
-rw-r--r--sw/source/ui/misc/outline.cxx1073
-rw-r--r--sw/source/ui/misc/pagenumberdlg.cxx143
-rw-r--r--sw/source/ui/misc/pgfnote.cxx313
-rw-r--r--sw/source/ui/misc/pggrid.cxx550
-rw-r--r--sw/source/ui/misc/srtdlg.cxx428
-rw-r--r--sw/source/ui/misc/swmodalredlineacceptdlg.cxx79
-rw-r--r--sw/source/ui/misc/titlepage.cxx335
-rw-r--r--sw/source/ui/misc/translatelangselect.cxx164
-rw-r--r--sw/source/ui/table/autoformatpreview.cxx466
-rw-r--r--sw/source/ui/table/colwd.cxx75
-rw-r--r--sw/source/ui/table/convert.cxx203
-rw-r--r--sw/source/ui/table/instable.cxx298
-rw-r--r--sw/source/ui/table/mergetbl.cxx40
-rw-r--r--sw/source/ui/table/rowht.cxx72
-rw-r--r--sw/source/ui/table/splittbl.cxx72
-rw-r--r--sw/source/ui/table/tabledlg.cxx1762
-rw-r--r--sw/source/ui/table/tautofmt.cxx408
-rw-r--r--sw/source/ui/uno/swdetect.cxx171
-rw-r--r--sw/source/ui/uno/swdetect.hxx51
-rw-r--r--sw/source/ui/utlui/swrenamexnameddlg.cxx78
-rw-r--r--sw/source/ui/vba/vbaaddin.cxx92
-rw-r--r--sw/source/ui/vba/vbaaddin.hxx53
-rw-r--r--sw/source/ui/vba/vbaaddins.cxx96
-rw-r--r--sw/source/ui/vba/vbaaddins.hxx46
-rw-r--r--sw/source/ui/vba/vbaapplication.cxx529
-rw-r--r--sw/source/ui/vba/vbaapplication.hxx129
-rw-r--r--sw/source/ui/vba/vbaautotextentry.cxx132
-rw-r--r--sw/source/ui/vba/vbaautotextentry.hxx69
-rw-r--r--sw/source/ui/vba/vbabookmark.cxx99
-rw-r--r--sw/source/ui/vba/vbabookmark.hxx60
-rw-r--r--sw/source/ui/vba/vbabookmarks.cxx229
-rw-r--r--sw/source/ui/vba/vbabookmarks.hxx66
-rw-r--r--sw/source/ui/vba/vbaborders.cxx366
-rw-r--r--sw/source/ui/vba/vbaborders.hxx54
-rw-r--r--sw/source/ui/vba/vbacell.cxx102
-rw-r--r--sw/source/ui/vba/vbacell.hxx58
-rw-r--r--sw/source/ui/vba/vbacells.cxx214
-rw-r--r--sw/source/ui/vba/vbacells.hxx63
-rw-r--r--sw/source/ui/vba/vbacolumn.cxx91
-rw-r--r--sw/source/ui/vba/vbacolumn.hxx53
-rw-r--r--sw/source/ui/vba/vbacolumns.cxx149
-rw-r--r--sw/source/ui/vba/vbacolumns.hxx66
-rw-r--r--sw/source/ui/vba/vbacontentcontrol.cxx753
-rw-r--r--sw/source/ui/vba/vbacontentcontrol.hxx142
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentries.cxx166
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentries.hxx51
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentry.cxx161
-rw-r--r--sw/source/ui/vba/vbacontentcontrollistentry.hxx54
-rw-r--r--sw/source/ui/vba/vbacontentcontrols.cxx268
-rw-r--r--sw/source/ui/vba/vbacontentcontrols.hxx40
-rw-r--r--sw/source/ui/vba/vbadialog.cxx73
-rw-r--r--sw/source/ui/vba/vbadialog.hxx42
-rw-r--r--sw/source/ui/vba/vbadialogs.cxx51
-rw-r--r--sw/source/ui/vba/vbadialogs.hxx44
-rw-r--r--sw/source/ui/vba/vbadocument.cxx795
-rw-r--r--sw/source/ui/vba/vbadocument.hxx125
-rw-r--r--sw/source/ui/vba/vbadocumentproperties.cxx921
-rw-r--r--sw/source/ui/vba/vbadocumentproperties.hxx58
-rw-r--r--sw/source/ui/vba/vbadocuments.cxx161
-rw-r--r--sw/source/ui/vba/vbadocuments.hxx52
-rw-r--r--sw/source/ui/vba/vbaeventshelper.cxx94
-rw-r--r--sw/source/ui/vba/vbaeventshelper.hxx47
-rw-r--r--sw/source/ui/vba/vbafield.cxx538
-rw-r--r--sw/source/ui/vba/vbafield.hxx74
-rw-r--r--sw/source/ui/vba/vbafilterpropsfromformat.hxx75
-rw-r--r--sw/source/ui/vba/vbafind.cxx431
-rw-r--r--sw/source/ui/vba/vbafind.hxx100
-rw-r--r--sw/source/ui/vba/vbafont.cxx235
-rw-r--r--sw/source/ui/vba/vbafont.hxx49
-rw-r--r--sw/source/ui/vba/vbaformfield.cxx255
-rw-r--r--sw/source/ui/vba/vbaformfield.hxx87
-rw-r--r--sw/source/ui/vba/vbaformfieldcheckbox.cxx117
-rw-r--r--sw/source/ui/vba/vbaformfieldcheckbox.hxx54
-rw-r--r--sw/source/ui/vba/vbaformfielddropdown.cxx99
-rw-r--r--sw/source/ui/vba/vbaformfielddropdown.hxx52
-rw-r--r--sw/source/ui/vba/vbaformfielddropdownlistentries.cxx162
-rw-r--r--sw/source/ui/vba/vbaformfielddropdownlistentries.hxx49
-rw-r--r--sw/source/ui/vba/vbaformfielddropdownlistentry.cxx56
-rw-r--r--sw/source/ui/vba/vbaformfielddropdownlistentry.hxx48
-rw-r--r--sw/source/ui/vba/vbaformfields.cxx235
-rw-r--r--sw/source/ui/vba/vbaformfields.hxx41
-rw-r--r--sw/source/ui/vba/vbaformfieldtextinput.cxx130
-rw-r--r--sw/source/ui/vba/vbaformfieldtextinput.hxx68
-rw-r--r--sw/source/ui/vba/vbaframe.cxx58
-rw-r--r--sw/source/ui/vba/vbaframe.hxx48
-rw-r--r--sw/source/ui/vba/vbaframes.cxx100
-rw-r--r--sw/source/ui/vba/vbaframes.hxx50
-rw-r--r--sw/source/ui/vba/vbaglobals.cxx224
-rw-r--r--sw/source/ui/vba/vbaglobals.hxx80
-rw-r--r--sw/source/ui/vba/vbaheaderfooter.cxx102
-rw-r--r--sw/source/ui/vba/vbaheaderfooter.hxx53
-rw-r--r--sw/source/ui/vba/vbaheaderfooterhelper.cxx174
-rw-r--r--sw/source/ui/vba/vbaheaderfooterhelper.hxx48
-rw-r--r--sw/source/ui/vba/vbaheadersfooters.cxx141
-rw-r--r--sw/source/ui/vba/vbaheadersfooters.hxx51
-rw-r--r--sw/source/ui/vba/vbainformationhelper.cxx66
-rw-r--r--sw/source/ui/vba/vbainformationhelper.hxx42
-rw-r--r--sw/source/ui/vba/vbalistformat.cxx328
-rw-r--r--sw/source/ui/vba/vbalistformat.hxx49
-rw-r--r--sw/source/ui/vba/vbalistgalleries.cxx108
-rw-r--r--sw/source/ui/vba/vbalistgalleries.hxx51
-rw-r--r--sw/source/ui/vba/vbalistgallery.cxx60
-rw-r--r--sw/source/ui/vba/vbalistgallery.hxx48
-rw-r--r--sw/source/ui/vba/vbalisthelper.cxx661
-rw-r--r--sw/source/ui/vba/vbalisthelper.hxx73
-rw-r--r--sw/source/ui/vba/vbalistlevel.cxx386
-rw-r--r--sw/source/ui/vba/vbalistlevel.hxx70
-rw-r--r--sw/source/ui/vba/vbalistlevels.cxx111
-rw-r--r--sw/source/ui/vba/vbalistlevels.hxx48
-rw-r--r--sw/source/ui/vba/vbalisttemplate.cxx66
-rw-r--r--sw/source/ui/vba/vbalisttemplate.hxx51
-rw-r--r--sw/source/ui/vba/vbalisttemplates.cxx106
-rw-r--r--sw/source/ui/vba/vbalisttemplates.hxx52
-rw-r--r--sw/source/ui/vba/vbamailmerge.cxx56
-rw-r--r--sw/source/ui/vba/vbamailmerge.hxx55
-rw-r--r--sw/source/ui/vba/vbaoptions.cxx274
-rw-r--r--sw/source/ui/vba/vbaoptions.hxx78
-rw-r--r--sw/source/ui/vba/vbapagesetup.cxx260
-rw-r--r--sw/source/ui/vba/vbapagesetup.hxx62
-rw-r--r--sw/source/ui/vba/vbapalette.cxx93
-rw-r--r--sw/source/ui/vba/vbapalette.hxx37
-rw-r--r--sw/source/ui/vba/vbapane.cxx65
-rw-r--r--sw/source/ui/vba/vbapane.hxx49
-rw-r--r--sw/source/ui/vba/vbapanes.cxx119
-rw-r--r--sw/source/ui/vba/vbapanes.hxx41
-rw-r--r--sw/source/ui/vba/vbaparagraph.cxx179
-rw-r--r--sw/source/ui/vba/vbaparagraph.hxx74
-rw-r--r--sw/source/ui/vba/vbaparagraphformat.cxx567
-rw-r--r--sw/source/ui/vba/vbaparagraphformat.hxx88
-rw-r--r--sw/source/ui/vba/vbarange.cxx434
-rw-r--r--sw/source/ui/vba/vbarange.hxx101
-rw-r--r--sw/source/ui/vba/vbarangehelper.cxx191
-rw-r--r--sw/source/ui/vba/vbarangehelper.hxx44
-rw-r--r--sw/source/ui/vba/vbareplacement.cxx67
-rw-r--r--sw/source/ui/vba/vbareplacement.hxx51
-rw-r--r--sw/source/ui/vba/vbarevision.cxx95
-rw-r--r--sw/source/ui/vba/vbarevision.hxx52
-rw-r--r--sw/source/ui/vba/vbarevisions.cxx185
-rw-r--r--sw/source/ui/vba/vbarevisions.hxx54
-rw-r--r--sw/source/ui/vba/vbarow.cxx121
-rw-r--r--sw/source/ui/vba/vbarow.hxx61
-rw-r--r--sw/source/ui/vba/vbarows.cxx370
-rw-r--r--sw/source/ui/vba/vbarows.hxx82
-rw-r--r--sw/source/ui/vba/vbasection.cxx84
-rw-r--r--sw/source/ui/vba/vbasection.hxx53
-rw-r--r--sw/source/ui/vba/vbasections.cxx195
-rw-r--r--sw/source/ui/vba/vbasections.hxx51
-rw-r--r--sw/source/ui/vba/vbaselection.cxx1169
-rw-r--r--sw/source/ui/vba/vbaselection.hxx120
-rw-r--r--sw/source/ui/vba/vbastyle.cxx228
-rw-r--r--sw/source/ui/vba/vbastyle.hxx78
-rw-r--r--sw/source/ui/vba/vbastyles.cxx378
-rw-r--r--sw/source/ui/vba/vbastyles.hxx48
-rw-r--r--sw/source/ui/vba/vbasystem.cxx275
-rw-r--r--sw/source/ui/vba/vbasystem.hxx64
-rw-r--r--sw/source/ui/vba/vbatable.cxx211
-rw-r--r--sw/source/ui/vba/vbatable.hxx59
-rw-r--r--sw/source/ui/vba/vbatablehelper.cxx276
-rw-r--r--sw/source/ui/vba/vbatablehelper.hxx67
-rw-r--r--sw/source/ui/vba/vbatableofcontents.cxx111
-rw-r--r--sw/source/ui/vba/vbatableofcontents.hxx61
-rw-r--r--sw/source/ui/vba/vbatables.cxx239
-rw-r--r--sw/source/ui/vba/vbatables.hxx48
-rw-r--r--sw/source/ui/vba/vbatablesofcontents.cxx186
-rw-r--r--sw/source/ui/vba/vbatablesofcontents.hxx54
-rw-r--r--sw/source/ui/vba/vbatabstop.cxx48
-rw-r--r--sw/source/ui/vba/vbatabstop.hxx41
-rw-r--r--sw/source/ui/vba/vbatabstops.cxx270
-rw-r--r--sw/source/ui/vba/vbatabstops.hxx53
-rw-r--r--sw/source/ui/vba/vbatemplate.cxx129
-rw-r--r--sw/source/ui/vba/vbatemplate.hxx46
-rw-r--r--sw/source/ui/vba/vbavariable.cxx92
-rw-r--r--sw/source/ui/vba/vbavariable.hxx53
-rw-r--r--sw/source/ui/vba/vbavariables.cxx95
-rw-r--r--sw/source/ui/vba/vbavariables.hxx51
-rw-r--r--sw/source/ui/vba/vbaview.cxx399
-rw-r--r--sw/source/ui/vba/vbaview.hxx63
-rw-r--r--sw/source/ui/vba/vbawindow.cxx179
-rw-r--r--sw/source/ui/vba/vbawindow.hxx59
-rw-r--r--sw/source/ui/vba/vbawordbasic.cxx265
-rw-r--r--sw/source/ui/vba/vbawordbasic.hxx95
-rw-r--r--sw/source/ui/vba/vbawrapformat.cxx243
-rw-r--r--sw/source/ui/vba/vbawrapformat.hxx66
-rw-r--r--sw/source/ui/vba/wordvbahelper.cxx176
-rw-r--r--sw/source/ui/vba/wordvbahelper.hxx63
290 files changed, 82521 insertions, 0 deletions
diff --git a/sw/source/ui/chrdlg/break.cxx b/sw/source/ui/chrdlg/break.cxx
new file mode 100644
index 0000000000..34048c2564
--- /dev/null
+++ b/sw/source/ui/chrdlg/break.cxx
@@ -0,0 +1,213 @@
+/* -*- 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 <osl/diagnose.h>
+
+#include <uitool.hxx>
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <break.hxx>
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+
+#include <strings.hrc>
+#include <SwStyleNameMapper.hxx>
+
+void SwBreakDlg::rememberResult()
+{
+ m_nKind = 0;
+ if (m_xLineBtn->get_active())
+ {
+ m_nKind = 1;
+ m_eClear = static_cast<SwLineBreakClear>(m_xLineClearBox->get_active());
+ }
+ else if(m_xColumnBtn->get_active())
+ m_nKind = 2;
+ else if(m_xPageBtn->get_active())
+ {
+ m_nKind = 3;
+ const int nPos = m_xPageCollBox->get_active();
+ if (nPos != 0 && nPos != -1)
+ {
+ m_aTemplate = m_xPageCollBox->get_active_text();
+ m_oPgNum.reset();
+ if (m_xPageNumBox->get_active())
+ {
+ m_oPgNum = o3tl::narrowing<sal_uInt16>(m_xPageNumEdit->get_value());
+ }
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SwBreakDlg, ToggleHdl, weld::Toggleable&, void)
+{
+ CheckEnable();
+}
+
+IMPL_LINK_NOARG(SwBreakDlg, ChangeHdl, weld::ComboBox&, void)
+{
+ CheckEnable();
+}
+
+// Handler for Change Page Number
+IMPL_LINK(SwBreakDlg, PageNumHdl, weld::Toggleable&, rBox, void)
+{
+ if (rBox.get_active())
+ m_xPageNumEdit->set_value(1);
+ else
+ m_xPageNumEdit->set_text(OUString());
+}
+
+// By changing the Page number the checkbox is checked.
+IMPL_LINK_NOARG(SwBreakDlg, PageNumModifyHdl, weld::SpinButton&, void)
+{
+ m_xPageNumBox->set_active(true);
+}
+
+/*
+ * Ok-Handler;
+ * checks whether pagenumber nPage is a legal pagenumber (left pages with even
+ * numbers etc. for a page template with alternating pages)
+ */
+IMPL_LINK_NOARG(SwBreakDlg, OkHdl, weld::Button&, void)
+{
+ if (m_xPageNumBox->get_active())
+ {
+ // In case of differing page descriptions, test validity
+ const int nPos = m_xPageCollBox->get_active();
+ // position 0 says 'Without'.
+ const SwPageDesc *pPageDesc;
+ if (nPos != 0 && nPos != -1)
+ pPageDesc = m_rSh.FindPageDescByName(m_xPageCollBox->get_active_text(), true);
+ else
+ pPageDesc = &m_rSh.GetPageDesc(m_rSh.GetCurPageDesc());
+
+ OSL_ENSURE(pPageDesc, "Page description not found.");
+ const sal_uInt16 nUserPage = sal_uInt16(m_xPageNumEdit->get_value());
+ bool bOk = true;
+ switch(pPageDesc->GetUseOn())
+ {
+ case UseOnPage::Mirror:
+ case UseOnPage::All: break;
+ case UseOnPage::Left: bOk = 0 == nUserPage % 2; break;
+ case UseOnPage::Right: bOk = 1 == nUserPage % 2; break;
+ default:; //prevent warning
+ }
+ if(!bOk)
+ {
+ std::unique_ptr<weld::Dialog> xDialog(Application::CreateMessageDialog(m_xPageNumEdit.get(), VclMessageType::Info,
+ VclButtonsType::Ok, SwResId(STR_ILLEGAL_PAGENUM)));
+ xDialog->run();
+ m_xPageNumEdit->grab_focus();
+ return;
+ }
+ }
+ rememberResult();
+ m_xDialog->response(RET_OK);
+}
+
+SwBreakDlg::SwBreakDlg(weld::Window *pParent, SwWrtShell &rS)
+ : GenericDialogController(pParent, "modules/swriter/ui/insertbreak.ui", "BreakDialog")
+ , m_xLineBtn(m_xBuilder->weld_radio_button("linerb"))
+ , m_xLineClearText(m_xBuilder->weld_label("clearft"))
+ , m_xLineClearBox(m_xBuilder->weld_combo_box("clearlb"))
+ , m_xColumnBtn(m_xBuilder->weld_radio_button("columnrb"))
+ , m_xPageBtn(m_xBuilder->weld_radio_button("pagerb"))
+ , m_xPageCollText(m_xBuilder->weld_label("styleft"))
+ , m_xPageCollBox(m_xBuilder->weld_combo_box("stylelb"))
+ , m_xPageNumBox(m_xBuilder->weld_check_button("pagenumcb"))
+ , m_xPageNumEdit(m_xBuilder->weld_spin_button("pagenumsb"))
+ , m_xOkBtn(m_xBuilder->weld_button("ok"))
+ , m_rSh(rS)
+ , m_nKind(0)
+ , m_bHtmlMode(0 != ::GetHtmlMode(rS.GetView().GetDocShell()))
+{
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwBreakDlg, ToggleHdl);
+ m_xPageBtn->connect_toggled(aLk);
+ m_xLineBtn->connect_toggled(aLk);
+ m_xColumnBtn->connect_toggled(aLk);
+ m_xPageCollBox->connect_changed(LINK(this, SwBreakDlg, ChangeHdl));
+
+ m_xOkBtn->connect_clicked(LINK(this, SwBreakDlg, OkHdl));
+ m_xPageNumBox->connect_toggled(LINK(this, SwBreakDlg, PageNumHdl));
+ m_xPageNumEdit->connect_value_changed(LINK(this, SwBreakDlg, PageNumModifyHdl));
+
+ // Insert page description to Listbox
+ const size_t nCount = m_rSh.GetPageDescCnt();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ const SwPageDesc &rPageDesc = m_rSh.GetPageDesc(i);
+ ::InsertStringSorted("", rPageDesc.GetName(), *m_xPageCollBox, 1 );
+ }
+
+ OUString aFormatName;
+ for (sal_uInt16 i = RES_POOLPAGE_BEGIN; i < RES_POOLPAGE_END; ++i)
+ {
+ aFormatName = SwStyleNameMapper::GetUIName( i, aFormatName );
+ if (m_xPageCollBox->find_text(aFormatName) == -1)
+ ::InsertStringSorted("", aFormatName, *m_xPageCollBox, 1 );
+ }
+ //add landscape page
+ aFormatName = SwStyleNameMapper::GetUIName( RES_POOLPAGE_LANDSCAPE, aFormatName );
+ if (m_xPageCollBox->find_text(aFormatName) == -1)
+ ::InsertStringSorted("", aFormatName, *m_xPageCollBox, 1);
+ CheckEnable();
+ m_xPageNumEdit->set_text(OUString());
+}
+
+void SwBreakDlg::CheckEnable()
+{
+ bool bEnable = true;
+ if ( m_bHtmlMode )
+ {
+ m_xColumnBtn->set_sensitive(false);
+ m_xPageCollBox->set_sensitive(false);
+ bEnable = false;
+ }
+ else if(m_rSh.GetFrameType(nullptr,true)
+ & (FrameTypeFlags::FLY_ANY | FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FOOTNOTE))
+ {
+ m_xPageBtn->set_sensitive(false);
+ if (m_xPageBtn->get_active())
+ m_xLineBtn->set_active(true);
+ bEnable = false;
+ }
+ const bool bPage = m_xPageBtn->get_active();
+ m_xPageCollText->set_sensitive(bPage);
+ m_xPageCollBox->set_sensitive(bPage);
+ bool bLine = m_xLineBtn->get_active();
+ m_xLineClearText->set_sensitive(bLine);
+ m_xLineClearBox->set_sensitive(bLine);
+
+ bEnable &= bPage;
+ if ( bEnable )
+ {
+ // position 0 says 'Without' page template.
+ const int nPos = m_xPageCollBox->get_active();
+ if (nPos == 0 || nPos == -1)
+ bEnable = false;
+ }
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPageNumEdit->set_sensitive(bEnable);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/chardlg.cxx b/sw/source/ui/chrdlg/chardlg.cxx
new file mode 100644
index 0000000000..ece33852d7
--- /dev/null
+++ b/sw/source/ui/chrdlg/chardlg.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 <memory>
+#include <hintids.hxx>
+
+#include <comphelper/fileurl.hxx>
+#include <svl/urihelper.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/flstitem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/macitem.hxx>
+#include <osl/diagnose.h>
+
+#include <cmdid.h>
+#include <swtypes.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <uitool.hxx>
+#include <fmtinfmt.hxx>
+#include <macassgn.hxx>
+#include <chrdlg.hxx>
+#include <swmodule.hxx>
+#include <poolfmt.hxx>
+
+#include <strings.hrc>
+#include <chrdlgmodes.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <SwStyleNameMapper.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/frame.hxx>
+#include <comphelper/lok.hxx>
+
+#include <svx/svxdlg.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/dialogs.hrc>
+
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::sfx2;
+
+SwCharDlg::SwCharDlg(weld::Window* pParent, SwView& rVw, const SfxItemSet& rCoreSet,
+ SwCharDlgMode nDialogMode, const OUString* pStr)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/characterproperties.ui",
+ "CharacterPropertiesDialog", &rCoreSet, pStr != nullptr)
+ , m_rView(rVw)
+ , m_nDialogMode(nDialogMode)
+{
+ if (pStr)
+ {
+ m_xDialog->set_title(m_xDialog->get_title() + SwResId(STR_TEXTCOLL_HEADER) + *pStr + ")");
+ }
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ AddTabPage("font", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_CHAR_NAME), nullptr);
+ AddTabPage("fonteffects", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_CHAR_EFFECTS), nullptr);
+ AddTabPage("position", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_POSITION ), nullptr );
+ AddTabPage("asianlayout", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_TWOLINES ), nullptr );
+ AddTabPage("hyperlink", SwCharURLPage::Create, nullptr);
+ AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr );
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), nullptr );
+
+ if (m_nDialogMode == SwCharDlgMode::Draw || m_nDialogMode == SwCharDlgMode::Ann)
+ {
+ RemoveTabPage("hyperlink");
+ RemoveTabPage("asianlayout");
+ }
+ else
+ {
+ if (!SvtCJKOptions::IsDoubleLinesEnabled())
+ RemoveTabPage("asianlayout");
+ }
+
+ if (m_nDialogMode != SwCharDlgMode::Std)
+ RemoveTabPage("borders");
+}
+
+SwCharDlg::~SwCharDlg()
+{
+}
+
+// set FontList
+void SwCharDlg::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ if (rId == "font")
+ {
+ SvxFontListItem aFontListItem( *static_cast<const SvxFontListItem*>(
+ ( m_rView.GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST ) ) ) );
+ aSet.Put (SvxFontListItem( aFontListItem.GetFontList(), SID_ATTR_CHAR_FONTLIST));
+ if(m_nDialogMode != SwCharDlgMode::Draw && m_nDialogMode != SwCharDlgMode::Ann)
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE,SVX_PREVIEW_CHARACTER));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "fonteffects")
+ {
+ aSet.Put(
+ SfxUInt32Item(SID_FLAG_TYPE, SVX_PREVIEW_CHARACTER | SVX_ENABLE_CHAR_TRANSPARENCY));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "position")
+ {
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE,SVX_PREVIEW_CHARACTER));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "asianlayout")
+ {
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE,SVX_PREVIEW_CHARACTER));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "background")
+ {
+ SvxBackgroundTabFlags eFlags(SvxBackgroundTabFlags::SHOW_HIGHLIGHTING);
+ if (m_nDialogMode == SwCharDlgMode::Draw || m_nDialogMode == SwCharDlgMode::Ann)
+ eFlags = SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR;
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE,static_cast<sal_uInt32>(eFlags)));
+ rPage.PageCreated(aSet);
+ }
+}
+
+SwCharURLPage::SwCharURLPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/charurlpage.ui", "CharURLPage", &rCoreSet)
+ , m_bModified(false)
+ , m_xURLED(m_xBuilder->weld_entry("urled"))
+ , m_xTextFT(m_xBuilder->weld_label("textft"))
+ , m_xTextED(m_xBuilder->weld_entry("texted"))
+ , m_xNameED(m_xBuilder->weld_entry("nameed"))
+ , m_xTargetFrameLB(m_xBuilder->weld_combo_box("targetfrmlb"))
+ , m_xURLPB(m_xBuilder->weld_button("urlpb"))
+ , m_xEventPB(m_xBuilder->weld_button("eventpb"))
+ , m_xVisitedLB(m_xBuilder->weld_combo_box("visitedlb"))
+ , m_xNotVisitedLB(m_xBuilder->weld_combo_box("unvisitedlb"))
+ , m_xCharStyleContainer(m_xBuilder->weld_widget("charstyle"))
+{
+ // tdf#120188 like SfxManageStyleSheetPage limit the width of the style combos
+ const int nMaxWidth(m_xVisitedLB->get_approximate_digit_width() * 50);
+ m_xVisitedLB->set_size_request(nMaxWidth , -1);
+ m_xNotVisitedLB->set_size_request(nMaxWidth , -1);
+
+ const SfxUInt16Item* pItem = rCoreSet.GetItemIfSet(SID_HTML_MODE, false);
+ if (!pItem)
+ {
+ if (SfxObjectShell* pShell = SfxObjectShell::Current())
+ pItem = pShell->GetItem(SID_HTML_MODE);
+ }
+ if (pItem)
+ {
+ sal_uInt16 nHtmlMode = pItem->GetValue();
+ if (HTMLMODE_ON & nHtmlMode)
+ m_xCharStyleContainer->hide();
+ }
+
+ if(comphelper::LibreOfficeKit::isActive())
+ m_xURLPB->hide(); // Hide browse button in online (not supported yet)
+ else
+ m_xURLPB->connect_clicked(LINK( this, SwCharURLPage, InsertFileHdl));
+ m_xEventPB->connect_clicked(LINK( this, SwCharURLPage, EventHdl));
+
+ if (SwView* pView = GetActiveView())
+ {
+ ::FillCharStyleListBox(*m_xVisitedLB, pView->GetDocShell());
+ ::FillCharStyleListBox(*m_xNotVisitedLB, pView->GetDocShell());
+ }
+ m_xVisitedLB->set_active_id(OUString::number(RES_POOLCHR_INET_VISIT));
+ m_xVisitedLB->save_value();
+ m_xNotVisitedLB->set_active_id(OUString::number(RES_POOLCHR_INET_NORMAL));
+ m_xNotVisitedLB->save_value();
+
+ TargetList aList;
+ SfxFrame::GetDefaultTargetList(aList);
+
+ m_xTargetFrameLB->freeze();
+ size_t nCount = aList.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ m_xTargetFrameLB->append_text(aList.at(i));
+ }
+ m_xTargetFrameLB->thaw();
+}
+
+SwCharURLPage::~SwCharURLPage()
+{
+}
+
+void SwCharURLPage::Reset(const SfxItemSet* rSet)
+{
+ if (const SwFormatINetFormat* pINetFormat = rSet->GetItemIfSet(RES_TXTATR_INETFMT, false))
+ {
+ m_xURLED->set_text(INetURLObject::decode(pINetFormat->GetValue(),
+ INetURLObject::DecodeMechanism::Unambiguous));
+ m_xURLED->save_value();
+ m_xNameED->set_text(pINetFormat->GetName());
+ m_xNameED->save_value();
+
+ OUString sEntry = pINetFormat->GetVisitedFormat();
+ if (sEntry.isEmpty())
+ {
+ OSL_ENSURE( false, "<SwCharURLPage::Reset(..)> - missing visited character format at hyperlink attribute" );
+ SwStyleNameMapper::FillUIName(RES_POOLCHR_INET_VISIT, sEntry);
+ }
+ m_xVisitedLB->set_active_text(sEntry);
+
+ sEntry = pINetFormat->GetINetFormat();
+ if (sEntry.isEmpty())
+ {
+ OSL_ENSURE( false, "<SwCharURLPage::Reset(..)> - missing unvisited character format at hyperlink attribute" );
+ SwStyleNameMapper::FillUIName(RES_POOLCHR_INET_NORMAL, sEntry);
+ }
+ m_xNotVisitedLB->set_active_text(sEntry);
+
+ m_xTargetFrameLB->set_entry_text(pINetFormat->GetTargetFrame());
+ m_xVisitedLB->save_value();
+ m_xNotVisitedLB->save_value();
+ m_xTargetFrameLB->save_value();
+ m_oINetMacroTable.emplace();
+
+ if( pINetFormat->GetMacroTable() )
+ m_oINetMacroTable = *pINetFormat->GetMacroTable();
+ }
+ if (const SfxStringItem* pItem = rSet->GetItemIfSet(FN_PARAM_SELECTION, false))
+ {
+ m_xTextED->set_text(pItem->GetValue());
+ m_xTextFT->set_sensitive(false);
+ m_xTextED->set_sensitive(false);
+ }
+}
+
+bool SwCharURLPage::FillItemSet(SfxItemSet* rSet)
+{
+ OUString sURL = m_xURLED->get_text();
+ if (!sURL.isEmpty())
+ {
+ sURL = URIHelper::SmartRel2Abs(INetURLObject(), sURL, Link<OUString *, bool>(), false );
+ // #i100683# file URLs should be normalized in the UI
+ if ( comphelper::isFileUrl(sURL) )
+ sURL = URIHelper::simpleNormalizedMakeRelative(OUString(), sURL);
+ }
+
+ SwFormatINetFormat aINetFormat(sURL, m_xTargetFrameLB->get_active_text());
+ aINetFormat.SetName(m_xNameED->get_text());
+ bool bURLModified = m_xURLED->get_value_changed_from_saved();
+ bool bNameModified = m_xNameED->get_value_changed_from_saved();
+ bool bTargetModified = m_xTargetFrameLB->get_value_changed_from_saved();
+ m_bModified = bURLModified || bNameModified || bTargetModified;
+
+ // set valid settings first
+ OUString sEntry = m_xVisitedLB->get_active_text();
+ sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( sEntry, SwGetPoolIdFromName::ChrFmt);
+ aINetFormat.SetVisitedFormatAndId( sEntry, nId );
+
+ sEntry = m_xNotVisitedLB->get_active_text();
+ nId = SwStyleNameMapper::GetPoolIdFromUIName( sEntry, SwGetPoolIdFromName::ChrFmt);
+ aINetFormat.SetINetFormatAndId( sEntry, nId );
+
+ if (m_oINetMacroTable && !m_oINetMacroTable->empty())
+ aINetFormat.SetMacroTable(&*m_oINetMacroTable);
+
+ if (m_xVisitedLB->get_value_changed_from_saved())
+ m_bModified = true;
+
+ if (m_xNotVisitedLB->get_value_changed_from_saved())
+ m_bModified = true;
+
+ if (bNameModified)
+ {
+ m_bModified = true;
+ rSet->Put(SfxStringItem(FN_PARAM_SELECTION, m_xTextED->get_text()));
+ }
+ if(m_bModified)
+ rSet->Put(aINetFormat);
+ return m_bModified;
+}
+
+std::unique_ptr<SfxTabPage> SwCharURLPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwCharURLPage>(pPage, pController, *rAttrSet);
+}
+
+IMPL_LINK_NOARG(SwCharURLPage, InsertFileHdl, weld::Button&, void)
+{
+ FileDialogHelper aDlgHelper(TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ aDlgHelper.SetContext(FileDialogHelper::WriterInsertHyperlink);
+ if( aDlgHelper.Execute() == ERRCODE_NONE )
+ {
+ const Reference<XFilePicker3>& xFP = aDlgHelper.GetFilePicker();
+ m_xURLED->set_text(xFP->getSelectedFiles().getConstArray()[0]);
+ }
+}
+
+IMPL_LINK_NOARG(SwCharURLPage, EventHdl, weld::Button&, void)
+{
+ if (SwView* pView = GetActiveView())
+ m_bModified |= SwMacroAssignDlg::INetFormatDlg(GetFrameWeld(),
+ pView->GetWrtShell(), m_oINetMacroTable);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/drpcps.cxx b/sw/source/ui/chrdlg/drpcps.cxx
new file mode 100644
index 0000000000..15bdd270a0
--- /dev/null
+++ b/sw/source/ui/chrdlg/drpcps.cxx
@@ -0,0 +1,760 @@
+/* -*- 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 <hintids.hxx>
+
+#include <cmdid.h>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <strings.hrc>
+
+#include <vcl/metric.hxx>
+#include <vcl/settings.hxx>
+
+#include <rtl/ustrbuf.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <svtools/unitconv.hxx>
+#include <vcl/print.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/i18n/BreakIterator.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+
+#include <charatr.hxx>
+#include <viewopt.hxx>
+#include <drpcps.hxx>
+#include <paratr.hxx>
+#include <uitool.hxx>
+#include <charfmt.hxx>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::lang;
+
+const WhichRangesContainer SwDropCapsPage::s_aPageRg(svl::Items<RES_PARATR_DROP, RES_PARATR_DROP>);
+
+void SwDropCapsPict::SetText( const OUString& rT )
+{
+ maText = rT;
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ Size aPrefSize(getParagraphPreviewOptimalSize(pDrawingArea->get_ref_device()));
+ pDrawingArea->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+}
+
+void SwDropCapsPict::Resize()
+{
+ CustomWidgetController::Resize();
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetLines( sal_uInt8 nL )
+{
+ mnLines = nL;
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetDistance( sal_uInt16 nD )
+{
+ mnDistance = nD;
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::SetValues( const OUString& rText, sal_uInt8 nLines, sal_uInt16 nDistance )
+{
+ maText = rText;
+ mnLines = nLines;
+ mnDistance = nDistance;
+
+ UpdatePaintSettings();
+}
+
+void SwDropCapsPict::InitPrinter()
+{
+ if( !mpPrinter )
+ InitPrinter_();
+}
+
+// Create Default-String from character-count (A, AB, ABC, ...)
+static OUString GetDefaultString(sal_Int32 nChars)
+{
+ OUStringBuffer aStr(nChars);
+ for (sal_Int32 i = 0; i < nChars; i++)
+ aStr.append(static_cast<sal_Unicode>(i + 65));
+ return aStr.makeStringAndClear();
+}
+
+static void calcFontHeightAnyAscent(vcl::RenderContext& rWin, vcl::Font const & _rFont, tools::Long& _nHeight, tools::Long& _nAscent)
+{
+ if ( !_nHeight )
+ {
+ rWin.Push(vcl::PushFlags::FONT);
+ rWin.SetFont(_rFont);
+ FontMetric aMetric(rWin.GetFontMetric());
+ _nHeight = aMetric.GetLineHeight();
+ _nAscent = aMetric.GetAscent();
+ rWin.Pop();
+ }
+}
+
+SwDropCapsPict::~SwDropCapsPict()
+{
+ if (mbDelPrinter)
+ mpPrinter.disposeAndClear();
+}
+
+/// Get the details of the first script change.
+/// @param[out] start The character position of the start of the segment.
+/// @param[out] end The character position of the end of the segment.
+/// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
+void SwDropCapsPict::GetFirstScriptSegment(sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
+{
+ start = 0;
+ if( maScriptChanges.empty() )
+ {
+ end = maText.getLength();
+ scriptType = css::i18n::ScriptType::LATIN;
+ }
+ else
+ {
+ end = maScriptChanges[ 0 ].changePos;
+ scriptType = maScriptChanges[ 0 ].scriptType;
+ }
+}
+
+/// Get the details of the first script change.
+/// @param[in,out] nIdx Index of the current script change.
+/// @param[out] start The character position of the start of the segment.
+/// @param[in,out] end The character position of the end of the segment.
+/// @param[out] scriptType The script type (Latin, Asian, Complex etc.)
+/// @returns True if there was a next segment, false if not.
+bool SwDropCapsPict::GetNextScriptSegment(size_t &nIdx, sal_Int32 &start, sal_Int32 &end, sal_uInt16 &scriptType)
+{
+ if (maScriptChanges.empty() || nIdx >= maScriptChanges.size() - 1 || end >= maText.getLength())
+ return false;
+ start = maScriptChanges[nIdx++].changePos;
+ end = maScriptChanges[ nIdx ].changePos;
+ scriptType = maScriptChanges[ nIdx ].scriptType;
+ return true;
+}
+
+#define LINES 10
+#define BORDER 2
+
+void SwDropCapsPict::GetFontSettings( vcl::Font& _rFont, sal_uInt16 _nWhich )
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+
+ SfxItemSet aSet( rWrtShell.GetAttrPool(), _nWhich, _nWhich);
+ rWrtShell.GetCurAttr(aSet);
+ SvxFontItem aFormatFont(static_cast<const SvxFontItem &>( aSet.Get(_nWhich)));
+
+ _rFont.SetFamily(aFormatFont.GetFamily());
+ _rFont.SetFamilyName(aFormatFont.GetFamilyName());
+ _rFont.SetPitch(aFormatFont.GetPitch());
+ _rFont.SetCharSet(aFormatFont.GetCharSet());
+}
+
+void SwDropCapsPict::UpdatePaintSettings()
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+
+ maBackColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
+ maTextLineColor = COL_LIGHTGRAY;
+
+ // gray lines
+ mnTotLineH = (GetOutputSizePixel().Height() - 2 * BORDER) / LINES;
+ mnLineH = mnTotLineH - 2;
+
+ vcl::Font aFont;
+ if (mpPage)
+ {
+ // tdf#135244: preview generation should not jump document view
+ auto aLock(rWrtShell.GetView().GetDocShell()->LockAllViews());
+
+ if (!mpPage->m_xTemplateBox->get_active())
+ {
+ // query the Font at paragraph's beginning
+ rWrtShell.Push();
+ rWrtShell.SttCursorMove();
+ rWrtShell.ClearMark();
+ SwWhichPara pSwuifnParaCurr = GoCurrPara;
+ SwMoveFnCollection const & pSwuifnParaStart = fnParaStart;
+ rWrtShell.MovePara(pSwuifnParaCurr,pSwuifnParaStart);
+ // normal
+ GetFontSettings( aFont, RES_CHRATR_FONT );
+
+ // CJK
+ GetFontSettings( maCJKFont, RES_CHRATR_CJK_FONT );
+
+ // CTL
+ GetFontSettings( maCTLFont, RES_CHRATR_CTL_FONT );
+
+ rWrtShell.EndCursorMove();
+ rWrtShell.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+ else
+ {
+ // query Font at character template
+ SwCharFormat *pFormat = rWrtShell.GetCharStyle(
+ mpPage->m_xTemplateBox->get_active_text(),
+ SwWrtShell::GETSTYLE_CREATEANY );
+ OSL_ENSURE(pFormat, "character style doesn't exist!");
+ const SvxFontItem &rFormatFont = pFormat->GetFont();
+
+ aFont.SetFamily(rFormatFont.GetFamily());
+ aFont.SetFamilyName(rFormatFont.GetFamilyName());
+ aFont.SetPitch(rFormatFont.GetPitch());
+ aFont.SetCharSet(rFormatFont.GetCharSet());
+ }
+
+ const Color& rFontColor = rWrtShell.GetViewOptions()->GetFontColor();
+ aFont.SetColor( rFontColor );
+ maCJKFont.SetColor( rFontColor );
+ maCTLFont.SetColor( rFontColor );
+ }
+
+ mnTextH = mnLines * mnTotLineH;
+ aFont.SetFontSize(Size(0, mnTextH));
+ maCJKFont.SetFontSize(Size(0, mnTextH));
+ maCTLFont.SetFontSize(Size(0, mnTextH));
+
+ aFont.SetTransparent(true);
+ maCJKFont.SetTransparent(true);
+ maCTLFont.SetTransparent(true);
+
+ aFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+ maCJKFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+ maCTLFont.SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
+
+ maCJKFont.SetFontSize(Size(0, maCJKFont.GetFontSize().Height()));
+ maCTLFont.SetFontSize(Size(0, maCTLFont.GetFontSize().Height()));
+
+ aFont.SetFontSize(Size(0, aFont.GetFontSize().Height()));
+ maFont = aFont;
+
+ CheckScript();
+
+ maTextSize = CalcTextSize();
+
+ Invalidate();
+}
+
+void SwDropCapsPict::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
+{
+ if (!IsVisible())
+ return;
+
+ rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
+ rRenderContext.SetLineColor();
+
+ rRenderContext.SetFillColor(maBackColor);
+
+ Size aOutputSizePixel(GetOutputSizePixel());
+
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aOutputSizePixel));
+ rRenderContext.SetClipRegion(vcl::Region(tools::Rectangle(Point(BORDER, BORDER),
+ Size(aOutputSizePixel.Width () - 2 * BORDER,
+ aOutputSizePixel.Height() - 2 * BORDER))));
+
+ OSL_ENSURE(mnLineH > 0, "We cannot make it that small");
+ tools::Long nY0 = (aOutputSizePixel.Height() - (LINES * mnTotLineH)) / 2;
+
+ rRenderContext.SetFillColor(maTextLineColor);
+
+ for (int i = 0; i < LINES; ++i)
+ {
+ rRenderContext.DrawRect(tools::Rectangle(Point(BORDER, nY0 + i * mnTotLineH),
+ Size(aOutputSizePixel.Width() - 2 * BORDER, mnLineH)));
+ }
+
+ // Text background with gap (240 twips ~ 1 line height)
+ const tools::Long nDistW = (((static_cast<tools::Long>(mnDistance) * 100) / 240) * mnTotLineH) / 100;
+ rRenderContext.SetFillColor(maBackColor);
+ if (mpPage && mpPage->m_xDropCapsBox->get_active())
+ {
+ const Size aTextSize(maTextSize.Width() + nDistW, maTextSize.Height());
+ rRenderContext.DrawRect(tools::Rectangle(Point(BORDER, nY0), aTextSize));
+
+ // draw Text
+ DrawPrev(rRenderContext, Point(BORDER, nY0));
+ }
+ rRenderContext.SetClipRegion();
+}
+
+void SwDropCapsPict::DrawPrev(vcl::RenderContext& rRenderContext, const Point& rPt)
+{
+ Point aPt(rPt);
+ InitPrinter();
+
+ vcl::Font aOldFont = mpPrinter->GetFont();
+ sal_uInt16 nScript;
+ size_t nIdx = 0;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+
+ GetFirstScriptSegment(nStart, nEnd, nScript);
+
+ do
+ {
+ SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
+ ? maCJKFont
+ : ((nScript == css::i18n::ScriptType::COMPLEX)
+ ? maCTLFont
+ : maFont);
+ mpPrinter->SetFont(rFnt);
+
+ rFnt.DrawPrev(&rRenderContext, mpPrinter, aPt, maText, nStart, nEnd - nStart);
+
+ if (!maScriptChanges.empty())
+ aPt.AdjustX(maScriptChanges[nIdx].textWidth );
+
+ if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
+ break;
+ }
+ while(true);
+
+ mpPrinter->SetFont(aOldFont);
+}
+
+void SwDropCapsPict::CheckScript()
+{
+ if( maScriptText == maText )
+ return;
+
+ maScriptText = maText;
+ maScriptChanges.clear();
+ if( !m_xBreak.is() )
+ {
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ m_xBreak = css::i18n::BreakIterator::create(xContext);
+ }
+ sal_Int16 nScript = m_xBreak->getScriptType( maText, 0 );
+ sal_Int32 nChg = 0;
+ if( css::i18n::ScriptType::WEAK == nScript )
+ {
+ nChg = m_xBreak->endOfScript( maText, nChg, nScript );
+ if( nChg < maText.getLength() )
+ nScript = m_xBreak->getScriptType( maText, nChg );
+ else
+ nScript = css::i18n::ScriptType::LATIN;
+ }
+
+ for(;;)
+ {
+ nChg = m_xBreak->endOfScript( maText, nChg, nScript );
+ maScriptChanges.emplace_back(nScript, nChg );
+ if( nChg >= maText.getLength() || nChg < 0 )
+ break;
+ nScript = m_xBreak->getScriptType( maText, nChg );
+ }
+}
+
+Size SwDropCapsPict::CalcTextSize()
+{
+ InitPrinter();
+
+ sal_uInt16 nScript;
+ size_t nIdx = 0;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+ GetFirstScriptSegment(nStart, nEnd, nScript);
+ tools::Long nTextWidth = 0;
+ tools::Long nCJKHeight = 0;
+ tools::Long nCTLHeight = 0;
+ tools::Long nHeight = 0;
+ tools::Long nAscent = 0;
+ tools::Long nCJKAscent = 0;
+ tools::Long nCTLAscent = 0;
+ do
+ {
+ SvxFont& rFnt = (nScript == css::i18n::ScriptType::ASIAN)
+ ? maCJKFont
+ : ((nScript == css::i18n::ScriptType::COMPLEX)
+ ? maCTLFont
+ : maFont);
+
+ sal_uLong nWidth = rFnt.GetTextSize(*mpPrinter, maText, nStart, nEnd-nStart ).Width();
+
+ if (nIdx < maScriptChanges.size())
+ maScriptChanges[nIdx].textWidth = nWidth;
+ nTextWidth += nWidth;
+ switch(nScript)
+ {
+ case css::i18n::ScriptType::ASIAN:
+ calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maCJKFont, nCJKHeight, nCJKAscent);
+ break;
+ case css::i18n::ScriptType::COMPLEX:
+ calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maCTLFont, nCTLHeight, nCTLAscent);
+ break;
+ default:
+ calcFontHeightAnyAscent(GetDrawingArea()->get_ref_device(), maFont, nHeight, nAscent);
+ }
+
+ if (!GetNextScriptSegment(nIdx, nStart, nEnd, nScript))
+ break;
+ }
+ while(true);
+
+ nHeight -= nAscent;
+ nCJKHeight -= nCJKAscent;
+ nCTLHeight -= nCTLAscent;
+ if (nHeight < nCJKHeight)
+ nHeight = nCJKHeight;
+ if (nAscent < nCJKAscent)
+ nAscent = nCJKAscent;
+ if (nHeight < nCTLHeight)
+ nHeight = nCTLHeight;
+ if (nAscent < nCTLAscent)
+ nAscent = nCTLAscent;
+ nHeight += nAscent;
+
+ Size aTextSize(nTextWidth, nHeight);
+ return aTextSize;
+}
+
+void SwDropCapsPict::InitPrinter_()
+{
+ SfxViewShell* pSh = SfxViewShell::Current();
+
+ if (pSh)
+ mpPrinter = pSh->GetPrinter();
+
+ if (!mpPrinter)
+ {
+ mpPrinter = VclPtr<Printer>::Create();
+ mbDelPrinter = true;
+ }
+}
+
+SwDropCapsDlg::SwDropCapsDlg(weld::Window *pParent, const SfxItemSet &rSet)
+ : SfxSingleTabDialogController(pParent, &rSet)
+{
+ auto xNewPage(SwDropCapsPage::Create(get_content_area(), this, &rSet));
+ static_cast<SwDropCapsPage*>(xNewPage.get())->SetFormat(false);
+ SetTabPage(std::move(xNewPage));
+}
+
+SwDropCapsPage::SwDropCapsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/dropcapspage.ui", "DropCapPage", &rSet)
+ , m_bModified(false)
+ , m_bFormat(true)
+ , m_xDropCapsBox(m_xBuilder->weld_check_button("checkCB_SWITCH"))
+ , m_xWholeWordCB(m_xBuilder->weld_check_button("checkCB_WORD"))
+ , m_xSwitchText(m_xBuilder->weld_label("labelFT_DROPCAPS"))
+ , m_xDropCapsField(m_xBuilder->weld_spin_button("spinFLD_DROPCAPS"))
+ , m_xLinesText(m_xBuilder->weld_label("labelTXT_LINES"))
+ , m_xLinesField(m_xBuilder->weld_spin_button("spinFLD_LINES"))
+ , m_xDistanceText(m_xBuilder->weld_label("labelTXT_DISTANCE"))
+ , m_xDistanceField(m_xBuilder->weld_metric_spin_button("spinFLD_DISTANCE", FieldUnit::CM))
+ , m_xTextText(m_xBuilder->weld_label("labelTXT_TEXT"))
+ , m_xTextEdit(m_xBuilder->weld_entry("entryEDT_TEXT"))
+ , m_xTemplateText(m_xBuilder->weld_label("labelTXT_TEMPLATE"))
+ , m_xTemplateBox(m_xBuilder->weld_combo_box("comboBOX_TEMPLATE"))
+ , m_xPict(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aPict))
+{
+ m_aPict.SetDropCapsPage(this);
+
+ SetExchangeSupport();
+
+ const sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ m_bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
+
+ // tdf#92154 limit comboBOX_TEMPLATE length
+ const int nMaxWidth(m_xTemplateBox->get_approximate_digit_width() * 50);
+ m_xTemplateBox->set_size_request(nMaxWidth , -1);
+
+ // In the template dialog the text is not influenceable
+ m_xTextText->set_sensitive(!m_bFormat);
+ m_xTextEdit->set_sensitive(!m_bFormat);
+
+ // Metrics
+ SetFieldUnit(*m_xDistanceField, GetDfltMetric(m_bHtmlMode));
+
+ // Install handler
+ Link<weld::SpinButton&,void> aValueChangedLk = LINK(this, SwDropCapsPage, ValueChangedHdl);
+ m_xDropCapsField->connect_value_changed(aValueChangedLk);
+ m_xLinesField->connect_value_changed(aValueChangedLk);
+ Link<weld::MetricSpinButton&,void> aMetricValueChangedLk = LINK(this, SwDropCapsPage, MetricValueChangedHdl);
+ m_xDistanceField->connect_value_changed(aMetricValueChangedLk);
+ m_xTextEdit->connect_changed(LINK(this, SwDropCapsPage, ModifyHdl));
+ m_xDropCapsBox->connect_toggled(LINK(this, SwDropCapsPage, ClickHdl));
+ m_xTemplateBox->connect_changed(LINK(this, SwDropCapsPage, SelectHdl));
+ m_xWholeWordCB->connect_toggled(LINK(this, SwDropCapsPage, WholeWordHdl));
+}
+
+SwDropCapsPage::~SwDropCapsPage()
+{
+}
+
+DeactivateRC SwDropCapsPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if (_pSet)
+ FillSet(*_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SwDropCapsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwDropCapsPage>(pPage, pController, *rSet);
+}
+
+bool SwDropCapsPage::FillItemSet(SfxItemSet *rSet)
+{
+ if (m_bModified)
+ FillSet(*rSet);
+ return m_bModified;
+}
+
+void SwDropCapsPage::Reset(const SfxItemSet *rSet)
+{
+ // Characters, lines, gap and text
+ SwFormatDrop aFormatDrop( rSet->Get(RES_PARATR_DROP) );
+ if (aFormatDrop.GetLines() > 1)
+ {
+ m_xDropCapsField->set_value(aFormatDrop.GetChars());
+ m_xLinesField->set_value(aFormatDrop.GetLines());
+ m_xDistanceField->set_value(m_xDistanceField->normalize(aFormatDrop.GetDistance()), FieldUnit::TWIP);
+ m_xWholeWordCB->set_active(aFormatDrop.GetWholeWord());
+ }
+ else
+ {
+ m_xDropCapsField->set_value(1);
+ m_xLinesField->set_value(3);
+ m_xDistanceField->set_value(0, FieldUnit::TWIP);
+ }
+
+ SwView* pView = GetActiveView();
+ if (pView)
+ ::FillCharStyleListBox(*m_xTemplateBox, pView->GetWrtShell().GetView().GetDocShell(), true);
+
+ m_xTemplateBox->insert_text(0, SwResId(SW_STR_NONE));
+
+ // Reset format
+ int nSelect = 0;
+ if (aFormatDrop.GetCharFormat())
+ {
+ int nPos = m_xTemplateBox->find_text(aFormatDrop.GetCharFormat()->GetName());
+ if (nPos != -1)
+ nSelect = nPos;
+ }
+ m_xTemplateBox->set_active(nSelect);
+
+ // Enable controls
+ m_xDropCapsBox->set_active(aFormatDrop.GetLines() > 1);
+ const sal_Int32 nVal = m_xDropCapsField->get_value();
+ if (m_bFormat)
+ m_xTextEdit->set_text(GetDefaultString(nVal));
+ else
+ {
+ if (pView)
+ m_xTextEdit->set_text(pView->GetWrtShell().GetDropText(nVal));
+ m_xTextEdit->set_sensitive(true);
+ m_xTextText->set_sensitive(true);
+ }
+
+ // Preview
+ m_aPict.SetValues(m_xTextEdit->get_text(),
+ sal_uInt8(m_xLinesField->get_value()),
+ sal_uInt16(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP))));
+
+ ClickHdl(*m_xDropCapsBox);
+ m_bModified = false;
+}
+
+IMPL_LINK_NOARG(SwDropCapsPage, ClickHdl, weld::Toggleable&, void)
+{
+ bool bChecked = m_xDropCapsBox->get_active();
+
+ m_xWholeWordCB->set_sensitive(bChecked && !m_bHtmlMode);
+
+ m_xSwitchText->set_sensitive(bChecked && !m_xWholeWordCB->get_active());
+ m_xDropCapsField->set_sensitive(bChecked && !m_xWholeWordCB->get_active());
+ m_xLinesText->set_sensitive( bChecked );
+ m_xLinesField->set_sensitive( bChecked );
+ m_xDistanceText->set_sensitive( bChecked );
+ m_xDistanceField->set_sensitive( bChecked );
+ m_xTemplateText->set_sensitive( bChecked );
+ m_xTemplateBox->set_sensitive( bChecked );
+ m_xTextEdit->set_sensitive( bChecked && !m_bFormat );
+ m_xTextText->set_sensitive( bChecked && !m_bFormat );
+
+ if ( bChecked )
+ {
+ ValueChangedHdl(*m_xDropCapsField);
+ m_xDropCapsField->grab_focus();
+ }
+ else
+ m_aPict.SetText("");
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SwDropCapsPage, WholeWordHdl, weld::Toggleable&, void)
+{
+ m_xDropCapsField->set_sensitive(!m_xWholeWordCB->get_active());
+ m_xSwitchText->set_sensitive(!m_xWholeWordCB->get_active());
+
+ ValueChangedHdl(*m_xDropCapsField);
+
+ m_bModified = true;
+}
+
+void SwDropCapsPage::ModifyEntry(const weld::Entry& rEdit)
+{
+ OUString sPreview;
+
+ // set text if applicable
+ if (&rEdit == m_xDropCapsField.get())
+ {
+ const sal_Int32 nVal = !m_xWholeWordCB->get_active()
+ ? static_cast<sal_Int32>(m_xDropCapsField->get_value())
+ : 0;
+ bool bSetText = false;
+
+ if (SwView* pView = GetActiveView())
+ {
+ if (m_bFormat || pView->GetWrtShell().GetDropText(1).isEmpty())
+ sPreview = GetDefaultString(nVal);
+ else
+ {
+ bSetText = true;
+ sPreview = pView->GetWrtShell().GetDropText(nVal);
+ }
+ }
+
+ OUString sEdit(m_xTextEdit->get_text());
+
+ if (!sEdit.isEmpty() && !sPreview.startsWith(sEdit))
+ {
+ sPreview = sEdit.copy(0, std::min(sEdit.getLength(), sPreview.getLength()));
+ bSetText = false;
+ }
+
+ if (bSetText)
+ m_xTextEdit->set_text(sPreview);
+ }
+ else if (&rEdit == m_xTextEdit.get()) // set quantity if applicable
+ {
+ const sal_Int32 nTmp = m_xTextEdit->get_text().getLength();
+ m_xDropCapsField->set_value(std::max<sal_Int32>(1, nTmp));
+ sPreview = m_xTextEdit->get_text();
+ }
+
+ // adjust image
+ if (&rEdit == m_xDropCapsField.get() || &rEdit == m_xTextEdit.get())
+ m_aPict.SetText(sPreview);
+ else if (&rEdit == m_xLinesField.get())
+ m_aPict.SetLines(static_cast<sal_uInt8>(m_xLinesField->get_value()));
+ else
+ m_aPict.SetDistance(o3tl::narrowing<sal_uInt16>(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP))));
+
+ m_bModified = true;
+}
+
+IMPL_LINK(SwDropCapsPage, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ ModifyEntry(rEdit);
+}
+
+IMPL_LINK(SwDropCapsPage, ValueChangedHdl, weld::SpinButton&, rEdit, void)
+{
+ ModifyEntry(rEdit);
+}
+
+IMPL_LINK(SwDropCapsPage, MetricValueChangedHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ ModifyEntry(rEdit.get_widget());
+}
+
+IMPL_LINK_NOARG(SwDropCapsPage, SelectHdl, weld::ComboBox&, void)
+{
+ m_aPict.UpdatePaintSettings();
+ m_bModified = true;
+}
+
+void SwDropCapsPage::FillSet( SfxItemSet &rSet )
+{
+ if(!m_bModified)
+ return;
+
+ SwFormatDrop aFormat;
+
+ bool bOn = m_xDropCapsBox->get_active();
+ if (bOn)
+ {
+ // quantity, lines, gap
+ aFormat.GetChars() = static_cast<sal_uInt8>(m_xDropCapsField->get_value());
+ aFormat.GetLines() = static_cast<sal_uInt8>(m_xLinesField->get_value());
+ aFormat.GetDistance() = o3tl::narrowing<sal_uInt16>(m_xDistanceField->denormalize(m_xDistanceField->get_value(FieldUnit::TWIP)));
+ aFormat.GetWholeWord() = m_xWholeWordCB->get_active();
+
+ // template
+ if (SwView* pView = GetActiveView())
+ if (m_xTemplateBox->get_active())
+ aFormat.SetCharFormat(pView->GetWrtShell().GetCharStyle(m_xTemplateBox->get_active_text()));
+ }
+ else
+ {
+ aFormat.GetChars() = 1;
+ aFormat.GetLines() = 1;
+ aFormat.GetDistance() = 0;
+ }
+
+ // set attributes
+ const SfxPoolItem* pOldItem;
+ if (nullptr == (pOldItem = GetOldItem(rSet, FN_FORMAT_DROPCAPS)) || aFormat != *pOldItem)
+ rSet.Put(aFormat);
+
+ // hard text formatting
+ // Bug 24974: in designer/template catalog this doesn't make sense!!
+ if (!m_bFormat && m_xDropCapsBox->get_active())
+ {
+ OUString sText(m_xTextEdit->get_text());
+
+ if (!m_xWholeWordCB->get_active())
+ {
+ sText = sText.copy(0, std::min<sal_Int32>(sText.getLength(), m_xDropCapsField->get_value()));
+ }
+
+ SfxStringItem aStr(FN_PARAM_1, sText);
+ rSet.Put(aStr);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/numpara.cxx b/sw/source/ui/chrdlg/numpara.cxx
new file mode 100644
index 0000000000..65875eb79c
--- /dev/null
+++ b/sw/source/ui/chrdlg/numpara.cxx
@@ -0,0 +1,418 @@
+/* -*- 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 <cmdid.h>
+#include <swtypes.hxx>
+#include <hintids.hxx>
+#include <strings.hrc>
+#include <sfx2/objsh.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <fmtline.hxx>
+#include <numpara.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/viewsh.hxx>
+
+// tdf#115871 - reset outline and list options to parent settings
+const WhichRangesContainer SwParagraphNumTabPage::s_aPageRg(
+ svl::Items<RES_LINENUMBER, RES_LINENUMBER, SID_ATTR_PARA_NUMRULE, SID_ATTR_PARA_NUMRULE,
+ SID_ATTR_PARA_OUTLINE_LEVEL, SID_ATTR_PARA_OUTLINE_LEVEL, FN_NUMBER_NEWSTART,
+ FN_NUMBER_NEWSTART_AT>);
+
+SwParagraphNumTabPage::SwParagraphNumTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/numparapage.ui", "NumParaPage", &rAttr)
+ , msOutlineNumbering(SwResId(STR_OUTLINE_NUMBERING ))
+ , m_bModified(false)
+ , m_bCurNumrule(false)
+ , m_xOutlineStartBX(m_xBuilder->weld_widget("boxOUTLINE"))
+ , m_xOutlineLvLB(m_xBuilder->weld_combo_box("comboLB_OUTLINE_LEVEL"))
+ , m_xNumberStyleBX(m_xBuilder->weld_widget("boxNUMBER_STYLE"))
+ , m_xNumberStyleLB(m_xBuilder->weld_combo_box("comboLB_NUMBER_STYLE"))
+ , m_xEditNumStyleBtn(m_xBuilder->weld_button("editnumstyle"))
+ , m_xListLvBX(m_xBuilder->weld_widget("boxLIST_LEVEL"))
+ , m_xListLvLB(m_xBuilder->weld_combo_box("comboLB_LIST_LEVEL"))
+ , m_xNewStartCB(m_xBuilder->weld_check_button("checkCB_NEW_START"))
+ , m_xNewStartBX(m_xBuilder->weld_widget("boxNEW_START"))
+ , m_xNewStartNumberCB(m_xBuilder->weld_check_button("checkCB_NUMBER_NEW_START"))
+ , m_xNewStartNF(m_xBuilder->weld_spin_button("spinNF_NEW_START"))
+ , m_xCountParaFram(m_xBuilder->weld_widget("frameFL_COUNT_PARA"))
+ , m_xCountParaCB(m_xBuilder->weld_check_button("checkCB_COUNT_PARA"))
+ , m_xRestartParaCountCB(m_xBuilder->weld_check_button("checkCB_RESTART_PARACOUNT"))
+ , m_xRestartBX(m_xBuilder->weld_widget("boxRESTART_NO"))
+ , m_xRestartNF(m_xBuilder->weld_spin_button("spinNF_RESTART_PARA"))
+{
+ m_xNewStartCB->set_state(TRISTATE_FALSE);
+ m_xNewStartNumberCB->set_state(TRISTATE_FALSE);
+ m_xCountParaCB->set_state(TRISTATE_FALSE);
+ m_xRestartParaCountCB->set_state(TRISTATE_FALSE);
+ m_xEditNumStyleBtn->set_sensitive(false);
+
+ const SfxUInt16Item* pItem = rAttr.GetItemIfSet(SID_HTML_MODE, false);
+ if (!pItem)
+ {
+ if (SfxObjectShell* pObjSh = SfxObjectShell::Current())
+ pItem = pObjSh->GetItem(SID_HTML_MODE);
+ }
+ if(pItem)
+ {
+ const sal_uInt16 nHtmlMode = pItem->GetValue();
+
+ if (HTMLMODE_ON & nHtmlMode)
+ m_xCountParaFram->hide();
+ }
+
+ m_xNewStartCB->connect_toggled(LINK(this, SwParagraphNumTabPage, NewStartHdl_Impl));
+ m_xNewStartNumberCB->connect_toggled(LINK(this, SwParagraphNumTabPage, NewStartHdl_Impl));
+ m_xNumberStyleLB->connect_changed(LINK(this, SwParagraphNumTabPage, StyleHdl_Impl));
+ m_xCountParaCB->connect_toggled(LINK(this, SwParagraphNumTabPage, LineCountHdl_Impl));
+ m_xRestartParaCountCB->connect_toggled(LINK(this, SwParagraphNumTabPage, LineCountHdl_Impl));
+ m_xNumberStyleLB->connect_changed(LINK(this, SwParagraphNumTabPage, EditNumStyleSelectHdl_Impl));
+ m_xEditNumStyleBtn->connect_clicked(LINK(this, SwParagraphNumTabPage, EditNumStyleHdl_Impl));
+
+ if (officecfg::Office::Common::Misc::ExperimentalMode::get())
+ m_xListLvBX->show();
+ else
+ m_xListLvBX->hide();
+}
+
+SwParagraphNumTabPage::~SwParagraphNumTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwParagraphNumTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwParagraphNumTabPage>(pPage, pController, *rSet);
+}
+
+bool SwParagraphNumTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if (m_xOutlineLvLB->get_value_changed_from_saved())
+ {
+ const sal_uInt16 aOutlineLv = m_xOutlineLvLB->get_active();
+ const SfxUInt16Item* pOldOutlineLv = GetOldItem( *rSet, SID_ATTR_PARA_OUTLINE_LEVEL);
+ if (pOldOutlineLv)
+ {
+ std::unique_ptr<SfxUInt16Item> pOutlineLv(pOldOutlineLv->Clone());
+ pOutlineLv->SetValue( aOutlineLv );
+ rSet->Put(std::move(pOutlineLv));
+ m_bModified = true;
+
+ // Does List Level need to be set to be the same as Outline Level?
+ if (!m_xListLvLB->get_active() && m_xListLvBX->get_visible()
+ && !m_xListLvLB->get_value_changed_from_saved())
+ {
+ sal_Int16 nListLevel = std::max<sal_Int16>(1, aOutlineLv);
+ --nListLevel; // Outline Level is 1 based. List Level is zero based.
+ rSet->Put(SfxInt16Item(RES_PARATR_LIST_LEVEL, nListLevel));
+ }
+ }
+ }
+
+ if (m_xListLvLB->get_value_changed_from_saved())
+ {
+ if (m_xListLvBX->get_visible())
+ {
+ sal_Int16 nListLevel = m_xListLvLB->get_active();
+ // Does List Level need to be set to be the same as Outline Level?
+ if (!nListLevel)
+ {
+ nListLevel = std::max<sal_Int16>(1, m_xOutlineLvLB->get_active());
+ }
+ --nListLevel; // List Level is zero based, but both listboxes are 1-based.
+
+ rSet->Put(SfxInt16Item(RES_PARATR_LIST_LEVEL, nListLevel));
+ m_bModified = true;
+ }
+ }
+
+ if (m_xNumberStyleLB->get_value_changed_from_saved())
+ {
+ OUString aStyle;
+ if (m_xNumberStyleLB->get_active())
+ aStyle = m_xNumberStyleLB->get_active_text();
+ const SfxStringItem* pOldRule = static_cast<const SfxStringItem*>(GetOldItem( *rSet, SID_ATTR_PARA_NUMRULE));
+ if (pOldRule)
+ {
+ std::unique_ptr<SfxStringItem> pRule(pOldRule->Clone());
+ pRule->SetValue(aStyle);
+ rSet->Put(std::move(pRule));
+ m_bModified = true;
+ }
+ }
+ if (m_xNewStartCB->get_state_changed_from_saved() ||
+ m_xNewStartNumberCB->get_state_changed_from_saved()||
+ m_xNewStartNF->get_value_changed_from_saved())
+ {
+ m_bModified = true;
+ bool bNewStartChecked = TRISTATE_TRUE == m_xNewStartCB->get_state();
+ bool bNumberNewStartChecked = TRISTATE_TRUE == m_xNewStartNumberCB->get_state();
+ rSet->Put(SfxBoolItem(FN_NUMBER_NEWSTART, bNewStartChecked));
+ rSet->Put(SfxUInt16Item(FN_NUMBER_NEWSTART_AT,
+ bNumberNewStartChecked && bNewStartChecked ? o3tl::narrowing<sal_uInt16>(m_xNewStartNF->get_value()) : USHRT_MAX));
+ }
+
+ if (m_xCountParaCB->get_state_changed_from_saved()||
+ m_xRestartParaCountCB->get_state_changed_from_saved() ||
+ m_xRestartNF->get_value_changed_from_saved())
+ {
+ SwFormatLineNumber aFormat;
+ aFormat.SetStartValue( static_cast< sal_uLong >(m_xRestartParaCountCB->get_state() == TRISTATE_TRUE ?
+ m_xRestartNF->get_value() : 0 ));
+ aFormat.SetCountLines(m_xCountParaCB->get_active());
+ rSet->Put(aFormat);
+ m_bModified = true;
+ }
+ return m_bModified;
+}
+
+void SwParagraphNumTabPage::ChangesApplied()
+{
+ m_xOutlineLvLB->save_value();
+ m_xNumberStyleLB->save_value();
+ m_xListLvLB->save_value();
+ m_xNewStartCB->save_state();
+ m_xNewStartNumberCB->save_state();
+ m_xCountParaCB->save_state();
+ m_xRestartParaCountCB->save_state();
+ m_xRestartNF->save_value();
+}
+
+void SwParagraphNumTabPage::Reset(const SfxItemSet* rSet)
+{
+ bool bHasNumberStyle = false;
+
+ SfxItemState eItemState = rSet->GetItemState( GetWhich(SID_ATTR_PARA_OUTLINE_LEVEL) );
+
+ sal_Int16 nOutlineLv = 1; // 0 is Text Body, 1 is level 1
+ if( eItemState >= SfxItemState::DEFAULT )
+ {
+ nOutlineLv = rSet->Get( GetWhich(SID_ATTR_PARA_OUTLINE_LEVEL) ).GetValue();
+ m_xOutlineLvLB->set_active(nOutlineLv) ;
+ }
+ else
+ {
+ m_xOutlineLvLB->set_active(-1);
+ }
+ m_xOutlineLvLB->save_value();
+
+ eItemState = rSet->GetItemState(RES_PARATR_LIST_LEVEL);
+ if (eItemState >= SfxItemState::DEFAULT)
+ {
+ sal_Int16 nListLevel = rSet->Get(RES_PARATR_LIST_LEVEL).GetValue(); // 0 is level 1
+ // Although listLevel doesn't have outline's "Text Body" level, treat it the same as level 1
+ // so that if the outline level is either 0 or 1, it is considered equal to list level 1.
+ // This is a rather crucial discrepancy - otherwise the user will rarely see
+ // list level using the special "Same as outline level,
+ // and the highly desirable state of keeping the two in sync will rarely be achieved.
+ if ((!nOutlineLv && !nListLevel) || nListLevel == nOutlineLv - 1)
+ m_xListLvLB->set_active(0); // highly encourage using "Same as outline level"
+ else
+ m_xListLvLB->set_active(nListLevel + 1);
+ }
+ else
+ {
+ m_xListLvBX->hide();
+ }
+ m_xListLvLB->save_value();
+
+ eItemState = rSet->GetItemState( GetWhich(SID_ATTR_PARA_NUMRULE) );
+
+ if( eItemState >= SfxItemState::DEFAULT )
+ {
+ OUString aStyle = static_cast<const SfxStringItem &>(rSet->Get( GetWhich(SID_ATTR_PARA_NUMRULE) )).GetValue();
+ if(aStyle.isEmpty())
+ aStyle = m_xNumberStyleLB->get_text(0);
+
+ if( aStyle == "Outline")
+ {
+ if (m_xNumberStyleLB->find_id("pseudo") == -1)
+ {
+ // tdf#145804 show "Chapter Numbering"
+ m_xNumberStyleLB->append("pseudo", msOutlineNumbering);
+ }
+ m_xNumberStyleLB->set_active_id("pseudo");
+ m_xNumberStyleLB->save_value();
+ }
+ else
+ m_xNumberStyleLB->set_active_text(aStyle);
+
+ bHasNumberStyle = true;
+ }
+ else
+ {
+ m_xNumberStyleLB->set_active(-1);
+ }
+
+ if (m_xNumberStyleBX->get_sensitive())
+ EditNumStyleSelectHdl_Impl(*m_xNumberStyleLB);
+
+ m_xNumberStyleLB->save_value();
+
+ eItemState = rSet->GetItemState( FN_NUMBER_NEWSTART );
+ if(eItemState > SfxItemState::DEFAULT )
+ {
+ m_bCurNumrule = true;
+ const SfxBoolItem& rStart = static_cast<const SfxBoolItem&>(rSet->Get(FN_NUMBER_NEWSTART));
+
+ m_xNewStartCB->set_state(rStart.GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xNewStartCB->set_state(bHasNumberStyle ? TRISTATE_FALSE : TRISTATE_INDET);
+
+ m_xNewStartCB->save_state();
+
+ eItemState = rSet->GetItemState( FN_NUMBER_NEWSTART_AT);
+ if( eItemState > SfxItemState::DEFAULT )
+ {
+ const sal_uInt16 nNewStart = rSet->Get(FN_NUMBER_NEWSTART_AT).GetValue();
+ const bool bNotMax = USHRT_MAX != nNewStart;
+ m_xNewStartNumberCB->set_active(bNotMax);
+ m_xNewStartNF->set_value(bNotMax ? nNewStart : 1);
+ }
+ else
+ m_xNewStartCB->set_state(TRISTATE_INDET);
+ NewStartHdl_Impl(*m_xNewStartCB);
+ m_xNewStartNF->save_value();
+ m_xNewStartNumberCB->save_state();
+ StyleHdl_Impl(*m_xNumberStyleLB);
+ if( SfxItemState::DEFAULT <= rSet->GetItemState(RES_LINENUMBER))
+ {
+ const SwFormatLineNumber& rNum = rSet->Get(RES_LINENUMBER);
+ sal_uLong nStartValue = rNum.GetStartValue();
+ bool bCount = rNum.IsCount();
+ m_xCountParaCB->set_state(bCount ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xRestartParaCountCB->set_state(0 != nStartValue ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xRestartNF->set_value(nStartValue == 0 ? 1 : nStartValue);
+ LineCountHdl_Impl(*m_xCountParaCB);
+ }
+ else
+ {
+ m_xCountParaCB->set_state(TRISTATE_INDET);
+ m_xRestartParaCountCB->set_state(TRISTATE_INDET);
+ }
+ m_xCountParaCB->save_state();
+ m_xRestartParaCountCB->save_state();
+ m_xRestartNF->save_value();
+
+ m_bModified = false;
+}
+
+void SwParagraphNumTabPage::DisableOutline()
+{
+ m_xOutlineStartBX->set_sensitive(false);
+ m_xOutlineStartBX->set_tooltip_text( SwResId(STR_OUTLINENUMBERING_DISABLED) );
+}
+
+void SwParagraphNumTabPage::DisableNumbering()
+{
+ m_xNumberStyleBX->set_sensitive(false);
+ m_xNumberStyleBX->set_tooltip_text( SwResId(STR_OUTLINENUMBERING_DISABLED) );
+ m_xListLvBX->set_sensitive(false);
+}
+
+void SwParagraphNumTabPage::EnableNewStart()
+{
+ m_xNewStartCB->show();
+ m_xNewStartBX->show();
+}
+
+IMPL_LINK_NOARG(SwParagraphNumTabPage, NewStartHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xNewStartCB->get_active();
+ m_xNewStartNumberCB->set_sensitive(bEnable);
+ m_xNewStartNF->set_sensitive(bEnable && m_xNewStartNumberCB->get_active());
+}
+
+IMPL_LINK_NOARG(SwParagraphNumTabPage, LineCountHdl_Impl, weld::Toggleable&, void)
+{
+ m_xRestartParaCountCB->set_sensitive(m_xCountParaCB->get_active());
+
+ bool bEnableRestartValue = m_xRestartParaCountCB->get_sensitive() &&
+ m_xRestartParaCountCB->get_active();
+ m_xRestartBX->set_sensitive(bEnableRestartValue);
+}
+
+IMPL_LINK_NOARG(SwParagraphNumTabPage, EditNumStyleSelectHdl_Impl, weld::ComboBox&, void)
+{
+ int numSelectPos = m_xNumberStyleLB->get_active();
+ // 0 is "None" and -1 is unselected state and a "pseudo" is uneditable "Chapter Numbering"
+ if (numSelectPos == 0 || numSelectPos == -1 || m_xNumberStyleLB->get_active_id() == "pseudo")
+ {
+ m_xEditNumStyleBtn->set_sensitive(false);
+ m_xListLvBX->set_sensitive(false);
+ }
+ else
+ {
+ m_xEditNumStyleBtn->set_sensitive(true);
+ m_xListLvBX->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SwParagraphNumTabPage, EditNumStyleHdl_Impl, weld::Button&, void)
+{
+ OUString aTemplName(m_xNumberStyleLB->get_active_text());
+ ExecuteEditNumStyle_Impl( SID_STYLE_EDIT, aTemplName, SfxStyleFamily::Pseudo );
+}
+
+// Internal: Perform functions through the Dispatcher
+void SwParagraphNumTabPage::ExecuteEditNumStyle_Impl(
+ sal_uInt16 nId, const OUString &rStr, SfxStyleFamily nFamily)
+{
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+
+ if( !pViewShell)
+ return;
+
+ SfxDispatcher* pDispatcher = pViewShell->GetDispatcher();
+ SfxStringItem aItem(nId, rStr);
+ SfxUInt16Item aFamily(SID_STYLE_FAMILY, static_cast<sal_uInt16>(nFamily));
+ const SfxPoolItem* pItems[ 3 ];
+ sal_uInt16 nCount = 0;
+ if( !rStr.isEmpty() )
+ pItems[ nCount++ ] = &aItem;
+ pItems[ nCount++ ] = &aFamily;
+
+ pItems[ nCount++ ] = nullptr;
+
+ // tdf#145363 we want the current dialog to be the parent of the new dialog
+ weld::Window* pDialogParent = GetFrameWeld();
+ css::uno::Any aAny(pDialogParent->GetXWindow());
+ SfxUnoAnyItem aDialogParent(SID_DIALOG_PARENT, aAny);
+ const SfxPoolItem* pInternalItems[ 2 ];
+ pInternalItems[ 0 ] = &aDialogParent;
+ pInternalItems[ 1 ] = nullptr;
+
+ pDispatcher->Execute(
+ nId, SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
+ pItems, 0, pInternalItems);
+}
+
+IMPL_LINK(SwParagraphNumTabPage, StyleHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ bool bEnable = m_bCurNumrule || rBox.get_active() > 0;
+ m_xNewStartCB->set_sensitive(bEnable);
+ NewStartHdl_Impl(*m_xNewStartCB);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/pardlg.cxx b/sw/source/ui/chrdlg/pardlg.cxx
new file mode 100644
index 0000000000..379ee335ca
--- /dev/null
+++ b/sw/source/ui/chrdlg/pardlg.cxx
@@ -0,0 +1,245 @@
+/* -*- 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/htmlmode.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svl/style.hxx>
+#include <svl/cjkoptions.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <swuipardlg.hxx>
+#include <pardlg.hxx>
+#include <drpcps.hxx>
+#include <viewopt.hxx>
+#include <numpara.hxx>
+#include <strings.hrc>
+#include <svx/svxids.hrc>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/flagsdef.hxx>
+#include <osl/diagnose.h>
+#include <officecfg/Office/Common.hxx>
+
+SwParaDlg::SwParaDlg(weld::Window *pParent,
+ SwView& rVw,
+ const SfxItemSet& rCoreSet,
+ sal_uInt8 nDialogMode,
+ const OUString *pTitle,
+ bool bDraw,
+ const OUString& sDefPage)
+ : SfxTabDialogController(pParent,
+ "modules/swriter/ui/paradialog.ui",
+ "ParagraphPropertiesDialog",
+ &rCoreSet, nullptr != pTitle)
+ , m_rView(rVw)
+ , m_bDrawParaDlg(bDraw)
+{
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(rVw.GetDocShell());
+ bool bHtmlMode = (nHtmlMode & HTMLMODE_ON) == HTMLMODE_ON;
+ if(pTitle)
+ {
+ // Update title
+ m_xDialog->set_title(m_xDialog->get_title() + SwResId(STR_TEXTCOLL_HEADER) + *pTitle + ")");
+ }
+ // tabs common to paragraph and draw paragraphs (paragraphs inside a text box)
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+
+ OSL_ENSURE(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_STD_PARAGRAPH), "GetTabPageCreatorFunc fail!");
+ OSL_ENSURE(pFact->GetTabPageRangesFunc(RID_SVXPAGE_STD_PARAGRAPH), "GetTabPageRangesFunc fail!");
+ AddTabPage("labelTP_PARA_STD", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_STD_PARAGRAPH),
+ pFact->GetTabPageRangesFunc(RID_SVXPAGE_STD_PARAGRAPH) );
+
+ OSL_ENSURE(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_ALIGN_PARAGRAPH), "GetTabPageCreatorFunc fail!");
+ OSL_ENSURE(pFact->GetTabPageRangesFunc(RID_SVXPAGE_ALIGN_PARAGRAPH), "GetTabPageRangesFunc fail!");
+ AddTabPage("labelTP_PARA_ALIGN", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_ALIGN_PARAGRAPH),
+ pFact->GetTabPageRangesFunc(RID_SVXPAGE_ALIGN_PARAGRAPH));
+
+ if (!m_bDrawParaDlg && (!bHtmlMode || officecfg::Office::Common::Filter::HTML::Export::PrintLayout::get()))
+ {
+ OSL_ENSURE(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_EXT_PARAGRAPH), "GetTabPageCreatorFunc fail!");
+ OSL_ENSURE(pFact->GetTabPageRangesFunc(RID_SVXPAGE_EXT_PARAGRAPH), "GetTabPageRangesFunc fail!");
+ AddTabPage("textflow", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_EXT_PARAGRAPH),
+ pFact->GetTabPageRangesFunc(RID_SVXPAGE_EXT_PARAGRAPH));
+
+ }
+ else
+ RemoveTabPage("textflow");
+
+ if(!bHtmlMode && SvtCJKOptions::IsAsianTypographyEnabled())
+ {
+ OSL_ENSURE(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN), "GetTabPageCreatorFunc fail!");
+ OSL_ENSURE(pFact->GetTabPageRangesFunc(RID_SVXPAGE_PARA_ASIAN), "GetTabPageRangesFunc fail!");
+ AddTabPage( "labelTP_PARA_ASIAN", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN),
+ pFact->GetTabPageRangesFunc(RID_SVXPAGE_PARA_ASIAN) );
+ }
+ else
+ RemoveTabPage("labelTP_PARA_ASIAN");
+
+ if(bHtmlMode)
+ RemoveTabPage("labelTP_TABULATOR");
+ else
+ {
+ OSL_ENSURE(pFact->GetTabPageCreatorFunc(RID_SVXPAGE_TABULATOR), "GetTabPageCreatorFunc fail!");
+ OSL_ENSURE(pFact->GetTabPageRangesFunc(RID_SVXPAGE_TABULATOR), "GetTabPageRangesFunc fail!");
+ AddTabPage( "labelTP_TABULATOR", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_TABULATOR), pFact->GetTabPageRangesFunc(RID_SVXPAGE_TABULATOR) );
+ }
+
+ // remove unwanted tabs for draw text box paragraph properties
+ if (m_bDrawParaDlg)
+ {
+ RemoveTabPage("labelTP_NUMPARA");
+ RemoveTabPage("labelTP_DROPCAPS");
+ RemoveTabPage("labelTP_BORDER");
+ RemoveTabPage("area");
+ RemoveTabPage("transparence");
+ }
+ else
+ {
+ if(!(nDialogMode & DLG_ENVELOP))
+ AddTabPage("labelTP_NUMPARA", SwParagraphNumTabPage::Create, SwParagraphNumTabPage::GetRanges);
+ else
+ RemoveTabPage("labelTP_NUMPARA");
+
+ AddTabPage("labelTP_DROPCAPS", SwDropCapsPage::Create, SwDropCapsPage::GetRanges);
+
+ if(!bHtmlMode || (nHtmlMode & (HTMLMODE_SOME_STYLES|HTMLMODE_FULL_STYLES)))
+ {
+ // add Area and Transparence TabPages
+ AddTabPage("area", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_AREA ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_AREA ));
+ AddTabPage("transparence", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TRANSPARENCE ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_TRANSPARENCE ) );
+ }
+ else
+ {
+ RemoveTabPage("area");
+ RemoveTabPage("transparence");
+ }
+
+ OSL_ENSURE(pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), "GetTabPageCreatorFunc fail!");
+ OSL_ENSURE(pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ), "GetTabPageRangesFunc fail!");
+ AddTabPage("labelTP_BORDER", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ) );
+ }
+
+ if (!sDefPage.isEmpty())
+ SetCurPageId(sDefPage);
+}
+
+SwParaDlg::~SwParaDlg()
+{
+}
+
+void SwParaDlg::PageCreated(const OUString& rId, SfxTabPage& rPage)
+{
+ SwWrtShell& rSh = m_rView.GetWrtShell();
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+
+ // Table borders cannot get any shade in Writer
+ if (rId == "labelTP_BORDER")
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE,static_cast<sal_uInt16>(SwBorderModes::PARA)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "labelTP_PARA_STD")
+ {
+ aSet.Put(SfxUInt16Item(SID_SVXSTDPARAGRAPHTABPAGE_PAGEWIDTH,
+ static_cast< sal_uInt16 >(rSh.GetAnyCurRect(CurRectType::PagePrt).Width()) ));
+
+ if (!m_bDrawParaDlg)
+ {
+ // See SvxStdParagraphTabPage::PageCreated: enable RegisterMode, AutoFirstLine, NegativeMode, ContextualMode
+ constexpr tools::Long constTwips_0_5mm = o3tl::toTwips(5, o3tl::Length::mm10);
+ aSet.Put(SfxUInt32Item(SID_SVXSTDPARAGRAPHTABPAGE_FLAGSET,0x0002|0x0004|0x0008|0x0010));
+ aSet.Put(SfxUInt32Item(SID_SVXSTDPARAGRAPHTABPAGE_ABSLINEDIST, constTwips_0_5mm));
+
+ }
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "labelTP_PARA_ALIGN")
+ {
+ if (!m_bDrawParaDlg)
+ {
+ aSet.Put(SfxBoolItem(SID_SVXPARAALIGNTABPAGE_ENABLEJUSTIFYEXT,true));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "textflow")
+ {
+ // pagebreak only when the cursor is in the body-area and not in a table
+ const FrameTypeFlags eType = rSh.GetFrameType(nullptr,true);
+ if( !(FrameTypeFlags::BODY & eType) ||
+ rSh.GetSelectionType() & SelectionType::Table )
+ {
+ aSet.Put(SfxBoolItem(SID_DISABLE_SVXEXTPARAGRAPHTABPAGE_PAGEBREAK,true));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "labelTP_DROPCAPS")
+ {
+ static_cast<SwDropCapsPage&>(rPage).SetFormat(false);
+ }
+ else if (rId == "labelTP_NUMPARA")
+ {
+ SwTextFormatColl* pTmpColl = rSh.GetCurTextFormatColl();
+ if( pTmpColl && pTmpColl->IsAssignedToListLevelOfOutlineStyle() )
+ {
+ static_cast<SwParagraphNumTabPage&>(rPage).DisableOutline() ;
+ }
+
+ static_cast<SwParagraphNumTabPage&>(rPage).EnableNewStart();
+ weld::ComboBox& rBox = static_cast<SwParagraphNumTabPage&>(rPage).GetStyleBox();
+ SfxStyleSheetBasePool* pPool = m_rView.GetDocShell()->GetStyleSheetPool();
+ const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Pseudo);
+ std::set<OUString> aNames;
+ while(pBase)
+ {
+ aNames.insert(pBase->GetName());
+ pBase = pPool->Next();
+ }
+ aNames.erase(SwResId(STR_POOLNUMRULE_NOLIST));
+ for (const auto& rName : aNames)
+ rBox.append_text(rName);
+ }
+ // 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 (rId == "area")
+ {
+ SfxItemSetFixed
+ <SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_OFFER_IMPORT, SID_OFFER_IMPORT> aNew(*aSet.GetPool());
+
+ aNew.Put(*GetInputSetImpl());
+
+ // add flag for direct graphic content selection
+ aNew.Put(SfxBoolItem(SID_OFFER_IMPORT, true));
+
+ rPage.PageCreated(aNew);
+ }
+ else if (rId == "transparence")
+ {
+ rPage.PageCreated(*GetInputSetImpl());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/swuiccoll.cxx b/sw/source/ui/chrdlg/swuiccoll.cxx
new file mode 100644
index 0000000000..8dddc8a410
--- /dev/null
+++ b/sw/source/ui/chrdlg/swuiccoll.cxx
@@ -0,0 +1,247 @@
+/* -*- 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 <cmdid.h>
+#include <o3tl/safeint.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+
+#include <sfx2/styfitem.hxx>
+
+#include <ccoll.hxx>
+#include <fmtcol.hxx>
+#include <hintids.hxx>
+#include <docsh.hxx>
+
+#include <swuiccoll.hxx>
+
+const WhichRangesContainer SwCondCollPage::s_aPageRg(svl::Items<FN_COND_COLL, FN_COND_COLL>);
+
+SwCondCollPage::SwCondCollPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/conditionpage.ui", "ConditionPage", &rSet)
+ , m_pCmds(SwCondCollItem::GetCmds())
+ , m_pFormat(nullptr)
+ , m_xTbLinks(m_xBuilder->weld_tree_view("links"))
+ , m_xStyleLB(m_xBuilder->weld_tree_view("styles"))
+ , m_xFilterLB(m_xBuilder->weld_combo_box("filter"))
+ , m_xRemovePB(m_xBuilder->weld_button("remove"))
+ , m_xAssignPB(m_xBuilder->weld_button("apply"))
+{
+ m_xStyleLB->make_sorted();
+ const auto nHeightRequest = m_xStyleLB->get_height_rows(12);
+ m_xStyleLB->set_size_request(-1, nHeightRequest);
+ m_xTbLinks->set_size_request(-1, nHeightRequest);
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xTbLinks->get_approximate_digit_width() * 40)
+ };
+ m_xTbLinks->set_column_fixed_widths(aWidths);
+
+ const sal_Int32 nStrCount = m_xFilterLB->get_count();
+ for (sal_Int32 i = 0; i < nStrCount; ++i)
+ m_aStrArr.push_back(m_xFilterLB->get_text(i));
+ m_xFilterLB->clear();
+
+ SetExchangeSupport();
+
+ // Install handlers
+ m_xTbLinks->connect_row_activated(LINK(this, SwCondCollPage, AssignRemoveTreeListBoxHdl));
+ m_xStyleLB->connect_row_activated(LINK(this, SwCondCollPage, AssignRemoveTreeListBoxHdl));
+ m_xRemovePB->connect_clicked(LINK(this, SwCondCollPage, AssignRemoveClickHdl));
+ m_xAssignPB->connect_clicked(LINK(this, SwCondCollPage, AssignRemoveClickHdl));
+ m_xTbLinks->connect_changed(LINK(this, SwCondCollPage, SelectTreeListBoxHdl));
+ m_xStyleLB->connect_changed(LINK(this, SwCondCollPage, SelectTreeListBoxHdl));
+ m_xFilterLB->connect_changed(LINK(this, SwCondCollPage, SelectListBoxHdl));
+
+ std::optional<SfxStyleFamilies> xFamilies(SW_MOD()->CreateStyleFamilies());
+ size_t nCount = xFamilies->size();
+ for (size_t j = 0; j < nCount; ++j)
+ {
+ const SfxStyleFamilyItem &rFamilyItem = xFamilies->at(j);
+ if (SfxStyleFamily::Para == rFamilyItem.GetFamily())
+ {
+ const SfxStyleFilter& rFilterList = rFamilyItem.GetFilterList();
+ for (size_t i = 0; i < rFilterList.size(); ++i)
+ m_xFilterLB->append(OUString::number(int(rFilterList[i].nFlags)), rFilterList[i].aName);
+ break;
+ }
+ }
+
+ m_xFilterLB->set_active(0);
+ m_xTbLinks->show();
+}
+
+SwCondCollPage::~SwCondCollPage()
+{
+}
+
+DeactivateRC SwCondCollPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if( _pSet )
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SwCondCollPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwCondCollPage>(pPage, pController, *rSet);
+}
+
+bool SwCondCollPage::FillItemSet(SfxItemSet *rSet)
+{
+ SwCondCollItem aCondItem;
+ for (size_t i = 0; i < m_aStrArr.size(); ++i)
+ {
+ const OUString sEntry = m_xTbLinks->get_text(i, 1);
+ aCondItem.SetStyle( &sEntry, i);
+ }
+ rSet->Put(aCondItem);
+ return true;
+}
+
+void SwCondCollPage::Reset(const SfxItemSet *)
+{
+ m_xTbLinks->clear();
+ m_xStyleLB->clear();
+
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+
+ SfxStyleSheetBasePool* pPool = pView->GetWrtShell().GetView().GetDocShell()->GetStyleSheetPool();
+ const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Para);
+ while (pBase)
+ {
+ if (!m_pFormat || pBase->GetName() != m_pFormat->GetName())
+ m_xStyleLB->append_text(pBase->GetName());
+ pBase = pPool->Next();
+ }
+ m_xStyleLB->select(0);
+
+ for (size_t n = 0; n < m_aStrArr.size(); ++n)
+ {
+ m_xTbLinks->append_text(m_aStrArr[n]);
+
+ const SwCollCondition* pCond = nullptr;
+ if( m_pFormat && RES_CONDTXTFMTCOLL == m_pFormat->Which() &&
+ nullptr != ( pCond = static_cast<SwConditionTextFormatColl*>(m_pFormat)->
+ HasCondition( SwCollCondition( nullptr, m_pCmds[n].nCnd, m_pCmds[n].nSubCond ) ) )
+ && pCond->GetTextFormatColl() )
+ {
+ m_xTbLinks->set_text(n, pCond->GetTextFormatColl()->GetName(), 1);
+ }
+
+ if (0 == n)
+ {
+ m_xTbLinks->select(0);
+ SelectTreeListBoxHdl(*m_xTbLinks);
+ }
+ }
+}
+
+IMPL_LINK(SwCondCollPage, AssignRemoveClickHdl, weld::Button&, rBtn, void)
+{
+ AssignRemove(&rBtn);
+}
+
+IMPL_LINK(SwCondCollPage, AssignRemoveTreeListBoxHdl, weld::TreeView&, rBtn, bool)
+{
+ AssignRemove(&rBtn);
+ return true;
+}
+
+void SwCondCollPage::AssignRemove(const weld::Widget* pBtn)
+{
+ int nPos = m_xTbLinks->get_selected_index();
+ if (nPos == -1)
+ {
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != m_xRemovePB.get() && m_xAssignPB->get_sensitive();
+ m_xAssignPB->set_sensitive(!bAssEnabled);
+ m_xRemovePB->set_sensitive(bAssEnabled);
+ if (bAssEnabled)
+ m_xTbLinks->set_text(nPos, m_xStyleLB->get_selected_text(), 1);
+ else
+ m_xTbLinks->set_text(nPos, "", 1);
+}
+
+IMPL_LINK(SwCondCollPage, SelectTreeListBoxHdl, weld::TreeView&, rBox, void)
+{
+ SelectHdl(&rBox);
+}
+
+IMPL_LINK(SwCondCollPage, SelectListBoxHdl, weld::ComboBox&, rBox, void)
+{
+ SelectHdl(&rBox);
+}
+
+void SwCondCollPage::SelectHdl(const weld::Widget* pBox)
+{
+ if (pBox == m_xFilterLB.get())
+ {
+ m_xStyleLB->clear();
+
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+
+ const sal_Int32 nSelPos = m_xFilterLB->get_active();
+ const SfxStyleSearchBits nSearchFlags = static_cast<SfxStyleSearchBits>(m_xFilterLB->get_id(nSelPos).toInt32());
+ SfxStyleSheetBasePool* pPool = pView->GetWrtShell().GetView().GetDocShell()->GetStyleSheetPool();
+ const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Para, nSearchFlags);
+
+ bool bEmpty = true;
+ while (pBase)
+ {
+ if (!m_pFormat || pBase->GetName() != m_pFormat->GetName())
+ {
+ m_xStyleLB->append_text(pBase->GetName());
+ bEmpty = false;
+ }
+ pBase = pPool->Next();
+ }
+ m_xStyleLB->select(bEmpty ? -1 : 0);
+ SelectHdl(m_xStyleLB.get());
+ }
+ else
+ {
+ int nSelected = m_xTbLinks->get_selected_index();
+ const OUString sTbEntry = nSelected != -1
+ ? m_xTbLinks->get_text(nSelected, 1)
+ : OUString();
+ const OUString sStyle = m_xStyleLB->get_selected_text();
+
+ m_xAssignPB->set_sensitive(sStyle != sTbEntry);
+
+ if (pBox != m_xStyleLB.get())
+ m_xRemovePB->set_sensitive(!sTbEntry.isEmpty());
+ }
+}
+
+void SwCondCollPage::SetCollection(SwFormat* pFormat)
+{
+ m_pFormat = pFormat;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/tblnumfm.cxx b/sw/source/ui/chrdlg/tblnumfm.cxx
new file mode 100644
index 0000000000..dd3f575e2b
--- /dev/null
+++ b/sw/source/ui/chrdlg/tblnumfm.cxx
@@ -0,0 +1,46 @@
+/* -*- 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/numinf.hxx>
+#include <tblnumfm.hxx>
+
+#include <svx/dialogs.hrc>
+#include <svl/itemset.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/tabdlg.hxx>
+
+SwNumFormatDlg::SwNumFormatDlg(weld::Widget* pParent, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet, "cui/ui/formatnumberdialog.ui", "FormatNumberDialog")
+ , m_xContent( m_xBuilder->weld_container("content") )
+{
+ // Create TabPage
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc(RID_SVXPAGE_NUMBERFORMAT);
+ if ( fnCreatePage )
+ {
+ std::unique_ptr<SfxTabPage> xNewPage = (*fnCreatePage)(m_xContent.get(), this, &rSet);
+ SfxAllItemSet aSet(*(rSet.GetPool()));
+ aSet.Put(xNewPage->GetItemSet().Get( SID_ATTR_NUMBERFORMAT_INFO));
+ xNewPage->PageCreated(aSet);
+ SetTabPage(std::move(xNewPage));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/config/mailconfigpage.cxx b/sw/source/ui/config/mailconfigpage.cxx
new file mode 100644
index 0000000000..0bf9633abd
--- /dev/null
+++ b/sw/source/ui/config/mailconfigpage.cxx
@@ -0,0 +1,578 @@
+/* -*- 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 <swtypes.hxx>
+#include <mailconfigpage.hxx>
+#include <mmconfigitem.hxx>
+#include <mailmergehelper.hxx>
+#include <officecfg/Office/Writer.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/mail/MailServiceType.hpp>
+#include <com/sun/star/mail/XMailService.hpp>
+#include <com/sun/star/mail/MailServiceProvider.hpp>
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::mail;
+using namespace ::com::sun::star::beans;
+
+class SwTestAccountSettingsDialog : public SfxDialogController
+{
+ ImplSVEvent* m_pPostedEvent;
+ OUString m_sCompleted;
+ OUString m_sFailed;
+ OUString m_sErrorServer;
+ bool m_bStop;
+
+ SwMailConfigPage* m_pParent;
+
+ std::unique_ptr<weld::Button> m_xStopPB;
+ std::unique_ptr<weld::TextView> m_xErrorsED;
+ std::unique_ptr<weld::Label> m_xResult1;
+ std::unique_ptr<weld::Label> m_xResult2;
+ std::unique_ptr<weld::Image> m_xImage1;
+ std::unique_ptr<weld::Image> m_xImage2;
+ std::unique_ptr<weld::Image> m_xImage3;
+ std::unique_ptr<weld::Image> m_xImage4;
+
+ void Test();
+ DECL_LINK(StopHdl, weld::Button&, void);
+ DECL_LINK(TestHdl, void*, void);
+public:
+ explicit SwTestAccountSettingsDialog(SwMailConfigPage* pParent);
+ virtual ~SwTestAccountSettingsDialog() override;
+};
+
+namespace {
+
+class SwAuthenticationSettingsDialog : public SfxDialogController
+{
+ SwMailMergeConfigItem& m_rConfigItem;
+
+ std::unique_ptr<weld::CheckButton> m_xAuthenticationCB;
+ std::unique_ptr<weld::Widget> m_xAuthenticationImg;
+ std::unique_ptr<weld::RadioButton> m_xSeparateAuthenticationRB;
+ std::unique_ptr<weld::Widget> m_xSeparateAuthenticationImg;
+ std::unique_ptr<weld::RadioButton> m_xSMTPAfterPOPRB;
+ std::unique_ptr<weld::Widget> m_xSMTPAfterPOPImg;
+ std::unique_ptr<weld::Label> m_xOutgoingServerFT;
+ std::unique_ptr<weld::Label> m_xUserNameFT;
+ std::unique_ptr<weld::Entry> m_xUserNameED;
+ std::unique_ptr<weld::Widget> m_xUserNameImg;
+ std::unique_ptr<weld::Label> m_xOutPasswordFT;
+ std::unique_ptr<weld::Entry> m_xOutPasswordED;
+ std::unique_ptr<weld::Label> m_xIncomingServerFT;
+ std::unique_ptr<weld::Label> m_xServerFT;
+ std::unique_ptr<weld::Entry> m_xServerED;
+ std::unique_ptr<weld::Widget> m_xServerImg;
+ std::unique_ptr<weld::Label> m_xPortFT;
+ std::unique_ptr<weld::SpinButton> m_xPortNF;
+ std::unique_ptr<weld::Widget> m_xPortImg;
+ std::unique_ptr<weld::Label> m_xProtocolFT;
+ std::unique_ptr<weld::RadioButton> m_xPOP3RB;
+ std::unique_ptr<weld::Widget> m_xPOP3Img;
+ std::unique_ptr<weld::RadioButton> m_xIMAPRB;
+ std::unique_ptr<weld::Label> m_xInUsernameFT;
+ std::unique_ptr<weld::Entry> m_xInUsernameED;
+ std::unique_ptr<weld::Widget> m_xInUsernameImg;
+ std::unique_ptr<weld::Label> m_xInPasswordFT;
+ std::unique_ptr<weld::Entry> m_xInPasswordED;
+ std::unique_ptr<weld::Button> m_xOKPB;
+
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckBoxHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(RadioButtonHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(InServerHdl_Impl, weld::Toggleable&, void);
+
+public:
+ SwAuthenticationSettingsDialog(weld::Window* pParent, SwMailMergeConfigItem& rItem);
+};
+
+}
+
+SwMailConfigPage::SwMailConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/mailconfigpage.ui", "MailConfigPage", &rSet)
+ , m_pConfigItem(new SwMailMergeConfigItem)
+ , m_xDisplayNameED(m_xBuilder->weld_entry("displayname"))
+ , m_xDisplayNameImg(m_xBuilder->weld_widget("lockdisplayname"))
+ , m_xAddressED(m_xBuilder->weld_entry("address"))
+ , m_xAddressImg(m_xBuilder->weld_widget("lockaddress"))
+ , m_xReplyToCB(m_xBuilder->weld_check_button("replytocb"))
+ , m_xReplyToCBImg(m_xBuilder->weld_widget("lockreplytocb"))
+ , m_xReplyToFT(m_xBuilder->weld_label("replyto_label"))
+ , m_xReplyToED(m_xBuilder->weld_entry("replyto"))
+ , m_xReplyToImg(m_xBuilder->weld_widget("lockreplyto"))
+ , m_xServerED(m_xBuilder->weld_entry("server"))
+ , m_xServerImg(m_xBuilder->weld_widget("lockserver"))
+ , m_xPortNF(m_xBuilder->weld_spin_button("port"))
+ , m_xPortImg(m_xBuilder->weld_widget("lockport"))
+ , m_xSecureCB(m_xBuilder->weld_check_button("secure"))
+ , m_xSecureImg(m_xBuilder->weld_widget("locksecure"))
+ , m_xServerAuthenticationPB(m_xBuilder->weld_button("serverauthentication"))
+ , m_xTestPB(m_xBuilder->weld_button("test"))
+{
+ m_xReplyToCB->connect_toggled(LINK(this, SwMailConfigPage, ReplyToHdl));
+ m_xServerAuthenticationPB->connect_clicked(LINK(this, SwMailConfigPage, AuthenticationHdl));
+ m_xTestPB->connect_clicked(LINK(this, SwMailConfigPage, TestHdl));
+ m_xSecureCB->connect_toggled(LINK(this, SwMailConfigPage, SecureHdl));
+}
+
+SwMailConfigPage::~SwMailConfigPage()
+{
+ m_pConfigItem.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwMailConfigPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwMailConfigPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwMailConfigPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label1", "displayname_label", "address_label", "replyto_label",
+ "label2", "server_label", "port_label" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[] = { "replytocb", "secure" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString buttons[] = { "serverauthentication", "test" };
+
+ for (const auto& btn : buttons)
+ {
+ if (const auto& pString = m_xBuilder->weld_button(btn))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwMailConfigPage::FillItemSet( SfxItemSet* /*rSet*/ )
+{
+ if (m_xDisplayNameED->get_value_changed_from_saved())
+ m_pConfigItem->SetMailDisplayName(m_xDisplayNameED->get_text());
+ if (m_xAddressED->get_value_changed_from_saved())
+ m_pConfigItem->SetMailAddress(m_xAddressED->get_text());
+ if (m_xReplyToCB->get_state_changed_from_saved() )
+ m_pConfigItem->SetMailReplyTo(m_xReplyToCB->get_active());
+ if (m_xReplyToED->get_value_changed_from_saved())
+ m_pConfigItem->SetMailReplyTo(m_xReplyToED->get_text());
+ if (m_xServerED->get_value_changed_from_saved())
+ m_pConfigItem->SetMailServer(m_xServerED->get_text());
+
+ m_pConfigItem->SetMailPort(m_xPortNF->get_value());
+ m_pConfigItem->SetSecureConnection(m_xSecureCB->get_active());
+
+ m_pConfigItem->Commit();
+ return true;
+}
+
+void SwMailConfigPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ m_xDisplayNameED->set_text(m_pConfigItem->GetMailDisplayName());
+ m_xDisplayNameED->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::MailDisplayName::isReadOnly());
+ m_xDisplayNameImg->set_visible(officecfg::Office::Writer::MailMergeWizard::MailDisplayName::isReadOnly());
+
+ m_xAddressED->set_text(m_pConfigItem->GetMailAddress());
+ m_xAddressED->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::MailAddress::isReadOnly());
+ m_xAddressImg->set_visible(officecfg::Office::Writer::MailMergeWizard::MailAddress::isReadOnly());
+
+ m_xReplyToED->set_text(m_pConfigItem->GetMailReplyTo());
+ m_xReplyToED->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::MailReplyTo::isReadOnly());
+ m_xReplyToImg->set_visible(officecfg::Office::Writer::MailMergeWizard::MailReplyTo::isReadOnly());
+
+ m_xReplyToCB->set_active(m_pConfigItem->IsMailReplyTo());
+ m_xReplyToCB->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::IsMailReplyTo::isReadOnly());
+ m_xReplyToCBImg->set_visible(officecfg::Office::Writer::MailMergeWizard::IsMailReplyTo::isReadOnly());
+
+ ReplyToHdl(*m_xReplyToCB);
+
+ m_xServerED->set_text(m_pConfigItem->GetMailServer());
+ m_xServerED->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::MailServer::isReadOnly());
+ m_xServerImg->set_visible(officecfg::Office::Writer::MailMergeWizard::MailServer::isReadOnly());
+
+ m_xPortNF->set_value(m_pConfigItem->GetMailPort());
+ m_xPortNF->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::MailPort::isReadOnly());
+ m_xPortImg->set_visible(officecfg::Office::Writer::MailMergeWizard::MailPort::isReadOnly());
+
+ m_xSecureCB->set_active(m_pConfigItem->IsSecureConnection());
+ m_xSecureCB->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::IsSecureConnection::isReadOnly());
+ m_xSecureImg->set_visible(officecfg::Office::Writer::MailMergeWizard::IsSecureConnection::isReadOnly());
+
+ m_xDisplayNameED->save_value();
+ m_xAddressED->save_value();
+ m_xReplyToCB->save_state();
+ m_xReplyToED->save_value();
+ m_xServerED->save_value();
+ m_xPortNF->save_value();
+ m_xSecureCB->save_state();
+}
+
+IMPL_LINK(SwMailConfigPage, ReplyToHdl, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = rBox.get_active() && !m_xReplyToImg->get_visible();
+ m_xReplyToFT->set_sensitive(bEnable);
+ m_xReplyToED->set_sensitive(bEnable);
+}
+
+IMPL_LINK_NOARG(SwMailConfigPage, AuthenticationHdl, weld::Button&, void)
+{
+ m_pConfigItem->SetMailAddress(m_xAddressED->get_text());
+
+ SwAuthenticationSettingsDialog aDlg(GetFrameWeld(), *m_pConfigItem);
+ aDlg.run();
+}
+
+IMPL_LINK_NOARG(SwMailConfigPage, TestHdl, weld::Button&, void)
+{
+ SwTestAccountSettingsDialog aDlg(this);
+ aDlg.run();
+}
+
+IMPL_LINK(SwMailConfigPage, SecureHdl, weld::Toggleable&, rBox, void)
+{
+ bool bEnable = rBox.get_active();
+ m_pConfigItem->SetSecureConnection(bEnable);
+ m_pConfigItem->SetMailPort(m_xPortNF->get_value());
+ m_xPortNF->set_value(m_pConfigItem->GetMailPort());
+}
+
+SwTestAccountSettingsDialog::SwTestAccountSettingsDialog(SwMailConfigPage* pParent)
+ : SfxDialogController(pParent->GetFrameWeld(), "modules/swriter/ui/testmailsettings.ui", "TestMailSettings")
+ , m_bStop(false)
+ , m_pParent(pParent)
+ , m_xStopPB(m_xBuilder->weld_button("stop"))
+ , m_xErrorsED(m_xBuilder->weld_text_view("errors"))
+ , m_xResult1(m_xBuilder->weld_label("result1"))
+ , m_xResult2(m_xBuilder->weld_label("result2"))
+ , m_xImage1(m_xBuilder->weld_image("image1"))
+ , m_xImage2(m_xBuilder->weld_image("image2"))
+ , m_xImage3(m_xBuilder->weld_image("image3"))
+ , m_xImage4(m_xBuilder->weld_image("image4"))
+{
+ m_xErrorsED->set_size_request(m_xErrorsED->get_approximate_digit_width() * 72,
+ m_xErrorsED->get_height_rows(8));
+ m_sErrorServer = m_xErrorsED->get_text();
+ m_xErrorsED->set_text("");
+ m_sCompleted = m_xResult1->get_label();
+ m_sFailed = m_xResult2->get_label();
+
+ m_xStopPB->connect_clicked(LINK(this, SwTestAccountSettingsDialog, StopHdl));
+
+ m_pPostedEvent = Application::PostUserEvent(LINK(this, SwTestAccountSettingsDialog, TestHdl));
+}
+
+SwTestAccountSettingsDialog::~SwTestAccountSettingsDialog()
+{
+ if (m_pPostedEvent)
+ {
+ Application::RemoveUserEvent(m_pPostedEvent);
+ }
+}
+
+IMPL_LINK_NOARG(SwTestAccountSettingsDialog, StopHdl, weld::Button&, void)
+{
+ m_bStop = true;
+}
+
+IMPL_LINK_NOARG(SwTestAccountSettingsDialog, TestHdl, void*, void)
+{
+ m_pPostedEvent = nullptr;
+ weld::WaitObject aWait(m_xDialog.get());
+ Test();
+}
+
+void SwTestAccountSettingsDialog::Test()
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ OUString sException;
+
+ bool bIsLoggedIn = false;
+ bool bIsServer = false;
+ try
+ {
+ uno::Reference< mail::XMailService > xInMailService;
+ uno::Reference< mail::XMailServiceProvider > xMailServiceProvider(
+ mail::MailServiceProvider::create(xContext) );
+ uno::Reference< mail::XMailService > xMailService =
+ xMailServiceProvider->create(
+ mail::MailServiceType_SMTP);
+ if(m_bStop)
+ return;
+ uno::Reference<XConnectionListener> xConnectionListener(new SwConnectionListener);
+
+ if(m_pParent->m_pConfigItem->IsAuthentication() &&
+ m_pParent->m_pConfigItem->IsSMTPAfterPOP())
+ {
+ xInMailService = xMailServiceProvider->create(
+ m_pParent->m_pConfigItem->IsInServerPOP() ?
+ mail::MailServiceType_POP3 : mail::MailServiceType_IMAP);
+ if(m_bStop)
+ return;
+ //authenticate at the POP or IMAP server first
+ uno::Reference<XAuthenticator> xAuthenticator =
+ new SwAuthenticator(
+ m_pParent->m_pConfigItem->GetInServerUserName(),
+ m_pParent->m_pConfigItem->GetInServerPassword(),
+ m_xDialog.get());
+
+ xInMailService->addConnectionListener(xConnectionListener);
+ //check connection
+ uno::Reference< uno::XCurrentContext> xConnectionContext =
+ new SwConnectionContext(
+ m_pParent->m_pConfigItem->GetInServerName(),
+ m_pParent->m_pConfigItem->GetInServerPort(),
+ "Insecure");
+ xInMailService->connect(xConnectionContext, xAuthenticator);
+ }
+ if(m_bStop)
+ return;
+ uno::Reference<XAuthenticator> xAuthenticator;
+ if(m_pParent->m_pConfigItem->IsAuthentication() &&
+ !m_pParent->m_pConfigItem->IsSMTPAfterPOP() &&
+ !m_pParent->m_pConfigItem->GetMailUserName().isEmpty())
+ xAuthenticator =
+ new SwAuthenticator(
+ m_pParent->m_pConfigItem->GetMailUserName(),
+ m_pParent->m_pConfigItem->GetMailPassword(),
+ m_xDialog.get());
+ else
+ xAuthenticator = new SwAuthenticator();
+
+ xMailService->addConnectionListener(xConnectionListener);
+ if(m_bStop)
+ return;
+ //just to check if the server exists
+ xMailService->getSupportedConnectionTypes();
+ if(m_bStop)
+ return;
+ bIsServer = true;
+ //check connection
+ uno::Reference< uno::XCurrentContext> xConnectionContext =
+ new SwConnectionContext(
+ m_pParent->m_xServerED->get_text(),
+ m_pParent->m_xPortNF->get_value(),
+ m_pParent->m_xSecureCB->get_active() ? OUString("Ssl") : OUString("Insecure"));
+ xMailService->connect(xConnectionContext, xAuthenticator);
+ bIsLoggedIn = xMailService->isConnected();
+ if( xInMailService.is() )
+ xInMailService->disconnect();
+ if( xMailService->isConnected())
+ xMailService->disconnect();
+ }
+ catch (const uno::Exception& e)
+ {
+ sException = e.Message;
+ }
+
+ m_xResult1->set_label(bIsServer ? m_sCompleted : m_sFailed);
+ m_xImage1->set_visible(!bIsServer);
+ m_xImage3->set_visible(bIsServer);
+
+ m_xResult2->set_label(bIsLoggedIn ? m_sCompleted : m_sFailed);
+ m_xImage2->set_visible(!bIsLoggedIn);
+ m_xImage4->set_visible(bIsLoggedIn);
+
+ if (!bIsServer || !bIsLoggedIn)
+ {
+ OUString aErrorMessage(m_sErrorServer);
+ if (!sException.isEmpty())
+ aErrorMessage += "\n--\n" + sException;
+ m_xErrorsED->set_text(aErrorMessage);
+ }
+}
+
+SwMailConfigDlg::SwMailConfigDlg(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet)
+{
+ // create TabPage
+ SetTabPage(SwMailConfigPage::Create(get_content_area(), this, &rSet));
+ m_xDialog->set_title(SwResId(STR_MAILCONFIG_DLG_TITLE));
+}
+
+SwAuthenticationSettingsDialog::SwAuthenticationSettingsDialog(
+ weld::Window* pParent, SwMailMergeConfigItem& rItem)
+ : SfxDialogController(pParent, "modules/swriter/ui/authenticationsettingsdialog.ui", "AuthenticationSettingsDialog")
+ , m_rConfigItem(rItem)
+ , m_xAuthenticationCB(m_xBuilder->weld_check_button("authentication"))
+ , m_xAuthenticationImg(m_xBuilder->weld_widget("lockauthentication"))
+ , m_xSeparateAuthenticationRB(m_xBuilder->weld_radio_button("separateauthentication"))
+ , m_xSeparateAuthenticationImg(m_xBuilder->weld_widget("lockseparaauth"))
+ , m_xSMTPAfterPOPRB(m_xBuilder->weld_radio_button("smtpafterpop"))
+ , m_xSMTPAfterPOPImg(m_xBuilder->weld_widget("locksmtpafterpop"))
+ , m_xOutgoingServerFT(m_xBuilder->weld_label("label1"))
+ , m_xUserNameFT(m_xBuilder->weld_label("username_label"))
+ , m_xUserNameED(m_xBuilder->weld_entry("username"))
+ , m_xUserNameImg(m_xBuilder->weld_widget("lockusername"))
+ , m_xOutPasswordFT(m_xBuilder->weld_label("outpassword_label"))
+ , m_xOutPasswordED(m_xBuilder->weld_entry("outpassword"))
+ , m_xIncomingServerFT(m_xBuilder->weld_label("label2"))
+ , m_xServerFT(m_xBuilder->weld_label("server_label"))
+ , m_xServerED(m_xBuilder->weld_entry("server"))
+ , m_xServerImg(m_xBuilder->weld_widget("lockserver"))
+ , m_xPortFT(m_xBuilder->weld_label("port_label"))
+ , m_xPortNF(m_xBuilder->weld_spin_button("port"))
+ , m_xPortImg(m_xBuilder->weld_widget("lockport"))
+ , m_xProtocolFT(m_xBuilder->weld_label("label3"))
+ , m_xPOP3RB(m_xBuilder->weld_radio_button("pop3"))
+ , m_xPOP3Img(m_xBuilder->weld_widget("lockpop3"))
+ , m_xIMAPRB(m_xBuilder->weld_radio_button("imap"))
+ , m_xInUsernameFT(m_xBuilder->weld_label("inusername_label"))
+ , m_xInUsernameED(m_xBuilder->weld_entry("inusername"))
+ , m_xInUsernameImg(m_xBuilder->weld_widget("lockinusername"))
+ , m_xInPasswordFT(m_xBuilder->weld_label("inpassword_label"))
+ , m_xInPasswordED(m_xBuilder->weld_entry("inpassword"))
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+{
+ m_xAuthenticationCB->connect_toggled( LINK( this, SwAuthenticationSettingsDialog, CheckBoxHdl_Impl));
+ Link<weld::Toggleable&,void> aRBLink = LINK( this, SwAuthenticationSettingsDialog, RadioButtonHdl_Impl );
+ m_xSeparateAuthenticationRB->connect_toggled( aRBLink );
+ m_xSMTPAfterPOPRB->connect_toggled( aRBLink );
+ m_xOKPB->connect_clicked( LINK( this, SwAuthenticationSettingsDialog, OKHdl_Impl));
+ m_xPOP3RB->connect_toggled(LINK(this, SwAuthenticationSettingsDialog, InServerHdl_Impl));
+
+ m_xAuthenticationCB->set_active(m_rConfigItem.IsAuthentication());
+ m_xAuthenticationCB->set_sensitive(!officecfg::Office::Writer::MailMergeWizard::IsAuthentication::isReadOnly());
+ m_xAuthenticationImg->set_visible(officecfg::Office::Writer::MailMergeWizard::IsAuthentication::isReadOnly());
+ if (m_rConfigItem.IsSMTPAfterPOP())
+ m_xSMTPAfterPOPRB->set_active(true);
+ else
+ m_xSeparateAuthenticationRB->set_active(true);
+ m_xUserNameED->set_text(m_rConfigItem.GetMailUserName());
+ m_xOutPasswordED->set_text(m_rConfigItem.GetMailPassword());
+
+ m_xServerED->set_text(m_rConfigItem.GetInServerName());
+ m_xPortNF->set_value(m_rConfigItem.GetInServerPort());
+ if (m_rConfigItem.IsInServerPOP())
+ m_xPOP3RB->set_active(true);
+ else
+ m_xIMAPRB->set_active(true);
+ m_xInUsernameED->set_text(m_rConfigItem.GetInServerUserName());
+ m_xInPasswordED->set_text(m_rConfigItem.GetInServerPassword());
+
+ CheckBoxHdl_Impl(*m_xAuthenticationCB);
+}
+
+IMPL_LINK_NOARG(SwAuthenticationSettingsDialog, OKHdl_Impl, weld::Button&, void)
+{
+ m_rConfigItem.SetAuthentication( m_xAuthenticationCB->get_active() );
+ m_rConfigItem.SetSMTPAfterPOP(m_xSMTPAfterPOPRB->get_active());
+ m_rConfigItem.SetMailUserName(m_xUserNameED->get_text());
+ m_rConfigItem.SetMailPassword(m_xOutPasswordED->get_text());
+ m_rConfigItem.SetInServerName(m_xServerED->get_text());
+ m_rConfigItem.SetInServerPort(m_xPortNF->get_value());
+ m_rConfigItem.SetInServerPOP(m_xPOP3RB->get_active());
+ m_rConfigItem.SetInServerUserName(m_xInUsernameED->get_text());
+ m_rConfigItem.SetInServerPassword(m_xInPasswordED->get_text());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK( SwAuthenticationSettingsDialog, CheckBoxHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bChecked = rBox.get_active();
+ m_xSeparateAuthenticationRB->set_sensitive(bChecked);
+ m_xSMTPAfterPOPRB->set_sensitive(bChecked);
+ RadioButtonHdl_Impl(*m_xSeparateAuthenticationRB);
+}
+
+IMPL_LINK_NOARG(SwAuthenticationSettingsDialog, RadioButtonHdl_Impl, weld::Toggleable&, void)
+{
+ bool bSeparate = m_xSeparateAuthenticationRB->get_active();
+ bool bIsEnabled = m_xSeparateAuthenticationRB->get_sensitive();
+ bool bNotSeparate = !bSeparate && bIsEnabled;
+ bSeparate &= bIsEnabled;
+
+ bool bReadOnly = officecfg::Office::Writer::MailMergeWizard::IsSMPTAfterPOP::isReadOnly();
+ if (bSeparate || bNotSeparate)
+ {
+ m_xSeparateAuthenticationRB->set_sensitive(!bReadOnly);
+ m_xSeparateAuthenticationImg->set_visible(bReadOnly);
+ m_xSMTPAfterPOPRB->set_sensitive(!bReadOnly);
+ m_xSMTPAfterPOPImg->set_visible(bReadOnly);
+ }
+ if (bSeparate && m_xUserNameED->get_text().isEmpty())
+ m_xUserNameED->set_text(m_rConfigItem.GetMailAddress());
+ else if (!bSeparate && m_xUserNameED->get_text() == m_rConfigItem.GetMailAddress())
+ m_xUserNameED->set_text("");
+
+ if (bNotSeparate && m_xInUsernameED->get_text().isEmpty())
+ m_xInUsernameED->set_text(m_rConfigItem.GetMailAddress());
+ else if (!bNotSeparate && m_xInUsernameED->get_text() == m_rConfigItem.GetMailAddress())
+ m_xInUsernameED->set_text("");
+
+ m_xOutgoingServerFT->set_sensitive(bSeparate);
+ m_xUserNameFT->set_sensitive(bSeparate);
+
+ bReadOnly = officecfg::Office::Writer::MailMergeWizard::MailUserName::isReadOnly();
+ m_xUserNameED->set_sensitive(bSeparate && !bReadOnly);
+ m_xUserNameImg->set_visible(bReadOnly);
+
+ m_xOutPasswordFT->set_sensitive(bSeparate);
+ m_xOutPasswordED->set_sensitive(bSeparate);
+
+ m_xIncomingServerFT->set_sensitive(bNotSeparate);
+ m_xServerFT->set_sensitive(bNotSeparate);
+
+ bReadOnly = officecfg::Office::Writer::MailMergeWizard::InServerName::isReadOnly();
+ m_xServerED->set_sensitive(bNotSeparate && !bReadOnly);
+ m_xServerImg->set_visible(bReadOnly);
+
+ m_xPortFT->set_sensitive(bNotSeparate);
+ bReadOnly = officecfg::Office::Writer::MailMergeWizard::InServerPort::isReadOnly();
+ m_xPortNF->set_sensitive(bNotSeparate && !bReadOnly);
+ m_xPortImg->set_visible(bReadOnly);
+
+ m_xInUsernameFT->set_sensitive(bNotSeparate);
+ bReadOnly = officecfg::Office::Writer::MailMergeWizard::InServerUserName::isReadOnly();
+ m_xInUsernameED->set_sensitive(bNotSeparate && !bReadOnly);
+ m_xInUsernameImg->set_visible(bReadOnly);
+ m_xProtocolFT->set_sensitive(bNotSeparate);
+
+ bReadOnly = officecfg::Office::Writer::MailMergeWizard::InServerIsPOP::isReadOnly();
+ m_xPOP3RB->set_sensitive(bNotSeparate && !bReadOnly);
+ m_xIMAPRB->set_sensitive(bNotSeparate && !bReadOnly);
+ m_xPOP3Img->set_visible(bReadOnly);
+
+ m_xInPasswordFT->set_sensitive(bNotSeparate);
+ m_xInPasswordED->set_sensitive(bNotSeparate);
+}
+
+IMPL_LINK_NOARG( SwAuthenticationSettingsDialog, InServerHdl_Impl, weld::Toggleable&, void)
+{
+ bool bPOP = m_xPOP3RB->get_active();
+ m_rConfigItem.SetInServerPOP(bPOP);
+ m_xPortNF->set_value(m_rConfigItem.GetInServerPort());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/config/optcomp.cxx b/sw/source/ui/config/optcomp.cxx
new file mode 100644
index 0000000000..1393b2864d
--- /dev/null
+++ b/sw/source/ui/config/optcomp.cxx
@@ -0,0 +1,481 @@
+/* -*- 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 <optcomp.hxx>
+
+#include <cmdid.h>
+#include <docsh.hxx>
+#include <uiitems.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <vector>
+#include <svtools/restartdialog.hxx>
+#include <comphelper/processfactory.hxx>
+#include <officecfg/Office/Compatibility.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::uno;
+
+struct SwCompatibilityOptPage_Impl
+{
+ std::vector< SvtCompatibilityEntry > m_aList;
+};
+
+SwCompatibilityOptPage::SwCompatibilityOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optcompatpage.ui", "OptCompatPage", &rSet)
+ , m_pWrtShell(nullptr)
+ , m_pImpl(new SwCompatibilityOptPage_Impl)
+ , m_nSavedOptions(0)
+ , m_xMain(m_xBuilder->weld_frame("compatframe"))
+ , m_xFormattingLB(m_xBuilder->weld_combo_box("format"))
+ , m_xOptionsLB(m_xBuilder->weld_tree_view("options"))
+ , m_xDefaultPB(m_xBuilder->weld_button("default"))
+{
+ m_xOptionsLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ int nPos = 0;
+ for (int i = static_cast<int>(SvtCompatibilityEntry::Index::Module) + 1;
+ i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID) - 1; // omit AddTableLineSpacing
+ ++i)
+ {
+ int nCoptIdx = i - 2; /* Do not consider "Name" & "Module" indexes */
+
+ const OUString sEntry = m_xFormattingLB->get_text(nCoptIdx);
+ m_xOptionsLB->append();
+ m_xOptionsLB->set_toggle(nPos, TRISTATE_FALSE);
+ m_xOptionsLB->set_text(nPos, sEntry, 0);
+ ++nPos;
+ }
+
+ m_sUserEntry = m_xFormattingLB->get_text(m_xFormattingLB->get_count() - 1);
+
+ m_xFormattingLB->clear();
+
+ InitControls( rSet );
+
+ // set handler
+ m_xFormattingLB->connect_changed( LINK( this, SwCompatibilityOptPage, SelectHdl ) );
+ m_xDefaultPB->connect_clicked( LINK( this, SwCompatibilityOptPage, UseAsDefaultHdl ) );
+}
+
+SwCompatibilityOptPage::~SwCompatibilityOptPage()
+{
+}
+
+static sal_uInt32 convertBools2Ulong_Impl
+(
+ bool _bAddSpacing,
+ bool _bAddSpacingAtPages,
+ bool _bUseOurTabStops,
+ bool _bNoExtLeading,
+ bool _bUseLineSpacing,
+ bool _bAddTableSpacing,
+ bool _bAddTableLineSpacing,
+ bool _bUseObjPos,
+ bool _bUseOurTextWrapping,
+ bool _bConsiderWrappingStyle,
+ bool _bExpandWordSpace,
+ bool _bProtectForm,
+ bool _bMsWordCompTrailingBlanks,
+ bool bSubtractFlysAnchoredAtFlys,
+ bool bEmptyDbFieldHidesPara,
+ bool bUseVariableWidthNBSP
+)
+{
+ sal_uInt32 nRet = 0;
+ sal_uInt32 nSetBit = 1;
+
+ if ( _bAddSpacing )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bAddSpacingAtPages )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bUseOurTabStops )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bNoExtLeading )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bUseLineSpacing )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bAddTableSpacing )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if (_bAddTableLineSpacing)
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bUseObjPos )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bUseOurTextWrapping )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bConsiderWrappingStyle )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bExpandWordSpace )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bProtectForm )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if ( _bMsWordCompTrailingBlanks )
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if (bSubtractFlysAnchoredAtFlys)
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if (bEmptyDbFieldHidesPara)
+ nRet |= nSetBit;
+ nSetBit = nSetBit << 1;
+ if (bUseVariableWidthNBSP)
+ nRet |= nSetBit;
+
+ return nRet;
+}
+
+void SwCompatibilityOptPage::InitControls( const SfxItemSet& rSet )
+{
+ // init objectshell and detect document name
+ OUString sDocTitle;
+ SfxObjectShell* pObjShell = nullptr;
+ if ( const SwPtrItem* pItem = rSet.GetItemIfSet( FN_PARAM_WRTSHELL, false ) )
+ m_pWrtShell = static_cast<SwWrtShell*>(pItem->GetValue());
+ if ( m_pWrtShell )
+ {
+ pObjShell = m_pWrtShell->GetView().GetDocShell();
+ if ( pObjShell )
+ sDocTitle = pObjShell->GetTitle();
+ }
+ else
+ {
+ m_xMain->set_sensitive(false);
+ }
+ const OUString& rText = m_xMain->get_label();
+ m_xMain->set_label(rText.replaceAll("%DOCNAME", sDocTitle));
+
+ // loading file formats
+ const std::vector< SvtCompatibilityEntry > aList = m_aConfigItem.GetList();
+
+ for ( const SvtCompatibilityEntry& rEntry : aList )
+ {
+ const OUString sEntryName = rEntry.getValue<OUString>( SvtCompatibilityEntry::Index::Name );
+ const bool bIsUserEntry = ( sEntryName == SvtCompatibilityEntry::USER_ENTRY_NAME );
+ const bool bIsDefaultEntry = ( sEntryName == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME );
+
+ m_pImpl->m_aList.push_back( rEntry );
+
+ if ( bIsDefaultEntry )
+ continue;
+
+ OUString sNewEntry;
+ if ( bIsUserEntry )
+ sNewEntry = m_sUserEntry;
+
+ else if ( pObjShell && !sEntryName.isEmpty() )
+ {
+ SfxFilterContainer* pFacCont = pObjShell->GetFactory().GetFilterContainer();
+ std::shared_ptr<const SfxFilter> pFilter = pFacCont->GetFilter4FilterName( sEntryName );
+ if ( pFilter )
+ sNewEntry = pFilter->GetUIName();
+ }
+
+ if ( sNewEntry.isEmpty() )
+ sNewEntry = sEntryName;
+
+ sal_uInt32 nOptions = convertBools2Ulong_Impl(
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddSpacing ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddSpacingAtPages ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseOurTabStops ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::NoExtLeading ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseLineSpacing ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddTableSpacing ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddTableLineSpacing),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseObjectPositioning ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseOurTextWrapping ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ConsiderWrappingStyle ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ExpandWordSpace ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ProtectForm ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::MsWordTrailingBlanks ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara ),
+ rEntry.getValue<bool>( SvtCompatibilityEntry::Index::UseVariableWidthNBSP ) );
+ m_xFormattingLB->append(OUString::number(nOptions), sNewEntry);
+ }
+}
+
+IMPL_LINK_NOARG(SwCompatibilityOptPage, SelectHdl, weld::ComboBox&, void)
+{
+ sal_uInt32 nOptions = m_xFormattingLB->get_active_id().toUInt32();
+ SetCurrentOptions(nOptions);
+}
+
+IMPL_LINK_NOARG(SwCompatibilityOptPage, UseAsDefaultHdl, weld::Button&, void)
+{
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/querydefaultcompatdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("QueryDefaultCompatDialog"));
+ if (xQueryBox->run() != RET_YES)
+ return;
+
+ auto pItem = std::find_if(m_pImpl->m_aList.begin(), m_pImpl->m_aList.end(),
+ [](const SvtCompatibilityEntry& rItem)
+ {
+ const OUString sEntryName = rItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name );
+ const bool bIsDefaultEntry = ( sEntryName == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME );
+ return bIsDefaultEntry;
+ });
+ if (pItem != m_pImpl->m_aList.end())
+ {
+ const sal_Int32 nCount = m_xOptionsLB->n_children();
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ bool bChecked = m_xOptionsLB->get_toggle(i);
+
+ int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
+ pItem->setValue<bool>( SvtCompatibilityEntry::Index(nCoptIdx), bChecked );
+ if (nCoptIdx == int(SvtCompatibilityEntry::Index::AddTableSpacing))
+ {
+ bool const isLineSpacing = m_xOptionsLB->get_toggle(i) == TRISTATE_TRUE;
+ pItem->setValue<bool>(SvtCompatibilityEntry::Index::AddTableLineSpacing, isLineSpacing);
+ }
+ else
+ {
+ assert(m_xOptionsLB->get_toggle(i) != TRISTATE_INDET);
+ }
+ }
+ }
+
+ WriteOptions();
+}
+
+void SwCompatibilityOptPage::SetCurrentOptions( sal_uInt32 nOptions )
+{
+ const int nCount = m_xOptionsLB->n_children();
+ const OUString aOptionsName = m_xFormattingLB->get_active_text();
+ OSL_ENSURE( nCount <= 32, "SwCompatibilityOptPage::Reset(): entry overflow" );
+ for (int i = 0; i < nCount; ++i)
+ {
+ bool bReadOnly = false;
+ bool bChecked = ( ( nOptions & 0x00000001 ) == 0x00000001 );
+ TriState value = bChecked ? TRISTATE_TRUE : TRISTATE_FALSE;
+ if (i == int(SvtCompatibilityEntry::Index::AddTableSpacing) - 2)
+ { // hack: map 2 bools to 1 tristate
+ nOptions = nOptions >> 1;
+ if (value == TRISTATE_TRUE
+ && (nOptions & 0x00000001) != 0x00000001) // ADD_PARA_LINE_SPACING_TO_TABLE_CELLS
+ {
+ value = TRISTATE_INDET; // 3 values possible here
+ }
+ }
+ m_xOptionsLB->set_toggle(i, value);
+
+ int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
+ if (aOptionsName.isEmpty() || aOptionsName == SvtCompatibilityEntry::DEFAULT_ENTRY_NAME)
+ {
+ bReadOnly = m_aConfigItem.GetDefaultPropertyReadOnly(SvtCompatibilityEntry::Index(nCoptIdx));
+ }
+ else
+ {
+ bReadOnly = m_aConfigItem.GetPropertyReadOnly(SvtCompatibilityEntry::Index(nCoptIdx));
+ }
+ m_xOptionsLB->set_sensitive(i, !bReadOnly);
+
+ nOptions = nOptions >> 1;
+ }
+
+ m_xDefaultPB->set_sensitive(!m_aConfigItem.HaveDefaultReadOnlyProperty());
+}
+
+sal_uInt32 SwCompatibilityOptPage::GetDocumentOptions() const
+{
+ sal_uInt32 nRet = 0;
+ if ( m_pWrtShell )
+ {
+ const IDocumentSettingAccess& rIDocumentSettingAccess = m_pWrtShell->getIDocumentSettingAccess();
+ nRet = convertBools2Ulong_Impl(
+ rIDocumentSettingAccess.get( DocumentSettingId::PARA_SPACE_MAX ),
+ rIDocumentSettingAccess.get( DocumentSettingId::PARA_SPACE_MAX_AT_PAGES ),
+ !rIDocumentSettingAccess.get( DocumentSettingId::TAB_COMPAT ),
+ !rIDocumentSettingAccess.get( DocumentSettingId::ADD_EXT_LEADING ),
+ rIDocumentSettingAccess.get( DocumentSettingId::OLD_LINE_SPACING ),
+ rIDocumentSettingAccess.get( DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS ),
+ rIDocumentSettingAccess.get( DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS ),
+ rIDocumentSettingAccess.get( DocumentSettingId::USE_FORMER_OBJECT_POS ),
+ rIDocumentSettingAccess.get( DocumentSettingId::USE_FORMER_TEXT_WRAPPING ),
+ rIDocumentSettingAccess.get( DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION ),
+ !rIDocumentSettingAccess.get( DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK ),
+ rIDocumentSettingAccess.get( DocumentSettingId::PROTECT_FORM ),
+ rIDocumentSettingAccess.get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ),
+ rIDocumentSettingAccess.get( DocumentSettingId::SUBTRACT_FLYS ),
+ rIDocumentSettingAccess.get( DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA ),
+ rIDocumentSettingAccess.get( DocumentSettingId::USE_VARIABLE_WIDTH_NBSP ) );
+ }
+ return nRet;
+}
+
+void SwCompatibilityOptPage::WriteOptions()
+{
+ m_aConfigItem.Clear();
+ for ( const auto& rItem : m_pImpl->m_aList )
+ m_aConfigItem.AppendItem(rItem);
+}
+
+std::unique_ptr<SfxTabPage> SwCompatibilityOptPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwCompatibilityOptPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwCompatibilityOptPage::GetAllStrings()
+{
+ OUString sAllStrings;
+
+ if (const auto& pString = m_xBuilder->weld_label(u"label11"_ustr))
+ sAllStrings += pString->get_label() + " ";
+
+ sAllStrings += m_xDefaultPB->get_label() + " ";
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwCompatibilityOptPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ if ( m_pWrtShell )
+ {
+ sal_uInt32 nSavedOptions = m_nSavedOptions;
+ const int nCount = m_xOptionsLB->n_children();
+ OSL_ENSURE( nCount <= 32, "SwCompatibilityOptPage::Reset(): entry overflow" );
+
+ for (int i = 0; i < nCount; ++i)
+ {
+ TriState const current = m_xOptionsLB->get_toggle(i);
+ TriState saved = ((nSavedOptions & 0x00000001) == 0x00000001) ? TRISTATE_TRUE : TRISTATE_FALSE;
+ if (i == int(SvtCompatibilityEntry::Index::AddTableSpacing) - 2)
+ { // hack: map 2 bools to 1 tristate
+ nSavedOptions = nSavedOptions >> 1;
+ if (saved == TRISTATE_TRUE
+ && ((nSavedOptions & 0x00000001) != 0x00000001))
+ {
+ saved = TRISTATE_INDET;
+ }
+ }
+ if (current != saved)
+ {
+ bool const bChecked(current != TRISTATE_FALSE);
+ assert(current != TRISTATE_INDET); // can't *change* it to that
+ int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
+ switch ( SvtCompatibilityEntry::Index(nCoptIdx) )
+ {
+ case SvtCompatibilityEntry::Index::AddSpacing:
+ m_pWrtShell->SetParaSpaceMax( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::AddSpacingAtPages:
+ m_pWrtShell->SetParaSpaceMaxAtPages( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::UseOurTabStops:
+ m_pWrtShell->SetTabCompat( !bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::NoExtLeading:
+ m_pWrtShell->SetAddExtLeading( !bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::UseLineSpacing:
+ m_pWrtShell->SetUseFormerLineSpacing( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::AddTableSpacing:
+ m_pWrtShell->SetAddParaSpacingToTableCells( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::UseObjectPositioning:
+ m_pWrtShell->SetUseFormerObjectPositioning( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::UseOurTextWrapping:
+ m_pWrtShell->SetUseFormerTextWrapping( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::ConsiderWrappingStyle:
+ m_pWrtShell->SetConsiderWrapOnObjPos( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::ExpandWordSpace:
+ m_pWrtShell->SetDoNotJustifyLinesWithManualBreak( !bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::ProtectForm:
+ m_pWrtShell->SetProtectForm( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::MsWordTrailingBlanks:
+ m_pWrtShell->SetMsWordCompTrailingBlanks( bChecked );
+ break;
+
+ case SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys:
+ m_pWrtShell->SetSubtractFlysAnchoredAtFlys(bChecked);
+ break;
+
+ case SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara:
+ m_pWrtShell->SetEmptyDbFieldHidesPara(bChecked);
+ break;
+
+ case SvtCompatibilityEntry::Index::UseVariableWidthNBSP:
+ m_pWrtShell->GetDoc()->getIDocumentSettingAccess()
+ .set(DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, bChecked);
+ break;
+
+ default:
+ break;
+ }
+ bModified = true;
+ }
+
+ nSavedOptions = nSavedOptions >> 1;
+ }
+ }
+
+ if ( bModified )
+ WriteOptions();
+
+ return bModified;
+}
+
+void SwCompatibilityOptPage::Reset( const SfxItemSet* )
+{
+ m_xOptionsLB->select(0);
+
+ sal_uInt32 nOptions = GetDocumentOptions();
+ SetCurrentOptions( nOptions );
+ m_nSavedOptions = nOptions;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/config/optload.cxx b/sw/source/ui/config/optload.cxx
new file mode 100644
index 0000000000..3adf4dce4e
--- /dev/null
+++ b/sw/source/ui/config/optload.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 <officecfg/Office/Writer.hxx>
+#include <comphelper/string.hxx>
+#include <swtypes.hxx>
+#include <uiitems.hxx>
+#include <modcfg.hxx>
+#include <swmodule.hxx>
+#include <usrpref.hxx>
+#include <wrtsh.hxx>
+#include <linkenum.hxx>
+#include <uitool.hxx>
+#include <view.hxx>
+
+#include <strings.hrc>
+#include <optload.hrc>
+#include <cmdid.h>
+
+#include <optload.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <fldmgr.hxx>
+#include <poolfmt.hxx>
+#include <expfld.hxx>
+
+#include <svtools/insdlg.hxx>
+#include <svtools/unitconv.hxx>
+#include <tools/resary.hxx>
+#include <vcl/settings.hxx>
+
+#include <comphelper/classids.hxx>
+#include <unotools/configmgr.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <numrule.hxx>
+
+#include <doc.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/eitem.hxx>
+
+using namespace ::com::sun::star;
+
+static bool lcl_isPropertyReadOnly(const SwCapObjType eType, const CapConfigProp ePropType, const SvGlobalName& rOleId)
+{
+ bool bReadOnly = false;
+
+ switch (ePropType)
+ {
+ case PROP_CAP_OBJECT_ENABLE:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Enable::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Enable::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Enable::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Enable::isReadOnly();
+ } else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_CATEGORY:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::Category::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::Category::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::Category::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::Category::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::Category::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::Category::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::Category::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::Category::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::Category::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_NUMBERING:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::Numbering::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::Numbering::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::Numbering::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::Numbering::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::Numbering::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::Numbering::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::Numbering::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::Numbering::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::Numbering::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_NUMBERINGSEPARATOR:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::NumberingSeparator::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::NumberingSeparator::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::NumberingSeparator::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::NumberingSeparator::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::NumberingSeparator::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::NumberingSeparator::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::NumberingSeparator::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::NumberingSeparator::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::NumberingSeparator::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_CAPTIONTEXT:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::CaptionText::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::CaptionText::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::CaptionText::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::CaptionText::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::CaptionText::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::CaptionText::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::CaptionText::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::CaptionText::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::CaptionText::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_DELIMITER:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::Delimiter::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::Delimiter::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::Delimiter::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::Delimiter::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::Delimiter::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::Delimiter::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::Delimiter::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::Delimiter::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::Delimiter::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_LEVEL:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::Level::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::Level::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::Level::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::Level::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::Level::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::Level::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::Level::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::Level::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::Level::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_POSITION:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::Position::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::Position::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::Position::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::Position::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::Position::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::Position::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::Position::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::Position::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::Position::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_CHARACTERSTYLE:
+ {
+ switch (eType)
+ {
+ case TABLE_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Settings::CharacterStyle::isReadOnly();
+ break;
+ case FRAME_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Settings::CharacterStyle::isReadOnly();
+ break;
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::CharacterStyle::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::CharacterStyle::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::CharacterStyle::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::CharacterStyle::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::CharacterStyle::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::CharacterStyle::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::CharacterStyle::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case PROP_CAP_OBJECT_APPLYATTRIBUTES:
+ {
+ switch (eType)
+ {
+ case GRAPHIC_CAP:
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Settings::ApplyAttributes::isReadOnly();
+ break;
+ case OLE_CAP:
+ {
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Settings::ApplyAttributes::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Settings::ApplyAttributes::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Settings::ApplyAttributes::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Settings::ApplyAttributes::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Settings::ApplyAttributes::isReadOnly();
+ }
+ else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Settings::ApplyAttributes::isReadOnly();
+ }
+ else {
+ // Should not reach it.
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return bReadOnly;
+}
+
+sal_uInt32 SwFieldUnitTable::Count()
+{
+ return SAL_N_ELEMENTS(STR_ARR_METRIC);
+}
+
+OUString SwFieldUnitTable::GetString(sal_uInt32 nPos)
+{
+ if (RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count())
+ return SwResId(STR_ARR_METRIC[nPos].first);
+ return OUString();
+}
+
+FieldUnit SwFieldUnitTable::GetValue(sal_uInt32 nPos)
+{
+ if (RESARRAY_INDEX_NOTFOUND != nPos && nPos < Count())
+ return STR_ARR_METRIC[nPos].second;
+ return FieldUnit::NONE;
+}
+
+SwLoadOptPage::SwLoadOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optgeneralpage.ui", "OptGeneralPage", &rSet)
+ , m_pWrtShell(nullptr)
+ , m_nLastTab(0)
+ , m_nOldLinkMode(MANUAL)
+ , m_xAlwaysRB(m_xBuilder->weld_radio_button("always"))
+ , m_xRequestRB(m_xBuilder->weld_radio_button("onrequest"))
+ , m_xNeverRB(m_xBuilder->weld_radio_button("never"))
+ , m_xGridupdatelink(m_xBuilder->weld_widget("gridupdatelink"))
+ , m_xUpdateLinkImg(m_xBuilder->weld_widget("lockupdatelink"))
+ , m_xAutoUpdateFields(m_xBuilder->weld_check_button("updatefields"))
+ , m_xAutoUpdateFieldsImg(m_xBuilder->weld_widget("lockupdatefields"))
+ , m_xAutoUpdateCharts(m_xBuilder->weld_check_button("updatecharts"))
+ , m_xAutoUpdateChartsImg(m_xBuilder->weld_widget("lockupdatecharts"))
+ , m_xMetricLB(m_xBuilder->weld_combo_box("metric"))
+ , m_xMetricImg(m_xBuilder->weld_widget("lockmetric"))
+ , m_xTabFT(m_xBuilder->weld_label("tablabel"))
+ , m_xTabMF(m_xBuilder->weld_metric_spin_button("tab", FieldUnit::CM))
+ , m_xTabImg(m_xBuilder->weld_widget("locktab"))
+ , m_xUseSquaredPageMode(m_xBuilder->weld_check_button("squaremode"))
+ , m_xUseSquaredPageModeImg(m_xBuilder->weld_widget("locksquaremode"))
+ , m_xUseCharUnit(m_xBuilder->weld_check_button("usecharunit"))
+ , m_xUseCharUnitImg(m_xBuilder->weld_widget("lockusecharunit"))
+ , m_xWordCountED(m_xBuilder->weld_entry("wordcount"))
+ , m_xWordCountImg(m_xBuilder->weld_widget("lockwordcount"))
+ , m_xShowStandardizedPageCount(m_xBuilder->weld_check_button("standardizedpageshow"))
+ , m_xShowStandardizedPageCountImg(m_xBuilder->weld_widget("lockstandardizedpageshow"))
+ , m_xStandardizedPageSizeNF(m_xBuilder->weld_spin_button("standardpagesize"))
+ , m_xStandardizedPageSizeImg(m_xBuilder->weld_widget("lockstandardpagesize"))
+{
+ for (sal_uInt32 i = 0; i < SwFieldUnitTable::Count(); ++i)
+ {
+ const OUString sMetric = SwFieldUnitTable::GetString(i);
+ FieldUnit eFUnit = SwFieldUnitTable::GetValue(i);
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::MM:
+ case FieldUnit::CM:
+ case FieldUnit::POINT:
+ case FieldUnit::PICA:
+ case FieldUnit::INCH:
+ {
+ // use only these metrics
+ m_xMetricLB->append(OUString::number(static_cast<sal_uInt32>(eFUnit)), sMetric);
+ break;
+ }
+ default:; //prevent warning
+ }
+ }
+ m_xMetricLB->connect_changed(LINK(this, SwLoadOptPage, MetricHdl));
+
+ const SfxUInt16Item* pItem = rSet.GetItemIfSet(SID_HTML_MODE, false);
+ if (pItem && pItem->GetValue() & HTMLMODE_ON)
+ {
+ m_xTabFT->hide();
+ m_xTabMF->hide();
+ }
+
+ if(!SvtCJKOptions::IsAsianTypographyEnabled())
+ {
+ m_xUseSquaredPageMode->hide();
+ m_xUseCharUnit->hide();
+ }
+
+ m_xShowStandardizedPageCount->connect_toggled(LINK(this, SwLoadOptPage, StandardizedPageCountCheckHdl));
+}
+
+SwLoadOptPage::~SwLoadOptPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwLoadOptPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SwLoadOptPage>(pPage, pController, *rAttrSet );
+}
+
+IMPL_LINK_NOARG(SwLoadOptPage, StandardizedPageCountCheckHdl, weld::Toggleable&, void)
+{
+ m_xStandardizedPageSizeNF->set_sensitive(m_xShowStandardizedPageCount->get_active());
+}
+
+OUString SwLoadOptPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label2", "label1", "label3", "label5",
+ "tablabel", "label4", "label7", "labelstandardpages" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[]
+ = { "updatefields", "updatecharts", "usecharunit", "squaremode", "standardizedpageshow" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString radioButton[] = { "always", "onrequest", "never" };
+
+ for (const auto& radio : radioButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_radio_button(radio))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwLoadOptPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bRet = false;
+ SwModule* pMod = SW_MOD();
+
+ sal_Int32 nNewLinkMode = AUTOMATIC;
+ if (m_xNeverRB->get_active())
+ nNewLinkMode = NEVER;
+ else if (m_xRequestRB->get_active())
+ nNewLinkMode = MANUAL;
+
+ SwFieldUpdateFlags eFieldFlags = m_xAutoUpdateFields->get_active() ?
+ m_xAutoUpdateCharts->get_active() ? AUTOUPD_FIELD_AND_CHARTS : AUTOUPD_FIELD_ONLY : AUTOUPD_OFF;
+
+ if (m_xAutoUpdateFields->get_state_changed_from_saved() ||
+ m_xAutoUpdateCharts->get_state_changed_from_saved())
+ {
+ pMod->ApplyFieldUpdateFlags(eFieldFlags);
+ if(m_pWrtShell)
+ {
+ m_pWrtShell->SetFieldUpdateFlags(eFieldFlags);
+ m_pWrtShell->SetModified();
+ }
+ }
+
+ if (nNewLinkMode != m_nOldLinkMode)
+ {
+ pMod->ApplyLinkMode(nNewLinkMode);
+ if (m_pWrtShell)
+ {
+ m_pWrtShell->SetLinkUpdMode( nNewLinkMode );
+ m_pWrtShell->SetModified();
+ }
+
+ bRet = true;
+ }
+
+ const sal_Int32 nMPos = m_xMetricLB->get_active();
+ if (m_xMetricLB->get_value_changed_from_saved())
+ {
+ // Double-Cast for VA3.0
+ const sal_uInt16 nFieldUnit = m_xMetricLB->get_id(nMPos).toUInt32();
+ rSet->Put( SfxUInt16Item( SID_ATTR_METRIC, nFieldUnit ) );
+ bRet = true;
+ }
+
+ if (m_xTabMF->get_visible() && m_xTabMF->get_value_changed_from_saved())
+ {
+ rSet->Put(SfxUInt16Item(SID_ATTR_DEFTABSTOP,
+ o3tl::narrowing<sal_uInt16>(m_xTabMF->denormalize(m_xTabMF->get_value(FieldUnit::TWIP)))));
+ bRet = true;
+ }
+
+ bool bIsUseCharUnitFlag = m_xUseCharUnit->get_active();
+ bIsUseCharUnitFlag = bIsUseCharUnitFlag && SvtCJKOptions::IsAsianTypographyEnabled();
+ if( (bIsUseCharUnitFlag ? 1 : 0) != m_xUseCharUnit->get_saved_state())
+ {
+ rSet->Put(SfxBoolItem(SID_ATTR_APPLYCHARUNIT, bIsUseCharUnitFlag ));
+ bRet = true;
+ }
+
+ if (m_xWordCountED->get_value_changed_from_saved())
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Writer::WordCount::AdditionalSeparators::set(m_xWordCountED->get_text(), batch);
+ batch->commit();
+ bRet = true;
+ }
+
+ if (m_xShowStandardizedPageCount->get_state_changed_from_saved())
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Writer::WordCount::ShowStandardizedPageCount::set(
+ m_xShowStandardizedPageCount->get_active(),
+ batch);
+ batch->commit();
+ bRet = true;
+ }
+
+ if (m_xStandardizedPageSizeNF->get_value_changed_from_saved())
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Writer::WordCount::StandardizedPageSize::set(
+ m_xStandardizedPageSizeNF->get_value(),
+ batch);
+ batch->commit();
+ bRet = true;
+ }
+
+ if (m_xUseSquaredPageMode->get_state_changed_from_saved())
+ {
+ bool bIsSquaredPageModeFlag = m_xUseSquaredPageMode->get_active();
+ pMod->ApplyDefaultPageMode( bIsSquaredPageModeFlag );
+ if ( m_pWrtShell )
+ {
+ SwDoc* pDoc = m_pWrtShell->GetDoc();
+ pDoc->SetDefaultPageMode( bIsSquaredPageModeFlag );
+ m_pWrtShell->SetModified();
+ }
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+void SwLoadOptPage::Reset( const SfxItemSet* rSet)
+{
+ const SwMasterUsrPref* pUsrPref = SW_MOD()->GetUsrPref(false);
+ const SwPtrItem* pShellItem = rSet->GetItemIfSet(FN_PARAM_WRTSHELL, false);
+
+ if(pShellItem)
+ m_pWrtShell = static_cast<SwWrtShell*>(pShellItem->GetValue());
+
+ SwFieldUpdateFlags eFieldFlags = AUTOUPD_GLOBALSETTING;
+ m_nOldLinkMode = GLOBALSETTING;
+ if (m_pWrtShell)
+ {
+ eFieldFlags = m_pWrtShell->GetFieldUpdateFlags();
+ m_nOldLinkMode = m_pWrtShell->GetLinkUpdMode();
+ }
+ if(GLOBALSETTING == m_nOldLinkMode)
+ m_nOldLinkMode = pUsrPref->GetUpdateLinkMode();
+ if(AUTOUPD_GLOBALSETTING == eFieldFlags)
+ eFieldFlags = pUsrPref->GetFieldUpdateFlags();
+
+ m_xAutoUpdateFields->set_active(eFieldFlags != AUTOUPD_OFF);
+ m_xAutoUpdateCharts->set_active(eFieldFlags == AUTOUPD_FIELD_AND_CHARTS);
+
+ switch (m_nOldLinkMode)
+ {
+ case NEVER: m_xNeverRB->set_active(true); break;
+ case MANUAL: m_xRequestRB->set_active(true); break;
+ case AUTOMATIC: m_xAlwaysRB->set_active(true); break;
+ }
+
+ m_xAutoUpdateFields->save_state();
+ m_xAutoUpdateCharts->save_state();
+ m_xMetricLB->set_active(-1);
+ if ( rSet->GetItemState( SID_ATTR_METRIC ) >= SfxItemState::DEFAULT )
+ {
+ const SfxUInt16Item& rItem = rSet->Get( SID_ATTR_METRIC );
+ FieldUnit eFieldUnit = static_cast<FieldUnit>(rItem.GetValue());
+
+ for (sal_Int32 i = 0, nEntryCount = m_xMetricLB->get_count(); i < nEntryCount; ++i)
+ {
+ if (m_xMetricLB->get_id(i).toUInt32() == static_cast<sal_uInt32>(eFieldUnit))
+ {
+ m_xMetricLB->set_active(i);
+ break;
+ }
+ }
+ ::SetFieldUnit(*m_xTabMF, eFieldUnit);
+ }
+ m_xMetricLB->save_value();
+ if(const SfxUInt16Item* pItem = rSet->GetItemIfSet(SID_ATTR_DEFTABSTOP, false))
+ {
+ m_nLastTab = pItem->GetValue();
+ m_xTabMF->set_value(m_xTabMF->normalize(m_nLastTab), FieldUnit::TWIP);
+ }
+ m_xTabMF->save_value();
+
+ //default page mode loading
+ if(m_pWrtShell)
+ {
+ bool bSquaredPageMode = m_pWrtShell->GetDoc()->IsSquaredPageMode();
+ m_xUseSquaredPageMode->set_active( bSquaredPageMode );
+ m_xUseSquaredPageMode->save_state();
+ }
+
+ if(const SfxBoolItem* pItem = rSet->GetItemIfSet(SID_ATTR_APPLYCHARUNIT, false))
+ {
+ bool bUseCharUnit = pItem->GetValue();
+ m_xUseCharUnit->set_active(bUseCharUnit);
+ }
+ else
+ {
+ m_xUseCharUnit->set_active(pUsrPref->IsApplyCharUnit());
+ }
+ m_xUseCharUnit->save_state();
+
+ bool bReadOnly = officecfg::Office::Writer::Content::Update::Link::isReadOnly();
+ m_xGridupdatelink->set_sensitive(!bReadOnly);
+ m_xUpdateLinkImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Update::Field::isReadOnly();
+ m_xAutoUpdateFields->set_sensitive(!bReadOnly);
+ m_xAutoUpdateFieldsImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Update::Chart::isReadOnly();
+ m_xAutoUpdateCharts->set_sensitive(!bReadOnly);
+ m_xAutoUpdateChartsImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Layout::Other::MeasureUnit::isReadOnly();
+ m_xMetricLB->set_sensitive(!bReadOnly);
+ m_xMetricImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Layout::Other::TabStop::isReadOnly();
+ m_xTabMF->set_sensitive(!bReadOnly);
+ m_xTabImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Layout::Other::ApplyCharUnit::isReadOnly();
+ m_xUseCharUnit->set_sensitive(!bReadOnly);
+ m_xUseCharUnitImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Layout::Other::IsSquaredPageMode::isReadOnly();
+ m_xUseSquaredPageMode->set_sensitive(!bReadOnly);
+ m_xUseSquaredPageModeImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::WordCount::AdditionalSeparators::isReadOnly();
+ m_xWordCountED->set_text(officecfg::Office::Writer::WordCount::AdditionalSeparators::get());
+ m_xWordCountED->set_sensitive(!bReadOnly);
+ m_xWordCountImg->set_visible(bReadOnly);
+ m_xWordCountED->save_value();
+
+ bReadOnly = officecfg::Office::Writer::WordCount::ShowStandardizedPageCount::isReadOnly();
+ m_xShowStandardizedPageCount->set_active(officecfg::Office::Writer::WordCount::ShowStandardizedPageCount::get());
+ m_xShowStandardizedPageCount->set_sensitive(!bReadOnly);
+ m_xShowStandardizedPageCountImg->set_visible(bReadOnly);
+ m_xShowStandardizedPageCount->save_state();
+
+ bReadOnly = officecfg::Office::Writer::WordCount::StandardizedPageSize::isReadOnly();
+ m_xStandardizedPageSizeNF->set_value(officecfg::Office::Writer::WordCount::StandardizedPageSize::get());
+ m_xStandardizedPageSizeNF->set_sensitive(!bReadOnly && m_xShowStandardizedPageCount->get_active());
+ m_xStandardizedPageSizeImg->set_visible(bReadOnly);
+ m_xStandardizedPageSizeNF->save_value();
+}
+
+IMPL_LINK_NOARG(SwLoadOptPage, MetricHdl, weld::ComboBox&, void)
+{
+ const sal_Int32 nMPos = m_xMetricLB->get_active();
+ if(nMPos == -1)
+ return;
+
+ // Double-Cast for VA3.0
+ FieldUnit eFieldUnit = static_cast<FieldUnit>(m_xMetricLB->get_id(nMPos).toUInt32());
+ bool bModified = m_xTabMF->get_value_changed_from_saved();
+ tools::Long nVal = bModified ?
+ sal::static_int_cast<sal_Int32, sal_Int64 >( m_xTabMF->denormalize( m_xTabMF->get_value( FieldUnit::TWIP ) )) :
+ m_nLastTab;
+ ::SetFieldUnit( *m_xTabMF, eFieldUnit );
+ m_xTabMF->set_value( m_xTabMF->normalize( nVal ), FieldUnit::TWIP );
+ if (!bModified)
+ m_xTabMF->save_value();
+}
+
+SwCaptionOptDlg::SwCaptionOptDlg(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet, "modules/swriter/ui/captiondialog.ui",
+ "CaptionDialog")
+{
+ // create TabPage
+ SetTabPage(SwCaptionOptPage::Create(get_content_area(), this, &rSet));
+}
+
+SwCaptionPreview::SwCaptionPreview()
+ : mbFontInitialized(false)
+{
+}
+
+void SwCaptionPreview::ApplySettings(vcl::RenderContext& rRenderContext)
+{
+ const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
+ Wallpaper aBack(rSettings.GetWindowColor());
+ rRenderContext.SetBackground(aBack);
+ rRenderContext.SetFillColor(aBack.GetColor());
+ rRenderContext.SetLineColor(aBack.GetColor());
+ rRenderContext.SetTextColor(rSettings.GetWindowTextColor());
+
+ if (!mbFontInitialized)
+ {
+ maFont = rRenderContext.GetFont();
+ maFont.SetFontHeight(maFont.GetFontHeight() * 120 / 100);
+ mbFontInitialized = true;
+ }
+ rRenderContext.SetFont(maFont);
+}
+
+void SwCaptionPreview::SetPreviewText(const OUString& rText)
+{
+ if (rText != maText)
+ {
+ maText = rText;
+ Invalidate();
+ }
+}
+
+void SwCaptionPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(106 , 20), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+}
+
+void SwCaptionPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ ApplySettings(rRenderContext);
+
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), GetOutputSizePixel()));
+ rRenderContext.DrawText(Point(4, 6), maText);
+}
+
+IMPL_LINK(SwCaptionOptPage, TextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = m_aTextFilter.filter(rTest);
+ return true;
+}
+
+SwCaptionOptPage::SwCaptionOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optcaptionpage.ui", "OptCaptionPage", &rSet)
+ , m_sSWTable(SwResId(STR_CAPTION_TABLE))
+ , m_sSWFrame(SwResId(STR_CAPTION_FRAME))
+ , m_sSWGraphic(SwResId(STR_CAPTION_GRAPHIC))
+ , m_sOLE(SwResId(STR_CAPTION_OLE))
+ , m_sBegin(SwResId(STR_CAPTION_BEGINNING))
+ , m_sEnd(SwResId(STR_CAPTION_END))
+ , m_sAbove(SwResId(STR_CAPTION_ABOVE))
+ , m_sBelow(SwResId(STR_CAPTION_BELOW))
+ , m_sNone(SwResId(SW_STR_NONE))
+ , m_nPrevSelectedEntry(-1)
+ , m_pMgr(new SwFieldMgr)
+ , m_bHTMLMode(false)
+ , m_aTextFilter(m_sNone)
+ , m_xCheckLB(m_xBuilder->weld_tree_view("objects"))
+ , m_xLbCaptionOrder(m_xBuilder->weld_combo_box("captionorder"))
+ , m_xLbCaptionOrderImg(m_xBuilder->weld_widget("lockcaptionorder"))
+ , m_xSettingsGroup(m_xBuilder->weld_widget("settings"))
+ , m_xCategoryBox(m_xBuilder->weld_combo_box("category"))
+ , m_xCategoryBoxImg(m_xBuilder->weld_widget("lockcategory"))
+ , m_xFormatText(m_xBuilder->weld_label("numberingft"))
+ , m_xFormatBox(m_xBuilder->weld_combo_box("numbering"))
+ , m_xFormatBoxImg(m_xBuilder->weld_widget("locknumbering"))
+ , m_xNumberingSeparatorFT(m_xBuilder->weld_label("numseparatorft"))
+ , m_xNumberingSeparatorED(m_xBuilder->weld_entry("numseparator"))
+ , m_xNumberingSeparatorImg(m_xBuilder->weld_widget("locknumseparator"))
+ , m_xTextText(m_xBuilder->weld_label("separatorft"))
+ , m_xTextEdit(m_xBuilder->weld_entry("separator"))
+ , m_xTextEditImg(m_xBuilder->weld_widget("lockseparator"))
+ , m_xPosBox(m_xBuilder->weld_combo_box("position"))
+ , m_xPosBoxImg(m_xBuilder->weld_widget("lockposition"))
+ , m_xNumCapt(m_xBuilder->weld_widget("numcaption"))
+ , m_xLbLevel(m_xBuilder->weld_combo_box("level"))
+ , m_xLbLevelImg(m_xBuilder->weld_widget("locklevel"))
+ , m_xEdDelim(m_xBuilder->weld_entry("chapseparator"))
+ , m_xEdDelimImg(m_xBuilder->weld_widget("lockchapseparator"))
+ , m_xCategory(m_xBuilder->weld_widget("categoryformat"))
+ , m_xCharStyleLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xCharStyleImg(m_xBuilder->weld_widget("lockcharstyle"))
+ , m_xApplyBorderCB(m_xBuilder->weld_check_button("applyborder"))
+ , m_xApplyBorderImg(m_xBuilder->weld_widget("lockapplyborder"))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreview))
+{
+ m_xCategoryBox->connect_entry_insert_text(LINK(this, SwCaptionOptPage, TextFilterHdl));
+
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ SwStyleNameMapper::FillUIName(RES_POOLCOLL_LABEL_ABB, m_sIllustration);
+ SwStyleNameMapper::FillUIName(RES_POOLCOLL_LABEL_TABLE, m_sTable);
+ SwStyleNameMapper::FillUIName(RES_POOLCOLL_LABEL_FRAME, m_sText);
+ SwStyleNameMapper::FillUIName(RES_POOLCOLL_LABEL_DRAWING, m_sDrawing);
+
+
+ // m_xFormatBox
+ sal_uInt16 nSelFormat = SVX_NUM_ARABIC;
+ SwWrtShell* pSh = ::GetActiveWrtShell();
+
+ if (pSh)
+ {
+ for ( auto i = m_pMgr->GetFieldTypeCount(); i; )
+ {
+ SwFieldType* pFieldType = m_pMgr->GetFieldType(SwFieldIds::Unknown, --i);
+ if (!pFieldType->GetName().isEmpty()
+ && pFieldType->GetName() == m_xCategoryBox->get_active_text())
+ {
+ nSelFormat = o3tl::narrowing<sal_uInt16>(static_cast<SwSetExpFieldType*>(pFieldType)->GetSeqFormat());
+ break;
+ }
+ }
+
+ ::FillCharStyleListBox( *m_xCharStyleLB, pSh->GetView().GetDocShell(), true, true );
+ }
+
+ const sal_uInt16 nCount = m_pMgr->GetFormatCount(SwFieldTypesEnum::Sequence, false);
+ for ( sal_uInt16 i = 0; i < nCount; ++i )
+ {
+ const sal_uInt16 nFormatId = m_pMgr->GetFormatId(SwFieldTypesEnum::Sequence, i);
+ m_xFormatBox->append(OUString::number(nFormatId), m_pMgr->GetFormatStr(SwFieldTypesEnum::Sequence, i));
+ if (nFormatId == nSelFormat)
+ m_xFormatBox->set_active(i);
+ }
+
+ for (int i = 0; i < MAXLEVEL; ++i)
+ m_xLbLevel->append_text(OUString::number(i + 1));
+
+ sal_Unicode nLvl = MAXLEVEL;
+ OUString sDelim(": ");
+
+ if (pSh)
+ {
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(m_pMgr->GetFieldType(
+ SwFieldIds::SetExp, m_xCategoryBox->get_active_text() ));
+ if( pFieldType )
+ {
+ sDelim = pFieldType->GetDelimiter();
+ nLvl = pFieldType->GetOutlineLvl();
+ }
+ }
+
+ m_xLbLevel->set_active(nLvl < MAXLEVEL ? nLvl + 1 : 0);
+ m_xEdDelim->set_text(sDelim);
+
+ m_xCategoryBox->connect_changed(LINK(this, SwCaptionOptPage, ModifyComboHdl));
+ Link<weld::Entry&,void> aLk = LINK(this, SwCaptionOptPage, ModifyEntryHdl);
+ m_xNumberingSeparatorED->connect_changed(aLk);
+ m_xTextEdit->connect_changed(aLk);
+
+ m_xCategoryBox->connect_changed(LINK(this, SwCaptionOptPage, SelectHdl));
+ m_xFormatBox->connect_changed(LINK(this, SwCaptionOptPage, SelectListBoxHdl));
+
+ m_xLbCaptionOrder->connect_changed(LINK(this, SwCaptionOptPage, OrderHdl));
+
+ m_xCheckLB->connect_changed(LINK(this, SwCaptionOptPage, ShowEntryHdl));
+ m_xCheckLB->connect_toggled(LINK(this, SwCaptionOptPage, ToggleEntryHdl));
+}
+
+SwCaptionOptPage::~SwCaptionOptPage()
+{
+ DelUserData();
+ m_pMgr.reset();
+ m_xPreview.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwCaptionOptPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwCaptionOptPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwCaptionOptPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label1", "label13", "label2", "label7", "numberingft",
+ "numseparatorft", "separatorft", "label18", "label11", "label4",
+ "label6", "label10", "label3" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ if (const auto& pString = m_xBuilder->weld_check_button("applyborder"))
+ sAllStrings += pString->get_label() + " ";
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwCaptionOptPage::FillItemSet( SfxItemSet* )
+{
+ bool bRet = false;
+ SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+
+ SaveEntry(m_xCheckLB->get_selected_index()); // apply current entry
+
+ int nCheckCount = 0;
+ for (int i = 0, nCount = m_xCheckLB->n_children(); i < nCount; ++i)
+ {
+ if (m_xCheckLB->get_toggle(i) == TRISTATE_TRUE)
+ ++nCheckCount;
+ InsCaptionOpt* pData = weld::fromId<InsCaptionOpt*>(m_xCheckLB->get_id(i));
+ bRet |= pModOpt->SetCapOption(m_bHTMLMode, pData);
+ }
+
+ pModOpt->SetInsWithCaption(m_bHTMLMode, nCheckCount > 0);
+
+ int nPos = m_xLbCaptionOrder->get_active();
+ pModOpt->SetCaptionOrderNumberingFirst(nPos == 1);
+
+ return bRet;
+}
+
+void SwCaptionOptPage::Reset( const SfxItemSet* rSet)
+{
+ if(const SfxUInt16Item* pItem = rSet->GetItemIfSet(SID_HTML_MODE, false))
+ {
+ m_bHTMLMode = 0 != (pItem->GetValue() & HTMLMODE_ON);
+ }
+
+ DelUserData();
+ m_xCheckLB->clear(); // remove all entries
+
+ // Writer objects
+ int nPos = 0;
+ bool bReadOnly = false;
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos, m_sSWTable, 0);
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Table::Enable::isReadOnly();
+ m_xCheckLB->set_sensitive(nPos, !bReadOnly);
+ SetOptions(nPos++, TABLE_CAP);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos, m_sSWFrame, 0);
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Frame::Enable::isReadOnly();
+ m_xCheckLB->set_sensitive(nPos, !bReadOnly);
+ SetOptions(nPos++, FRAME_CAP);
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos, m_sSWGraphic, 0);
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::WriterObject::Graphic::Enable::isReadOnly();
+ m_xCheckLB->set_sensitive(nPos, !bReadOnly);
+ SetOptions(nPos++, GRAPHIC_CAP);
+
+ // get Productname and -version
+ const OUString sWithoutVersion( utl::ConfigManager::getProductName() );
+ const OUString sComplete(
+ sWithoutVersion + " " +
+ utl::ConfigManager::getProductVersion() );
+
+ SvObjectServerList aObjS;
+ aObjS.FillInsertObjects();
+ aObjS.Remove( SvGlobalName( SO3_SW_CLASSID ) ); // remove Writer-ID
+
+ for ( sal_uLong i = 0; i < aObjS.Count(); ++i )
+ {
+ const SvGlobalName &rOleId = aObjS[i].GetClassName();
+ OUString sClass;
+ if (rOleId == SvGlobalName(SO3_OUT_CLASSID))
+ sClass = m_sOLE;
+ else
+ sClass = aObjS[i].GetHumanName();
+ // don't show product version
+ sClass = sClass.replaceFirst( sComplete, sWithoutVersion );
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE);
+ m_xCheckLB->set_text(nPos, sClass, 0);
+ if (rOleId == SvGlobalName(SO3_SC_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Calc::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SDRAW_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Draw::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SM_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Formula::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SCH_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Chart::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_SIMPRESS_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::Impress::Enable::isReadOnly();
+ } else if (rOleId == SvGlobalName(SO3_OUT_CLASSID)) {
+ bReadOnly = officecfg::Office::Writer::Insert::Caption::OfficeObject::OLEMisc::Enable::isReadOnly();
+ }
+ else {
+ //
+ }
+ m_xCheckLB->set_sensitive(nPos, !bReadOnly);
+ SetOptions( nPos++, OLE_CAP, &rOleId );
+ }
+ m_xLbCaptionOrder->set_active(
+ SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst() ? 1 : 0);
+ m_xLbCaptionOrder->set_sensitive(!officecfg::Office::Writer::Insert::Caption::CaptionOrderNumberingFirst::isReadOnly());
+ m_xLbCaptionOrderImg->set_visible(officecfg::Office::Writer::Insert::Caption::CaptionOrderNumberingFirst::isReadOnly());
+ m_xCheckLB->select(0);
+ ShowEntryHdl(*m_xCheckLB);
+}
+
+void SwCaptionOptPage::SetOptions(const sal_uLong nPos,
+ const SwCapObjType eObjType, const SvGlobalName *pOleId)
+{
+ SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+ const InsCaptionOpt* pOpt = pModOpt->GetCapOption(m_bHTMLMode, eObjType, pOleId);
+
+ if (pOpt)
+ {
+ InsCaptionOpt* pIns = new InsCaptionOpt(*pOpt);
+ m_xCheckLB->set_id(nPos, weld::toId(pIns));
+ m_xCheckLB->set_toggle(nPos, pOpt->UseCaption() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ }
+ else
+ {
+ InsCaptionOpt* pIns = new InsCaptionOpt(eObjType, pOleId);
+ m_xCheckLB->set_id(nPos, weld::toId(pIns));
+ }
+}
+
+void SwCaptionOptPage::DelUserData()
+{
+ for (int i = 0, nCount = m_xCheckLB->n_children(); i < nCount; ++i)
+ {
+ delete weld::fromId<InsCaptionOpt*>(m_xCheckLB->get_id(i));
+ m_xCheckLB->set_id(i, "0");
+ }
+}
+
+void SwCaptionOptPage::UpdateEntry(int nSelEntry)
+{
+ if (nSelEntry != -1)
+ {
+ bool bChecked = m_xCheckLB->get_toggle(nSelEntry) == TRISTATE_TRUE;
+
+ m_xSettingsGroup->set_sensitive(bChecked);
+ bool bNumSep = bChecked && m_xLbCaptionOrder->get_active() == 1;
+ m_xNumberingSeparatorED->set_sensitive( bNumSep );
+ m_xNumberingSeparatorFT->set_sensitive( bNumSep );
+
+ m_xNumCapt->set_sensitive(bChecked);
+ m_xCategory->set_sensitive(bChecked);
+ m_xPreview->set_sensitive(bChecked);
+
+
+ InsCaptionOpt* pOpt = weld::fromId<InsCaptionOpt*>(m_xCheckLB->get_id(nSelEntry));
+
+ m_xCategoryBox->clear();
+ m_xCategoryBox->append_text(m_sNone);
+ if (::GetActiveWrtShell())
+ {
+ const size_t nCount = m_pMgr->GetFieldTypeCount();
+
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ SwFieldType *pType = m_pMgr->GetFieldType( SwFieldIds::Unknown, i );
+ if( pType->Which() == SwFieldIds::SetExp &&
+ static_cast<SwSetExpFieldType *>( pType)->GetType() & nsSwGetSetExpType::GSE_SEQ )
+ {
+ m_xCategoryBox->append_text(pType->GetName());
+ }
+ }
+ }
+ else
+ {
+ m_xCategoryBox->append_text(m_sIllustration);
+ m_xCategoryBox->append_text(m_sTable);
+ m_xCategoryBox->append_text(m_sText);
+ m_xCategoryBox->append_text(m_sDrawing);
+ }
+
+ if (!pOpt->GetCategory().isEmpty())
+ {
+ if (m_xCategoryBox->find_text(pOpt->GetCategory()) == -1)
+ m_xCategoryBox->insert_text(0, pOpt->GetCategory());
+ m_xCategoryBox->set_active_text(pOpt->GetCategory());
+ }
+ else
+ m_xCategoryBox->set_active_text(m_sNone);
+
+ if (m_xCategoryBox->get_active_text().isEmpty())
+ {
+ sal_Int32 nPos = 0;
+ switch(pOpt->GetObjType())
+ {
+ case OLE_CAP:
+ case GRAPHIC_CAP: nPos = 1; break;
+ case TABLE_CAP: nPos = 2; break;
+ case FRAME_CAP: nPos = 3; break;
+ }
+ m_xCategoryBox->set_active(nPos);
+ }
+
+ bool bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_CATEGORY, pOpt->GetOleId());
+ m_xCategoryBox->set_sensitive(bChecked && !bReadOnly);
+ m_xCategoryBoxImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_NUMBERING, pOpt->GetOleId());
+ m_xFormatBox->set_sensitive(bChecked && !bReadOnly);
+ m_xFormatBoxImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_NUMBERINGSEPARATOR, pOpt->GetOleId());
+ m_xNumberingSeparatorED->set_sensitive(bNumSep && !bReadOnly);
+ m_xNumberingSeparatorImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_CAPTIONTEXT, pOpt->GetOleId());
+ m_xTextEdit->set_sensitive(bChecked && !bReadOnly);
+ m_xTextEditImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_DELIMITER, pOpt->GetOleId());
+ m_xPosBox->set_sensitive(bChecked && !bReadOnly);
+ m_xPosBoxImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_LEVEL, pOpt->GetOleId());
+ m_xLbLevel->set_sensitive(bChecked && !bReadOnly);
+ m_xLbLevelImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_POSITION, pOpt->GetOleId());
+ m_xEdDelim->set_sensitive(bChecked && !bReadOnly);
+ m_xEdDelimImg->set_visible(bReadOnly);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_CHARACTERSTYLE, pOpt->GetOleId());
+ m_xCharStyleLB->set_sensitive(bChecked && !bReadOnly);
+ m_xCharStyleImg->set_visible(bReadOnly);
+
+ for (sal_Int32 i = 0; i < m_xFormatBox->get_count(); i++)
+ {
+ if (pOpt->GetNumType() == m_xFormatBox->get_id(i).toUInt32())
+ {
+ m_xFormatBox->set_active(i);
+ break;
+ }
+ }
+ m_xTextEdit->set_text(pOpt->GetCaption());
+
+ m_xPosBox->clear();
+ switch (pOpt->GetObjType())
+ {
+ case GRAPHIC_CAP:
+ case TABLE_CAP:
+ case OLE_CAP:
+ m_xPosBox->append_text(m_sAbove);
+ m_xPosBox->append_text(m_sBelow);
+ break;
+ case FRAME_CAP:
+ m_xPosBox->append_text(m_sBegin);
+ m_xPosBox->append_text(m_sEnd);
+ break;
+ }
+ m_xPosBox->set_active(pOpt->GetPos());
+
+ sal_Int32 nLevelPos = ( pOpt->GetLevel() < MAXLEVEL ) ? pOpt->GetLevel() + 1 : 0;
+ m_xLbLevel->set_active(nLevelPos);
+ m_xEdDelim->set_text(pOpt->GetSeparator());
+ m_xNumberingSeparatorED->set_text(pOpt->GetNumSeparator());
+ if (!pOpt->GetCharacterStyle().isEmpty())
+ m_xCharStyleLB->set_active_text(pOpt->GetCharacterStyle());
+ else
+ m_xCharStyleLB->set_active(0);
+
+ bReadOnly = lcl_isPropertyReadOnly(pOpt->GetObjType(), PROP_CAP_OBJECT_APPLYATTRIBUTES, pOpt->GetOleId());
+ m_xApplyBorderCB->set_sensitive(m_xCategoryBox->get_sensitive() && !bReadOnly &&
+ pOpt->GetObjType() != TABLE_CAP && pOpt->GetObjType() != FRAME_CAP );
+ m_xApplyBorderImg->set_visible(bReadOnly);
+ m_xApplyBorderCB->set_active(pOpt->CopyAttributes());
+ }
+
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwCaptionOptPage, ShowEntryHdl, weld::TreeView&, void)
+{
+ if (m_nPrevSelectedEntry != -1)
+ SaveEntry(m_nPrevSelectedEntry);
+ UpdateEntry(m_xCheckLB->get_selected_index());
+ m_nPrevSelectedEntry = m_xCheckLB->get_selected_index();
+}
+
+IMPL_LINK(SwCaptionOptPage, ToggleEntryHdl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ UpdateEntry(m_xCheckLB->get_iter_index_in_parent(rRowCol.first));
+}
+
+void SwCaptionOptPage::SaveEntry(int nEntry)
+{
+ if (nEntry == -1)
+ return;
+
+ InsCaptionOpt* pOpt = weld::fromId<InsCaptionOpt*>(m_xCheckLB->get_id(nEntry));
+
+ pOpt->UseCaption() = m_xCheckLB->get_toggle(nEntry) == TRISTATE_TRUE;
+ const OUString aName(m_xCategoryBox->get_active_text());
+ if (aName == m_sNone)
+ pOpt->SetCategory("");
+ else
+ pOpt->SetCategory(comphelper::string::strip(aName, ' '));
+ pOpt->SetNumType(m_xFormatBox->get_active_id().toUInt32());
+ pOpt->SetCaption(m_xTextEdit->get_sensitive() ? m_xTextEdit->get_text() : OUString() );
+ pOpt->SetPos(m_xPosBox->get_active());
+ int nPos = m_xLbLevel->get_active();
+ sal_Int32 nLevel = (nPos > 0) ? nPos - 1 : MAXLEVEL;
+ pOpt->SetLevel(nLevel);
+ pOpt->SetSeparator(m_xEdDelim->get_text());
+ pOpt->SetNumSeparator(m_xNumberingSeparatorED->get_text());
+ if (m_xCharStyleLB->get_active() == -1)
+ pOpt->SetCharacterStyle("");
+ else
+ pOpt->SetCharacterStyle(m_xCharStyleLB->get_active_text());
+ pOpt->CopyAttributes() = m_xApplyBorderCB->get_active();
+}
+
+void SwCaptionOptPage::ModifyHdl()
+{
+ const OUString sFieldTypeName = m_xCategoryBox->get_active_text();
+
+ if (SfxSingleTabDialogController* pDlg = dynamic_cast<SfxSingleTabDialogController*>(GetDialogController()))
+ pDlg->GetOKButton().set_sensitive(!sFieldTypeName.isEmpty());
+ bool bEnable = m_xCategoryBox->get_sensitive() && sFieldTypeName != m_sNone;
+
+ m_xFormatText->set_sensitive(bEnable);
+ m_xFormatBox->set_sensitive(bEnable);
+ m_xTextText->set_sensitive(bEnable);
+ m_xTextEdit->set_sensitive(bEnable);
+
+ InvalidatePreview();
+}
+
+IMPL_LINK_NOARG(SwCaptionOptPage, ModifyEntryHdl, weld::Entry&, void)
+{
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwCaptionOptPage, ModifyComboHdl, weld::ComboBox&, void)
+{
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwCaptionOptPage, SelectHdl, weld::ComboBox&, void)
+{
+ InvalidatePreview();
+}
+
+IMPL_LINK_NOARG(SwCaptionOptPage, SelectListBoxHdl, weld::ComboBox&, void)
+{
+ InvalidatePreview();
+}
+
+IMPL_LINK(SwCaptionOptPage, OrderHdl, weld::ComboBox&, rBox, void)
+{
+ InvalidatePreview();
+
+ int nSelEntry = m_xCheckLB->get_selected_index();
+ bool bChecked = false;
+ if (nSelEntry != -1)
+ {
+ bChecked = m_xCheckLB->get_toggle(nSelEntry) == TRISTATE_TRUE;
+ }
+
+ int nPos = rBox.get_active();
+ m_xNumberingSeparatorFT->set_sensitive(bChecked && nPos == 1);
+ m_xNumberingSeparatorED->set_sensitive(bChecked && nPos == 1);
+}
+
+void SwCaptionOptPage::InvalidatePreview()
+{
+ OUString aStr;
+
+ if (m_xCategoryBox->get_active_text() != m_sNone)
+ {
+ //#i61007# order of captions
+ bool bOrderNumberingFirst = m_xLbCaptionOrder->get_active() == 1;
+ // number
+ const sal_uInt16 nNumFormat = m_xFormatBox->get_active_id().toUInt32();
+ if (SVX_NUM_NUMBER_NONE != nNumFormat)
+ {
+ //#i61007# order of captions
+ if( !bOrderNumberingFirst )
+ {
+ // category
+ aStr += m_xCategoryBox->get_active_text() + " ";
+ }
+
+ if (SwWrtShell *pSh = ::GetActiveWrtShell())
+ {
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(m_pMgr->GetFieldType(
+ SwFieldIds::SetExp, m_xCategoryBox->get_active_text() ));
+ if( pFieldType && pFieldType->GetOutlineLvl() < MAXLEVEL )
+ {
+ sal_uInt8 nLvl = pFieldType->GetOutlineLvl();
+ SwNumberTree::tNumberVector aNumVector;
+ for( sal_uInt8 i = 0; i <= nLvl; ++i )
+ aNumVector.push_back(1);
+
+ const OUString sNumber( pSh->GetOutlineNumRule()->MakeNumString(
+ aNumVector, false ));
+ if( !sNumber.isEmpty() )
+ aStr += sNumber + pFieldType->GetDelimiter();
+ }
+ }
+
+ switch( nNumFormat )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER: aStr += "A"; break;
+ case SVX_NUM_CHARS_UPPER_LETTER_N: aStr += "A"; break;
+ case SVX_NUM_CHARS_LOWER_LETTER: aStr += "a"; break;
+ case SVX_NUM_CHARS_LOWER_LETTER_N: aStr += "a"; break;
+ case SVX_NUM_ROMAN_UPPER: aStr += "I"; break;
+ case SVX_NUM_ROMAN_LOWER: aStr += "i"; break;
+ //case ARABIC:
+ default: aStr += "1"; break;
+ }
+ }
+ //#i61007# order of captions
+ if( bOrderNumberingFirst )
+ {
+ aStr += m_xNumberingSeparatorED->get_text() + m_xCategoryBox->get_active_text();
+ }
+ aStr += m_xTextEdit->get_text();
+ }
+ m_aPreview.SetPreviewText(aStr);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/config/optpage.cxx b/sw/source/ui/config/optpage.cxx
new file mode 100644
index 0000000000..a2af6912b7
--- /dev/null
+++ b/sw/source/ui/config/optpage.cxx
@@ -0,0 +1,2848 @@
+/* -*- 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 <utility>
+
+#include <optpage.hxx>
+#include <doc.hxx>
+#include <hintids.hxx>
+#include <cmdid.h>
+#include <fmtcol.hxx>
+#include <charatr.hxx>
+#include <swtypes.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <IDocumentSettingAccess.hxx>
+
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <cfgitems.hxx>
+#include <poolfmt.hxx>
+#include <uiitems.hxx>
+#include <printdata.hxx>
+#include <modcfg.hxx>
+#include <crstate.hxx>
+#include <viewopt.hxx>
+#include <globals.hrc>
+#include <strings.hrc>
+#include <swwrtshitem.hxx>
+
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/svxenum.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Writer.hxx>
+#include <officecfg/Office/WriterWeb.hxx>
+#include <sal/macros.h>
+#include <sfx2/dialoghelper.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/ctloptions.hxx>
+#include <svl/eitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/unitconv.hxx>
+#include <sfx2/htmlmode.hxx>
+
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <optload.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+void drawRect(vcl::RenderContext& rRenderContext, const tools::Rectangle &rRect, const Color &rFillColor, const Color &rLineColor)
+{
+ rRenderContext.SetFillColor(rFillColor);
+ rRenderContext.SetLineColor(rLineColor);
+ rRenderContext.DrawRect(rRect);
+}
+
+}
+
+// Tools->Options->Writer->View
+// Tools->Options->Writer/Web->View
+SwContentOptPage::SwContentOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/viewoptionspage.ui", "ViewOptionsPage", &rCoreSet)
+ , m_xCrossCB(m_xBuilder->weld_check_button("helplines"))
+ , m_xCrossImg(m_xBuilder->weld_widget("lockhelplines"))
+ , m_xHMetric(m_xBuilder->weld_combo_box("hrulercombobox"))
+ , m_xHMetricImg(m_xBuilder->weld_widget("lockhruler"))
+ , m_xVRulerCBox(m_xBuilder->weld_check_button("vruler"))
+ , m_xVRulerImg(m_xBuilder->weld_widget("lockvruler"))
+ , m_xVRulerRightCBox(m_xBuilder->weld_check_button("vrulerright"))
+ , m_xVRulerRightImg(m_xBuilder->weld_widget("lockvrulerright"))
+ , m_xVMetric(m_xBuilder->weld_combo_box("vrulercombobox"))
+ , m_xSmoothCBox(m_xBuilder->weld_check_button("smoothscroll"))
+ , m_xSmoothImg(m_xBuilder->weld_widget("locksmoothscroll"))
+ , m_xGrfCB(m_xBuilder->weld_check_button("graphics"))
+ , m_xGrfImg(m_xBuilder->weld_widget("lockgraphics"))
+ , m_xTableCB(m_xBuilder->weld_check_button("tables"))
+ , m_xTableImg(m_xBuilder->weld_widget("locktables"))
+ , m_xDrwCB(m_xBuilder->weld_check_button("drawings"))
+ , m_xDrwImg(m_xBuilder->weld_widget("lockdrawings"))
+ , m_xPostItCB(m_xBuilder->weld_check_button("comments"))
+ , m_xSettingsFrame(m_xBuilder->weld_frame("settingsframe"))
+ , m_xSettingsLabel(m_xBuilder->weld_label("settingslabel"))
+ , m_xMetricLabel(m_xBuilder->weld_label("measureunitlabel"))
+ , m_xMetricLB(m_xBuilder->weld_combo_box("measureunit"))
+ , m_xMetricImg(m_xBuilder->weld_widget("lockmeasureunit"))
+ , m_xShowInlineTooltips(m_xBuilder->weld_check_button("changestooltip"))
+ , m_xShowInlineTooltipsImg(m_xBuilder->weld_widget("lockchangestooltip"))
+ , m_xShowOutlineContentVisibilityButton(m_xBuilder->weld_check_button("outlinecontentvisibilitybutton"))
+ , m_xShowOutlineContentVImg(m_xBuilder->weld_widget("lockoutlinecontentvisibility"))
+ , m_xTreatSubOutlineLevelsAsContent(m_xBuilder->weld_check_button("suboutlinelevelsascontent"))
+ , m_xTreatSubOutlineLevelsImg(m_xBuilder->weld_widget("locksuboutlinelevels"))
+ , m_xShowChangesInMargin(m_xBuilder->weld_check_button("changesinmargin"))
+ , m_xShowChangesInMarginImg(m_xBuilder->weld_widget("lockchangesinmargin"))
+ , m_xFieldHiddenCB(m_xBuilder->weld_check_button("hiddentextfield"))
+ , m_xFieldHiddenImg(m_xBuilder->weld_widget("lockhiddentextfield"))
+ , m_xFieldHiddenParaCB(m_xBuilder->weld_check_button("hiddenparafield"))
+ , m_xFieldHiddenParaImg(m_xBuilder->weld_widget("lockhiddenparafield"))
+{
+ m_xShowOutlineContentVisibilityButton->connect_toggled(LINK(this, SwContentOptPage, ShowOutlineContentVisibilityButtonHdl));
+
+ /* This part is visible only with Writer/Web->View dialogue. */
+ const SfxUInt16Item* pItem = rCoreSet.GetItemIfSet(SID_HTML_MODE, false );
+ if (!pItem || !(pItem->GetValue() & HTMLMODE_ON))
+ {
+ m_xSettingsFrame->hide();
+ m_xSettingsLabel->hide();
+ m_xMetricLabel->hide();
+ m_xMetricLB->hide();
+ }
+
+ if(!SvtCJKOptions::IsVerticalTextEnabled() )
+ m_xVRulerRightCBox->hide();
+ m_xVRulerCBox->connect_toggled(LINK(this, SwContentOptPage, VertRulerHdl ));
+
+ for (size_t i = 0; i < SwFieldUnitTable::Count(); ++i)
+ {
+ const OUString sMetric = SwFieldUnitTable::GetString(i);
+ FieldUnit eFUnit = SwFieldUnitTable::GetValue(i);
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::MM:
+ case FieldUnit::CM:
+ case FieldUnit::POINT:
+ case FieldUnit::PICA:
+ case FieldUnit::INCH:
+ case FieldUnit::CHAR: // add two units , 'character' and 'line' , their ticks are not fixed
+ case FieldUnit::LINE:
+ {
+ // only use these metrics
+ // a horizontal ruler has not the 'line' unit
+ // there isn't 'line' unit in HTML format
+ if (eFUnit != FieldUnit::LINE)
+ {
+ m_xMetricLB->append(OUString::number(static_cast<sal_uInt32>(eFUnit)), sMetric);
+ m_xHMetric->append(OUString::number(static_cast<sal_uInt32>(eFUnit)), sMetric);
+ }
+ // a vertical ruler has not the 'character' unit
+ if (eFUnit != FieldUnit::CHAR)
+ {
+ m_xVMetric->append(OUString::number(static_cast<sal_uInt32>(eFUnit)), sMetric);
+ }
+ break;
+ }
+ default:;//prevent warning
+ }
+ }
+}
+
+SwContentOptPage::~SwContentOptPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwContentOptPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwContentOptPage>(pPage, pController, *rAttrSet);
+}
+
+static void lcl_SelectMetricLB(weld::ComboBox& rMetric, TypedWhichId<SfxUInt16Item> nSID, const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ if( rSet.GetItemState( nSID, false, &pItem ) >= SfxItemState::DEFAULT )
+ {
+ FieldUnit eFieldUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
+ for (sal_Int32 i = 0, nEntryCount = rMetric.get_count(); i < nEntryCount; ++i)
+ {
+ if (rMetric.get_id(i).toUInt32() == static_cast<sal_uInt32>(eFieldUnit))
+ {
+ rMetric.set_active(i);
+ break;
+ }
+ }
+ }
+ rMetric.save_value();
+}
+
+void SwContentOptPage::Reset(const SfxItemSet* rSet)
+{
+ bool bReadOnly = false;
+ bool bWebOptionsPage = m_xSettingsFrame->is_visible();
+ const SwElemItem* pElemAttr = rSet->GetItemIfSet( FN_PARAM_ELEM , false );
+ if(pElemAttr)
+ {
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Content::Display::Table::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::Display::Table::isReadOnly();
+ m_xTableCB->set_active(pElemAttr->m_bTable);
+ m_xTableCB->set_sensitive(!bReadOnly);
+ m_xTableImg->set_visible(bReadOnly);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Content::Display::GraphicObject::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::Display::GraphicObject::isReadOnly();
+ m_xGrfCB->set_active(pElemAttr->m_bGraphic);
+ m_xGrfCB->set_sensitive(!bReadOnly);
+ m_xGrfImg->set_visible(bReadOnly);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Content::Display::DrawingControl::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::Display::DrawingControl::isReadOnly();
+ m_xDrwCB->set_active(pElemAttr->m_bDrawing);
+ m_xDrwCB->set_sensitive(!bReadOnly);
+ m_xDrwImg->set_visible(bReadOnly);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Content::Display::Note::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::Display::Note::isReadOnly();
+ m_xPostItCB->set_active(pElemAttr->m_bNotes);
+ m_xPostItCB->set_sensitive(!bReadOnly);
+ m_xPostItCB->set_visible(pElemAttr->m_bNotes);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Layout::Line::Guide::isReadOnly() :
+ officecfg::Office::WriterWeb::Layout::Line::Guide::isReadOnly();
+ m_xCrossCB->set_active(pElemAttr->m_bCrosshair);
+ m_xCrossCB->set_sensitive(!bReadOnly);
+ m_xCrossImg->set_visible(bReadOnly);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Layout::Window::VerticalRuler::isReadOnly() :
+ officecfg::Office::WriterWeb::Layout::Window::VerticalRuler::isReadOnly();
+ m_xVRulerCBox->set_active(pElemAttr->m_bVertRuler);
+ m_xVRulerCBox->set_sensitive(!bReadOnly);
+ m_xVRulerImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Layout::Window::IsVerticalRulerRight::isReadOnly();
+ m_xVRulerRightCBox->set_active(pElemAttr->m_bVertRulerRight);
+ m_xVRulerRightCBox->set_sensitive(!bReadOnly);
+ m_xVRulerRightImg->set_visible(bReadOnly);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Layout::Window::SmoothScroll::isReadOnly() :
+ officecfg::Office::WriterWeb::Layout::Window::SmoothScroll::isReadOnly();
+ m_xSmoothCBox->set_active(pElemAttr->m_bSmoothScroll);
+ m_xSmoothCBox->set_sensitive(!bReadOnly);
+ m_xSmoothImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Display::ShowInlineTooltips::isReadOnly();
+ m_xShowInlineTooltips->set_active(pElemAttr->m_bShowInlineTooltips);
+ m_xShowInlineTooltips->set_sensitive(!bReadOnly);
+ m_xShowInlineTooltipsImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Display::ShowOutlineContentVisibilityButton::isReadOnly();
+ m_xShowOutlineContentVisibilityButton->set_active(pElemAttr->m_bShowOutlineContentVisibilityButton);
+ m_xShowOutlineContentVisibilityButton->set_sensitive(!bReadOnly);
+ m_xShowOutlineContentVImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Display::TreatSubOutlineLevelsAsContent::isReadOnly();
+ m_xTreatSubOutlineLevelsAsContent->set_active(pElemAttr->m_bTreatSubOutlineLevelsAsContent);
+ m_xTreatSubOutlineLevelsAsContent->set_sensitive(pElemAttr->m_bShowOutlineContentVisibilityButton && !bReadOnly);
+ m_xTreatSubOutlineLevelsImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Display::ShowChangesInMargin::isReadOnly();
+ m_xShowChangesInMargin->set_active(pElemAttr->m_bShowChangesInMargin);
+ m_xShowChangesInMargin->set_sensitive(!bReadOnly);
+ m_xShowChangesInMarginImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::NonprintingCharacter::HiddenText::isReadOnly();
+ m_xFieldHiddenCB->set_active( pElemAttr->m_bFieldHiddenText );
+ m_xFieldHiddenCB->set_sensitive(!bReadOnly);
+ m_xFieldHiddenImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::NonprintingCharacter::HiddenParagraph::isReadOnly();
+ m_xFieldHiddenParaCB->set_active( pElemAttr->m_bShowHiddenPara );
+ m_xFieldHiddenParaCB->set_sensitive(!bReadOnly);
+ m_xFieldHiddenParaImg->set_visible(bReadOnly);
+ }
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Layout::Window::HorizontalRulerUnit::isReadOnly() :
+ officecfg::Office::WriterWeb::Layout::Window::HorizontalRulerUnit::isReadOnly();
+ m_xHMetric->set_sensitive(!bReadOnly);
+ m_xHMetricImg->set_visible(bReadOnly);
+
+ bReadOnly = !bWebOptionsPage ? officecfg::Office::Writer::Layout::Window::VerticalRulerUnit::isReadOnly() :
+ officecfg::Office::WriterWeb::Layout::Window::VerticalRulerUnit::isReadOnly();
+ m_xVMetric->set_sensitive(!bReadOnly);
+
+ m_xMetricLB->set_active(-1);
+ if (bWebOptionsPage)
+ {
+ bReadOnly = officecfg::Office::WriterWeb::Layout::Other::MeasureUnit::isReadOnly();
+ m_xMetricLB->set_sensitive(!bReadOnly);
+ m_xMetricImg->set_visible(bReadOnly);
+ }
+ lcl_SelectMetricLB(*m_xMetricLB, SID_ATTR_METRIC, *rSet);
+ lcl_SelectMetricLB(*m_xHMetric, FN_HSCROLL_METRIC, *rSet);
+ lcl_SelectMetricLB(*m_xVMetric, FN_VSCROLL_METRIC, *rSet);
+}
+
+OUString SwContentOptPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[]
+ = { "guideslabel", "displaylabel", "displayfl1", "changeslabel", "label3",
+ "hruler", "settingslabel", "measureunitlabel", "outlinelabel" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[] = { "helplines",
+ "graphics",
+ "tables",
+ "drawings",
+ "comments",
+ "resolvedcomments",
+ "hiddentextfield",
+ "hiddenparafield",
+ "changesinmargin",
+ "changestooltip",
+ "vruler",
+ "vrulerright",
+ "smoothscroll",
+ "outlinecontentvisibilitybutton",
+ "suboutlinelevelsascontent" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwContentOptPage::FillItemSet(SfxItemSet* rSet)
+{
+ const SwElemItem* pOldAttr = GetOldItem(GetItemSet(), FN_PARAM_ELEM);
+
+ SwElemItem aElem;
+ aElem.m_bTable = m_xTableCB->get_active();
+ aElem.m_bGraphic = m_xGrfCB->get_active();
+ aElem.m_bDrawing = m_xDrwCB->get_active();
+ aElem.m_bNotes = m_xPostItCB->get_active();
+ aElem.m_bCrosshair = m_xCrossCB->get_active();
+ aElem.m_bVertRuler = m_xVRulerCBox->get_active();
+ aElem.m_bVertRulerRight = m_xVRulerRightCBox->get_active();
+ aElem.m_bSmoothScroll = m_xSmoothCBox->get_active();
+ aElem.m_bShowInlineTooltips = m_xShowInlineTooltips->get_active();
+ aElem.m_bShowOutlineContentVisibilityButton = m_xShowOutlineContentVisibilityButton->get_active();
+ aElem.m_bTreatSubOutlineLevelsAsContent = m_xTreatSubOutlineLevelsAsContent->get_active();
+ aElem.m_bShowChangesInMargin = m_xShowChangesInMargin->get_active();
+ aElem.m_bFieldHiddenText = m_xFieldHiddenCB->get_active();
+ aElem.m_bShowHiddenPara = m_xFieldHiddenParaCB->get_active();
+
+ bool bRet = !pOldAttr || aElem != *pOldAttr;
+ if(bRet)
+ bRet = nullptr != rSet->Put(aElem);
+
+ sal_Int32 nMPos = m_xMetricLB->get_active();
+ sal_Int32 nGlobalMetricPos = nMPos;
+ if ( m_xMetricLB->get_value_changed_from_saved() )
+ {
+ const sal_uInt16 nFieldUnit = m_xMetricLB->get_id(nMPos).toUInt32();
+ rSet->Put( SfxUInt16Item( SID_ATTR_METRIC, nFieldUnit ) );
+ bRet = true;
+ }
+
+ nMPos = m_xHMetric->get_active();
+ if ( m_xHMetric->get_value_changed_from_saved() || nMPos != nGlobalMetricPos )
+ {
+ const sal_uInt16 nFieldUnit = m_xHMetric->get_id(nMPos).toUInt32();
+ rSet->Put( SfxUInt16Item( FN_HSCROLL_METRIC, nFieldUnit ) );
+ bRet = true;
+ }
+ nMPos = m_xVMetric->get_active();
+ if ( m_xVMetric->get_value_changed_from_saved() || nMPos != nGlobalMetricPos )
+ {
+ const sal_uInt16 nFieldUnit = m_xVMetric->get_id(nMPos).toUInt32();
+ rSet->Put( SfxUInt16Item( FN_VSCROLL_METRIC, nFieldUnit ) );
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+IMPL_LINK(SwContentOptPage, VertRulerHdl, weld::Toggleable&, rBox, void)
+{
+ m_xVRulerRightCBox->set_sensitive(rBox.get_sensitive() && rBox.get_active() &&
+ !officecfg::Office::Writer::Layout::Window::IsVerticalRulerRight::isReadOnly());
+}
+
+IMPL_LINK(SwContentOptPage, ShowOutlineContentVisibilityButtonHdl, weld::Toggleable&, rBox, void)
+{
+ m_xTreatSubOutlineLevelsAsContent->set_sensitive(rBox.get_active());
+}
+
+// TabPage Printer additional settings
+SwAddPrinterTabPage::SwAddPrinterTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/printoptionspage.ui", "PrintOptionsPage", &rCoreSet)
+ , m_sNone(SwResId(SW_STR_NONE))
+ , m_bAttrModified(false)
+ , m_bPreview(false)
+ , m_bHTMLMode(false)
+ , m_xGrfCB(m_xBuilder->weld_check_button("graphics"))
+ , m_xGrfImg(m_xBuilder->weld_widget("lockgraphics"))
+ , m_xCtrlFieldCB(m_xBuilder->weld_check_button("formcontrols"))
+ , m_xCtrlFieldImg(m_xBuilder->weld_widget("lockformcontrols"))
+ , m_xBackgroundCB(m_xBuilder->weld_check_button("background"))
+ , m_xBackgroundImg(m_xBuilder->weld_widget("lockbackground"))
+ , m_xBlackFontCB(m_xBuilder->weld_check_button("inblack"))
+ , m_xBlackFontImg(m_xBuilder->weld_widget("lockinblack"))
+ , m_xPrintHiddenTextCB(m_xBuilder->weld_check_button("hiddentext"))
+ , m_xPrintHiddenTextImg(m_xBuilder->weld_widget("lockhiddentext"))
+ , m_xPrintTextPlaceholderCB(m_xBuilder->weld_check_button("textplaceholder"))
+ , m_xPrintTextPlaceholderImg(m_xBuilder->weld_widget("locktextplaceholder"))
+ , m_xPagesFrame(m_xBuilder->weld_widget("pagesframe"))
+ , m_xLeftPageCB(m_xBuilder->weld_check_button("leftpages"))
+ , m_xLeftPageImg(m_xBuilder->weld_widget("lockleftpages"))
+ , m_xRightPageCB(m_xBuilder->weld_check_button("rightpages"))
+ , m_xRightPageImg(m_xBuilder->weld_widget("lockrightpages"))
+ , m_xProspectCB(m_xBuilder->weld_check_button("brochure"))
+ , m_xProspectImg(m_xBuilder->weld_widget("lockbrochure"))
+ , m_xProspectCB_RTL(m_xBuilder->weld_check_button("rtl"))
+ , m_xProspectImg_RTL(m_xBuilder->weld_widget("lockrtl"))
+ , m_xCommentsFrame(m_xBuilder->weld_widget("commentsframe"))
+ , m_xNoRB(m_xBuilder->weld_radio_button("none"))
+ , m_xOnlyRB(m_xBuilder->weld_radio_button("only"))
+ , m_xEndRB(m_xBuilder->weld_radio_button("end"))
+ , m_xEndPageRB(m_xBuilder->weld_radio_button("endpage"))
+ , m_xInMarginsRB(m_xBuilder->weld_radio_button("inmargins"))
+ , m_xMarginsImg(m_xBuilder->weld_widget("lockcomments"))
+ , m_xPrintEmptyPagesCB(m_xBuilder->weld_check_button("blankpages"))
+ , m_xPrintEmptyPagesImg(m_xBuilder->weld_widget("lockblankpages"))
+ , m_xPaperFromSetupCB(m_xBuilder->weld_check_button("papertray"))
+ , m_xPaperFromSetupImg(m_xBuilder->weld_widget("lockpapertray"))
+ , m_xFaxLB(m_xBuilder->weld_combo_box("fax"))
+ , m_xFaxImg(m_xBuilder->weld_widget("lockfax"))
+{
+ Link<weld::Toggleable&,void> aLk = LINK( this, SwAddPrinterTabPage, AutoClickHdl);
+ m_xGrfCB->connect_toggled( aLk );
+ m_xRightPageCB->connect_toggled( aLk );
+ m_xLeftPageCB->connect_toggled( aLk );
+ m_xCtrlFieldCB->connect_toggled( aLk );
+ m_xBackgroundCB->connect_toggled( aLk );
+ m_xBlackFontCB->connect_toggled( aLk );
+ m_xPrintHiddenTextCB->connect_toggled( aLk );
+ m_xPrintTextPlaceholderCB->connect_toggled( aLk );
+ m_xProspectCB->connect_toggled( aLk );
+ m_xProspectCB_RTL->connect_toggled( aLk );
+ m_xPaperFromSetupCB->connect_toggled( aLk );
+ m_xPrintEmptyPagesCB->connect_toggled( aLk );
+ m_xEndPageRB->connect_toggled( aLk );
+ m_xInMarginsRB->connect_toggled( aLk );
+ m_xEndRB->connect_toggled( aLk );
+ m_xOnlyRB->connect_toggled( aLk );
+ m_xNoRB->connect_toggled( aLk );
+ m_xFaxLB->connect_changed( LINK( this, SwAddPrinterTabPage, SelectHdl ) );
+
+ const SfxUInt16Item* pItem = rCoreSet.GetItemIfSet(SID_HTML_MODE, false );
+ if(pItem && pItem->GetValue() & HTMLMODE_ON)
+ {
+ m_bHTMLMode = true;
+ m_xLeftPageCB->hide();
+ m_xRightPageCB->hide();
+ m_xPrintHiddenTextCB->hide();
+ m_xPrintTextPlaceholderCB->hide();
+ m_xPrintEmptyPagesCB->hide();
+ }
+ m_xProspectCB_RTL->set_sensitive(false);
+ SvtCTLOptions aCTLOptions;
+ m_xProspectCB_RTL->set_visible(SvtCTLOptions::IsCTLFontEnabled());
+}
+
+SwAddPrinterTabPage::~SwAddPrinterTabPage()
+{
+}
+
+void SwAddPrinterTabPage::SetPreview(bool bPrev)
+{
+ m_bPreview = bPrev;
+ m_xCommentsFrame->set_sensitive(!m_bPreview);
+ m_xPagesFrame->set_sensitive(!m_bPreview);
+}
+
+std::unique_ptr<SfxTabPage> SwAddPrinterTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SwAddPrinterTabPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwAddPrinterTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label2", "label10", "label1", "label5", "4" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[]
+ = { "graphics", "formcontrols", "background", "inblack", "hiddentext", "textplaceholder",
+ "leftpages", "rightpages", "brochure", "rtl", "blankpages", "papertray" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString radioButton[] = { "none", "only", "end", "endpage", "inmargins" };
+
+ for (const auto& radio : radioButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_radio_button(radio))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwAddPrinterTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ if ( m_bAttrModified )
+ {
+ SwAddPrinterItem aAddPrinterAttr;
+ aAddPrinterAttr.m_bPrintGraphic = m_xGrfCB->get_active();
+ aAddPrinterAttr.m_bPrintTable = true; // always enabled since CWS printerpullgpages /*m_xTabCB->get_active();*/
+ aAddPrinterAttr.m_bPrintDraw = m_xGrfCB->get_active(); // UI merged with m_xGrfCB in CWS printerpullgpages
+ aAddPrinterAttr.m_bPrintControl = m_xCtrlFieldCB->get_active();
+ aAddPrinterAttr.m_bPrintPageBackground = m_xBackgroundCB->get_active();
+ aAddPrinterAttr.m_bPrintBlackFont = m_xBlackFontCB->get_active();
+ aAddPrinterAttr.m_bPrintHiddenText = m_xPrintHiddenTextCB->get_active();
+ aAddPrinterAttr.m_bPrintTextPlaceholder = m_xPrintTextPlaceholderCB->get_active();
+
+ aAddPrinterAttr.m_bPrintLeftPages = m_xLeftPageCB->get_active();
+ aAddPrinterAttr.m_bPrintRightPages = m_xRightPageCB->get_active();
+ aAddPrinterAttr.m_bPrintReverse = false; // handled by vcl itself since CWS printerpullpages /*m_xReverseCB->get_active()*/;
+ aAddPrinterAttr.m_bPrintProspect = m_xProspectCB->get_active();
+ aAddPrinterAttr.m_bPrintProspectRTL = m_xProspectCB_RTL->get_active();
+ aAddPrinterAttr.m_bPaperFromSetup = m_xPaperFromSetupCB->get_active();
+ aAddPrinterAttr.m_bPrintEmptyPages = m_xPrintEmptyPagesCB->get_active();
+ aAddPrinterAttr.m_bPrintSingleJobs = true; // handled by vcl in new print dialog since CWS printerpullpages /*m_xSingleJobsCB->get_active()*/;
+
+ if (m_xNoRB->get_active()) aAddPrinterAttr.m_nPrintPostIts =
+ SwPostItMode::NONE;
+ if (m_xOnlyRB->get_active()) aAddPrinterAttr.m_nPrintPostIts =
+ SwPostItMode::Only;
+ if (m_xEndRB->get_active()) aAddPrinterAttr.m_nPrintPostIts =
+ SwPostItMode::EndDoc;
+ if (m_xEndPageRB->get_active()) aAddPrinterAttr.m_nPrintPostIts =
+ SwPostItMode::EndPage;
+ if (m_xInMarginsRB->get_active()) aAddPrinterAttr.m_nPrintPostIts =
+ SwPostItMode::InMargins;
+
+ const OUString sFax = m_xFaxLB->get_active_text();
+ aAddPrinterAttr.m_sFaxName = m_sNone == sFax ? OUString() : sFax;
+ rCoreSet->Put(aAddPrinterAttr);
+ }
+ return m_bAttrModified;
+}
+
+void SwAddPrinterTabPage::Reset( const SfxItemSet* )
+{
+ const SfxItemSet& rSet = GetItemSet();
+ bool bReadOnly = false;
+
+ if( const SwAddPrinterItem* pAddPrinterAttr = rSet.GetItemIfSet( FN_PARAM_ADDPRINTER , false ) )
+ {
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Content::Graphic::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Content::Graphic::isReadOnly();
+ m_xGrfCB->set_active(pAddPrinterAttr->m_bPrintGraphic || pAddPrinterAttr->m_bPrintDraw);
+ m_xGrfCB->set_sensitive(!bReadOnly);
+ m_xGrfImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Content::Control::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Content::Control::isReadOnly();
+ m_xCtrlFieldCB->set_active( pAddPrinterAttr->m_bPrintControl);
+ m_xCtrlFieldCB->set_sensitive(!bReadOnly);
+ m_xCtrlFieldImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Content::Background::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Content::Background::isReadOnly();
+ m_xBackgroundCB->set_active( pAddPrinterAttr->m_bPrintPageBackground);
+ m_xBackgroundCB->set_sensitive(!bReadOnly);
+ m_xBackgroundImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Content::PrintBlack::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Content::PrintBlack::isReadOnly();
+ m_xBlackFontCB->set_active( pAddPrinterAttr->m_bPrintBlackFont);
+ m_xBlackFontCB->set_sensitive(!bReadOnly);
+ m_xBlackFontImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Print::Content::PrintHiddenText::isReadOnly();
+ m_xPrintHiddenTextCB->set_active( pAddPrinterAttr->m_bPrintHiddenText);
+ m_xPrintHiddenTextCB->set_sensitive(!bReadOnly);
+ m_xPrintHiddenTextImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Print::Content::PrintPlaceholders::isReadOnly();
+ m_xPrintTextPlaceholderCB->set_active(pAddPrinterAttr->m_bPrintTextPlaceholder);
+ m_xPrintTextPlaceholderCB->set_sensitive(!bReadOnly);
+ m_xPrintTextPlaceholderImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Print::Page::LeftPage::isReadOnly();
+ m_xLeftPageCB->set_active( pAddPrinterAttr->m_bPrintLeftPages);
+ m_xLeftPageCB->set_sensitive(!bReadOnly);
+ m_xLeftPageImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Print::Page::RightPage::isReadOnly();
+ m_xRightPageCB->set_active( pAddPrinterAttr->m_bPrintRightPages);
+ m_xRightPageCB->set_sensitive(!bReadOnly);
+ m_xRightPageImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Papertray::FromPrinterSetup::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Papertray::FromPrinterSetup::isReadOnly();
+ m_xPaperFromSetupCB->set_active(pAddPrinterAttr->m_bPaperFromSetup);
+ m_xPaperFromSetupCB->set_sensitive(!bReadOnly);
+ m_xPaperFromSetupImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Print::EmptyPages::isReadOnly();
+ m_xPrintEmptyPagesCB->set_active(pAddPrinterAttr->m_bPrintEmptyPages);
+ m_xPrintEmptyPagesCB->set_sensitive(!bReadOnly);
+ m_xPrintEmptyPagesImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Page::Brochure::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Page::Brochure::isReadOnly();
+ m_xProspectCB->set_active( pAddPrinterAttr->m_bPrintProspect);
+ m_xProspectCB->set_sensitive(!bReadOnly);
+ m_xProspectImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Page::BrochureRightToLeft::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Page::BrochureRightToLeft::isReadOnly();
+ m_xProspectCB_RTL->set_active( pAddPrinterAttr->m_bPrintProspectRTL);
+ m_xProspectCB_RTL->set_sensitive(!bReadOnly);
+ m_xProspectImg_RTL->set_visible(bReadOnly);
+
+ m_xNoRB->set_active(pAddPrinterAttr->m_nPrintPostIts== SwPostItMode::NONE ) ;
+ m_xOnlyRB->set_active(pAddPrinterAttr->m_nPrintPostIts== SwPostItMode::Only ) ;
+ m_xEndRB->set_active(pAddPrinterAttr->m_nPrintPostIts== SwPostItMode::EndDoc ) ;
+ m_xEndPageRB->set_active(pAddPrinterAttr->m_nPrintPostIts== SwPostItMode::EndPage ) ;
+ m_xInMarginsRB->set_active(pAddPrinterAttr->m_nPrintPostIts== SwPostItMode::InMargins ) ;
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Content::Note::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Content::Note::isReadOnly();
+ m_xNoRB->set_sensitive(!bReadOnly);
+ m_xOnlyRB->set_sensitive(!bReadOnly);
+ m_xEndRB->set_sensitive(!bReadOnly);
+ m_xEndPageRB->set_sensitive(!bReadOnly);
+ m_xInMarginsRB->set_sensitive(!bReadOnly);
+ m_xMarginsImg->set_visible(bReadOnly);
+
+ auto nFound = m_xFaxLB->find_text(pAddPrinterAttr->m_sFaxName);
+ if (nFound != -1)
+ m_xFaxLB->set_active(nFound);
+ else if (m_xFaxLB->get_count())
+ m_xFaxLB->set_active(0);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Output::Fax::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Output::Fax::isReadOnly();
+ m_xFaxLB->set_sensitive(!bReadOnly);
+ m_xFaxImg->set_visible(bReadOnly);
+ }
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Print::Page::BrochureRightToLeft::isReadOnly() :
+ officecfg::Office::WriterWeb::Print::Page::BrochureRightToLeft::isReadOnly();
+ if (m_xProspectCB->get_active())
+ {
+ m_xProspectCB_RTL->set_sensitive(!bReadOnly);
+ m_xNoRB->set_sensitive( false );
+ m_xOnlyRB->set_sensitive( false );
+ m_xEndRB->set_sensitive( false );
+ m_xEndPageRB->set_sensitive( false );
+ }
+ else
+ m_xProspectCB_RTL->set_sensitive( false );
+
+ m_xProspectImg_RTL->set_visible(bReadOnly);
+}
+
+IMPL_LINK_NOARG(SwAddPrinterTabPage, AutoClickHdl, weld::Toggleable&, void)
+{
+ m_bAttrModified = true;
+ bool bIsProspect = m_xProspectCB->get_active();
+ if (!bIsProspect)
+ m_xProspectCB_RTL->set_active( false );
+ m_xProspectCB_RTL->set_sensitive( bIsProspect );
+ m_xNoRB->set_sensitive( !bIsProspect );
+ m_xOnlyRB->set_sensitive( !bIsProspect );
+ m_xEndRB->set_sensitive( !bIsProspect );
+ m_xEndPageRB->set_sensitive( !bIsProspect );
+ m_xInMarginsRB->set_sensitive( !bIsProspect );
+}
+
+void SwAddPrinterTabPage::SetFax( const std::vector<OUString>& rFaxLst )
+{
+ m_xFaxLB->append_text(m_sNone);
+ for(const auto & i : rFaxLst)
+ {
+ m_xFaxLB->append_text(i);
+ }
+ m_xFaxLB->set_active(0);
+}
+
+IMPL_LINK_NOARG(SwAddPrinterTabPage, SelectHdl, weld::ComboBox&, void)
+{
+ m_bAttrModified=true;
+}
+
+void SwAddPrinterTabPage::PageCreated( const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pListItem = aSet.GetItem<SfxBoolItem>(SID_FAX_LIST, false);
+ const SfxBoolItem* pPreviewItem = aSet.GetItem<SfxBoolItem>(SID_PREVIEWFLAG_TYPE, false);
+ if (pPreviewItem)
+ {
+ SetPreview(pPreviewItem->GetValue());
+ Reset(&aSet);
+ }
+ if (pListItem && pListItem->GetValue())
+ {
+ std::vector<OUString> aFaxList;
+ const std::vector<OUString>& rPrinters = Printer::GetPrinterQueues();
+ for (const auto & rPrinter : rPrinters)
+ aFaxList.insert(aFaxList.begin(), rPrinter);
+ SetFax( aFaxList );
+ }
+}
+
+// Tabpage Standardfonts
+SwStdFontTabPage::SwStdFontTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optfonttabpage.ui", "OptFontTabPage", &rSet)
+ , m_pPrt(nullptr)
+ , m_pFontConfig(nullptr)
+ , m_pWrtShell(nullptr)
+ , m_eLanguage( GetAppLanguage() )
+ , m_bListDefault(false)
+ , m_bSetListDefault(true)
+ , m_bLabelDefault(false)
+ , m_bSetLabelDefault(true)
+ , m_bIdxDefault(false)
+ , m_bSetIdxDefault(true)
+ , m_bDisposePrinter(false)
+ , m_nFontGroup(FONT_GROUP_DEFAULT)
+ , m_sScriptWestern(SwResId(ST_SCRIPT_WESTERN))
+ , m_sScriptAsian(SwResId(ST_SCRIPT_ASIAN))
+ , m_sScriptComplex(SwResId(ST_SCRIPT_CTL))
+ , m_xLabelFT(m_xBuilder->weld_label("label1"))
+ , m_xStandardBox(m_xBuilder->weld_combo_box("standardbox"))
+ , m_xStandardBoxImg(m_xBuilder->weld_widget("lockstandardbox"))
+ , m_xStandardHeightLB(new FontSizeBox(m_xBuilder->weld_combo_box("standardheight")))
+ , m_xStandardHeightImg(m_xBuilder->weld_widget("lockstandardheight"))
+ , m_xTitleBox(m_xBuilder->weld_combo_box("titlebox"))
+ , m_xTitleBoxImg(m_xBuilder->weld_widget("locktitlebox"))
+ , m_xTitleHeightLB(new FontSizeBox(m_xBuilder->weld_combo_box("titleheight")))
+ , m_xTitleHeightImg(m_xBuilder->weld_widget("locktitleheight"))
+ , m_xListBox(m_xBuilder->weld_combo_box("listbox"))
+ , m_xListBoxImg(m_xBuilder->weld_widget("locklistbox"))
+ , m_xListHeightLB(new FontSizeBox(m_xBuilder->weld_combo_box("listheight")))
+ , m_xListHeightImg(m_xBuilder->weld_widget("locklistheight"))
+ , m_xLabelBox(m_xBuilder->weld_combo_box("labelbox"))
+ , m_xLabelBoxImg(m_xBuilder->weld_widget("locklabelbox"))
+ , m_xLabelHeightLB(new FontSizeBox(m_xBuilder->weld_combo_box("labelheight")))
+ , m_xLabelHeightImg(m_xBuilder->weld_widget("locklabelheight"))
+ , m_xIdxBox(m_xBuilder->weld_combo_box("idxbox"))
+ , m_xIdxBoxImg(m_xBuilder->weld_widget("lockidxbox"))
+ , m_xIndexHeightLB(new FontSizeBox(m_xBuilder->weld_combo_box("indexheight")))
+ , m_xIndexHeightImg(m_xBuilder->weld_widget("lockindexheight"))
+ , m_xStandardPB(m_xBuilder->weld_button("standard"))
+{
+ m_xStandardBox->make_sorted();
+ m_xTitleBox->make_sorted();
+ m_xListBox->make_sorted();
+ m_xLabelBox->make_sorted();
+ m_xIdxBox->make_sorted();
+
+ m_xStandardPB->connect_clicked(LINK(this, SwStdFontTabPage, StandardHdl));
+ m_xStandardBox->connect_changed( LINK(this, SwStdFontTabPage, ModifyHdl));
+ m_xListBox->connect_changed( LINK(this, SwStdFontTabPage, ModifyHdl));
+ m_xLabelBox->connect_changed( LINK(this, SwStdFontTabPage, ModifyHdl));
+ m_xIdxBox->connect_changed( LINK(this, SwStdFontTabPage, ModifyHdl));
+ Link<weld::Widget&,void> aFocusLink = LINK( this, SwStdFontTabPage, LoseFocusHdl);
+ m_xStandardBox->connect_focus_out( aFocusLink );
+ m_xTitleBox->connect_focus_out( aFocusLink );
+ m_xListBox->connect_focus_out( aFocusLink );
+ m_xLabelBox->connect_focus_out( aFocusLink );
+ m_xIdxBox->connect_focus_out( aFocusLink );
+}
+
+SwStdFontTabPage::~SwStdFontTabPage()
+{
+ m_xIndexHeightLB.reset();
+ m_xLabelHeightLB.reset();
+ m_xListHeightLB.reset();
+ m_xTitleHeightLB.reset();
+ m_xStandardHeightLB.reset();
+ m_pFontList.reset();
+ if (m_bDisposePrinter)
+ m_pPrt.disposeAndClear();
+ else
+ m_pPrt.clear();
+}
+
+std::unique_ptr<SfxTabPage> SwStdFontTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SwStdFontTabPage>(pPage, pController, *rAttrSet);
+}
+
+static void lcl_SetColl(SwWrtShell* pWrtShell, sal_uInt16 nType,
+ SfxPrinter const * pPrt, const OUString& rStyle,
+ sal_uInt16 nFontWhich)
+{
+ vcl::Font aFont( rStyle, Size( 0, 10 ) );
+ if( pPrt )
+ aFont = pPrt->GetFontMetric( aFont );
+ SwTextFormatColl *pColl = pWrtShell->GetTextCollFromPool(nType);
+ pColl->SetFormatAttr(SvxFontItem(aFont.GetFamilyType(), aFont.GetFamilyName(),
+ OUString(), aFont.GetPitch(), aFont.GetCharSet(), nFontWhich));
+}
+
+static void lcl_SetColl(SwWrtShell* pWrtShell, sal_uInt16 nType,
+ sal_Int32 nHeight, sal_uInt16 nFontHeightWhich)
+{
+ float fSize = static_cast<float>(nHeight) / 10;
+ nHeight = CalcToUnit( fSize, MapUnit::MapTwip );
+ SwTextFormatColl *pColl = pWrtShell->GetTextCollFromPool(nType);
+ pColl->SetFormatAttr(SvxFontHeightItem(nHeight, 100, nFontHeightWhich));
+}
+
+OUString SwStdFontTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label1", "font_label", "size_label", "default_label",
+ "heading_label", "list_label", "caption_label", "index_label" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ sAllStrings += m_xStandardPB->get_label() + " ";
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwStdFontTabPage::FillItemSet( SfxItemSet* )
+{
+ SW_MOD()->GetModuleConfig()->SetDefaultFontInCurrDocOnly(false);
+
+ const OUString sStandard = m_xStandardBox->get_active_text();
+ const OUString sTitle = m_xTitleBox->get_active_text();
+ const OUString sList = m_xListBox->get_active_text();
+ const OUString sLabel = m_xLabelBox->get_active_text();
+ const OUString sIdx = m_xIdxBox->get_active_text();
+
+ bool bStandardHeightChanged = m_xStandardHeightLB->get_value_changed_from_saved();
+ bool bTitleHeightChanged = m_xTitleHeightLB->get_value_changed_from_saved();
+ bool bListHeightChanged = m_xListHeightLB->get_value_changed_from_saved();
+ bool bLabelHeightChanged = m_xLabelHeightLB->get_value_changed_from_saved();
+ bool bIndexHeightChanged = m_xIndexHeightLB->get_value_changed_from_saved();
+
+ m_pFontConfig->SetFontStandard(sStandard, m_nFontGroup);
+ m_pFontConfig->SetFontOutline(sTitle, m_nFontGroup);
+ m_pFontConfig->SetFontList(sList, m_nFontGroup);
+ m_pFontConfig->SetFontCaption(sLabel, m_nFontGroup);
+ m_pFontConfig->SetFontIndex(sIdx, m_nFontGroup);
+ if(bStandardHeightChanged)
+ {
+ float fSize = static_cast<float>(m_xStandardHeightLB->get_value()) / 10;
+ m_pFontConfig->SetFontHeight( CalcToUnit( fSize, MapUnit::MapTwip ), FONT_STANDARD, m_nFontGroup );
+ }
+ if(bTitleHeightChanged)
+ {
+ float fSize = static_cast<float>(m_xTitleHeightLB->get_value()) / 10;
+ m_pFontConfig->SetFontHeight( CalcToUnit( fSize, MapUnit::MapTwip ), FONT_OUTLINE, m_nFontGroup );
+ }
+ if(bListHeightChanged)
+ {
+ float fSize = static_cast<float>(m_xListHeightLB->get_value()) / 10;
+ m_pFontConfig->SetFontHeight( CalcToUnit( fSize, MapUnit::MapTwip ), FONT_LIST, m_nFontGroup );
+ }
+ if(bLabelHeightChanged)
+ {
+ float fSize = static_cast<float>(m_xLabelHeightLB->get_value()) / 10;
+ m_pFontConfig->SetFontHeight( CalcToUnit( fSize, MapUnit::MapTwip ), FONT_CAPTION, m_nFontGroup );
+ }
+ if(bIndexHeightChanged)
+ {
+ float fSize = static_cast<float>(m_xIndexHeightLB->get_value()) / 10;
+ m_pFontConfig->SetFontHeight( CalcToUnit( fSize, MapUnit::MapTwip ), FONT_INDEX, m_nFontGroup );
+ }
+
+ if(m_pWrtShell)
+ {
+ m_pWrtShell->StartAllAction();
+ SfxPrinter* pPrinter = m_pWrtShell->getIDocumentDeviceAccess().getPrinter( false );
+ bool bMod = false;
+ const sal_uInt16 nFontWhich =
+ m_nFontGroup == FONT_GROUP_DEFAULT ? RES_CHRATR_FONT :
+ FONT_GROUP_CJK == m_nFontGroup ? RES_CHRATR_CJK_FONT : RES_CHRATR_CTL_FONT;
+ const sal_uInt16 nFontHeightWhich =
+ m_nFontGroup == FONT_GROUP_DEFAULT ? RES_CHRATR_FONTSIZE :
+ FONT_GROUP_CJK == m_nFontGroup ? RES_CHRATR_CJK_FONTSIZE : RES_CHRATR_CTL_FONTSIZE;
+ if(sStandard != m_sShellStd)
+ {
+ vcl::Font aFont( sStandard, Size( 0, 10 ) );
+ if( pPrinter )
+ aFont = pPrinter->GetFontMetric( aFont );
+ m_pWrtShell->SetDefault(SvxFontItem(aFont.GetFamilyType(), aFont.GetFamilyName(),
+ OUString(), aFont.GetPitch(), aFont.GetCharSet(), nFontWhich));
+ SwTextFormatColl *pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+ pColl->ResetFormatAttr(nFontWhich);
+ bMod = true;
+ }
+ if(bStandardHeightChanged)
+ {
+ float fSize = static_cast<float>(m_xStandardHeightLB->get_value()) / 10;
+ m_pWrtShell->SetDefault(SvxFontHeightItem( CalcToUnit( fSize, MapUnit::MapTwip ), 100, nFontHeightWhich ) );
+ SwTextFormatColl *pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+ pColl->ResetFormatAttr(nFontHeightWhich);
+ bMod = true;
+ }
+
+ if(sTitle != m_sShellTitle )
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_HEADLINE_BASE, pPrinter, sTitle, nFontWhich);
+ bMod = true;
+ }
+ if(bTitleHeightChanged)
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_HEADLINE_BASE,
+ sal::static_int_cast< sal_uInt16, sal_Int64 >(m_xTitleHeightLB->get_value()), nFontHeightWhich);
+ bMod = true;
+ }
+ if(sList != m_sShellList && (!m_bListDefault || !m_bSetListDefault ))
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_NUMBER_BULLET_BASE, pPrinter, sList, nFontWhich);
+ bMod = true;
+ }
+ if(bListHeightChanged)
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_NUMBER_BULLET_BASE,
+ sal::static_int_cast< sal_uInt16, sal_Int64 >(m_xListHeightLB->get_value()), nFontHeightWhich);
+ bMod = true;
+ }
+ if(sLabel != m_sShellLabel && (!m_bLabelDefault || !m_bSetLabelDefault))
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_LABEL, pPrinter, sLabel, nFontWhich);
+ bMod = true;
+ }
+ if(bLabelHeightChanged)
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_LABEL,
+ sal::static_int_cast< sal_uInt16, sal_Int64 >(m_xLabelHeightLB->get_value()), nFontHeightWhich);
+ bMod = true;
+ }
+ if(sIdx != m_sShellIndex && (!m_bIdxDefault || !m_bSetIdxDefault))
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_REGISTER_BASE, pPrinter, sIdx, nFontWhich);
+ bMod = true;
+ }
+ if(bIndexHeightChanged)
+ {
+ lcl_SetColl(m_pWrtShell, RES_POOLCOLL_REGISTER_BASE,
+ sal::static_int_cast< sal_uInt16, sal_Int64 >(m_xIndexHeightLB->get_value()), nFontHeightWhich);
+ bMod = true;
+ }
+ if ( bMod )
+ m_pWrtShell->SetModified();
+ m_pWrtShell->EndAllAction();
+ }
+ return false;
+}
+
+void SwStdFontTabPage::Reset( const SfxItemSet* rSet)
+{
+ const TypedWhichId<SvxLanguageItem> nLangSlot = m_nFontGroup == FONT_GROUP_DEFAULT ? SID_ATTR_LANGUAGE :
+ FONT_GROUP_CJK == m_nFontGroup ? SID_ATTR_CHAR_CJK_LANGUAGE : SID_ATTR_CHAR_CTL_LANGUAGE;
+
+ if( const SvxLanguageItem* pLang = rSet->GetItemIfSet(nLangSlot, false) )
+ m_eLanguage = pLang->GetValue();
+
+ OUString sToReplace = m_sScriptWestern;
+ if(FONT_GROUP_CJK == m_nFontGroup )
+ sToReplace = m_sScriptAsian;
+ else if(FONT_GROUP_CTL == m_nFontGroup )
+ sToReplace = m_sScriptComplex;
+ m_xLabelFT->set_label(m_xLabelFT->get_label().replaceFirst("%1", sToReplace));
+
+ if (m_bDisposePrinter)
+ {
+ m_pPrt.disposeAndClear();
+ m_bDisposePrinter = false;
+ }
+
+ if(const SwPtrItem* pItem = rSet->GetItemIfSet(FN_PARAM_PRINTER, false))
+ {
+ m_pPrt = static_cast<SfxPrinter*>(pItem->GetValue());
+ }
+ else
+ {
+ auto pPrinterSet = std::make_unique<SfxItemSetFixed
+ <SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
+ SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC>>( *rSet->GetPool() );
+ m_pPrt = VclPtr<SfxPrinter>::Create(std::move(pPrinterSet));
+ m_bDisposePrinter = true;
+ }
+ m_pFontList.reset(new FontList( m_pPrt ));
+ // #i94536# prevent duplication of font entries when 'reset' button is pressed
+ if( !m_xStandardBox->get_count() )
+ {
+ // get the set of distinct available family names
+ std::set< OUString > aFontNames;
+ int nFontNames = m_pPrt->GetFontFaceCollectionCount();
+ for( int i = 0; i < nFontNames; i++ )
+ {
+ FontMetric aFontMetric( m_pPrt->GetFontMetricFromCollection( i ) );
+ aFontNames.insert( aFontMetric.GetFamilyName() );
+ }
+
+ // insert to listboxes
+ for( const auto& rFontName : aFontNames )
+ {
+ m_xStandardBox->append_text( rFontName );
+ m_xTitleBox->append_text( rFontName );
+ m_xListBox->append_text( rFontName );
+ m_xLabelBox->append_text( rFontName );
+ m_xIdxBox->append_text( rFontName );
+ }
+ }
+ if(const SwPtrItem* pItem = rSet->GetItemIfSet(FN_PARAM_STDFONTS, false))
+ {
+ m_pFontConfig = static_cast<SwStdFontConfig*>(pItem->GetValue());
+ }
+
+ if(const SwPtrItem* pItem = rSet->GetItemIfSet(FN_PARAM_WRTSHELL, false))
+ {
+ m_pWrtShell = static_cast<SwWrtShell*>(pItem->GetValue());
+ }
+ OUString sStdBackup;
+ OUString sOutBackup;
+ OUString sListBackup;
+ OUString sCapBackup;
+ OUString sIdxBackup;
+ sal_Int32 nStandardHeight = -1;
+ sal_Int32 nTitleHeight = -1;
+ sal_Int32 nListHeight = -1;
+ sal_Int32 nLabelHeight = -1;
+ sal_Int32 nIndexHeight = -1;
+
+ if(!m_pWrtShell)
+ {
+ sStdBackup = m_pFontConfig->GetFontStandard(m_nFontGroup);
+ sOutBackup = m_pFontConfig->GetFontOutline(m_nFontGroup);
+ sListBackup= m_pFontConfig->GetFontList(m_nFontGroup);
+ sCapBackup = m_pFontConfig->GetFontCaption(m_nFontGroup);
+ sIdxBackup = m_pFontConfig->GetFontIndex(m_nFontGroup);
+ nStandardHeight = m_pFontConfig->GetFontHeight( FONT_STANDARD, m_nFontGroup, m_eLanguage );
+ nTitleHeight = m_pFontConfig->GetFontHeight( FONT_OUTLINE , m_nFontGroup, m_eLanguage );
+ nListHeight = m_pFontConfig->GetFontHeight( FONT_LIST , m_nFontGroup, m_eLanguage );
+ nLabelHeight = m_pFontConfig->GetFontHeight( FONT_CAPTION , m_nFontGroup, m_eLanguage );
+ nIndexHeight = m_pFontConfig->GetFontHeight( FONT_INDEX , m_nFontGroup, m_eLanguage );
+ if( nStandardHeight <= 0)
+ nStandardHeight = SwStdFontConfig::GetDefaultHeightFor( FONT_STANDARD + m_nFontGroup * FONT_PER_GROUP, m_eLanguage);
+ if( nTitleHeight <= 0)
+ nTitleHeight = SwStdFontConfig::GetDefaultHeightFor( FONT_OUTLINE + m_nFontGroup * FONT_PER_GROUP, m_eLanguage);
+ if( nListHeight <= 0)
+ nListHeight = SwStdFontConfig::GetDefaultHeightFor( FONT_LIST + m_nFontGroup * FONT_PER_GROUP, m_eLanguage);
+ if( nLabelHeight <= 0)
+ nLabelHeight = SwStdFontConfig::GetDefaultHeightFor( FONT_CAPTION + m_nFontGroup * FONT_PER_GROUP, m_eLanguage);
+ if( nIndexHeight <= 0)
+ nIndexHeight = SwStdFontConfig::GetDefaultHeightFor( FONT_INDEX + m_nFontGroup * FONT_PER_GROUP, m_eLanguage);
+ }
+ else
+ {
+ SwTextFormatColl *pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+ const SvxFontItem& rFont = !m_nFontGroup ? pColl->GetFont() :
+ FONT_GROUP_CJK == m_nFontGroup ? pColl->GetCJKFont() : pColl->GetCTLFont();
+ m_sShellStd = sStdBackup = rFont.GetFamilyName();
+
+ const TypedWhichId<SvxFontHeightItem> nFontHeightWhich =
+ m_nFontGroup == FONT_GROUP_DEFAULT ? RES_CHRATR_FONTSIZE :
+ FONT_GROUP_CJK == m_nFontGroup ? RES_CHRATR_CJK_FONTSIZE : RES_CHRATR_CTL_FONTSIZE;
+ const SvxFontHeightItem& rFontHeightStandard = pColl->GetFormatAttr(nFontHeightWhich);
+ nStandardHeight = static_cast<sal_Int32>(rFontHeightStandard.GetHeight());
+
+ pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_HEADLINE_BASE);
+ const SvxFontItem& rFontHL = !m_nFontGroup ? pColl->GetFont() :
+ FONT_GROUP_CJK == m_nFontGroup ? pColl->GetCJKFont() : pColl->GetCTLFont();
+ m_sShellTitle = sOutBackup = rFontHL.GetFamilyName();
+
+ const SvxFontHeightItem& rFontHeightTitle = pColl->GetFormatAttr( nFontHeightWhich );
+ nTitleHeight = static_cast<sal_Int32>(rFontHeightTitle.GetHeight());
+
+ const sal_uInt16 nFontWhich =
+ m_nFontGroup == FONT_GROUP_DEFAULT ? RES_CHRATR_FONT :
+ FONT_GROUP_CJK == m_nFontGroup ? RES_CHRATR_CJK_FONT : RES_CHRATR_CTL_FONT;
+ pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_NUMBER_BULLET_BASE);
+ const SvxFontItem& rFontLS = !m_nFontGroup ? pColl->GetFont() :
+ FONT_GROUP_CJK == m_nFontGroup ? pColl->GetCJKFont() : pColl->GetCTLFont();
+ m_bListDefault = SfxItemState::DEFAULT == pColl->GetAttrSet().GetItemState(nFontWhich, false);
+ m_sShellList = sListBackup = rFontLS.GetFamilyName();
+
+ const SvxFontHeightItem& rFontHeightList = pColl->GetFormatAttr(nFontHeightWhich);
+ nListHeight = static_cast<sal_Int32>(rFontHeightList.GetHeight());
+
+ pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_LABEL);
+ m_bLabelDefault = SfxItemState::DEFAULT == pColl->GetAttrSet().GetItemState(nFontWhich, false);
+ const SvxFontItem& rFontCP = !m_nFontGroup ? pColl->GetFont() :
+ FONT_GROUP_CJK == m_nFontGroup ? pColl->GetCJKFont() : pColl->GetCTLFont();
+ m_sShellLabel = sCapBackup = rFontCP.GetFamilyName();
+ const SvxFontHeightItem& rFontHeightLabel = pColl->GetFormatAttr(nFontHeightWhich);
+ nLabelHeight = static_cast<sal_Int32>(rFontHeightLabel.GetHeight());
+
+ pColl = m_pWrtShell->GetTextCollFromPool(RES_POOLCOLL_REGISTER_BASE);
+ m_bIdxDefault = SfxItemState::DEFAULT == pColl->GetAttrSet().GetItemState(nFontWhich, false);
+ const SvxFontItem& rFontIDX = !m_nFontGroup ? pColl->GetFont() :
+ FONT_GROUP_CJK == m_nFontGroup ? pColl->GetCJKFont() : pColl->GetCTLFont();
+ m_sShellIndex = sIdxBackup = rFontIDX.GetFamilyName();
+ const SvxFontHeightItem& rFontHeightIndex = pColl->GetFormatAttr(nFontHeightWhich);
+ nIndexHeight = static_cast<sal_Int32>(rFontHeightIndex.GetHeight());
+ }
+ m_xStandardBox->set_entry_text(sStdBackup );
+ m_xTitleBox->set_entry_text(sOutBackup );
+ m_xListBox->set_entry_text(sListBackup);
+ m_xLabelBox->set_entry_text(sCapBackup );
+ m_xIdxBox->set_entry_text(sIdxBackup );
+
+ m_xStandardHeightLB->Fill( m_pFontList.get() );
+ m_xTitleHeightLB->Fill( m_pFontList.get() );
+ m_xListHeightLB->Fill( m_pFontList.get() );
+ m_xLabelHeightLB->Fill( m_pFontList.get() );
+ m_xIndexHeightLB->Fill( m_pFontList.get() );
+
+ m_xStandardHeightLB->set_value( CalcToPoint( nStandardHeight, MapUnit::MapTwip, 10 ) );
+ m_xTitleHeightLB->set_value( CalcToPoint( nTitleHeight , MapUnit::MapTwip, 10 ) );
+ m_xListHeightLB->set_value( CalcToPoint( nListHeight , MapUnit::MapTwip, 10 ) );
+ m_xLabelHeightLB->set_value( CalcToPoint( nLabelHeight , MapUnit::MapTwip, 10 ));
+ m_xIndexHeightLB->set_value( CalcToPoint( nIndexHeight , MapUnit::MapTwip, 10 ));
+
+
+ if (m_nFontGroup == FONT_GROUP_DEFAULT)
+ {
+ bool bReadonly = officecfg::Office::Writer::DefaultFont::Standard::isReadOnly();
+ m_xStandardBox->set_sensitive(!bReadonly);
+ m_xStandardBoxImg->set_visible(bReadonly);
+ bReadonly = officecfg::Office::Writer::DefaultFont::StandardHeight::isReadOnly();
+ m_xStandardHeightLB->set_sensitive(!bReadonly);
+ m_xStandardHeightImg->set_visible(bReadonly);
+
+ bReadonly = officecfg::Office::Writer::DefaultFont::Heading::isReadOnly();
+ m_xTitleBox->set_sensitive(!bReadonly);
+ m_xTitleBoxImg->set_visible(bReadonly);
+ bReadonly = officecfg::Office::Writer::DefaultFont::HeadingHeight::isReadOnly();
+ m_xTitleHeightLB->set_sensitive(!bReadonly);
+ m_xTitleHeightImg->set_visible(bReadonly);
+
+ bReadonly = officecfg::Office::Writer::DefaultFont::List::isReadOnly();
+ m_xListBox->set_sensitive(!bReadonly);
+ m_xListBoxImg->set_visible(bReadonly);
+ bReadonly = officecfg::Office::Writer::DefaultFont::ListHeight::isReadOnly();
+ m_xListHeightLB->set_sensitive(!bReadonly);
+ m_xListHeightImg->set_visible(bReadonly);
+
+ bReadonly = officecfg::Office::Writer::DefaultFont::Caption::isReadOnly();
+ m_xLabelBox->set_sensitive(!bReadonly);
+ m_xLabelBoxImg->set_visible(bReadonly);
+ bReadonly = officecfg::Office::Writer::DefaultFont::CaptionHeight::isReadOnly();
+ m_xLabelHeightLB->set_sensitive(!bReadonly);
+ m_xLabelHeightImg->set_visible(bReadonly);
+
+ bReadonly = officecfg::Office::Writer::DefaultFont::Index::isReadOnly();
+ m_xIdxBox->set_sensitive(!bReadonly);
+ m_xIdxBoxImg->set_visible(bReadonly);
+ bReadonly = officecfg::Office::Writer::DefaultFont::IndexHeight::isReadOnly();
+ m_xIndexHeightLB->set_sensitive(!bReadonly);
+ m_xIndexHeightImg->set_visible(bReadonly);
+ }
+
+ m_xStandardBox->save_value();
+ m_xTitleBox->save_value();
+ m_xListBox->save_value();
+ m_xLabelBox->save_value();
+ m_xIdxBox->save_value();
+
+ m_xStandardHeightLB->save_value();
+ m_xTitleHeightLB->save_value();
+ m_xListHeightLB->save_value();
+ m_xLabelHeightLB->save_value();
+ m_xIndexHeightLB->save_value();
+}
+
+IMPL_LINK_NOARG(SwStdFontTabPage, StandardHdl, weld::Button&, void)
+{
+ sal_uInt8 nFontOffset = m_nFontGroup * FONT_PER_GROUP;
+ m_xStandardBox->set_entry_text(SwStdFontConfig::GetDefaultFor(FONT_STANDARD + nFontOffset, m_eLanguage));
+ m_xTitleBox->set_entry_text(SwStdFontConfig::GetDefaultFor(FONT_OUTLINE + nFontOffset, m_eLanguage));
+ m_xListBox->set_entry_text(SwStdFontConfig::GetDefaultFor(FONT_LIST + nFontOffset, m_eLanguage));
+ m_xLabelBox->set_entry_text(SwStdFontConfig::GetDefaultFor(FONT_CAPTION + nFontOffset, m_eLanguage));
+ m_xIdxBox->set_entry_text(SwStdFontConfig::GetDefaultFor(FONT_INDEX + nFontOffset, m_eLanguage));
+
+ m_xStandardBox->save_value();
+ m_xTitleBox->save_value();
+ m_xListBox->save_value();
+ m_xLabelBox->save_value();
+ m_xIdxBox->save_value();
+
+ m_xStandardHeightLB->set_value( CalcToPoint(
+ SwStdFontConfig::GetDefaultHeightFor(FONT_STANDARD + nFontOffset, m_eLanguage),
+ MapUnit::MapTwip, 10 ));
+ m_xTitleHeightLB->set_value(CalcToPoint(
+ SwStdFontConfig::GetDefaultHeightFor(FONT_OUTLINE +
+ nFontOffset, m_eLanguage), MapUnit::MapTwip, 10 ));
+ m_xListHeightLB->set_value(CalcToPoint(
+ SwStdFontConfig::GetDefaultHeightFor(FONT_LIST + nFontOffset, m_eLanguage),
+ MapUnit::MapTwip, 10 ));
+ m_xLabelHeightLB->set_value(CalcToPoint(
+ SwStdFontConfig::GetDefaultHeightFor(FONT_CAPTION + nFontOffset, m_eLanguage),
+ MapUnit::MapTwip, 10 ));
+ m_xIndexHeightLB->set_value(CalcToPoint(
+ SwStdFontConfig::GetDefaultHeightFor(FONT_INDEX + nFontOffset, m_eLanguage),
+ MapUnit::MapTwip, 10 ));
+}
+
+IMPL_LINK( SwStdFontTabPage, ModifyHdl, weld::ComboBox&, rBox, void )
+{
+ if (&rBox == m_xStandardBox.get())
+ {
+ const OUString sEntry = rBox.get_active_text();
+ if(m_bSetListDefault && m_bListDefault)
+ m_xListBox->set_entry_text(sEntry);
+ if(m_bSetLabelDefault && m_bLabelDefault)
+ m_xLabelBox->set_entry_text(sEntry);
+ if(m_bSetIdxDefault && m_bIdxDefault)
+ m_xIdxBox->set_entry_text(sEntry);
+ }
+ else if (&rBox == m_xListBox.get())
+ {
+ m_bSetListDefault = false;
+ }
+ else if (&rBox == m_xLabelBox.get())
+ {
+ m_bSetLabelDefault = false;
+ }
+ else if (&rBox == m_xIdxBox.get())
+ {
+ m_bSetIdxDefault = false;
+ }
+}
+
+IMPL_LINK( SwStdFontTabPage, LoseFocusHdl, weld::Widget&, rControl, void )
+{
+ weld::ComboBox& rBox = dynamic_cast<weld::ComboBox&>(rControl);
+ FontSizeBox* pHeightLB = nullptr;
+
+ if (&rBox == m_xStandardBox.get())
+ {
+ pHeightLB = m_xStandardHeightLB.get();
+ }
+ else if (&rBox == m_xTitleBox.get())
+ {
+ pHeightLB = m_xTitleHeightLB.get();
+ }
+ else if (&rBox == m_xListBox.get())
+ {
+ pHeightLB = m_xListHeightLB.get();
+ }
+ else if (&rBox == m_xLabelBox.get())
+ {
+ pHeightLB = m_xLabelHeightLB.get();
+ }
+ else /*if (&rBox == m_xIndexHeightLB.get())*/
+ {
+ pHeightLB = m_xIndexHeightLB.get();
+ }
+
+ pHeightLB->Fill( m_pFontList.get() );
+}
+
+void SwStdFontTabPage::PageCreated( const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pFlagItem = aSet.GetItem<SfxUInt16Item>(SID_FONTMODE_TYPE, false);
+ if (pFlagItem)
+ m_nFontGroup = sal::static_int_cast< sal_uInt8, sal_uInt16>( pFlagItem->GetValue() );
+}
+
+SwTableOptionsTabPage::SwTableOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/opttablepage.ui", "OptTablePage", &rSet)
+ , m_pWrtShell(nullptr)
+ , m_bHTMLMode(false)
+ , m_xHeaderCB(m_xBuilder->weld_check_button("header"))
+ , m_xHeaderImg(m_xBuilder->weld_widget("lockheader"))
+ , m_xRepeatHeaderCB(m_xBuilder->weld_check_button("repeatheader"))
+ , m_xRepeatHeaderImg(m_xBuilder->weld_widget("lockrepeatheader"))
+ , m_xDontSplitCB(m_xBuilder->weld_check_button("dontsplit"))
+ , m_xDontSplitImg(m_xBuilder->weld_widget("lockdontsplit"))
+ , m_xBorderCB(m_xBuilder->weld_check_button("border"))
+ , m_xBorderImg(m_xBuilder->weld_widget("lockborder"))
+ , m_xNumFormattingCB(m_xBuilder->weld_check_button("numformatting"))
+ , m_xNumFormattingImg(m_xBuilder->weld_widget("locknumformatting"))
+ , m_xNumFormatFormattingCB(m_xBuilder->weld_check_button("numfmtformatting"))
+ , m_xNumFormatFormattingImg(m_xBuilder->weld_widget("locknumfmtformatting"))
+ , m_xNumAlignmentCB(m_xBuilder->weld_check_button("numalignment"))
+ , m_xNumAlignmentImg(m_xBuilder->weld_widget("locknumalignment"))
+ , m_xRowMoveMF(m_xBuilder->weld_metric_spin_button("rowmove", FieldUnit::CM))
+ , m_xRowMoveImg(m_xBuilder->weld_widget("lockrowmove"))
+ , m_xColMoveMF(m_xBuilder->weld_metric_spin_button("colmove", FieldUnit::CM))
+ , m_xColMoveImg(m_xBuilder->weld_widget("lockcolmove"))
+ , m_xRowInsertMF(m_xBuilder->weld_metric_spin_button("rowinsert", FieldUnit::CM))
+ , m_xRowInsertImg(m_xBuilder->weld_widget("lockrowinsert"))
+ , m_xColInsertMF(m_xBuilder->weld_metric_spin_button("colinsert", FieldUnit::CM))
+ , m_xColInsertImg(m_xBuilder->weld_widget("lockcolinsert"))
+ , m_xFixRB(m_xBuilder->weld_radio_button("fix"))
+ , m_xFixPropRB(m_xBuilder->weld_radio_button("fixprop"))
+ , m_xVarRB(m_xBuilder->weld_radio_button("var"))
+ , m_xBehaviorOfImg(m_xBuilder->weld_widget("lockbehaviorof"))
+{
+ Link<weld::Toggleable&,void> aLnk(LINK(this, SwTableOptionsTabPage, CheckBoxHdl));
+ m_xNumFormattingCB->connect_toggled(aLnk);
+ m_xNumFormatFormattingCB->connect_toggled(aLnk);
+ m_xHeaderCB->connect_toggled(aLnk);
+}
+
+SwTableOptionsTabPage::~SwTableOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwTableOptionsTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SwTableOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwTableOptionsTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[]
+ = { "label1", "label3", "label4", "label5", "label6", "label10", "label2",
+ "label14", "label15", "label16", "label11", "label12", "label13" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[] = { "header", "repeatheader", "dontsplit", "border",
+ "numformatting", "numfmtformatting", "numalignment" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString radioButton[] = { "fix", "fixprop", "var" };
+
+ for (const auto& radio : radioButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_radio_button(radio))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwTableOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bRet = false;
+ SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+
+ if (m_xRowMoveMF->get_value_changed_from_saved())
+ pModOpt->SetTableHMove( o3tl::narrowing<sal_uInt16>(m_xRowMoveMF->denormalize( m_xRowMoveMF->get_value(FieldUnit::TWIP))));
+
+ if (m_xColMoveMF->get_value_changed_from_saved())
+ pModOpt->SetTableVMove( o3tl::narrowing<sal_uInt16>(m_xColMoveMF->denormalize( m_xColMoveMF->get_value(FieldUnit::TWIP))));
+
+ if (m_xRowInsertMF->get_value_changed_from_saved())
+ pModOpt->SetTableHInsert(o3tl::narrowing<sal_uInt16>(m_xRowInsertMF->denormalize( m_xRowInsertMF->get_value(FieldUnit::TWIP))));
+
+ if (m_xColInsertMF->get_value_changed_from_saved())
+ pModOpt->SetTableVInsert(o3tl::narrowing<sal_uInt16>(m_xColInsertMF->denormalize( m_xColInsertMF->get_value(FieldUnit::TWIP))));
+
+ TableChgMode eMode;
+ if (m_xFixRB->get_active())
+ eMode = TableChgMode::FixedWidthChangeAbs;
+ else if(m_xFixPropRB->get_active())
+ eMode = TableChgMode::FixedWidthChangeProp;
+ else
+ eMode = TableChgMode::VarWidthChangeAbs;
+ if(eMode != pModOpt->GetTableMode())
+ {
+ pModOpt->SetTableMode(eMode);
+ // the table-keyboard-mode has changed, now the current
+ // table should know about that too.
+ if(m_pWrtShell && SelectionType::Table & m_pWrtShell->GetSelectionType())
+ {
+ m_pWrtShell->SetTableChgMode(eMode);
+ static sal_uInt16 aInva[] =
+ { FN_TABLE_MODE_FIX,
+ FN_TABLE_MODE_FIX_PROP,
+ FN_TABLE_MODE_VARIABLE,
+ 0
+ };
+ m_pWrtShell->GetView().GetViewFrame().GetBindings().Invalidate( aInva );
+ }
+
+ bRet = true;
+ }
+
+ SwInsertTableOptions aInsOpts( SwInsertTableFlags::NONE, 0 );
+
+ if (m_xHeaderCB->get_active())
+ aInsOpts.mnInsMode |= SwInsertTableFlags::Headline;
+
+ if (m_xRepeatHeaderCB->get_sensitive())
+ aInsOpts.mnRowsToRepeat = m_xRepeatHeaderCB->get_active() ? 1 : 0;
+
+ if (!m_xDontSplitCB->get_active())
+ aInsOpts.mnInsMode |= SwInsertTableFlags::SplitLayout;
+
+ if (m_xBorderCB->get_active())
+ aInsOpts.mnInsMode |= SwInsertTableFlags::DefaultBorder;
+
+ if (m_xHeaderCB->get_state_changed_from_saved() ||
+ m_xRepeatHeaderCB->get_state_changed_from_saved() ||
+ m_xDontSplitCB->get_state_changed_from_saved() ||
+ m_xBorderCB->get_state_changed_from_saved())
+ {
+ pModOpt->SetInsTableFlags(m_bHTMLMode, aInsOpts);
+ }
+
+ if (m_xNumFormattingCB->get_state_changed_from_saved())
+ {
+ pModOpt->SetInsTableFormatNum(m_bHTMLMode, m_xNumFormattingCB->get_active());
+ bRet = true;
+ }
+
+ if (m_xNumFormatFormattingCB->get_state_changed_from_saved())
+ {
+ pModOpt->SetInsTableChangeNumFormat(m_bHTMLMode, m_xNumFormatFormattingCB->get_active());
+ bRet = true;
+ }
+
+ if (m_xNumAlignmentCB->get_state_changed_from_saved())
+ {
+ pModOpt->SetInsTableAlignNum(m_bHTMLMode, m_xNumAlignmentCB->get_active());
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+void SwTableOptionsTabPage::Reset( const SfxItemSet* rSet)
+{
+ if (const SfxUInt16Item* pItem = rSet->GetItemIfSet(SID_HTML_MODE, false))
+ {
+ m_bHTMLMode = 0 != (pItem->GetValue() & HTMLMODE_ON);
+ }
+
+ const SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+ if ( rSet->GetItemState( SID_ATTR_METRIC ) >= SfxItemState::DEFAULT )
+ {
+ const SfxUInt16Item& rItem = rSet->Get( SID_ATTR_METRIC );
+ FieldUnit eFieldUnit = static_cast<FieldUnit>(rItem.GetValue());
+ ::SetFieldUnit( *m_xRowMoveMF, eFieldUnit );
+ ::SetFieldUnit( *m_xColMoveMF, eFieldUnit );
+ ::SetFieldUnit( *m_xRowInsertMF, eFieldUnit );
+ ::SetFieldUnit( *m_xColInsertMF, eFieldUnit );
+ }
+
+ bool bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Shift::Row::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Shift::Row::isReadOnly();
+ m_xRowMoveMF->set_value(m_xRowMoveMF->normalize(pModOpt->GetTableHMove()), FieldUnit::TWIP);
+ m_xRowMoveMF->set_sensitive(!bReadOnly);
+ m_xRowMoveImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Shift::Column::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Shift::Column::isReadOnly();
+ m_xColMoveMF->set_value(m_xColMoveMF->normalize(pModOpt->GetTableVMove()), FieldUnit::TWIP);
+ m_xColMoveMF->set_sensitive(!bReadOnly);
+ m_xColMoveImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Insert::Row::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Insert::Row::isReadOnly();
+ m_xRowInsertMF->set_value(m_xRowInsertMF->normalize(pModOpt->GetTableHInsert()), FieldUnit::TWIP);
+ m_xRowInsertMF->set_sensitive(!bReadOnly);
+ m_xRowInsertImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Insert::Column::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Insert::Column::isReadOnly();
+ m_xColInsertMF->set_value(m_xColInsertMF->normalize(pModOpt->GetTableVInsert()), FieldUnit::TWIP);
+ m_xColInsertMF->set_sensitive(!bReadOnly);
+ m_xColInsertImg->set_visible(bReadOnly);
+
+ switch(pModOpt->GetTableMode())
+ {
+ case TableChgMode::FixedWidthChangeAbs: m_xFixRB->set_active(true); break;
+ case TableChgMode::FixedWidthChangeProp: m_xFixPropRB->set_active(true); break;
+ case TableChgMode::VarWidthChangeAbs: m_xVarRB->set_active(true); break;
+ }
+
+ // hide certain controls for html
+ if (m_bHTMLMode)
+ {
+ m_xRepeatHeaderCB->hide();
+ m_xDontSplitCB->hide();
+ }
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Change::Effect::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Change::Effect::isReadOnly();
+ if (bReadOnly)
+ {
+ m_xFixRB->set_sensitive(false);
+ m_xFixPropRB->set_sensitive(false);
+ m_xVarRB->set_sensitive(false);
+ m_xBehaviorOfImg->set_visible(true);
+ }
+
+ SwInsertTableOptions aInsOpts = pModOpt->GetInsTableFlags(m_bHTMLMode);
+ const SwInsertTableFlags nInsTableFlags = aInsOpts.mnInsMode;
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Insert::Table::Header::isReadOnly() :
+ officecfg::Office::WriterWeb::Insert::Table::Header::isReadOnly();
+ m_xHeaderCB->set_active(bool(nInsTableFlags & SwInsertTableFlags::Headline));
+ m_xHeaderCB->set_sensitive(!bReadOnly);
+ m_xHeaderImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Insert::Table::RepeatHeader::isReadOnly();
+ m_xRepeatHeaderCB->set_active((!m_bHTMLMode) && (aInsOpts.mnRowsToRepeat > 0));
+ m_xRepeatHeaderCB->set_sensitive(!bReadOnly);
+ m_xRepeatHeaderImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Insert::Table::Split::isReadOnly();
+ m_xDontSplitCB->set_active(!(nInsTableFlags & SwInsertTableFlags::SplitLayout));
+ m_xDontSplitCB->set_sensitive(!bReadOnly);
+ m_xDontSplitImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Insert::Table::Border::isReadOnly() :
+ officecfg::Office::WriterWeb::Insert::Table::Border::isReadOnly();
+ m_xBorderCB->set_active(bool(nInsTableFlags & SwInsertTableFlags::DefaultBorder));
+ m_xBorderCB->set_sensitive(!bReadOnly);
+ m_xBorderImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Input::NumberRecognition::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Input::NumberRecognition::isReadOnly();
+ m_xNumFormattingCB->set_active(pModOpt->IsInsTableFormatNum(m_bHTMLMode));
+ m_xNumFormattingCB->set_sensitive(!bReadOnly);
+ m_xNumFormattingImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Input::NumberFormatRecognition::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Input::NumberFormatRecognition::isReadOnly();
+ m_xNumFormatFormattingCB->set_active(pModOpt->IsInsTableChangeNumFormat(m_bHTMLMode));
+ m_xNumFormatFormattingCB->set_sensitive(!bReadOnly);
+ m_xNumFormatFormattingImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Input::Alignment::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Input::Alignment::isReadOnly();
+ m_xNumAlignmentCB->set_active(pModOpt->IsInsTableAlignNum(m_bHTMLMode));
+ m_xNumAlignmentCB->set_sensitive(!bReadOnly);
+ m_xNumAlignmentImg->set_visible(bReadOnly);
+
+ m_xHeaderCB->save_state();
+ m_xRepeatHeaderCB->save_state();
+ m_xDontSplitCB->save_state();
+ m_xBorderCB->save_state();
+ m_xNumFormattingCB->save_state();
+ m_xNumFormatFormattingCB->save_state();
+ m_xNumAlignmentCB->save_state();
+ m_xRowMoveMF->save_value();
+ m_xColMoveMF->save_value();
+ m_xRowInsertMF->save_value();
+ m_xColInsertMF->save_value();
+
+ CheckBoxHdl(*m_xHeaderCB);
+}
+
+IMPL_LINK_NOARG(SwTableOptionsTabPage, CheckBoxHdl, weld::Toggleable&, void)
+{
+ bool bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Input::NumberFormatRecognition::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Input::NumberFormatRecognition::isReadOnly();
+ m_xNumFormatFormattingCB->set_sensitive(m_xNumFormattingCB->get_active() && !bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Table::Input::Alignment::isReadOnly() :
+ officecfg::Office::WriterWeb::Table::Input::Alignment::isReadOnly();
+ m_xNumAlignmentCB->set_sensitive(m_xNumFormattingCB->get_active() && !bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Insert::Table::RepeatHeader::isReadOnly() : false;
+ m_xRepeatHeaderCB->set_sensitive(m_xHeaderCB->get_active() && !bReadOnly);
+}
+
+void SwTableOptionsTabPage::PageCreated( const SfxAllItemSet& aSet)
+{
+ const SwWrtShellItem* pWrtSh = aSet.GetItem<SwWrtShellItem>(SID_WRT_SHELL, false);
+ if (pWrtSh)
+ m_pWrtShell = pWrtSh->GetValue();
+}
+
+SwShdwCursorOptionsTabPage::SwShdwCursorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optformataidspage.ui", "OptFormatAidsPage", &rSet)
+ , m_pWrtShell(nullptr)
+ , m_bHTMLMode(false)
+ , m_xParaCB(m_xBuilder->weld_check_button("paragraph"))
+ , m_xParaImg(m_xBuilder->weld_widget("lockparagraph"))
+ , m_xSHyphCB(m_xBuilder->weld_check_button("hyphens"))
+ , m_xSHyphImg(m_xBuilder->weld_widget("lockhyphens"))
+ , m_xSpacesCB(m_xBuilder->weld_check_button("spaces"))
+ , m_xSpacesImg(m_xBuilder->weld_widget("lockspaces"))
+ , m_xHSpacesCB(m_xBuilder->weld_check_button("nonbreak"))
+ , m_xHSpacesImg(m_xBuilder->weld_widget("locknonbreak"))
+ , m_xTabCB(m_xBuilder->weld_check_button("tabs"))
+ , m_xTabImg(m_xBuilder->weld_widget("locktabs"))
+ , m_xTabLabel(m_xBuilder->weld_label("tabs_label"))
+ , m_xBreakCB(m_xBuilder->weld_check_button("break"))
+ , m_xBreakImg(m_xBuilder->weld_widget("lockbreak"))
+ , m_xCharHiddenCB(m_xBuilder->weld_check_button("hiddentext"))
+ , m_xCharHiddenImg(m_xBuilder->weld_widget("lockhiddentext"))
+ , m_xBookmarkCB(m_xBuilder->weld_check_button("bookmarks"))
+ , m_xBookmarkImg(m_xBuilder->weld_widget("lockbookmarks"))
+ , m_xBookmarkLabel(m_xBuilder->weld_label("bookmarks_label"))
+ , m_xDirectCursorFrame(m_xBuilder->weld_frame("directcrsrframe"))
+ , m_xOnOffCB(m_xBuilder->weld_check_button("cursoronoff"))
+ , m_xOnOffImg(m_xBuilder->weld_widget("lockcursoronoff"))
+ , m_xDirectCursorFillMode(m_xBuilder->weld_combo_box("cxDirectCursorFillMode"))
+ , m_xDirectCursorFillModeImg(m_xBuilder->weld_widget("lockfillmode"))
+ , m_xCursorProtFrame(m_xBuilder->weld_frame("crsrprotframe"))
+ , m_xImageFrame(m_xBuilder->weld_frame("frmImage"))
+ , m_xCursorInProtCB(m_xBuilder->weld_check_button("cursorinprot"))
+ , m_xCursorInProtImg(m_xBuilder->weld_widget("lockcursorinprot"))
+ , m_xDefaultAnchorType(m_xBuilder->weld_combo_box("cxDefaultAnchor"))
+ , m_xDefaultAnchorTypeImg(m_xBuilder->weld_widget("lockAnchor"))
+ , m_xMathBaselineAlignmentCB(m_xBuilder->weld_check_button("mathbaseline"))
+ , m_xMathBaselineAlignmentImg(m_xBuilder->weld_widget("lockmathbaseline"))
+{
+ SwFillMode eMode = SwFillMode::Tab;
+ bool bIsOn = false;
+
+ if( const SwShadowCursorItem* pItem = rSet.GetItemIfSet( FN_PARAM_SHADOWCURSOR, false ))
+ {
+ eMode = pItem->GetMode();
+ bIsOn = pItem->IsOn();
+ }
+ m_xOnOffCB->set_active( bIsOn );
+
+ m_xDirectCursorFillMode->set_active( static_cast<int>(eMode) );
+ const SfxUInt16Item* pHtmlModeItem = rSet.GetItemIfSet(SID_HTML_MODE, false);
+ if(!pHtmlModeItem || !(pHtmlModeItem->GetValue() & HTMLMODE_ON))
+ return;
+
+ m_bHTMLMode = true;
+
+ m_xTabCB->hide();
+ m_xTabLabel->hide();
+ m_xCharHiddenCB->hide();
+ m_xBookmarkCB->hide();
+ m_xBookmarkLabel->hide();
+
+ m_xDirectCursorFrame->hide();
+ m_xOnOffCB->hide();
+ m_xDirectCursorFillMode->hide();
+ m_xCursorProtFrame->hide();
+ m_xCursorInProtCB->hide();
+ m_xImageFrame->hide();
+}
+
+SwShdwCursorOptionsTabPage::~SwShdwCursorOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwShdwCursorOptionsTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SwShdwCursorOptionsTabPage>(pPage, pController, *rSet);
+}
+
+void SwShdwCursorOptionsTabPage::PageCreated( const SfxAllItemSet& aSet )
+{
+ const SwWrtShellItem* pWrtSh = aSet.GetItem<SwWrtShellItem>(SID_WRT_SHELL, false);
+ if (pWrtSh)
+ m_pWrtShell = pWrtSh->GetValue();
+}
+
+OUString SwShdwCursorOptionsTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "layoutopt", "displayfl", "cursoropt", "cursorlabel",
+ "fillmode", "lbImage", "lbDefaultAnchor" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[]
+ = { "mathbaseline", "paragraph", "hyphens", "spaces", "nonbreak", "tabs",
+ "break", "hiddentext", "bookmarks", "cursorinprot", "cursoronoff" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwShdwCursorOptionsTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ SwShadowCursorItem aOpt;
+ aOpt.SetOn( m_xOnOffCB->get_active() );
+
+ SwFillMode eMode = static_cast<SwFillMode>(m_xDirectCursorFillMode->get_active());
+ aOpt.SetMode( eMode );
+
+ bool bRet = false;
+ const SwShadowCursorItem* pShadowCursorItem = rSet->GetItemIfSet( FN_PARAM_SHADOWCURSOR, false );
+ if( !pShadowCursorItem || *pShadowCursorItem != aOpt )
+ {
+ rSet->Put( aOpt );
+ bRet = true;
+ }
+
+ if (m_pWrtShell) {
+ m_pWrtShell->GetDoc()->getIDocumentSettingAccess().set( DocumentSettingId::MATH_BASELINE_ALIGNMENT,
+ m_xMathBaselineAlignmentCB->get_active() );
+ bRet |= m_xMathBaselineAlignmentCB->get_state_changed_from_saved();
+ }
+
+ if( m_xCursorInProtCB->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(FN_PARAM_CRSR_IN_PROTECTED, m_xCursorInProtCB->get_active()));
+ bRet = true;
+ }
+
+ const SwDocDisplayItem* pOldAttr = GetOldItem(GetItemSet(), FN_PARAM_DOCDISP);
+
+ SwDocDisplayItem aDisp;
+
+ aDisp.m_bParagraphEnd = m_xParaCB->get_active();
+ aDisp.m_bTab = m_xTabCB->get_active();
+ aDisp.m_bSpace = m_xSpacesCB->get_active();
+ aDisp.m_bNonbreakingSpace = m_xHSpacesCB->get_active();
+ aDisp.m_bSoftHyphen = m_xSHyphCB->get_active();
+ aDisp.m_bCharHiddenText = m_xCharHiddenCB->get_active();
+ aDisp.m_bBookmarks = m_xBookmarkCB->get_active();
+ aDisp.m_bManualBreak = m_xBreakCB->get_active();
+ aDisp.m_xDefaultAnchor = m_xDefaultAnchorType->get_active();
+
+ bRet |= (!pOldAttr || aDisp != *pOldAttr);
+ if(bRet)
+ bRet = nullptr != rSet->Put(aDisp);
+
+ return bRet;
+}
+
+void SwShdwCursorOptionsTabPage::Reset( const SfxItemSet* rSet )
+{
+ SwFillMode eMode = SwFillMode::Tab;
+ bool bIsOn = false;
+
+ if( const SwShadowCursorItem* pItem = rSet->GetItemIfSet( FN_PARAM_SHADOWCURSOR, false ))
+ {
+ eMode = pItem->GetMode();
+ bIsOn = pItem->IsOn();
+ }
+
+ bool bReadOnly = officecfg::Office::Writer::Cursor::DirectCursor::UseDirectCursor::isReadOnly();
+ m_xOnOffCB->set_active( bIsOn );
+ m_xOnOffCB->set_sensitive(!bReadOnly);
+ m_xOnOffImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Cursor::DirectCursor::Insert::isReadOnly();
+ m_xDirectCursorFillMode->set_active( static_cast<int>(eMode) );
+ m_xDirectCursorFillMode->set_sensitive(!bReadOnly);
+ m_xDirectCursorFillModeImg->set_visible(bReadOnly);
+
+ if (m_pWrtShell) {
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Layout::Other::IsAlignMathObjectsToBaseline::isReadOnly() :
+ officecfg::Office::WriterWeb::Layout::Other::IsAlignMathObjectsToBaseline::isReadOnly();
+ m_xMathBaselineAlignmentCB->set_active( m_pWrtShell->GetDoc()->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT ) );
+ m_xMathBaselineAlignmentCB->set_sensitive(!bReadOnly);
+ m_xMathBaselineAlignmentImg->set_visible(bReadOnly);
+ m_xMathBaselineAlignmentCB->save_state();
+ } else {
+ m_xMathBaselineAlignmentCB->hide();
+ }
+
+ if( const SfxBoolItem* pItem = rSet->GetItemIfSet( FN_PARAM_CRSR_IN_PROTECTED, false ) )
+ m_xCursorInProtCB->set_active(pItem->GetValue());
+ bReadOnly = officecfg::Office::Writer::Cursor::Option::ProtectedArea::isReadOnly();
+ m_xCursorInProtCB->set_sensitive(!bReadOnly);
+ m_xCursorInProtImg->set_visible(bReadOnly);
+ m_xCursorInProtCB->save_state();
+
+ const SwDocDisplayItem* pDocDisplayAttr = rSet->GetItemIfSet( FN_PARAM_DOCDISP, false );
+ if(pDocDisplayAttr)
+ {
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Content::NonprintingCharacter::ParagraphEnd::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::NonprintingCharacter::ParagraphEnd::isReadOnly();
+ m_xParaCB->set_active( pDocDisplayAttr->m_bParagraphEnd );
+ m_xParaCB->set_sensitive(!bReadOnly);
+ m_xParaImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::NonprintingCharacter::Tab::isReadOnly();
+ m_xTabCB->set_active( pDocDisplayAttr->m_bTab );
+ m_xTabCB->set_sensitive(!bReadOnly);
+ m_xTabImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Content::NonprintingCharacter::Space::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::NonprintingCharacter::Space::isReadOnly();
+ m_xSpacesCB->set_active( pDocDisplayAttr->m_bSpace );
+ m_xSpacesCB->set_sensitive(!bReadOnly);
+ m_xSpacesImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Content::NonprintingCharacter::ProtectedSpace::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::NonprintingCharacter::ProtectedSpace::isReadOnly();
+ m_xHSpacesCB->set_active( pDocDisplayAttr->m_bNonbreakingSpace );
+ m_xHSpacesCB->set_sensitive(!bReadOnly);
+ m_xHSpacesImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Content::NonprintingCharacter::OptionalHyphen::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::NonprintingCharacter::OptionalHyphen::isReadOnly();
+ m_xSHyphCB->set_active( pDocDisplayAttr->m_bSoftHyphen );
+ m_xSHyphCB->set_sensitive(!bReadOnly);
+ m_xSHyphImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::NonprintingCharacter::HiddenCharacter::isReadOnly();
+ m_xCharHiddenCB->set_active( pDocDisplayAttr->m_bCharHiddenText );
+ m_xCharHiddenCB->set_sensitive(!bReadOnly);
+ m_xCharHiddenImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::NonprintingCharacter::Bookmarks::isReadOnly();
+ m_xBookmarkCB->set_active(pDocDisplayAttr->m_bBookmarks);
+ m_xBookmarkCB->set_sensitive(!bReadOnly);
+ m_xBookmarkImg->set_visible(bReadOnly);
+
+ bReadOnly = !m_bHTMLMode ? officecfg::Office::Writer::Content::NonprintingCharacter::Break::isReadOnly() :
+ officecfg::Office::WriterWeb::Content::NonprintingCharacter::Break::isReadOnly();
+ m_xBreakCB->set_active( pDocDisplayAttr->m_bManualBreak );
+ m_xBreakCB->set_sensitive(!bReadOnly);
+ m_xBreakImg->set_visible(bReadOnly);
+
+ bReadOnly = officecfg::Office::Writer::Content::Display::DefaultAnchor::isReadOnly();
+ m_xDefaultAnchorType->set_active( pDocDisplayAttr->m_xDefaultAnchor );
+ m_xDefaultAnchorType->set_sensitive(!bReadOnly);
+ m_xDefaultAnchorTypeImg->set_visible(bReadOnly);
+ }
+}
+
+namespace {
+
+// TabPage for Redlining
+struct CharAttr
+{
+ sal_uInt16 nItemId;
+ sal_uInt16 nAttr;
+};
+
+}
+
+// Edit corresponds to Paste-attributes
+CharAttr const aRedlineAttr[] =
+{
+ { SID_ATTR_CHAR_CASEMAP, sal_uInt16(SvxCaseMap::NotMapped) },
+ { SID_ATTR_CHAR_WEIGHT, WEIGHT_BOLD },
+ { SID_ATTR_CHAR_POSTURE, ITALIC_NORMAL },
+ { SID_ATTR_CHAR_UNDERLINE, LINESTYLE_SINGLE },
+ { SID_ATTR_CHAR_UNDERLINE, LINESTYLE_DOUBLE },
+ { SID_ATTR_CHAR_STRIKEOUT, STRIKEOUT_SINGLE },
+ { SID_ATTR_CHAR_CASEMAP, sal_uInt16(SvxCaseMap::Uppercase) },
+ { SID_ATTR_CHAR_CASEMAP, sal_uInt16(SvxCaseMap::Lowercase) },
+ { SID_ATTR_CHAR_CASEMAP, sal_uInt16(SvxCaseMap::SmallCaps) },
+ { SID_ATTR_CHAR_CASEMAP, sal_uInt16(SvxCaseMap::Capitalize) },
+ { SID_ATTR_BRUSH, 0 }
+};
+// Items from aRedlineAttr relevant for InsertAttr: strikethrough is
+// not used
+static sal_uInt16 aInsertAttrMap[] = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 10 };
+
+// Items from aRedlineAttr relevant for DeleteAttr: underline and
+// double underline is not used
+static sal_uInt16 aDeletedAttrMap[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10 };
+
+// Items from aRedlineAttr relevant for ChangeAttr: strikethrough is
+// not used
+static sal_uInt16 aChangedAttrMap[] = { 0, 1, 2, 3, 4, 6, 7, 8, 9, 10 };
+
+// Preview of selection
+SwMarkPreview::SwMarkPreview()
+ : m_aTransCol(COL_TRANSPARENT)
+ , m_aMarkCol(COL_LIGHTRED)
+ , m_nMarkPos(0)
+
+{
+ InitColors();
+}
+
+SwMarkPreview::~SwMarkPreview()
+{
+}
+
+void SwMarkPreview::InitColors()
+{
+ // m_aTransCol and m_aMarkCol are _not_ changed because they are set from outside!
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ m_aBgCol = rSettings.GetWindowColor();
+
+ bool bHC = rSettings.GetHighContrastMode();
+ const Color& rFontColor = SwViewOption::GetCurrentViewOptions().GetFontColor();
+ m_aLineCol = bHC? rFontColor : COL_BLACK;
+ m_aShadowCol = bHC? m_aBgCol : rSettings.GetShadowColor();
+ m_aTextCol = bHC? rFontColor : COL_GRAY;
+ m_aPrintAreaCol = m_aTextCol;
+}
+
+void SwMarkPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle &/*rRect*/)
+{
+ const Size aSz(GetOutputSizePixel());
+
+ // Page
+ m_aPage.SetSize(Size(aSz.Width() - 3, aSz.Height() - 3));
+
+ const tools::Long nOutWPix = m_aPage.GetWidth();
+ const tools::Long nOutHPix = m_aPage.GetHeight();
+
+ // PrintArea
+ const tools::Long nLBorder = 8;
+ const tools::Long nRBorder = 8;
+ const tools::Long nTBorder = 4;
+ const tools::Long nBBorder = 4;
+
+ m_aLeftPagePrtArea = tools::Rectangle(Point(nLBorder, nTBorder), Point((nOutWPix - 1) - nRBorder, (nOutHPix - 1) - nBBorder));
+ const tools::Long nWidth = m_aLeftPagePrtArea.GetWidth();
+ const tools::Long nCorr = (nWidth & 1) != 0 ? 0 : 1;
+ m_aLeftPagePrtArea.SetSize(Size(nWidth / 2 - (nLBorder + nRBorder) / 2 + nCorr, m_aLeftPagePrtArea.GetHeight()));
+
+ m_aRightPagePrtArea = m_aLeftPagePrtArea;
+ m_aRightPagePrtArea.Move(m_aLeftPagePrtArea.GetWidth() + nLBorder + nRBorder + 1, 0);
+
+ // draw shadow
+ tools::Rectangle aShadow(m_aPage);
+ aShadow += Point(3, 3);
+ drawRect(rRenderContext, aShadow, m_aShadowCol, m_aTransCol);
+
+ // draw page
+ drawRect(rRenderContext, m_aPage, m_aBgCol, m_aLineCol);
+
+ // draw separator
+ tools::Rectangle aPageSeparator(m_aPage);
+ aPageSeparator.SetSize(Size(2, aPageSeparator.GetHeight()));
+ aPageSeparator.Move(m_aPage.GetWidth() / 2 - 1, 0);
+ drawRect(rRenderContext, aPageSeparator, m_aLineCol, m_aTransCol);
+
+ PaintPage(rRenderContext, m_aLeftPagePrtArea);
+ PaintPage(rRenderContext, m_aRightPagePrtArea);
+
+ tools::Rectangle aLeftMark(Point(m_aPage.Left() + 2, m_aLeftPagePrtArea.Top() + 4), Size(m_aLeftPagePrtArea.Left() - 4, 2));
+ tools::Rectangle aRightMark(Point(m_aRightPagePrtArea.Right() + 2, m_aRightPagePrtArea.Bottom() - 6), Size(m_aLeftPagePrtArea.Left() - 4, 2));
+
+ switch (m_nMarkPos)
+ {
+ case 1: // left
+ aRightMark.SetPos(Point(m_aRightPagePrtArea.Left() - 2 - aRightMark.GetWidth(), aRightMark.Top()));
+ break;
+
+ case 2: // right
+ aLeftMark.SetPos(Point(m_aLeftPagePrtArea.Right() + 2, aLeftMark.Top()));
+ break;
+
+ case 3: // outside
+ break;
+
+ case 4: // inside
+ aLeftMark.SetPos(Point(m_aLeftPagePrtArea.Right() + 2, aLeftMark.Top()));
+ aRightMark.SetPos(Point(m_aRightPagePrtArea.Left() - 2 - aRightMark.GetWidth(), aRightMark.Top()));
+ break;
+
+ case 0: // none
+ default:
+ return;
+ }
+ drawRect(rRenderContext, aLeftMark, m_aMarkCol, m_aTransCol);
+ drawRect(rRenderContext, aRightMark, m_aMarkCol, m_aTransCol);
+}
+
+void SwMarkPreview::PaintPage(vcl::RenderContext& rRenderContext, const tools::Rectangle &rRect)
+{
+ // draw PrintArea
+ drawRect(rRenderContext, rRect, m_aTransCol, m_aPrintAreaCol);
+
+ // draw Testparagraph
+
+ tools::Rectangle aTextLine = rRect;
+ aTextLine.SetSize(Size(aTextLine.GetWidth(), 2));
+ aTextLine.AdjustLeft(4 );
+ aTextLine.AdjustRight( -4 );
+ aTextLine.Move(0, 4);
+
+ const tools::Long nStep = aTextLine.GetHeight() + 2;
+ const tools::Long nLines = rRect.GetHeight() / (aTextLine.GetHeight() + 2) - 1;
+
+ // simulate text
+ for (tools::Long i = 0; i < nLines; ++i)
+ {
+ if (i == (nLines - 1))
+ aTextLine.SetSize(Size(aTextLine.GetWidth() / 2, aTextLine.GetHeight()));
+
+ if (m_aPage.Contains(aTextLine))
+ drawRect(rRenderContext, aTextLine, m_aTextCol, m_aTransCol);
+
+ aTextLine.Move(0, nStep);
+ }
+ aTextLine.Move(0, -nStep);
+}
+
+void SwMarkPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ Size aInitialSize = getPreviewOptionsSize(pDrawingArea->get_ref_device());
+ pDrawingArea->set_size_request(aInitialSize.Width(), aInitialSize.Height());
+ weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
+ SetOutputSizePixel(aInitialSize);
+}
+
+namespace
+{
+ void lcl_FillRedlineAttrListBox(
+ weld::ComboBox& rLB, const AuthorCharAttr& rAttrToSelect,
+ const sal_uInt16* pAttrMap, const size_t nAttrMapSize)
+ {
+ for (size_t i = 0; i != nAttrMapSize; ++i)
+ {
+ CharAttr const & rAttr(aRedlineAttr[pAttrMap[i]]);
+ rLB.set_id(i, weld::toId(&rAttr));
+ if (rAttr.nItemId == rAttrToSelect.m_nItemId &&
+ rAttr.nAttr == rAttrToSelect.m_nAttr)
+ rLB.set_active(i);
+ }
+ }
+}
+
+SwRedlineOptionsTabPage::SwRedlineOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optredlinepage.ui", "OptRedLinePage", &rSet)
+ , m_xInsertLB(m_xBuilder->weld_combo_box("insert"))
+ , m_xInsertImg(m_xBuilder->weld_widget("lockinsert"))
+ , m_xInsertColorLB(new ColorListBox(m_xBuilder->weld_menu_button("insertcolor"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xInsertColorImg(m_xBuilder->weld_widget("lockinsertcolor"))
+ , m_xInsertedPreviewWN(new SvxFontPrevWindow)
+ , m_xInsertedPreview(new weld::CustomWeld(*m_xBuilder, "insertedpreview", *m_xInsertedPreviewWN))
+ , m_xDeletedLB(m_xBuilder->weld_combo_box("deleted"))
+ , m_xDeletedImg(m_xBuilder->weld_widget("lockdeleted"))
+ , m_xDeletedColorLB(new ColorListBox(m_xBuilder->weld_menu_button("deletedcolor"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xDeletedColorImg(m_xBuilder->weld_widget("lockdeletedcolor"))
+ , m_xDeletedPreviewWN(new SvxFontPrevWindow)
+ , m_xDeletedPreview(new weld::CustomWeld(*m_xBuilder, "deletedpreview", *m_xDeletedPreviewWN))
+ , m_xChangedLB(m_xBuilder->weld_combo_box("changed"))
+ , m_xChangedImg(m_xBuilder->weld_widget("lockchanged"))
+ , m_xChangedColorLB(new ColorListBox(m_xBuilder->weld_menu_button("changedcolor"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xChangedColorImg(m_xBuilder->weld_widget("lockchangedcolor"))
+ , m_xChangedPreviewWN(new SvxFontPrevWindow)
+ , m_xChangedPreview(new weld::CustomWeld(*m_xBuilder, "changedpreview", *m_xChangedPreviewWN))
+ , m_xMarkPosLB(m_xBuilder->weld_combo_box("markpos"))
+ , m_xMarkPosImg(m_xBuilder->weld_widget("lockmarkpos"))
+ , m_xMarkColorLB(new ColorListBox(m_xBuilder->weld_menu_button("markcolor"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xMarkColorImg(m_xBuilder->weld_widget("lockmarkcolor"))
+ , m_xMarkPreviewWN(new SwMarkPreview)
+ , m_xMarkPreview(new weld::CustomWeld(*m_xBuilder, "markpreview", *m_xMarkPreviewWN))
+{
+ Size aPreviewSize(getPreviewOptionsSize(m_xMarkPreviewWN->GetDrawingArea()->get_ref_device()));
+
+ m_xInsertColorLB->SetSlotId(SID_AUTHOR_COLOR, true);
+ m_xDeletedColorLB->SetSlotId(SID_AUTHOR_COLOR, true);
+ m_xChangedColorLB->SetSlotId(SID_AUTHOR_COLOR, true);
+
+ m_xInsertedPreviewWN->set_size_request(aPreviewSize.Width(), aPreviewSize.Height());
+ m_xDeletedPreviewWN->set_size_request(aPreviewSize.Width(), aPreviewSize.Height());
+ m_xChangedPreviewWN->set_size_request(aPreviewSize.Width(), aPreviewSize.Height());
+ m_xMarkPreviewWN->set_size_request(aPreviewSize.Width(), aPreviewSize.Height());
+
+ for (sal_Int32 i = 0, nEntryCount = m_xInsertLB->get_count(); i < nEntryCount; ++i)
+ {
+ const OUString sEntry(m_xInsertLB->get_text(i));
+ m_xDeletedLB->append_text(sEntry);
+ m_xChangedLB->append_text(sEntry);
+ };
+
+ // remove strikethrough from insert and change and underline + double
+ // underline from delete
+ m_xInsertLB->remove(5);
+ m_xChangedLB->remove(5);
+ m_xDeletedLB->remove(4);
+ m_xDeletedLB->remove(3);
+
+ Link<weld::ComboBox&,void> aLk = LINK(this, SwRedlineOptionsTabPage, AttribHdl);
+ m_xInsertLB->connect_changed( aLk );
+ m_xDeletedLB->connect_changed( aLk );
+ m_xChangedLB->connect_changed( aLk );
+
+ Link<ColorListBox&,void> aLk2 = LINK(this, SwRedlineOptionsTabPage, ColorHdl);
+ m_xInsertColorLB->SetSelectHdl( aLk2 );
+ m_xDeletedColorLB->SetSelectHdl( aLk2 );
+ m_xChangedColorLB->SetSelectHdl( aLk2 );
+
+ m_xMarkPosLB->connect_changed(LINK(this, SwRedlineOptionsTabPage, ChangedMaskPrevHdl));
+ m_xMarkColorLB->SetSelectHdl(LINK(this, SwRedlineOptionsTabPage, ChangedMaskColorPrevHdl));
+}
+
+SwRedlineOptionsTabPage::~SwRedlineOptionsTabPage()
+{
+ m_xInsertColorLB.reset();
+ m_xInsertedPreview.reset();
+ m_xInsertedPreviewWN.reset();
+ m_xDeletedColorLB.reset();
+ m_xDeletedPreview.reset();
+ m_xDeletedPreviewWN.reset();
+ m_xChangedColorLB.reset();
+ m_xChangedPreview.reset();
+ m_xChangedPreviewWN.reset();
+ m_xMarkColorLB.reset();
+ m_xMarkPreview.reset();
+ m_xMarkPreviewWN.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwRedlineOptionsTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwRedlineOptionsTabPage>(pPage, pController, *rSet);
+}
+
+OUString SwRedlineOptionsTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label2", "insert_label", "insertcolor_label",
+ "label3", "deleted_label", "deletedcolor_label",
+ "label4", "changed_label", "changedcolor_label",
+ "label5", "markpos_label", "markcolor_label" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwRedlineOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ CharAttr *pAttr;
+ SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
+
+ AuthorCharAttr aInsertedAttr;
+ AuthorCharAttr aDeletedAttr;
+ AuthorCharAttr aChangedAttr;
+
+ AuthorCharAttr aOldInsertAttr(pOpt->GetInsertAuthorAttr());
+ AuthorCharAttr aOldDeletedAttr(pOpt->GetDeletedAuthorAttr());
+ AuthorCharAttr aOldChangedAttr(pOpt->GetFormatAuthorAttr());
+
+ Color nOldMarkColor = pOpt->GetMarkAlignColor();
+ sal_uInt16 nOldMarkMode = pOpt->GetMarkAlignMode();
+
+ sal_Int32 nPos = m_xInsertLB->get_active();
+ if (nPos != -1)
+ {
+ pAttr = weld::fromId<CharAttr*>(m_xInsertLB->get_id(nPos));
+ aInsertedAttr.m_nItemId = pAttr->nItemId;
+ aInsertedAttr.m_nAttr = pAttr->nAttr;
+ aInsertedAttr.m_nColor = m_xInsertColorLB->GetSelectEntryColor();
+ pOpt->SetInsertAuthorAttr(aInsertedAttr);
+ }
+
+ nPos = m_xDeletedLB->get_active();
+ if (nPos != -1)
+ {
+ pAttr = weld::fromId<CharAttr*>(m_xDeletedLB->get_id(nPos));
+ aDeletedAttr.m_nItemId = pAttr->nItemId;
+ aDeletedAttr.m_nAttr = pAttr->nAttr;
+ aDeletedAttr.m_nColor = m_xDeletedColorLB->GetSelectEntryColor();
+ pOpt->SetDeletedAuthorAttr(aDeletedAttr);
+ }
+
+ nPos = m_xChangedLB->get_active();
+ if (nPos != -1)
+ {
+ pAttr = weld::fromId<CharAttr*>(m_xChangedLB->get_id(nPos));
+ aChangedAttr.m_nItemId = pAttr->nItemId;
+ aChangedAttr.m_nAttr = pAttr->nAttr;
+ aChangedAttr.m_nColor = m_xChangedColorLB->GetSelectEntryColor();
+ pOpt->SetFormatAuthorAttr(aChangedAttr);
+ }
+
+ nPos = 0;
+ switch (m_xMarkPosLB->get_active())
+ {
+ case 0: nPos = text::HoriOrientation::NONE; break;
+ case 1: nPos = text::HoriOrientation::LEFT; break;
+ case 2: nPos = text::HoriOrientation::RIGHT; break;
+ case 3: nPos = text::HoriOrientation::OUTSIDE; break;
+ case 4: nPos = text::HoriOrientation::INSIDE; break;
+ }
+ pOpt->SetMarkAlignMode(nPos);
+ pOpt->SetMarkAlignColor(m_xMarkColorLB->GetSelectEntryColor());
+
+ if (!(aInsertedAttr == aOldInsertAttr) ||
+ !(aDeletedAttr == aOldDeletedAttr) ||
+ !(aChangedAttr == aOldChangedAttr) ||
+ nOldMarkColor != pOpt->GetMarkAlignColor() ||
+ nOldMarkMode != pOpt->GetMarkAlignMode() )
+ {
+ // update all documents
+ SwDocShell* pDocShell = static_cast<SwDocShell*>(SfxObjectShell::GetFirst(checkSfxObjectShell<SwDocShell>));
+
+ while( pDocShell )
+ {
+ pDocShell->GetWrtShell()->UpdateRedlineAttr();
+ pDocShell = static_cast<SwDocShell*>(SfxObjectShell::GetNext(*pDocShell, checkSfxObjectShell<SwDocShell>));
+ }
+ }
+
+ return false;
+}
+
+void SwRedlineOptionsTabPage::Reset( const SfxItemSet* )
+{
+ const SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
+
+ const AuthorCharAttr &rInsertAttr = pOpt->GetInsertAuthorAttr();
+ const AuthorCharAttr &rDeletedAttr = pOpt->GetDeletedAuthorAttr();
+ const AuthorCharAttr &rChangedAttr = pOpt->GetFormatAuthorAttr();
+
+ // initialise preview
+ InitFontStyle(*m_xInsertedPreviewWN, SwResId(STR_OPT_PREVIEW_INSERTED));
+ InitFontStyle(*m_xDeletedPreviewWN, SwResId(STR_OPT_PREVIEW_DELETED));
+ InitFontStyle(*m_xChangedPreviewWN, SwResId(STR_OPT_PREVIEW_CHANGED));
+
+ Color nColor = rInsertAttr.m_nColor;
+ m_xInsertColorLB->SelectEntry(nColor);
+ m_xInsertColorLB->set_sensitive(!officecfg::Office::Writer::Revision::TextDisplay::Insert::Attribute::isReadOnly());
+ m_xInsertColorImg->set_visible(officecfg::Office::Writer::Revision::TextDisplay::Insert::Attribute::isReadOnly());
+
+ nColor = rDeletedAttr.m_nColor;
+ m_xDeletedColorLB->SelectEntry(nColor);
+ m_xDeletedColorLB->set_sensitive(!officecfg::Office::Writer::Revision::TextDisplay::Delete::Attribute::isReadOnly());
+ m_xDeletedColorImg->set_visible(officecfg::Office::Writer::Revision::TextDisplay::Delete::Attribute::isReadOnly());
+
+ nColor = rChangedAttr.m_nColor;
+ m_xChangedColorLB->SelectEntry(nColor);
+ m_xChangedColorLB->set_sensitive(!officecfg::Office::Writer::Revision::TextDisplay::ChangedAttribute::Attribute::isReadOnly());
+ m_xChangedColorImg->set_visible(officecfg::Office::Writer::Revision::TextDisplay::ChangedAttribute::Attribute::isReadOnly());
+
+ m_xMarkColorLB->SelectEntry(pOpt->GetMarkAlignColor());
+ m_xMarkColorLB->set_sensitive(!officecfg::Office::Writer::Revision::LinesChanged::Color::isReadOnly());
+ m_xMarkColorImg->set_visible(officecfg::Office::Writer::Revision::LinesChanged::Color::isReadOnly());
+
+ m_xInsertLB->set_active(0);
+ m_xInsertLB->set_sensitive(!officecfg::Office::Writer::Revision::TextDisplay::Insert::Color::isReadOnly());
+ m_xInsertImg->set_visible(officecfg::Office::Writer::Revision::TextDisplay::Insert::Color::isReadOnly());
+ m_xDeletedLB->set_active(0);
+ m_xDeletedLB->set_sensitive(!officecfg::Office::Writer::Revision::TextDisplay::Delete::Color::isReadOnly());
+ m_xDeletedImg->set_visible(officecfg::Office::Writer::Revision::TextDisplay::Delete::Color::isReadOnly());
+ m_xChangedLB->set_active(0);
+ m_xChangedLB->set_sensitive(!officecfg::Office::Writer::Revision::TextDisplay::ChangedAttribute::Color::isReadOnly());
+ m_xChangedImg->set_visible(officecfg::Office::Writer::Revision::TextDisplay::ChangedAttribute::Color::isReadOnly());
+
+ lcl_FillRedlineAttrListBox(*m_xInsertLB, rInsertAttr, aInsertAttrMap, SAL_N_ELEMENTS(aInsertAttrMap));
+ lcl_FillRedlineAttrListBox(*m_xDeletedLB, rDeletedAttr, aDeletedAttrMap, SAL_N_ELEMENTS(aDeletedAttrMap));
+ lcl_FillRedlineAttrListBox(*m_xChangedLB, rChangedAttr, aChangedAttrMap, SAL_N_ELEMENTS(aChangedAttrMap));
+
+ sal_Int32 nPos = 0;
+ switch (pOpt->GetMarkAlignMode())
+ {
+ case text::HoriOrientation::NONE: nPos = 0; break;
+ case text::HoriOrientation::LEFT: nPos = 1; break;
+ case text::HoriOrientation::RIGHT: nPos = 2; break;
+ case text::HoriOrientation::OUTSIDE: nPos = 3; break;
+ case text::HoriOrientation::INSIDE: nPos = 4; break;
+ }
+ m_xMarkPosLB->set_active(nPos);
+ m_xMarkPosLB->set_sensitive(!officecfg::Office::Writer::Revision::LinesChanged::Mark::isReadOnly());
+ m_xMarkPosImg->set_visible(officecfg::Office::Writer::Revision::LinesChanged::Mark::isReadOnly());
+
+ // show settings in preview
+ AttribHdl(*m_xInsertLB);
+ ColorHdl(*m_xInsertColorLB);
+ AttribHdl(*m_xDeletedLB);
+ ColorHdl(*m_xInsertColorLB);
+ AttribHdl(*m_xChangedLB);
+ ColorHdl(*m_xChangedColorLB);
+
+ ChangedMaskPrev();
+}
+
+IMPL_LINK( SwRedlineOptionsTabPage, AttribHdl, weld::ComboBox&, rLB, void )
+{
+ SvxFontPrevWindow *pPrev = nullptr;
+ ColorListBox *pColorLB;
+
+ if (&rLB == m_xInsertLB.get())
+ {
+ pColorLB = m_xInsertColorLB.get();
+ pPrev = m_xInsertedPreviewWN.get();
+ }
+ else if (&rLB == m_xDeletedLB.get())
+ {
+ pColorLB = m_xDeletedColorLB.get();
+ pPrev = m_xDeletedPreviewWN.get();
+ }
+ else
+ {
+ pColorLB = m_xChangedColorLB.get();
+ pPrev = m_xChangedPreviewWN.get();
+ }
+
+ SvxFont& rFont = pPrev->GetFont();
+ SvxFont& rCJKFont = pPrev->GetCJKFont();
+
+ rFont.SetWeight(WEIGHT_NORMAL);
+ rCJKFont.SetWeight(WEIGHT_NORMAL);
+ rFont.SetItalic(ITALIC_NONE);
+ rCJKFont.SetItalic(ITALIC_NONE);
+ rFont.SetUnderline(LINESTYLE_NONE);
+ rCJKFont.SetUnderline(LINESTYLE_NONE);
+ rFont.SetStrikeout(STRIKEOUT_NONE);
+ rCJKFont.SetStrikeout(STRIKEOUT_NONE);
+ rFont.SetCaseMap(SvxCaseMap::NotMapped);
+ rCJKFont.SetCaseMap(SvxCaseMap::NotMapped);
+
+ Color aColor = pColorLB->GetSelectEntryColor();
+
+ if (aColor == COL_NONE_COLOR)
+ {
+ rFont.SetColor( COL_BLACK );
+ rCJKFont.SetColor( COL_BLACK );
+ }
+ else if (aColor == COL_TRANSPARENT)
+ {
+ rFont.SetColor( COL_RED );
+ rCJKFont.SetColor( COL_RED );
+ }
+ else
+ {
+ rFont.SetColor(aColor);
+ rCJKFont.SetColor(aColor);
+ }
+
+ sal_Int32 nPos = rLB.get_active();
+ if( nPos == -1)
+ nPos = 0;
+
+ CharAttr* pAttr = weld::fromId<CharAttr*>(rLB.get_id(nPos));
+ //switch off preview background color
+ pPrev->ResetColor();
+ switch (pAttr->nItemId)
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ rFont.SetWeight( static_cast<FontWeight>(pAttr->nAttr) );
+ rCJKFont.SetWeight( static_cast<FontWeight>(pAttr->nAttr) );
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ rFont.SetItalic( static_cast<FontItalic>(pAttr->nAttr) );
+ rCJKFont.SetItalic( static_cast<FontItalic>(pAttr->nAttr) );
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ rFont.SetUnderline( static_cast<FontLineStyle>(pAttr->nAttr) );
+ rCJKFont.SetUnderline( static_cast<FontLineStyle>(pAttr->nAttr) );
+ break;
+
+ case SID_ATTR_CHAR_STRIKEOUT:
+ rFont.SetStrikeout( static_cast<FontStrikeout>(pAttr->nAttr) );
+ rCJKFont.SetStrikeout( static_cast<FontStrikeout>(pAttr->nAttr) );
+ break;
+
+ case SID_ATTR_CHAR_CASEMAP:
+ rFont.SetCaseMap( static_cast<SvxCaseMap>(pAttr->nAttr) );
+ rCJKFont.SetCaseMap( static_cast<SvxCaseMap>(pAttr->nAttr) );
+ break;
+
+ case SID_ATTR_BRUSH:
+ {
+ Color aBgColor = pColorLB->GetSelectEntryColor();
+ if (aBgColor != COL_NONE_COLOR)
+ pPrev->SetColor(aBgColor);
+ else
+ pPrev->SetColor(COL_LIGHTGRAY);
+ rFont.SetColor( COL_BLACK );
+ rCJKFont.SetColor( COL_BLACK );
+ }
+ break;
+ }
+
+ pPrev->Invalidate();
+}
+
+IMPL_LINK(SwRedlineOptionsTabPage, ColorHdl, ColorListBox&, rListBox, void)
+{
+ ColorListBox* pColorLB = &rListBox;
+ SvxFontPrevWindow *pPrev = nullptr;
+ weld::ComboBox* pLB;
+
+ if (pColorLB == m_xInsertColorLB.get())
+ {
+ pLB = m_xInsertLB.get();
+ pPrev = m_xInsertedPreviewWN.get();
+ }
+ else if (pColorLB == m_xDeletedColorLB.get())
+ {
+ pLB = m_xDeletedLB.get();
+ pPrev = m_xDeletedPreviewWN.get();
+ }
+ else
+ {
+ pLB = m_xChangedLB.get();
+ pPrev = m_xChangedPreviewWN.get();
+ }
+
+ SvxFont& rFont = pPrev->GetFont();
+ SvxFont& rCJKFont = pPrev->GetCJKFont();
+ sal_Int32 nPos = pLB->get_active();
+ if( nPos == -1)
+ nPos = 0;
+
+ CharAttr* pAttr = weld::fromId<CharAttr*>(pLB->get_id(nPos));
+
+ if( pAttr->nItemId == SID_ATTR_BRUSH )
+ {
+ rFont.SetColor( COL_BLACK );
+ rCJKFont.SetColor( COL_BLACK );
+
+ Color aBgColor = pColorLB->GetSelectEntryColor();
+ if (aBgColor != COL_NONE_COLOR)
+ pPrev->SetColor(aBgColor);
+ else
+ pPrev->SetColor(COL_LIGHTGRAY);
+ }
+ else
+ {
+ Color aColor = pColorLB->GetSelectEntryColor();
+
+ if (aColor == COL_NONE_COLOR)
+ {
+ rFont.SetColor( COL_BLACK );
+ rCJKFont.SetColor( COL_BLACK );
+ }
+ else if (aColor == COL_TRANSPARENT)
+ {
+ rFont.SetColor( COL_RED );
+ rCJKFont.SetColor( COL_RED );
+ }
+ else
+ {
+ rFont.SetColor(aColor);
+ rCJKFont.SetColor(aColor);
+ }
+ }
+
+ pPrev->Invalidate();
+}
+
+void SwRedlineOptionsTabPage::ChangedMaskPrev()
+{
+ m_xMarkPreviewWN->SetMarkPos(m_xMarkPosLB->get_active());
+ m_xMarkPreviewWN->SetColor(m_xMarkColorLB->GetSelectEntryColor());
+
+ m_xMarkPreviewWN->Invalidate();
+}
+
+IMPL_LINK_NOARG(SwRedlineOptionsTabPage, ChangedMaskPrevHdl, weld::ComboBox&, void)
+{
+ ChangedMaskPrev();
+}
+
+IMPL_LINK_NOARG(SwRedlineOptionsTabPage, ChangedMaskColorPrevHdl, ColorListBox&, void)
+{
+ ChangedMaskPrev();
+}
+
+void SwRedlineOptionsTabPage::InitFontStyle(SvxFontPrevWindow& rExampleWin, const OUString& rText)
+{
+ const AllSettings& rAllSettings = Application::GetSettings();
+ LanguageType eLangType = rAllSettings.GetUILanguageTag().getLanguageType();
+ Color aBackCol( rAllSettings.GetStyleSettings().GetWindowColor() );
+ SvxFont& rFont = rExampleWin.GetFont();
+ SvxFont& rCJKFont = rExampleWin.GetCJKFont();
+ SvxFont& rCTLFont = rExampleWin.GetCTLFont();
+
+ OutputDevice& rDevice = rExampleWin.GetDrawingArea()->get_ref_device();
+
+ vcl::Font aFont( OutputDevice::GetDefaultFont( DefaultFontType::SERIF, eLangType,
+ GetDefaultFontFlags::OnlyOne, &rDevice ) );
+ vcl::Font aCJKFont( OutputDevice::GetDefaultFont( DefaultFontType::CJK_TEXT, eLangType,
+ GetDefaultFontFlags::OnlyOne, &rDevice ) );
+ vcl::Font aCTLFont( OutputDevice::GetDefaultFont( DefaultFontType::CTL_TEXT, eLangType,
+ GetDefaultFontFlags::OnlyOne, &rDevice ) );
+ const Size aDefSize( 0, 12 );
+ aFont.SetFontSize( aDefSize );
+ aCJKFont.SetFontSize( aDefSize );
+ aCTLFont.SetFontSize( aDefSize );
+
+ aFont.SetFillColor( aBackCol );
+ aCJKFont.SetFillColor( aBackCol );
+ aCTLFont.SetFillColor( aBackCol );
+
+ aFont.SetWeight( WEIGHT_NORMAL );
+ aCJKFont.SetWeight( WEIGHT_NORMAL );
+ aCTLFont.SetWeight( WEIGHT_NORMAL );
+
+ rFont = aFont;
+ rCJKFont = aCJKFont;
+ rCTLFont = aCTLFont;
+
+ const Size aNewSize( 0, rExampleWin.GetOutputSizePixel().Height() * 2 / 3 );
+ rFont.SetFontSize( aNewSize );
+ rCJKFont.SetFontSize( aNewSize );
+
+ rExampleWin.SetFont( rFont, rCJKFont,rCTLFont );
+ rExampleWin.SetPreviewText(rText);
+}
+
+SwCompareOptionsTabPage::SwCompareOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/optcomparison.ui", "OptComparison", &rSet)
+ , m_xAutoRB(m_xBuilder->weld_radio_button("auto"))
+ , m_xWordRB(m_xBuilder->weld_radio_button("byword"))
+ , m_xCharRB(m_xBuilder->weld_radio_button("bycharacter"))
+ , m_xCompareModeImg(m_xBuilder->weld_widget("lockcomparemode"))
+ , m_xRsidCB(m_xBuilder->weld_check_button("useRSID"))
+ , m_xRsidImg(m_xBuilder->weld_widget("lockuseRSID"))
+ , m_xIgnoreCB(m_xBuilder->weld_check_button("ignore"))
+ , m_xIgnoreImg(m_xBuilder->weld_widget("lockignore"))
+ , m_xLenNF(m_xBuilder->weld_spin_button("ignorelen"))
+ , m_xLenImg(m_xBuilder->weld_widget("lockignorelen"))
+ , m_xStoreRsidCB(m_xBuilder->weld_check_button("storeRSID"))
+ , m_xStoreRsidImg(m_xBuilder->weld_widget("lockstoreRSID"))
+{
+ Link<weld::Toggleable&,void> aLnk( LINK( this, SwCompareOptionsTabPage, ComparisonHdl ) );
+ m_xAutoRB->connect_toggled( aLnk );
+ m_xWordRB->connect_toggled( aLnk );
+ m_xCharRB->connect_toggled( aLnk );
+
+ m_xIgnoreCB->connect_toggled( LINK( this, SwCompareOptionsTabPage, IgnoreHdl) );
+}
+
+SwCompareOptionsTabPage::~SwCompareOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwCompareOptionsTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SwCompareOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwCompareOptionsTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString labels[] = { "label1", "setting" };
+
+ for (const auto& label : labels)
+ {
+ if (const auto& pString = m_xBuilder->weld_label(label))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString checkButton[] = { "useRSID", "ignore", "storeRSID" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ OUString radioButton[] = { "auto", "byword", "bycharacter" };
+
+ for (const auto& radio : radioButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_radio_button(radio))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwCompareOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bRet = false;
+ SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
+
+ if( m_xAutoRB->get_state_changed_from_saved() ||
+ m_xWordRB->get_state_changed_from_saved() ||
+ m_xCharRB->get_state_changed_from_saved() )
+ {
+ SwCompareMode eCmpMode = SwCompareMode::Auto;
+
+ if ( m_xAutoRB->get_active() ) eCmpMode = SwCompareMode::Auto;
+ if ( m_xWordRB->get_active() ) eCmpMode = SwCompareMode::ByWord;
+ if ( m_xCharRB->get_active() ) eCmpMode = SwCompareMode::ByChar;
+
+ pOpt->SetCompareMode( eCmpMode );
+ bRet = true;
+ }
+
+ if( m_xRsidCB->get_state_changed_from_saved() )
+ {
+ pOpt->SetUseRsid( m_xRsidCB->get_active() );
+ bRet = true;
+ }
+
+ if( m_xIgnoreCB->get_state_changed_from_saved() )
+ {
+ pOpt->SetIgnorePieces( m_xIgnoreCB->get_active() );
+ bRet = true;
+ }
+
+ if( m_xLenNF->get_value_changed_from_saved() )
+ {
+ pOpt->SetPieceLen( m_xLenNF->get_value() );
+ bRet = true;
+ }
+
+ if (m_xStoreRsidCB->get_state_changed_from_saved())
+ {
+ pOpt->SetStoreRsid(m_xStoreRsidCB->get_active());
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+void SwCompareOptionsTabPage::Reset( const SfxItemSet* )
+{
+ SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
+
+ SwCompareMode eCmpMode = pOpt->GetCompareMode();
+ if( eCmpMode == SwCompareMode::Auto )
+ {
+ m_xAutoRB->set_active(true);
+ m_xRsidCB->set_sensitive(false);
+ m_xIgnoreCB->set_sensitive(false);
+ m_xLenNF->set_sensitive(false);
+ }
+ else if( eCmpMode == SwCompareMode::ByWord )
+ {
+ m_xWordRB->set_active(true);
+ m_xRsidCB->set_sensitive(true);
+ m_xIgnoreCB->set_sensitive(true);
+ m_xLenNF->set_sensitive(true);
+ }
+ else if( eCmpMode == SwCompareMode::ByChar)
+ {
+ m_xCharRB->set_active(true);
+ m_xRsidCB->set_sensitive(true);
+ m_xIgnoreCB->set_sensitive(true);
+ m_xLenNF->set_sensitive(true);
+ }
+
+ if (officecfg::Office::Writer::Comparison::Mode::isReadOnly())
+ {
+ m_xAutoRB->set_sensitive(false);
+ m_xWordRB->set_sensitive(false);
+ m_xCharRB->set_sensitive(false);
+ m_xCompareModeImg->set_visible(true);
+ }
+
+ m_xAutoRB->save_state();
+ m_xWordRB->save_state();
+ m_xCharRB->save_state();
+
+ m_xRsidCB->set_active( pOpt->IsUseRsid() );
+ if (officecfg::Office::Writer::Comparison::UseRSID::isReadOnly())
+ {
+ m_xRsidCB->set_sensitive(false);
+ m_xRsidImg->set_visible(true);
+ }
+ m_xRsidCB->save_state();
+
+ m_xIgnoreCB->set_active( pOpt->IsIgnorePieces() );
+ if (officecfg::Office::Writer::Comparison::IgnorePieces::isReadOnly())
+ {
+ m_xIgnoreCB->set_sensitive(false);
+ m_xIgnoreImg->set_visible(true);
+ }
+ m_xIgnoreCB->save_state();
+
+ m_xLenNF->set_sensitive( m_xIgnoreCB->get_active() && eCmpMode != SwCompareMode::Auto );
+
+ m_xLenNF->set_value( pOpt->GetPieceLen() );
+ if (officecfg::Office::Writer::Comparison::IgnoreLength::isReadOnly())
+ {
+ m_xLenNF->set_sensitive(false);
+ m_xLenImg->set_visible(true);
+ }
+ m_xLenNF->save_value();
+
+ m_xStoreRsidCB->set_active(pOpt->IsStoreRsid());
+ m_xStoreRsidCB->set_sensitive(!officecfg::Office::Writer::Comparison::StoreRSID::isReadOnly());
+ m_xStoreRsidImg->set_visible(officecfg::Office::Writer::Comparison::StoreRSID::isReadOnly());
+ m_xStoreRsidCB->save_state();
+}
+
+IMPL_LINK(SwCompareOptionsTabPage, ComparisonHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ bool bChecked = !m_xAutoRB->get_active();
+ m_xRsidCB->set_sensitive( bChecked );
+ m_xIgnoreCB->set_sensitive( bChecked );
+ m_xLenNF->set_sensitive( bChecked && m_xIgnoreCB->get_active() );
+}
+
+IMPL_LINK_NOARG(SwCompareOptionsTabPage, IgnoreHdl, weld::Toggleable&, void)
+{
+ m_xLenNF->set_sensitive(m_xIgnoreCB->get_active());
+}
+
+#ifdef DBG_UTIL
+
+SwTestTabPage::SwTestTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/opttestpage.ui", "OptTestPage", &rCoreSet)
+ , m_bAttrModified( false )
+ , m_xTest1CBox(m_xBuilder->weld_check_button("unused"))
+ , m_xTest2CBox(m_xBuilder->weld_check_button("dynamic"))
+ , m_xTest3CBox(m_xBuilder->weld_check_button("nocalm"))
+ , m_xTest4CBox(m_xBuilder->weld_check_button("wysiwygdbg"))
+ , m_xTest5CBox(m_xBuilder->weld_check_button("noidle"))
+ , m_xTest6CBox(m_xBuilder->weld_check_button("noscreenadj"))
+ , m_xTest7CBox(m_xBuilder->weld_check_button("winformat"))
+ , m_xTest8CBox(m_xBuilder->weld_check_button("noscroll"))
+ , m_xTest9CBox(m_xBuilder->weld_check_button("DrawingLayerNotLoading"))
+ , m_xTest10CBox(m_xBuilder->weld_check_button("AutoFormatByInput"))
+{
+ Init();
+}
+
+SwTestTabPage::~SwTestTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwTestTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SwTestTabPage>(pPage, pController, *rAttrSet);
+}
+
+OUString SwTestTabPage::GetAllStrings()
+{
+ OUString sAllStrings;
+ OUString checkButton[] = { "unused", "dynamic", "nocalm",
+ "wysiwygdbg", "noidle", "noscreenadj",
+ "winformat", "noscroll", "DrawingLayerNotLoading",
+ "AutoFormatByInput" };
+
+ for (const auto& check : checkButton)
+ {
+ if (const auto& pString = m_xBuilder->weld_check_button(check))
+ sAllStrings += pString->get_label() + " ";
+ }
+
+ if (const auto& pString = m_xBuilder->weld_label("label1"))
+ sAllStrings += pString->get_label() + " ";
+
+ return sAllStrings.replaceAll("_", "");
+}
+
+bool SwTestTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+
+ if ( m_bAttrModified )
+ {
+ SwTestItem aTestItem;
+ aTestItem.m_bTest1=m_xTest1CBox->get_active();
+ aTestItem.m_bTest2=m_xTest2CBox->get_active();
+ aTestItem.m_bTest3=m_xTest3CBox->get_active();
+ aTestItem.m_bTest4=m_xTest4CBox->get_active();
+ aTestItem.m_bTest5=m_xTest5CBox->get_active();
+ aTestItem.m_bTest6=m_xTest6CBox->get_active();
+ aTestItem.m_bTest7=m_xTest7CBox->get_active();
+ aTestItem.m_bTest8=m_xTest8CBox->get_active();
+ aTestItem.m_bTest9=m_xTest9CBox->get_active();
+ aTestItem.m_bTest10=m_xTest10CBox->get_active();
+ rCoreSet->Put(aTestItem);
+ }
+ return m_bAttrModified;
+}
+
+void SwTestTabPage::Reset( const SfxItemSet* )
+{
+ const SfxItemSet& rSet = GetItemSet();
+ const SwTestItem* pTestAttr = rSet.GetItemIfSet( FN_PARAM_SWTEST, false );
+ if(!pTestAttr)
+ return;
+
+ m_xTest1CBox->set_active(pTestAttr->m_bTest1);
+ m_xTest2CBox->set_active(pTestAttr->m_bTest2);
+ m_xTest3CBox->set_active(pTestAttr->m_bTest3);
+ m_xTest4CBox->set_active(pTestAttr->m_bTest4);
+ m_xTest5CBox->set_active(pTestAttr->m_bTest5);
+ m_xTest6CBox->set_active(pTestAttr->m_bTest6);
+ m_xTest7CBox->set_active(pTestAttr->m_bTest7);
+ m_xTest8CBox->set_active(pTestAttr->m_bTest8);
+ m_xTest9CBox->set_active(pTestAttr->m_bTest9);
+ m_xTest10CBox->set_active(pTestAttr->m_bTest10);
+}
+
+void SwTestTabPage::Init()
+{
+ // handler
+ Link<weld::Toggleable&,void> aLk = LINK( this, SwTestTabPage, AutoClickHdl );
+ m_xTest1CBox->connect_toggled( aLk );
+ m_xTest2CBox->connect_toggled( aLk );
+ m_xTest3CBox->connect_toggled( aLk );
+ m_xTest4CBox->connect_toggled( aLk );
+ m_xTest5CBox->connect_toggled( aLk );
+ m_xTest6CBox->connect_toggled( aLk );
+ m_xTest7CBox->connect_toggled( aLk );
+ m_xTest8CBox->connect_toggled( aLk );
+ m_xTest9CBox->connect_toggled( aLk );
+ m_xTest10CBox->connect_toggled( aLk );
+}
+
+IMPL_LINK_NOARG(SwTestTabPage, AutoClickHdl, weld::Toggleable&, void)
+{
+ m_bAttrModified = true;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/addresslistdialog.cxx b/sw/source/ui/dbui/addresslistdialog.cxx
new file mode 100644
index 0000000000..9cb433974b
--- /dev/null
+++ b/sw/source/ui/dbui/addresslistdialog.cxx
@@ -0,0 +1,641 @@
+/* -*- 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 <swtypes.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include "addresslistdialog.hxx"
+#include "selectdbtabledialog.hxx"
+#include "createaddresslistdialog.hxx"
+#include <mailmergewizard.hxx>
+#include <mmconfigitem.hxx>
+#include "mmaddressblockpage.hxx"
+#include <dbmgr.hxx>
+#include <dbconfig.hxx>
+#include <unotools/tempfile.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/types.hxx>
+#include <com/sun/star/sdbc/XCloseable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/XCompletedConnection.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/FilterDialog.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <o3tl/safeint.hxx>
+#include <swunohelper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <svl/urihelper.hxx>
+#include <strings.hrc>
+#include <view.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ui::dialogs;
+
+struct AddressUserData_Impl
+{
+ uno::Reference<XDataSource> xSource;
+ SharedConnection xConnection;
+ uno::Reference< XColumnsSupplier> xColumnsSupplier;
+ uno::Reference< sdbc::XResultSet> xResultSet;
+ OUString sFilter;
+ OUString sURL; // data is editable
+ sal_Int32 nCommandType;
+ sal_Int32 nTableAndQueryCount;
+ AddressUserData_Impl() :
+ nCommandType(0),
+ nTableAndQueryCount(-1)
+ {}
+};
+
+static OUString lcl_getFlatURL( uno::Reference<beans::XPropertySet> const & xSourceProperties )
+{
+ if(xSourceProperties.is())
+ {
+ OUString sDBURL;
+ xSourceProperties->getPropertyValue("URL") >>= sDBURL;
+ if (sDBURL.startsWith("sdbc:flat:"))
+ {
+ uno::Sequence<OUString> aFilters;
+ xSourceProperties->getPropertyValue("TableFilter") >>= aFilters;
+ uno::Sequence<PropertyValue> aInfo;
+ xSourceProperties->getPropertyValue("Info") >>= aInfo;
+ if(aFilters.getLength() == 1 && aInfo.hasElements() )
+ {
+ OUString sExtension;
+ OUString sCharSet;
+ for(const auto& rInfo : std::as_const(aInfo))
+ {
+ if(rInfo.Name == "Extension")
+ rInfo.Value >>= sExtension;
+ else if(rInfo.Name == "CharSet")
+ rInfo.Value >>= sCharSet;
+ }
+ if (sCharSet=="UTF-8")
+ {
+ //#i97577# at this point the 'URL' can also be a file name!
+ return URIHelper::SmartRel2Abs( INetURLObject(), sDBURL.copy(10) )
+ + "/" + aFilters[0] + "." + sExtension;
+ }
+ }
+ }
+ }
+ return OUString();
+}
+
+SwAddressListDialog::SwAddressListDialog(SwMailMergeAddressBlockPage* pParent)
+ : SfxDialogController(pParent->GetWizard()->getDialog(), "modules/swriter/ui/selectaddressdialog.ui", "SelectAddressDialog")
+ , m_bInSelectHdl(false)
+ , m_pAddressPage(pParent)
+ , m_xDescriptionFI(m_xBuilder->weld_label("desc"))
+ , m_xConnecting(m_xBuilder->weld_label("connecting"))
+ , m_xListLB(m_xBuilder->weld_tree_view("sources"))
+ , m_xLoadListPB(m_xBuilder->weld_button("add"))
+ , m_xRemovePB(m_xBuilder->weld_button("remove"))
+ , m_xCreateListPB(m_xBuilder->weld_button("create"))
+ , m_xFilterPB(m_xBuilder->weld_button("filter"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+ , m_xTablePB(m_xBuilder->weld_button("changetable"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xIter(m_xListLB->make_iterator())
+{
+ m_sConnecting = m_xConnecting->get_label();
+
+ const OUString sTemp(m_xDescriptionFI->get_label()
+ .replaceFirst("%1", m_xLoadListPB->strip_mnemonic(m_xLoadListPB->get_label()))
+ .replaceFirst("%2", m_xCreateListPB->strip_mnemonic(m_xCreateListPB->get_label())));
+ m_xDescriptionFI->set_label(sTemp);
+ m_xFilterPB->connect_clicked( LINK( this, SwAddressListDialog, FilterHdl_Impl ));
+ m_xLoadListPB->connect_clicked( LINK( this, SwAddressListDialog, LoadHdl_Impl ));
+ m_xRemovePB->connect_clicked( LINK(this, SwAddressListDialog, RemoveHdl_Impl ));
+ m_xCreateListPB->connect_clicked( LINK( this, SwAddressListDialog,CreateHdl_Impl ));
+ m_xEditPB->connect_clicked(LINK( this, SwAddressListDialog, EditHdl_Impl));
+ m_xTablePB->connect_clicked(LINK( this, SwAddressListDialog, TableSelectHdl_Impl));
+
+ m_xListLB->set_size_request(m_xListLB->get_approximate_digit_width() * 52,
+ m_xListLB->get_height_rows(9));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xListLB->get_approximate_digit_width() * 26)
+ };
+ m_xListLB->set_column_fixed_widths(aWidths);
+
+ m_xListLB->make_sorted();
+ m_xOK->connect_clicked(LINK(this, SwAddressListDialog, OKHdl_Impl));
+
+ uno::Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+ m_xDBContext = DatabaseContext::create(xContext);
+
+ SwMailMergeConfigItem& rConfigItem = m_pAddressPage->GetWizard()->GetConfigItem();
+ const SwDBData& rCurrentData = rConfigItem.GetCurrentDBData();
+
+ bool bEnableEdit = false;
+ bool bEnableOK = true;
+ bool bSelected = false;
+ m_xListLB->unselect_all();
+
+ SwDBConfig aDb;
+ const OUString sBibliography = aDb.GetBibliographySource().sDataSource;
+ const uno::Sequence< OUString> aNames = m_xDBContext->getElementNames();
+ for(const OUString& rName : aNames)
+ {
+ if ( rName == sBibliography )
+ continue;
+ m_xListLB->append(m_xIter.get());
+ m_xListLB->set_text(*m_xIter, rName, 0);
+ m_aUserData.emplace_back(new AddressUserData_Impl);
+ AddressUserData_Impl* pUserData = m_aUserData.back().get();
+ m_xListLB->set_id(*m_xIter, weld::toId(pUserData));
+ if (rName == rCurrentData.sDataSource)
+ {
+ m_xListLB->select(*m_xIter);
+ bSelected = true;
+ m_xListLB->set_text(*m_xIter, rCurrentData.sCommand, 1);
+ pUserData->nCommandType = rCurrentData.nCommandType;
+ pUserData->xSource = rConfigItem.GetSource();
+ pUserData->xConnection = rConfigItem.GetConnection();
+ pUserData->xColumnsSupplier = rConfigItem.GetColumnsSupplier();
+ pUserData->xResultSet = rConfigItem.GetResultSet();
+ pUserData->sFilter = rConfigItem.GetFilter();
+ //is the data source editable (csv, Unicode, single table)
+ uno::Reference<beans::XPropertySet> xSourceProperties;
+ try
+ {
+ m_xDBContext->getByName(rName) >>= xSourceProperties;
+ pUserData->sURL = lcl_getFlatURL( xSourceProperties );
+ bEnableEdit = !pUserData->sURL.isEmpty() &&
+ SWUnoHelper::UCB_IsFile( pUserData->sURL ) && //#i97577#
+ !SWUnoHelper::UCB_IsReadOnlyFileName( pUserData->sURL );
+ }
+ catch (const uno::Exception&)
+ {
+ bEnableOK = false;
+ }
+ m_aDBData = rCurrentData;
+ }
+ }
+
+ bool bHasChildren = m_xListLB->n_children() > 0;
+ if (bHasChildren && !bSelected)
+ m_xListLB->select(0); // select the first entry if nothing else selected
+ m_xOK->set_sensitive(bHasChildren && bEnableOK);
+ m_xEditPB->set_sensitive(bEnableEdit);
+ m_xRemovePB->set_sensitive(m_xListLB->n_children() > 0);
+ m_xFilterPB->set_sensitive(m_xListLB->n_children() > 0);
+ m_xTablePB->set_sensitive(m_xListLB->n_children() > 0);
+ m_xListLB->connect_changed(LINK(this, SwAddressListDialog, ListBoxSelectHdl_Impl));
+ TableSelectHdl(nullptr);
+}
+
+SwAddressListDialog::~SwAddressListDialog()
+{
+}
+
+IMPL_LINK_NOARG(SwAddressListDialog, FilterHdl_Impl, weld::Button&, void)
+{
+ int nSelect = m_xListLB->get_selected_index();
+ uno::Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
+ if (nSelect == -1)
+ return;
+
+ const OUString sCommand = m_xListLB->get_text(nSelect, 1);
+ if (sCommand.isEmpty())
+ return;
+
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ if (!pUserData->xConnection.is() )
+ return;
+
+ try
+ {
+ uno::Reference<lang::XMultiServiceFactory> xConnectFactory(pUserData->xConnection, UNO_QUERY_THROW);
+ uno::Reference<XSingleSelectQueryComposer> xComposer(
+ xConnectFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"), UNO_QUERY_THROW);
+
+ uno::Reference<XRowSet> xRowSet(
+ xMgr->createInstance("com.sun.star.sdb.RowSet"), UNO_QUERY);
+ uno::Reference<XPropertySet> xRowProperties(xRowSet, UNO_QUERY);
+ xRowProperties->setPropertyValue("DataSourceName",
+ Any(m_xListLB->get_text(nSelect, 0)));
+ xRowProperties->setPropertyValue("Command", Any(sCommand));
+ xRowProperties->setPropertyValue("CommandType", Any(pUserData->nCommandType));
+ xRowProperties->setPropertyValue("ActiveConnection", Any(pUserData->xConnection.getTyped()));
+ xRowSet->execute();
+
+ OUString sQuery;
+ xRowProperties->getPropertyValue("ActiveCommand")>>= sQuery;
+ xComposer->setQuery(sQuery);
+ if(!pUserData->sFilter.isEmpty())
+ xComposer->setFilter(pUserData->sFilter);
+
+ uno::Reference< XExecutableDialog> xDialog = sdb::FilterDialog::createWithQuery( comphelper::getComponentContext(xMgr),
+ xComposer,xRowSet, uno::Reference<awt::XWindow>() );
+
+ if ( RET_OK == xDialog->execute() )
+ {
+ weld::WaitObject aWait(m_xDialog.get());
+ pUserData->sFilter = xComposer->getFilter();
+ }
+ ::comphelper::disposeComponent(xRowSet);
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "exception caught in SwAddressListDialog::FilterHdl_Impl");
+ }
+}
+
+IMPL_LINK_NOARG(SwAddressListDialog, LoadHdl_Impl, weld::Button&, void)
+{
+ SwView* pView = m_pAddressPage->GetWizard()->GetSwView();
+
+ const OUString sNewSource = SwDBManager::LoadAndRegisterDataSource(m_xDialog.get(), pView ? pView->GetDocShell() : nullptr);
+ if(!sNewSource.isEmpty())
+ {
+ m_xListLB->append(m_xIter.get());
+ m_xListLB->set_text(*m_xIter, sNewSource, 0);
+ m_aUserData.emplace_back(new AddressUserData_Impl);
+ AddressUserData_Impl* pUserData = m_aUserData.back().get();
+ m_xListLB->set_id(*m_xIter, weld::toId(pUserData));
+ m_xListLB->select(*m_xIter);
+ ListBoxSelectHdl_Impl(*m_xListLB);
+ m_xRemovePB->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SwAddressListDialog, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nEntry = m_xListLB->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(getDialog(),
+ VclMessageType::Question, VclButtonsType::YesNo, SwResId(ST_DELETE_CONFIRM)));
+ if (xQuery->run() != RET_YES)
+ return;
+
+ // Remove data source connection
+ SwDBManager::RevokeDataSource(m_xListLB->get_selected_text());
+ // Remove item from the list
+ m_xListLB->remove(nEntry);
+ // If this was the last item, disable the Remove & Edit buttons and enable Create
+ if (m_xListLB->n_children() < 1 )
+ {
+ m_xRemovePB->set_sensitive(false);
+ m_xEditPB->set_sensitive(false);
+ m_xFilterPB->set_sensitive(false);
+ m_xCreateListPB->set_sensitive(true);
+ }
+
+
+}
+
+IMPL_LINK_NOARG(SwAddressListDialog, CreateHdl_Impl, weld::Button&, void)
+{
+ SwCreateAddressListDialog aDlg(m_xDialog.get(), /*sInputURL*/OUString(), m_pAddressPage->GetWizard()->GetConfigItem());
+ if (RET_OK != aDlg.run())
+ return;
+
+ //register the URL a new datasource
+ const OUString sURL = aDlg.GetURL();
+ try
+ {
+ uno::Reference<XInterface> xNewInstance = m_xDBContext->createInstance();
+ INetURLObject aURL( sURL );
+ const OUString sNewName = aURL.getBase();
+ //find a unique name if sNewName already exists
+ OUString sFind(sNewName);
+ sal_Int32 nIndex = 0;
+ while(m_xDBContext->hasByName(sFind))
+ {
+ sFind = sNewName + OUString::number(++nIndex);
+ }
+ uno::Reference<XPropertySet> xDataProperties(xNewInstance, UNO_QUERY);
+
+ //only the 'path' has to be added
+ INetURLObject aTempURL(aURL);
+ aTempURL.removeSegment();
+ aTempURL.removeFinalSlash();
+ const OUString sDBURL("sdbc:flat:" + aTempURL.GetMainURL(INetURLObject::DecodeMechanism::NONE));
+ xDataProperties->setPropertyValue("URL", Any(sDBURL));
+ //set the filter to the file name without extension
+ uno::Sequence<OUString> aFilters { sNewName };
+ xDataProperties->setPropertyValue("TableFilter", Any(aFilters));
+
+ uno::Sequence<PropertyValue> aInfo
+ {
+ comphelper::makePropertyValue("FieldDelimiter", OUString('\t')),
+ comphelper::makePropertyValue("StringDelimiter", OUString('"')),
+ comphelper::makePropertyValue("Extension", aURL.getExtension()), //"csv
+ comphelper::makePropertyValue("CharSet", OUString("UTF-8"))
+ };
+ xDataProperties->setPropertyValue("Info", Any(aInfo));
+
+ uno::Reference<sdb::XDocumentDataSource> xDS(xNewInstance, UNO_QUERY_THROW);
+ uno::Reference<frame::XStorable> xStore(xDS->getDatabaseDocument(), UNO_QUERY_THROW);
+ OUString sTmpName;
+ {
+ OUString sHomePath(SvtPathOptions().GetWorkPath());
+ utl::TempFileNamed aTempFile(sFind, true, u".odb", &sHomePath);
+ aTempFile.EnableKillingFile();
+ sTmpName = aTempFile.GetURL();
+ }
+ xStore->storeAsURL(sTmpName, Sequence< PropertyValue >());
+
+ m_xDBContext->registerObject( sFind, xNewInstance );
+ //now insert the new source into the ListBox
+ m_xListLB->append(m_xIter.get());
+ m_xListLB->set_text(*m_xIter, sFind, 0);
+ m_xListLB->set_text(*m_xIter, aFilters[0], 1);
+ m_aUserData.emplace_back(new AddressUserData_Impl);
+ AddressUserData_Impl* pUserData = m_aUserData.back().get();
+ m_xListLB->set_id(*m_xIter, weld::toId(pUserData));
+ m_xListLB->select(*m_xIter);
+ ListBoxSelectHdl_Impl(*m_xListLB);
+ m_xCreateListPB->set_sensitive(false);
+ m_xRemovePB->set_sensitive(true);
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+IMPL_LINK_NOARG(SwAddressListDialog, EditHdl_Impl, weld::Button&, void)
+{
+ int nEntry = m_xListLB->get_selected_index();
+ AddressUserData_Impl* pUserData = nEntry != -1 ? weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nEntry)) : nullptr;
+ if (!pUserData || pUserData->sURL.isEmpty())
+ return;
+
+ if(pUserData->xResultSet.is())
+ {
+ SwMailMergeConfigItem& rConfigItem = m_pAddressPage->GetWizard()->GetConfigItem();
+ if(rConfigItem.GetResultSet() != pUserData->xResultSet)
+ ::comphelper::disposeComponent( pUserData->xResultSet );
+ pUserData->xResultSet = nullptr;
+
+ rConfigItem.DisposeResultSet();
+ }
+ pUserData->xSource.clear();
+ pUserData->xColumnsSupplier.clear();
+ pUserData->xConnection.clear();
+ // will automatically close if it was the las reference
+ SwCreateAddressListDialog aDlg(m_xDialog.get(), pUserData->sURL,
+ m_pAddressPage->GetWizard()->GetConfigItem());
+ aDlg.run();
+};
+
+IMPL_LINK_NOARG(SwAddressListDialog, ListBoxSelectHdl_Impl, weld::TreeView&, void)
+{
+ int nSelect = m_xListLB->get_selected_index();
+ Application::PostUserEvent( LINK( this, SwAddressListDialog,
+ StaticListBoxSelectHdl_Impl ), reinterpret_cast<void*>(nSelect) );
+}
+
+IMPL_LINK(SwAddressListDialog, StaticListBoxSelectHdl_Impl, void*, p, void)
+{
+ int nSelect = reinterpret_cast<sal_IntPtr>(p);
+ //prevent nested calls of the select handler
+ if (m_bInSelectHdl)
+ return;
+ weld::WaitObject aWait(m_xDialog.get());
+ m_bInSelectHdl = true;
+ AddressUserData_Impl* pUserData = nullptr;
+ if (nSelect != -1)
+ {
+ const OUString sTable(m_xListLB->get_text(nSelect, 1));
+ if (sTable.isEmpty())
+ {
+ m_xListLB->set_text(nSelect, m_sConnecting, 1);
+ }
+
+ pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ if(pUserData->nTableAndQueryCount > 1 || pUserData->nTableAndQueryCount == -1)
+ {
+ DetectTablesAndQueries(nSelect, sTable.isEmpty());
+ }
+ else
+ {
+ //otherwise set the selected db-data
+ m_aDBData.sDataSource = m_xListLB->get_text(nSelect, 0);
+ m_aDBData.sCommand = m_xListLB->get_text(nSelect, 1);
+ m_aDBData.nCommandType = pUserData->nCommandType;
+ m_xOK->set_sensitive(true);
+ }
+ if (m_xListLB->get_text(nSelect, 1) == m_sConnecting)
+ m_xListLB->set_text(nSelect, OUString(), 1);
+ }
+ m_xEditPB->set_sensitive(pUserData && !pUserData->sURL.isEmpty() &&
+ SWUnoHelper::UCB_IsFile( pUserData->sURL ) && //#i97577#
+ !SWUnoHelper::UCB_IsReadOnlyFileName( pUserData->sURL ) );
+ m_bInSelectHdl = false;
+}
+
+// detect the number of tables for a data source
+// if only one is available then set it at the entry
+void SwAddressListDialog::DetectTablesAndQueries(
+ int nSelect,
+ bool bWidthDialog)
+{
+ try
+ {
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ uno::Reference<XCompletedConnection> xComplConnection;
+ if(!pUserData->xConnection.is())
+ {
+ m_aDBData.sDataSource = m_xListLB->get_text(nSelect, 0);
+ m_xDBContext->getByName(m_aDBData.sDataSource) >>= xComplConnection;
+ pUserData->xSource.set(xComplConnection, UNO_QUERY);
+
+ uno::Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference< XInteractionHandler > xHandler = InteractionHandler::createWithParent(xContext, nullptr);
+ pUserData->xConnection = SharedConnection( xComplConnection->connectWithCompletion( xHandler ) );
+ }
+ if(pUserData->xConnection.is())
+ {
+ sal_Int32 nTables = 0;
+ uno::Sequence<OUString> aTables;
+ uno::Sequence<OUString> aQueries;
+ uno::Reference<XTablesSupplier> xTSupplier(pUserData->xConnection, UNO_QUERY);
+ if(xTSupplier.is())
+ {
+ uno::Reference<XNameAccess> xTables = xTSupplier->getTables();
+ aTables = xTables->getElementNames();
+ nTables += aTables.getLength();
+ }
+ uno::Reference<XQueriesSupplier> xQSupplier(pUserData->xConnection, UNO_QUERY);
+ if(xQSupplier.is())
+ {
+ uno::Reference<XNameAccess> xQueries = xQSupplier->getQueries();
+ aQueries = xQueries->getElementNames();
+ nTables += aQueries.getLength();
+ }
+ pUserData->nTableAndQueryCount = nTables;
+ if(nTables > 1 && bWidthDialog)
+ {
+ //now call the table select dialog - if more than one table exists
+ SwSelectDBTableDialog aDlg(m_xDialog.get(), pUserData->xConnection);
+ const OUString sTable = m_xListLB->get_text(nSelect, 1);
+ if(!sTable.isEmpty())
+ aDlg.SetSelectedTable(sTable, pUserData->nCommandType == CommandType::TABLE);
+ if(RET_OK == aDlg.run())
+ {
+ bool bIsTable;
+ m_aDBData.sCommand = aDlg.GetSelectedTable(bIsTable);
+ m_aDBData.nCommandType = bIsTable ? CommandType::TABLE : CommandType::QUERY;
+ pUserData->nCommandType = m_aDBData.nCommandType;
+ }
+ }
+ else if(nTables == 1)
+ {
+ if(aTables.hasElements())
+ {
+ m_aDBData.sCommand = aTables[0];
+ m_aDBData.nCommandType = CommandType::TABLE;
+ }
+ else
+ {
+ m_aDBData.sCommand = aQueries[0];
+ m_aDBData.nCommandType = CommandType::QUERY;
+ }
+ }
+ }
+ if ( !m_aDBData.sCommand.isEmpty() )
+ {
+ uno::Reference<beans::XPropertySet> xSourceProperties;
+ m_xDBContext->getByName(m_aDBData.sDataSource) >>= xSourceProperties;
+ pUserData->sURL = lcl_getFlatURL( xSourceProperties );
+
+ pUserData->xColumnsSupplier = SwDBManager::GetColumnSupplier(pUserData->xConnection,
+ m_aDBData.sCommand,
+ m_aDBData.nCommandType == CommandType::TABLE ?
+ SwDBSelect::TABLE : SwDBSelect::QUERY );
+ //#i97577#
+ if( pUserData->xColumnsSupplier.is() )
+ m_xListLB->set_text(nSelect, m_aDBData.sCommand, 1);
+ else
+ m_xListLB->set_text(nSelect, OUString(), 1);
+ }
+ const OUString sCommand = m_xListLB->get_text(nSelect, 1);
+ m_xOK->set_sensitive(!sCommand.isEmpty());
+ m_xFilterPB->set_sensitive( pUserData->xConnection.is() && !sCommand.isEmpty() );
+ m_xTablePB->set_sensitive( pUserData->nTableAndQueryCount > 1 );
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "exception caught in SwAddressListDialog::DetectTablesAndQueries");
+ m_xOK->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SwAddressListDialog, TableSelectHdl_Impl, weld::Button&, rButton, void)
+{
+ TableSelectHdl(&rButton);
+}
+
+void SwAddressListDialog::TableSelectHdl(const weld::Button* pButton)
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ int nSelect = m_xListLB->get_selected_index();
+ if (nSelect != -1)
+ {
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ //only call the table select dialog if tables have not been searched for or there
+ //are more than 1
+ const OUString sTable = m_xListLB->get_text(nSelect, 1);
+ if( pUserData->nTableAndQueryCount > 1 || pUserData->nTableAndQueryCount == -1)
+ {
+ DetectTablesAndQueries(nSelect, (pButton != nullptr) || sTable.isEmpty());
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SwAddressListDialog, OKHdl_Impl, weld::Button&, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+uno::Reference< XDataSource> SwAddressListDialog::GetSource() const
+{
+ uno::Reference< XDataSource> xRet;
+ int nSelect = m_xListLB->get_selected_index();
+ if (nSelect != -1)
+ {
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ xRet = pUserData->xSource;
+ }
+ return xRet;
+
+}
+
+SharedConnection SwAddressListDialog::GetConnection() const
+{
+ SharedConnection xRet;
+ int nSelect = m_xListLB->get_selected_index();
+ if (nSelect != -1)
+ {
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ xRet = pUserData->xConnection;
+ }
+ return xRet;
+}
+
+uno::Reference< XColumnsSupplier> SwAddressListDialog::GetColumnsSupplier() const
+{
+ uno::Reference< XColumnsSupplier> xRet;
+ int nSelect = m_xListLB->get_selected_index();
+ if (nSelect != -1)
+ {
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ xRet = pUserData->xColumnsSupplier;
+ }
+ return xRet;
+}
+
+OUString SwAddressListDialog::GetFilter() const
+{
+ int nSelect = m_xListLB->get_selected_index();
+ if (nSelect != -1)
+ {
+ AddressUserData_Impl* pUserData = weld::fromId<AddressUserData_Impl*>(m_xListLB->get_id(nSelect));
+ return pUserData->sFilter;
+ }
+ return OUString();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/addresslistdialog.hxx b/sw/source/ui/dbui/addresslistdialog.hxx
new file mode 100644
index 0000000000..dc0873af00
--- /dev/null
+++ b/sw/source/ui/dbui/addresslistdialog.hxx
@@ -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/.
+ *
+ * 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_ADDRESSLISTDIALOG_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_ADDRESSLISTDIALOG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <swdbdata.hxx>
+#include <sharedconnection.hxx>
+
+namespace com::sun::star{
+ namespace container{
+ class XNameAccess;
+ }
+ namespace sdb{
+ class XDatabaseContext;
+ }
+ namespace sdbc{
+ class XDataSource;
+ }
+ namespace sdbcx{
+ class XColumnsSupplier;
+ }
+}
+class SwMailMergeAddressBlockPage;
+
+struct AddressUserData_Impl;
+
+class SwAddressListDialog : public SfxDialogController
+{
+ OUString m_sConnecting;
+
+ bool m_bInSelectHdl;
+
+ SwMailMergeAddressBlockPage* m_pAddressPage;
+
+ css::uno::Reference< css::sdb::XDatabaseContext> m_xDBContext;
+
+ SwDBData m_aDBData;
+
+ std::vector<std::unique_ptr<AddressUserData_Impl>> m_aUserData;
+
+ std::unique_ptr<weld::Label> m_xDescriptionFI;
+ std::unique_ptr<weld::Label> m_xConnecting;
+ std::unique_ptr<weld::TreeView> m_xListLB;
+ std::unique_ptr<weld::Button> m_xLoadListPB;
+ std::unique_ptr<weld::Button> m_xRemovePB;
+ std::unique_ptr<weld::Button> m_xCreateListPB;
+ std::unique_ptr<weld::Button> m_xFilterPB;
+ std::unique_ptr<weld::Button> m_xEditPB;
+ std::unique_ptr<weld::Button> m_xTablePB;
+ std::unique_ptr<weld::Button> m_xOK;
+ std::unique_ptr<weld::TreeIter> m_xIter;
+
+ void DetectTablesAndQueries(int Select, bool bWidthDialog);
+
+ DECL_LINK(FilterHdl_Impl, weld::Button&, void);
+ DECL_LINK(LoadHdl_Impl, weld::Button&, void);
+ DECL_LINK(CreateHdl_Impl, weld::Button&, void);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(ListBoxSelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(EditHdl_Impl, weld::Button&, void);
+ DECL_LINK(TableSelectHdl_Impl, weld::Button&, void);
+ void TableSelectHdl(const weld::Button* pButton);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+
+ DECL_LINK(StaticListBoxSelectHdl_Impl, void*, void);
+
+public:
+ SwAddressListDialog(SwMailMergeAddressBlockPage* pParent);
+ virtual ~SwAddressListDialog() override;
+
+ css::uno::Reference< css::sdbc::XDataSource>
+ GetSource() const;
+
+ SharedConnection GetConnection() const;
+
+ css::uno::Reference< css::sdbcx::XColumnsSupplier>
+ GetColumnsSupplier() const;
+
+ const SwDBData& GetDBData() const {return m_aDBData;}
+ OUString GetFilter() const;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/createaddresslistdialog.cxx b/sw/source/ui/dbui/createaddresslistdialog.cxx
new file mode 100644
index 0000000000..e6de5544ce
--- /dev/null
+++ b/sw/source/ui/dbui/createaddresslistdialog.cxx
@@ -0,0 +1,590 @@
+/* -*- 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 <cstddef>
+
+#include <osl/diagnose.h>
+#include <swtypes.hxx>
+#include "createaddresslistdialog.hxx"
+#include "customizeaddresslistdialog.hxx"
+#include <mmconfigitem.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docfile.hxx>
+#include <rtl/textenc.h>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <tools/urlobj.hxx>
+#include <o3tl/string_view.hxx>
+#include <strings.hrc>
+#include <map>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+
+namespace {
+
+struct SwAddressFragment
+{
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Label> m_xLabel;
+ std::unique_ptr<weld::Entry> m_xEntry;
+ weld::Container* m_pGrid;
+
+ SwAddressFragment(weld::Container* pGrid, int nLine)
+ : m_xBuilder(Application::CreateBuilder(pGrid, "modules/swriter/ui/addressfragment.ui"))
+ , m_xLabel(m_xBuilder->weld_label("label"))
+ , m_xEntry(m_xBuilder->weld_entry("entry"))
+ , m_pGrid(pGrid)
+ {
+ m_xLabel->set_grid_left_attach(0);
+ m_xLabel->set_grid_top_attach(nLine);
+
+ m_xEntry->set_grid_left_attach(1);
+ m_xEntry->set_grid_top_attach(nLine);
+ }
+
+ ~SwAddressFragment()
+ {
+ m_pGrid->move(m_xEntry.get(), nullptr);
+ m_pGrid->move(m_xLabel.get(), nullptr);
+ }
+};
+
+}
+
+class SwAddressControl_Impl
+{
+ std::map<weld::Entry*, sal_Int32> m_aEditLines;
+
+ SwCSVData* m_pData;
+ sal_uInt32 m_nCurrentDataSet;
+
+ bool m_bNoDataSet;
+
+ std::unique_ptr<weld::ScrolledWindow> m_xScrollBar;
+ std::unique_ptr<weld::Container> m_xWindow;
+ std::vector<std::unique_ptr<SwAddressFragment>> m_aLines;
+
+ DECL_LINK(GotFocusHdl_Impl, weld::Widget&, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void);
+
+ void MakeVisible(const tools::Rectangle& aRect);
+
+public:
+ SwAddressControl_Impl(weld::Builder& rBuilder);
+
+ void SetData(SwCSVData& rDBData);
+
+ void SetCurrentDataSet(sal_uInt32 nSet);
+ void CurrentDataSetInvalidated() { m_nCurrentDataSet = std::numeric_limits<sal_uInt32>::max(); }
+ sal_uInt32 GetCurrentDataSet() const { return m_nCurrentDataSet; }
+ void SetCursorTo(std::size_t nElement);
+};
+
+SwAddressControl_Impl::SwAddressControl_Impl(weld::Builder& rBuilder)
+ : m_pData(nullptr)
+ , m_nCurrentDataSet(0)
+ , m_bNoDataSet(true)
+ , m_xScrollBar(rBuilder.weld_scrolled_window("scrollwin"))
+ , m_xWindow(rBuilder.weld_container("CONTAINER"))
+{
+}
+
+void SwAddressControl_Impl::SetData(SwCSVData& rDBData)
+{
+ m_pData = &rDBData;
+ //when the address data is updated then remove the controls and build again
+ if (!m_aLines.empty())
+ {
+ m_aLines.clear();
+ m_bNoDataSet = true;
+ }
+
+ Link<weld::Widget&,void> aFocusLink = LINK(this, SwAddressControl_Impl, GotFocusHdl_Impl);
+ Link<weld::Entry&,void> aEditModifyLink = LINK(this, SwAddressControl_Impl, EditModifyHdl_Impl);
+ sal_Int32 nLines = 0;
+ for (const auto& rHeader : m_pData->aDBColumnHeaders)
+ {
+ m_aLines.emplace_back(new SwAddressFragment(m_xWindow.get(), nLines));
+
+ // when we have one line, measure it to get the line height to use as
+ // the basis for overall size request
+ if (nLines == 0)
+ {
+ auto nLineHeight = m_xWindow->get_preferred_size().Height();
+ m_xScrollBar->set_size_request(m_xScrollBar->get_approximate_digit_width() * 65,
+ nLineHeight * 10);
+ }
+
+ weld::Label* pNewFT = m_aLines.back()->m_xLabel.get();
+ weld::Entry* pNewED = m_aLines.back()->m_xEntry.get();
+ //set nLines a position identifier - used in the ModifyHdl
+ m_aEditLines[pNewED] = nLines;
+ pNewED->connect_focus_in(aFocusLink);
+ pNewED->connect_changed(aEditModifyLink);
+
+ pNewFT->set_label(rHeader);
+
+ nLines++;
+ }
+}
+
+void SwAddressControl_Impl::SetCurrentDataSet(sal_uInt32 nSet)
+{
+ if(!(m_bNoDataSet || m_nCurrentDataSet != nSet))
+ return;
+
+ m_bNoDataSet = false;
+ m_nCurrentDataSet = nSet;
+ OSL_ENSURE(m_pData->aDBData.size() > m_nCurrentDataSet, "wrong data set index");
+ if(m_pData->aDBData.size() > m_nCurrentDataSet)
+ {
+ sal_uInt32 nIndex = 0;
+ for(auto& rLine : m_aLines)
+ {
+ OSL_ENSURE(nIndex < m_pData->aDBData[m_nCurrentDataSet].size(),
+ "number of columns doesn't match number of Edits");
+ rLine->m_xEntry->set_text(m_pData->aDBData[m_nCurrentDataSet][nIndex]);
+ ++nIndex;
+ }
+ }
+}
+
+IMPL_LINK(SwAddressControl_Impl, GotFocusHdl_Impl, weld::Widget&, rEdit, void)
+{
+ int x, y, width, height;
+ rEdit.get_extents_relative_to(*m_xWindow, x, y, width, height);
+ // the container has a border of 3 in the .ui
+ tools::Rectangle aRect(Point(x - 3, y - 3), Size(width + 6, height + 6));
+ MakeVisible(aRect);
+}
+
+void SwAddressControl_Impl::MakeVisible(const tools::Rectangle & rRect)
+{
+ //determine range of visible positions
+ auto nMinVisiblePos = m_xScrollBar->vadjustment_get_value();
+ auto nMaxVisiblePos = nMinVisiblePos + m_xScrollBar->vadjustment_get_page_size();
+ if (rRect.Top() < nMinVisiblePos || rRect.Bottom() > nMaxVisiblePos)
+ m_xScrollBar->vadjustment_set_value(rRect.Top());
+}
+
+// copy data changes into database
+IMPL_LINK(SwAddressControl_Impl, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ //get the data element number of the current set
+ sal_Int32 nIndex = m_aEditLines[&rEdit];
+ //get the index of the set
+ OSL_ENSURE(m_pData->aDBData.size() > m_nCurrentDataSet, "wrong data set index" );
+ if (m_pData->aDBData.size() > m_nCurrentDataSet)
+ {
+ m_pData->aDBData[m_nCurrentDataSet][nIndex] = rEdit.get_text();
+ }
+}
+
+void SwAddressControl_Impl::SetCursorTo(std::size_t nElement)
+{
+ if (nElement < m_aLines.size())
+ {
+ weld::Entry* pEdit = m_aLines[nElement]->m_xEntry.get();
+ pEdit->grab_focus();
+ }
+
+}
+
+SwCreateAddressListDialog::SwCreateAddressListDialog(
+ weld::Window* pParent, OUString aURL, SwMailMergeConfigItem const & rConfig)
+ : SfxDialogController(pParent, "modules/swriter/ui/createaddresslist.ui", "CreateAddressList")
+ , m_sAddressListFilterName(SwResId(ST_FILTERNAME))
+ , m_sURL(std::move(aURL))
+ , m_pCSVData(new SwCSVData)
+ , m_xAddressControl(new SwAddressControl_Impl(*m_xBuilder))
+ , m_xNewPB(m_xBuilder->weld_button("NEW"))
+ , m_xDeletePB(m_xBuilder->weld_button("DELETE"))
+ , m_xFindPB(m_xBuilder->weld_button("FIND"))
+ , m_xCustomizePB(m_xBuilder->weld_button("CUSTOMIZE"))
+ , m_xStartPB(m_xBuilder->weld_button("START"))
+ , m_xPrevPB(m_xBuilder->weld_button("PREV"))
+ , m_xSetNoED(m_xBuilder->weld_entry("SETNOED"))
+ , m_xSetNoNF(m_xBuilder->weld_spin_button("SETNOSB"))
+ , m_xNextPB(m_xBuilder->weld_button("NEXT"))
+ , m_xEndPB(m_xBuilder->weld_button("END"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+{
+ m_xSetNoNF->set_min(1);
+
+ m_xNewPB->connect_clicked(LINK(this, SwCreateAddressListDialog, NewHdl_Impl));
+ m_xDeletePB->connect_clicked(LINK(this, SwCreateAddressListDialog, DeleteHdl_Impl));
+ m_xFindPB->connect_clicked(LINK(this, SwCreateAddressListDialog, FindHdl_Impl));
+ m_xCustomizePB->connect_clicked(LINK(this, SwCreateAddressListDialog, CustomizeHdl_Impl));
+ m_xOK->connect_clicked(LINK(this, SwCreateAddressListDialog, OkHdl_Impl));
+
+ Link<weld::Button&,void> aLk = LINK(this, SwCreateAddressListDialog, DBCursorHdl_Impl);
+ m_xStartPB->connect_clicked(aLk);
+ m_xPrevPB->connect_clicked(aLk);
+ m_xSetNoED->connect_changed(LINK(this, SwCreateAddressListDialog, DBNumCursorHdl_Impl));
+ m_xSetNoED->connect_focus_out(LINK(this, SwCreateAddressListDialog, RefreshNum_Impl));
+ m_xNextPB->connect_clicked(aLk);
+ m_xEndPB->connect_clicked(aLk);
+
+ if (!m_sURL.isEmpty())
+ {
+ //file exists, has to be loaded here
+ SfxMedium aMedium( m_sURL, StreamMode::READ );
+ SvStream* pStream = aMedium.GetInStream();
+ if(pStream)
+ {
+ pStream->SetLineDelimiter( LINEEND_LF );
+ pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8);
+
+ OUString sLine;
+ bool bRead = pStream->ReadByteStringLine( sLine, RTL_TEXTENCODING_UTF8 );
+
+ if(bRead && !sLine.isEmpty())
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ const std::u16string_view sHeader = o3tl::getToken(sLine, 0, '\t', nIndex );
+ OSL_ENSURE(sHeader.size() > 2 &&
+ o3tl::starts_with(sHeader, u"\"") && o3tl::ends_with(sHeader, u"\""),
+ "Wrong format of header");
+ if(sHeader.size() > 2)
+ {
+ m_pCSVData->aDBColumnHeaders.push_back( OUString(sHeader.substr(1, sHeader.size() -2)));
+ }
+ }
+ while (nIndex > 0);
+ }
+ while(pStream->ReadByteStringLine( sLine, RTL_TEXTENCODING_UTF8 ))
+ {
+ std::vector<OUString> aNewData;
+ //analyze data line
+ sal_Int32 nIndex = { sLine.isEmpty() ? -1 : 0 };
+ while (nIndex >= 0)
+ {
+ const OUString sData = sLine.getToken( 0, '\t', nIndex );
+ OSL_ENSURE( sData.startsWith("\"") && sData.endsWith("\""),
+ "Wrong format of line");
+ if(sData.getLength() >= 2)
+ aNewData.push_back(sData.copy(1, sData.getLength() - 2));
+ else
+ aNewData.push_back(sData);
+ }
+ m_pCSVData->aDBData.push_back( aNewData );
+ }
+ }
+ }
+ else
+ {
+ //database has to be created
+ const std::vector<std::pair<OUString, int>>& rAddressHeader = rConfig.GetDefaultAddressHeaders();
+ const sal_uInt32 nCount = rAddressHeader.size();
+ for(sal_uInt32 nHeader = 0; nHeader < nCount; ++nHeader)
+ m_pCSVData->aDBColumnHeaders.push_back(rAddressHeader[nHeader].first);
+ std::vector<OUString> aNewData;
+ aNewData.insert(aNewData.begin(), nCount, OUString());
+ m_pCSVData->aDBData.push_back(aNewData);
+ }
+ //now fill the address control
+ m_xAddressControl->SetData(*m_pCSVData);
+ m_xAddressControl->SetCurrentDataSet(0);
+ m_xSetNoNF->set_max(m_pCSVData->aDBData.size());
+
+ m_xSetNoNF->set_value(1);
+ RefreshNum_Impl(*m_xSetNoED);
+
+ UpdateButtons();
+}
+
+SwCreateAddressListDialog::~SwCreateAddressListDialog()
+{
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, NewHdl_Impl, weld::Button&, void)
+{
+ sal_uInt32 nCurrent = m_xAddressControl->GetCurrentDataSet();
+ std::vector<OUString> aNewData;
+ aNewData.insert(aNewData.begin(), m_pCSVData->aDBColumnHeaders.size(), OUString());
+ m_pCSVData->aDBData.insert(m_pCSVData->aDBData.begin() + ++nCurrent, aNewData);
+ m_xSetNoNF->set_max(m_pCSVData->aDBData.size());
+ //the NumericField start at 1
+ m_xSetNoNF->set_value(nCurrent + 1);
+ RefreshNum_Impl(*m_xSetNoED);
+ //the address control starts at 0
+ m_xAddressControl->SetCurrentDataSet(nCurrent);
+ UpdateButtons();
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ sal_uInt32 nCurrent = m_xAddressControl->GetCurrentDataSet();
+ if (m_pCSVData->aDBData.size() > 1)
+ {
+ m_pCSVData->aDBData.erase(m_pCSVData->aDBData.begin() + nCurrent);
+ if (nCurrent)
+ --nCurrent;
+ }
+ else
+ {
+ // if only one set is available then clear the data
+ m_pCSVData->aDBData[0].assign(m_pCSVData->aDBData[0].size(), OUString());
+ m_xDeletePB->set_sensitive(false);
+ }
+ m_xAddressControl->CurrentDataSetInvalidated();
+ m_xAddressControl->SetCurrentDataSet(nCurrent);
+ m_xSetNoNF->set_max(m_pCSVData->aDBData.size());
+ UpdateButtons();
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, FindHdl_Impl, weld::Button&, void)
+{
+ if (!m_xFindDlg)
+ {
+ m_xFindDlg.reset(new SwFindEntryDialog(this));
+ weld::ComboBox& rColumnBox = m_xFindDlg->GetFieldsListBox();
+ for(const auto& rHeader : m_pCSVData->aDBColumnHeaders)
+ rColumnBox.append_text(rHeader);
+ rColumnBox.set_active(0);
+ m_xFindDlg->show();
+ }
+ else
+ m_xFindDlg->set_visible(!m_xFindDlg->get_visible());
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, CustomizeHdl_Impl, weld::Button&, void)
+{
+ SwCustomizeAddressListDialog aDlg(m_xDialog.get(), *m_pCSVData);
+ if (aDlg.run() == RET_OK)
+ {
+ m_pCSVData = aDlg.ReleaseNewData();
+ m_xAddressControl->SetData(*m_pCSVData);
+ m_xAddressControl->SetCurrentDataSet(m_xAddressControl->GetCurrentDataSet());
+ }
+
+ //update find dialog
+ if (m_xFindDlg)
+ {
+ weld::ComboBox& rColumnBox = m_xFindDlg->GetFieldsListBox();
+ rColumnBox.clear();
+ for(const auto& rHeader : m_pCSVData->aDBColumnHeaders)
+ rColumnBox.append_text(rHeader);
+ }
+}
+
+namespace
+{
+
+void lcl_WriteValues(const std::vector<OUString> *pFields, SvStream* pStream)
+{
+ OUStringBuffer sLine;
+ const std::vector< OUString >::const_iterator aBegin = pFields->begin();
+ const std::vector< OUString >::const_iterator aEnd = pFields->end();
+ for(std::vector< OUString >::const_iterator aIter = aBegin; aIter != aEnd; ++aIter)
+ {
+ if (aIter==aBegin)
+ {
+ sLine.append("\"" + *aIter + "\"");
+ }
+ else
+ {
+ sLine.append("\t\"" + *aIter + "\"");
+ }
+ }
+ pStream->WriteByteStringLine( sLine, RTL_TEXTENCODING_UTF8 );
+}
+
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, OkHdl_Impl, weld::Button&, void)
+{
+ if(m_sURL.isEmpty())
+ {
+ sfx2::FileDialogHelper aDlgHelper(TemplateDescription::FILESAVE_SIMPLE,
+ FileDialogFlags::NONE, m_xDialog.get());
+ aDlgHelper.SetContext(sfx2::FileDialogHelper::WriterCreateAddressList);
+ uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+ xFP->appendFilter( m_sAddressListFilterName, "*.csv" );
+ xFP->setCurrentFilter( m_sAddressListFilterName ) ;
+
+ if( ERRCODE_NONE == aDlgHelper.Execute() )
+ {
+ m_sURL = xFP->getSelectedFiles().getConstArray()[0];
+ INetURLObject aResult( m_sURL );
+ aResult.setExtension(u"csv");
+ m_sURL = aResult.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+ }
+ }
+ if(m_sURL.isEmpty())
+ return;
+
+ SfxMedium aMedium( m_sURL, StreamMode::READWRITE|StreamMode::TRUNC );
+ SvStream* pStream = aMedium.GetOutStream();
+ pStream->SetLineDelimiter( LINEEND_LF );
+ pStream->SetStreamCharSet(RTL_TEXTENCODING_UTF8);
+
+ lcl_WriteValues(&(m_pCSVData->aDBColumnHeaders), pStream);
+
+ for(const auto& rData : m_pCSVData->aDBData)
+ {
+ lcl_WriteValues(&rData, pStream);
+ }
+ aMedium.Commit();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwCreateAddressListDialog, DBCursorHdl_Impl, weld::Button&, rButton, void)
+{
+ int nValue = m_xSetNoNF->get_value();
+
+ if (&rButton == m_xStartPB.get())
+ nValue = 1;
+ else if (&rButton == m_xPrevPB.get())
+ {
+ if (nValue > 1)
+ --nValue;
+ }
+ else if (&rButton == m_xNextPB.get())
+ {
+ if (nValue < m_xSetNoNF->get_max())
+ ++nValue;
+ }
+ else //m_aEndPB
+ nValue = m_xSetNoNF->get_max();
+ if (nValue != m_xSetNoNF->get_value())
+ {
+ m_xSetNoNF->set_value(nValue);
+ RefreshNum_Impl(*m_xSetNoED);
+ DBNumCursor();
+ }
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, DBNumCursorHdl_Impl, weld::Entry&, void)
+{
+ m_xSetNoNF->set_text(m_xSetNoED->get_text());
+ DBNumCursor();
+}
+
+IMPL_LINK_NOARG(SwCreateAddressListDialog, RefreshNum_Impl, weld::Widget&, void)
+{
+ m_xSetNoED->set_text(OUString::number(m_xSetNoNF->get_value()));
+}
+
+void SwCreateAddressListDialog::DBNumCursor()
+{
+ m_xAddressControl->SetCurrentDataSet(m_xSetNoNF->get_value() - 1);
+ UpdateButtons();
+}
+
+void SwCreateAddressListDialog::UpdateButtons()
+{
+ sal_uInt32 nCurrent = static_cast< sal_uInt32 >(m_xSetNoNF->get_value() );
+ sal_uInt32 nSize = static_cast<sal_uInt32>(m_pCSVData->aDBData.size());
+ m_xStartPB->set_sensitive(nCurrent != 1);
+ m_xPrevPB->set_sensitive(nCurrent != 1);
+ m_xNextPB->set_sensitive(nCurrent != nSize);
+ m_xEndPB->set_sensitive(nCurrent != nSize);
+ m_xDeletePB->set_sensitive(nSize > 0);
+}
+
+void SwCreateAddressListDialog::Find(const OUString& rSearch, sal_Int32 nColumn)
+{
+ const OUString sSearch = rSearch.toAsciiLowerCase();
+ sal_uInt32 nCurrent = m_xAddressControl->GetCurrentDataSet();
+ //search forward
+ bool bFound = false;
+ sal_uInt32 nStart = nCurrent + 1;
+ sal_uInt32 nEnd = m_pCSVData->aDBData.size();
+ std::size_t nElement = 0;
+ sal_uInt32 nPos = 0;
+ for(short nTemp = 0; nTemp < 2 && !bFound; nTemp++)
+ {
+ for(nPos = nStart; nPos < nEnd; ++nPos)
+ {
+ std::vector< OUString> const & aData = m_pCSVData->aDBData[nPos];
+ if(nColumn >=0)
+ bFound = -1 != aData[static_cast<sal_uInt32>(nColumn)].toAsciiLowerCase().indexOf(sSearch);
+ else
+ {
+ for( nElement = 0; nElement < aData.size(); ++nElement)
+ {
+ bFound = -1 != aData[nElement].toAsciiLowerCase().indexOf(sSearch);
+ if(bFound)
+ {
+ nColumn = nElement; //TODO: std::size_t -> sal_Int32!
+ break;
+ }
+ }
+ }
+ if(bFound)
+ break;
+ }
+ nStart = 0;
+ nEnd = nCurrent + 1;
+ }
+ if(bFound)
+ {
+ m_xAddressControl->SetCurrentDataSet(nPos);
+ m_xSetNoNF->set_value( nPos + 1 );
+ RefreshNum_Impl(*m_xSetNoED);
+ UpdateButtons();
+ m_xAddressControl->SetCursorTo(nElement);
+ }
+}
+
+SwFindEntryDialog::SwFindEntryDialog(SwCreateAddressListDialog* pParent)
+ : GenericDialogController(pParent->getDialog(), "modules/swriter/ui/findentrydialog.ui", "FindEntryDialog")
+ , m_pParent(pParent)
+ , m_xFindED(m_xBuilder->weld_entry("entry"))
+ , m_xFindOnlyCB(m_xBuilder->weld_check_button("findin"))
+ , m_xFindOnlyLB(m_xBuilder->weld_combo_box("area"))
+ , m_xFindPB(m_xBuilder->weld_button("find"))
+ , m_xCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xFindPB->connect_clicked(LINK(this, SwFindEntryDialog, FindHdl_Impl));
+ m_xFindED->connect_changed(LINK(this, SwFindEntryDialog, FindEnableHdl_Impl));
+ m_xCancel->connect_clicked(LINK(this, SwFindEntryDialog, CloseHdl_Impl));
+}
+
+SwFindEntryDialog::~SwFindEntryDialog()
+{
+}
+
+IMPL_LINK_NOARG(SwFindEntryDialog, FindHdl_Impl, weld::Button&, void)
+{
+ sal_Int32 nColumn = -1;
+ if (m_xFindOnlyCB->get_active())
+ nColumn = m_xFindOnlyLB->get_active();
+ m_pParent->Find(m_xFindED->get_text(), nColumn);
+}
+
+IMPL_LINK_NOARG(SwFindEntryDialog, FindEnableHdl_Impl, weld::Entry&, void)
+{
+ m_xFindPB->set_sensitive(!m_xFindED->get_text().isEmpty());
+}
+
+IMPL_LINK_NOARG(SwFindEntryDialog, CloseHdl_Impl, weld::Button&, void)
+{
+ m_xDialog->hide();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/createaddresslistdialog.hxx b/sw/source/ui/dbui/createaddresslistdialog.hxx
new file mode 100644
index 0000000000..693dffed39
--- /dev/null
+++ b/sw/source/ui/dbui/createaddresslistdialog.hxx
@@ -0,0 +1,108 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_CREATEADDRESSLISTDIALOG_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_CREATEADDRESSLISTDIALOG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <vcl/weld.hxx>
+#include <vector>
+
+class SwAddressControl_Impl;
+class SwMailMergeConfigItem;
+
+// container of the created database
+struct SwCSVData
+{
+ std::vector< OUString > aDBColumnHeaders;
+ std::vector< std::vector< OUString> > aDBData;
+};
+
+class SwFindEntryDialog;
+class SwCreateAddressListDialog : public SfxDialogController
+{
+ OUString m_sAddressListFilterName;
+ OUString m_sURL;
+
+ std::unique_ptr<SwCSVData> m_pCSVData;
+ std::unique_ptr<SwFindEntryDialog> m_xFindDlg;
+
+ std::unique_ptr<SwAddressControl_Impl> m_xAddressControl;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<weld::Button> m_xFindPB;
+ std::unique_ptr<weld::Button> m_xCustomizePB;
+ std::unique_ptr<weld::Button> m_xStartPB;
+ std::unique_ptr<weld::Button> m_xPrevPB;
+ std::unique_ptr<weld::Entry> m_xSetNoED;
+ std::unique_ptr<weld::SpinButton> m_xSetNoNF;
+ std::unique_ptr<weld::Button> m_xNextPB;
+ std::unique_ptr<weld::Button> m_xEndPB;
+ std::unique_ptr<weld::Button> m_xOK;
+
+ DECL_LINK(NewHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(FindHdl_Impl, weld::Button&, void);
+ DECL_LINK(CustomizeHdl_Impl, weld::Button&, void);
+ DECL_LINK(OkHdl_Impl, weld::Button&, void);
+ DECL_LINK(DBCursorHdl_Impl, weld::Button&, void);
+ DECL_LINK(DBNumCursorHdl_Impl, weld::Entry&, void);
+ DECL_LINK(RefreshNum_Impl, weld::Widget&, void);
+ void DBNumCursor();
+
+ void UpdateButtons();
+
+public:
+ SwCreateAddressListDialog(weld::Window* pParent, OUString aURL, SwMailMergeConfigItem const & rConfig);
+ virtual ~SwCreateAddressListDialog() override;
+
+ const OUString& GetURL() const { return m_sURL; }
+ void Find( const OUString& rSearch, sal_Int32 nColumn);
+};
+
+class SwFindEntryDialog : public weld::GenericDialogController
+{
+ SwCreateAddressListDialog* m_pParent;
+
+ std::unique_ptr<weld::Entry> m_xFindED;
+ std::unique_ptr<weld::CheckButton> m_xFindOnlyCB;
+ std::unique_ptr<weld::ComboBox> m_xFindOnlyLB;
+ std::unique_ptr<weld::Button> m_xFindPB;
+ std::unique_ptr<weld::Button> m_xCancel;
+
+ DECL_LINK(FindHdl_Impl, weld::Button&, void);
+ DECL_LINK(FindEnableHdl_Impl, weld::Entry&, void);
+ DECL_LINK(CloseHdl_Impl, weld::Button&, void);
+
+public:
+ SwFindEntryDialog(SwCreateAddressListDialog* pParent);
+ virtual ~SwFindEntryDialog() override;
+
+ void show() { m_xDialog->show(); }
+ void set_visible(bool bVisible) { m_xDialog->set_visible(bVisible); }
+ bool get_visible() const { return m_xDialog->get_visible(); }
+
+ weld::ComboBox& GetFieldsListBox()
+ {
+ return *m_xFindOnlyLB;
+ }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/customizeaddresslistdialog.cxx b/sw/source/ui/dbui/customizeaddresslistdialog.cxx
new file mode 100644
index 0000000000..e80e75678c
--- /dev/null
+++ b/sw/source/ui/dbui/customizeaddresslistdialog.cxx
@@ -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 .
+ */
+
+#include "customizeaddresslistdialog.hxx"
+#include "createaddresslistdialog.hxx"
+
+SwCustomizeAddressListDialog::SwCustomizeAddressListDialog(
+ weld::Window* pParent, const SwCSVData& rOldData)
+ : SfxDialogController(pParent, "modules/swriter/ui/customizeaddrlistdialog.ui",
+ "CustomizeAddrListDialog")
+ , m_xNewData(new SwCSVData(rOldData))
+ , m_xFieldsLB(m_xBuilder->weld_tree_view("treeview"))
+ , m_xAddPB(m_xBuilder->weld_button("add"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ , m_xRenamePB(m_xBuilder->weld_button("rename"))
+ , m_xUpPB(m_xBuilder->weld_button("up"))
+ , m_xDownPB(m_xBuilder->weld_button("down"))
+{
+ m_xFieldsLB->set_size_request(-1, m_xFieldsLB->get_height_rows(14));
+
+ m_xFieldsLB->connect_changed(LINK(this, SwCustomizeAddressListDialog, ListBoxSelectHdl_Impl));
+ Link<weld::Button&,void> aAddRenameLk = LINK(this, SwCustomizeAddressListDialog, AddRenameHdl_Impl );
+ m_xAddPB->connect_clicked(aAddRenameLk);
+ m_xRenamePB->connect_clicked(aAddRenameLk);
+ m_xDeletePB->connect_clicked(LINK(this, SwCustomizeAddressListDialog, DeleteHdl_Impl ));
+ Link<weld::Button&,void> aUpDownLk = LINK(this, SwCustomizeAddressListDialog, UpDownHdl_Impl);
+ m_xUpPB->connect_clicked(aUpDownLk);
+ m_xDownPB->connect_clicked(aUpDownLk);
+
+ for (const auto& rHeader : m_xNewData->aDBColumnHeaders)
+ m_xFieldsLB->append_text(rHeader);
+
+ m_xFieldsLB->select(0);
+ UpdateButtons();
+}
+
+SwCustomizeAddressListDialog::~SwCustomizeAddressListDialog()
+{
+}
+
+IMPL_LINK_NOARG(SwCustomizeAddressListDialog, ListBoxSelectHdl_Impl, weld::TreeView&, void)
+{
+ UpdateButtons();
+}
+
+IMPL_LINK(SwCustomizeAddressListDialog, AddRenameHdl_Impl, weld::Button&, rButton, void)
+{
+ bool bRename = &rButton == m_xRenamePB.get();
+ auto nPos = m_xFieldsLB->get_selected_index();
+ if (nPos == -1)
+ nPos = 0;
+
+ std::unique_ptr<SwAddRenameEntryDialog> xDlg;
+ if (bRename)
+ xDlg.reset(new SwRenameEntryDialog(m_xDialog.get(), m_xNewData->aDBColumnHeaders));
+ else
+ xDlg.reset(new SwAddEntryDialog(m_xDialog.get(), m_xNewData->aDBColumnHeaders));
+ if (bRename)
+ {
+ OUString aTemp = m_xFieldsLB->get_text(nPos);
+ xDlg->SetFieldName(aTemp);
+ }
+ if (xDlg->run() == RET_OK)
+ {
+ OUString sNew = xDlg->GetFieldName();
+ if(bRename)
+ {
+ m_xNewData->aDBColumnHeaders[nPos] = sNew;
+ m_xFieldsLB->remove(nPos);
+ }
+ else
+ {
+ if (m_xFieldsLB->get_selected_index() != -1)
+ ++nPos; // append the new entry behind the selected
+ //add the new column
+ m_xNewData->aDBColumnHeaders.insert(m_xNewData->aDBColumnHeaders.begin() + nPos, sNew);
+ //add a new entry into all data arrays
+ for (auto& rData : m_xNewData->aDBData)
+ rData.insert(rData.begin() + nPos, OUString());
+
+ }
+
+ m_xFieldsLB->insert_text(nPos, sNew);
+ m_xFieldsLB->select(nPos);
+ }
+ UpdateButtons();
+}
+
+IMPL_LINK_NOARG(SwCustomizeAddressListDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ auto nPos = m_xFieldsLB->get_selected_index();
+ m_xFieldsLB->remove(nPos);
+ m_xFieldsLB->select(nPos > m_xFieldsLB->n_children() - 1 ? nPos - 1 : nPos);
+
+ //remove the column
+ m_xNewData->aDBColumnHeaders.erase(m_xNewData->aDBColumnHeaders.begin() + nPos);
+ //remove the data
+ for (auto& rData : m_xNewData->aDBData)
+ rData.erase(rData.begin() + nPos);
+
+ UpdateButtons();
+}
+
+IMPL_LINK(SwCustomizeAddressListDialog, UpDownHdl_Impl, weld::Button&, rButton, void)
+{
+ auto nPos = m_xFieldsLB->get_selected_index();
+ auto nOldPos = nPos;
+ OUString aTemp = m_xFieldsLB->get_text(nPos);
+ m_xFieldsLB->remove(nPos);
+ if (&rButton == m_xUpPB.get())
+ --nPos;
+ else
+ ++nPos;
+ m_xFieldsLB->insert_text(nPos, aTemp);
+ m_xFieldsLB->select(nPos);
+ //align m_xNewData
+ OUString sHeader = m_xNewData->aDBColumnHeaders[nOldPos];
+ m_xNewData->aDBColumnHeaders.erase(m_xNewData->aDBColumnHeaders.begin() + nOldPos);
+ m_xNewData->aDBColumnHeaders.insert(m_xNewData->aDBColumnHeaders.begin() + nPos, sHeader);
+ for (auto& rData : m_xNewData->aDBData)
+ {
+ OUString sData = rData[nOldPos];
+ rData.erase(rData.begin() + nOldPos);
+ rData.insert(rData.begin() + nPos, sData);
+ }
+
+ UpdateButtons();
+}
+
+void SwCustomizeAddressListDialog::UpdateButtons()
+{
+ auto nPos = m_xFieldsLB->get_selected_index();
+ auto nEntries = m_xFieldsLB->n_children();
+ m_xUpPB->set_sensitive(nPos > 0 && nEntries > 0);
+ m_xDownPB->set_sensitive(nPos < nEntries -1);
+ m_xDeletePB->set_sensitive(nEntries > 0);
+ m_xRenamePB->set_sensitive(nEntries > 0);
+}
+
+SwAddRenameEntryDialog::SwAddRenameEntryDialog(
+ weld::Window* pParent, const OUString& rUIXMLDescription, const OUString& rID,
+ const std::vector< OUString >& rCSVHeader)
+ : SfxDialogController(pParent, rUIXMLDescription, rID)
+ , m_rCSVHeader(rCSVHeader)
+ , m_xFieldNameED(m_xBuilder->weld_entry("entry"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+{
+ m_xFieldNameED->connect_changed(LINK(this, SwAddRenameEntryDialog, ModifyHdl_Impl));
+ ModifyHdl_Impl(*m_xFieldNameED);
+}
+
+IMPL_LINK(SwAddRenameEntryDialog, ModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ OUString sEntry = rEdit.get_text();
+ bool bFound = sEntry.isEmpty();
+
+ if(!bFound)
+ {
+ bFound = std::any_of(m_rCSVHeader.begin(), m_rCSVHeader.end(),
+ [&sEntry](const OUString& rHeader) { return rHeader == sEntry; });
+ }
+ m_xOK->set_sensitive(!bFound);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/customizeaddresslistdialog.hxx b/sw/source/ui/dbui/customizeaddresslistdialog.hxx
new file mode 100644
index 0000000000..a683ccb829
--- /dev/null
+++ b/sw/source/ui/dbui/customizeaddresslistdialog.hxx
@@ -0,0 +1,91 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_CUSTOMIZEADDRESSLISTDIALOG_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_CUSTOMIZEADDRESSLISTDIALOG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <vcl/weld.hxx>
+
+#include "createaddresslistdialog.hxx"
+
+struct SwCSVData;
+
+class SwCustomizeAddressListDialog : public SfxDialogController
+{
+ std::unique_ptr<SwCSVData> m_xNewData;
+ std::unique_ptr<weld::TreeView> m_xFieldsLB;
+ std::unique_ptr<weld::Button> m_xAddPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<weld::Button> m_xRenamePB;
+ std::unique_ptr<weld::Button> m_xUpPB;
+ std::unique_ptr<weld::Button> m_xDownPB;
+
+ DECL_LINK(AddRenameHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(UpDownHdl_Impl, weld::Button&, void);
+ DECL_LINK(ListBoxSelectHdl_Impl, weld::TreeView&, void);
+
+ void UpdateButtons();
+public:
+ SwCustomizeAddressListDialog(weld::Window* pParent, const SwCSVData& rOldData);
+ virtual ~SwCustomizeAddressListDialog() override;
+
+ std::unique_ptr<SwCSVData> ReleaseNewData() { return std::move(m_xNewData);}
+};
+
+class SwAddRenameEntryDialog : public SfxDialogController
+{
+ const std::vector< OUString >& m_rCSVHeader;
+ std::unique_ptr<weld::Entry> m_xFieldNameED;
+ std::unique_ptr<weld::Button> m_xOK;
+
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+protected:
+ SwAddRenameEntryDialog(weld::Window* pParent, const OUString& rUIXMLDescription,
+ const OUString& rID, const std::vector< OUString >& rCSVHeader);
+
+public:
+ void SetFieldName(const OUString& rName) { m_xFieldNameED->set_text(rName); }
+ OUString GetFieldName() const { return m_xFieldNameED->get_text(); }
+
+};
+
+class SwAddEntryDialog : public SwAddRenameEntryDialog
+{
+public:
+ SwAddEntryDialog(weld::Window* pParent, const std::vector< OUString >& rCSVHeader)
+ : SwAddRenameEntryDialog(pParent, "modules/swriter/ui/addentrydialog.ui",
+ "AddEntryDialog", rCSVHeader)
+ {
+ }
+};
+
+class SwRenameEntryDialog : public SwAddRenameEntryDialog
+{
+public:
+ SwRenameEntryDialog(weld::Window* pParent, const std::vector< OUString >& rCSVHeader)
+ : SwAddRenameEntryDialog(pParent, "modules/swriter/ui/renameentrydialog.ui",
+ "RenameEntryDialog", rCSVHeader)
+ {
+ }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/dbinsdlg.cxx b/sw/source/ui/dbui/dbinsdlg.cxx
new file mode 100644
index 0000000000..e6dac3049c
--- /dev/null
+++ b/sw/source/ui/dbui/dbinsdlg.cxx
@@ -0,0 +1,1750 @@
+/* -*- 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 <dbinsdlg.hxx>
+
+#include <float.h>
+
+#include <hintids.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/NumberFormatter.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <comphelper/types.hxx>
+#include <svl/numuno.hxx>
+#include <svl/numformat.hxx>
+#include <svl/stritem.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <utility>
+#include <vcl/mnemonic.hxx>
+#include <svl/style.hxx>
+#include <svl/zformat.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <fmtclds.hxx>
+#include <tabcol.hxx>
+#include <uiitems.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <dbmgr.hxx>
+#include <tblafmt.hxx>
+#include <cellatr.hxx>
+#include <swtablerep.hxx>
+#include <dbfld.hxx>
+#include <fmtcol.hxx>
+#include <swwait.hxx>
+#include <modcfg.hxx>
+#include <swmodule.hxx>
+#include <poolfmt.hxx>
+#include <connectivity/dbtools.hxx>
+
+#include <cmdid.h>
+#include <SwStyleNameMapper.hxx>
+#include <tabsh.hxx>
+#include <swabstdlg.hxx>
+#include <strings.hrc>
+#include <IDocumentMarkAccess.hxx>
+
+#include <o3tl/any.hxx>
+
+#include <memory>
+#include <string_view>
+
+#include <swuiexp.hxx>
+
+using namespace ::dbtools;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::uno;
+
+const char cDBFieldStart = '<';
+const char cDBFieldEnd = '>';
+
+// Helper structure for adding database rows as fields or text
+struct DB_Column
+{
+ const enum class Type { FILLTEXT, COL_FIELD, COL_TEXT, SPLITPARA } eColType;
+
+ union {
+ OUString* pText;
+ SwField* pField;
+ sal_uInt32 nFormat;
+ };
+ const SwInsDBColumn* pColInfo;
+
+ DB_Column() : eColType(Type::SPLITPARA),
+ pText(nullptr),
+ pColInfo(nullptr)
+ {}
+
+ explicit DB_Column( const OUString& rText )
+ : eColType(Type::FILLTEXT),
+ pText(new OUString(rText)),
+ pColInfo(nullptr)
+ {}
+
+ DB_Column( const SwInsDBColumn& rInfo, sal_uInt32 nFormat_ )
+ : eColType(Type::COL_TEXT),
+ nFormat(nFormat_),
+ pColInfo(&rInfo)
+ {}
+
+ DB_Column( const SwInsDBColumn& rInfo, SwDBField& rField )
+ : eColType(Type::COL_FIELD),
+ pField(&rField),
+ pColInfo(&rInfo)
+ {}
+
+ ~DB_Column()
+ {
+ if( Type::COL_FIELD == eColType )
+ delete pField;
+ else if( Type::FILLTEXT == eColType )
+ delete pText;
+ }
+};
+
+namespace {
+
+struct DB_ColumnConfigData
+{
+ SwInsDBColumns aDBColumns;
+ OUString sEdit;
+ OUString sTableList;
+ OUString sTmplNm;
+ OUString sTAutoFormatNm;
+ bool bIsTable : 1,
+ bIsField : 1,
+ bIsHeadlineOn : 1,
+ bIsEmptyHeadln : 1;
+
+ DB_ColumnConfigData(DB_ColumnConfigData const&) = delete;
+ DB_ColumnConfigData& operator=(DB_ColumnConfigData const&) = delete;
+
+ DB_ColumnConfigData()
+ {
+ bIsTable = bIsHeadlineOn = true;
+ bIsField = bIsEmptyHeadln = false;
+ }
+};
+
+}
+
+bool SwInsDBColumn::operator<( const SwInsDBColumn& rCmp ) const
+{
+ return 0 > GetAppCollator().compareString( sColumn, rCmp.sColumn );
+}
+
+SwInsertDBColAutoPilot::SwInsertDBColAutoPilot( SwView& rView,
+ Reference<XDataSource> const & xDataSource,
+ Reference<sdbcx::XColumnsSupplier> const & xColSupp,
+ SwDBData aData )
+ : SfxDialogController(rView.GetWindow()->GetFrameWeld(), "modules/swriter/ui/insertdbcolumnsdialog.ui", "InsertDbColumnsDialog")
+ , ConfigItem("Office.Writer/InsertData/DataSet", ConfigItemMode::NONE)
+ , m_aDBData(std::move(aData))
+ , m_sNoTmpl(SwResId(SW_STR_NONE))
+ , m_pView(&rView)
+ , m_xRbAsTable(m_xBuilder->weld_radio_button("astable"))
+ , m_xRbAsField(m_xBuilder->weld_radio_button("asfields"))
+ , m_xRbAsText(m_xBuilder->weld_radio_button("astext"))
+ , m_xHeadFrame(m_xBuilder->weld_frame("dbframe"))
+ , m_xLbTableDbColumn(m_xBuilder->weld_tree_view("tabledbcols"))
+ , m_xLbTextDbColumn(m_xBuilder->weld_tree_view("tabletxtcols"))
+ , m_xFormatFrame(m_xBuilder->weld_frame("formatframe"))
+ , m_xRbDbFormatFromDb(m_xBuilder->weld_radio_button("fromdatabase"))
+ , m_xRbDbFormatFromUsr(m_xBuilder->weld_radio_button("userdefined"))
+ , m_xLbDbFormatFromUsr(new NumFormatListBox(m_xBuilder->weld_combo_box("numformat")))
+ , m_xIbDbcolToEdit(m_xBuilder->weld_button("toedit"))
+ , m_xEdDbText(m_xBuilder->weld_text_view("textview"))
+ , m_xFtDbParaColl(m_xBuilder->weld_label("parastylelabel"))
+ , m_xLbDbParaColl(m_xBuilder->weld_combo_box("parastyle"))
+ , m_xIbDbcolAllTo(m_xBuilder->weld_button("oneright"))
+ , m_xIbDbcolOneTo(m_xBuilder->weld_button("allright"))
+ , m_xIbDbcolOneFrom(m_xBuilder->weld_button("oneleft"))
+ , m_xIbDbcolAllFrom(m_xBuilder->weld_button("allleft"))
+ , m_xFtTableCol(m_xBuilder->weld_label("tablecolft"))
+ , m_xLbTableCol(m_xBuilder->weld_tree_view("tablecols"))
+ , m_xCbTableHeadon(m_xBuilder->weld_check_button("tableheading"))
+ , m_xRbHeadlColnms(m_xBuilder->weld_radio_button("columnname"))
+ , m_xRbHeadlEmpty(m_xBuilder->weld_radio_button("rowonly"))
+ , m_xPbTableFormat(m_xBuilder->weld_button("tableformat"))
+ , m_xPbTableAutofmt(m_xBuilder->weld_button("autoformat"))
+{
+ m_xEdDbText->set_size_request(m_xEdDbText->get_approximate_digit_width() * 40, -1);
+ m_xLbDbParaColl->make_sorted();
+
+ m_nGBFormatLen = m_xFormatFrame->get_label().getLength();
+
+ if (xColSupp.is())
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SvNumberFormatter* pNumFormatr = rSh.GetNumberFormatter();
+ rtl::Reference<SvNumberFormatsSupplierObj> pNumFormat = new SvNumberFormatsSupplierObj( pNumFormatr );
+ Reference< util::XNumberFormats > xDocNumberFormats = pNumFormat->getNumberFormats();
+ Reference< util::XNumberFormatTypes > xDocNumberFormatTypes(xDocNumberFormats, UNO_QUERY);
+
+ Reference<XPropertySet> xSourceProps(xDataSource, UNO_QUERY);
+ Reference< util::XNumberFormats > xNumberFormats;
+ if(xSourceProps.is())
+ {
+ Any aFormats = xSourceProps->getPropertyValue("NumberFormatsSupplier");
+ if(aFormats.hasValue())
+ {
+ Reference< util::XNumberFormatsSupplier> xSuppl;
+ aFormats >>= xSuppl;
+ if(xSuppl.is())
+ {
+ xNumberFormats = xSuppl->getNumberFormats( );
+ }
+ }
+ }
+ Reference <XNameAccess> xCols = xColSupp->getColumns();
+ const Sequence<OUString> aColNames = xCols->getElementNames();
+ for (const OUString& rColName : aColNames)
+ {
+ std::unique_ptr<SwInsDBColumn> pNew(new SwInsDBColumn( rColName ));
+ Any aCol = xCols->getByName(rColName);
+ Reference <XPropertySet> xCol;
+ aCol >>= xCol;
+ Any aType = xCol->getPropertyValue("Type");
+ sal_Int32 eDataType = 0;
+ aType >>= eDataType;
+ switch(eDataType)
+ {
+ case DataType::BIT:
+ case DataType::BOOLEAN:
+ case DataType::TINYINT:
+ case DataType::SMALLINT:
+ case DataType::INTEGER:
+ case DataType::BIGINT:
+ case DataType::FLOAT:
+ case DataType::REAL:
+ case DataType::DOUBLE:
+ case DataType::NUMERIC:
+ case DataType::DECIMAL:
+ case DataType::DATE:
+ case DataType::TIME:
+ case DataType::TIMESTAMP:
+ {
+ pNew->bHasFormat = true;
+ Any aFormat = xCol->getPropertyValue("FormatKey");
+ if(aFormat.hasValue())
+ {
+ sal_Int32 nFormat = 0;
+ aFormat >>= nFormat;
+ if(xNumberFormats.is())
+ {
+ try
+ {
+ Reference<XPropertySet> xNumProps = xNumberFormats->getByKey( nFormat );
+ Any aFormatVal = xNumProps->getPropertyValue("FormatString");
+ Any aLocale = xNumProps->getPropertyValue("Locale");
+ OUString sFormat;
+ aFormatVal >>= sFormat;
+ lang::Locale aLoc;
+ aLocale >>= aLoc;
+ sal_Int32 nKey = xDocNumberFormats->queryKey( sFormat, aLoc, true);
+ if(nKey < 0)
+ {
+ nKey = xDocNumberFormats->addNew( sFormat, aLoc );
+ }
+ pNew->nDBNumFormat = nKey;
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("illegal number format key");
+ }
+ }
+ }
+ else
+ {
+ pNew->nDBNumFormat = getDefaultNumberFormat(xCol,
+ xDocNumberFormatTypes, LanguageTag( rSh.GetCurLang() ).getLocale());
+ }
+
+ }
+ break;
+ }
+ if( !m_aDBColumns.insert( std::move(pNew) ).second )
+ {
+ OSL_ENSURE( false, "Spaltenname mehrfach vergeben?" );
+ }
+ }
+ }
+
+ // fill paragraph templates-ListBox
+ {
+ SfxStyleSheetBasePool* pPool = m_pView->GetDocShell()->GetStyleSheetPool();
+ m_xLbDbParaColl->append_text( m_sNoTmpl );
+
+ const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Para);
+ while( pBase )
+ {
+ m_xLbDbParaColl->append_text( pBase->GetName() );
+ pBase = pPool->Next();
+ }
+ m_xLbDbParaColl->set_active( 0 );
+ }
+
+ // when the cursor is inside of a table, table must NEVER be selectable
+ if( m_pView->GetWrtShell().GetTableFormat() )
+ {
+ m_xRbAsField->set_active(true);
+ m_xRbAsTable->set_sensitive(false);
+ m_xRbDbFormatFromDb->set_active(true);
+ }
+ else
+ {
+ m_xRbAsTable->set_active(true);
+ m_xRbDbFormatFromDb->set_active(true);
+ m_xIbDbcolOneFrom->set_sensitive( false );
+ m_xIbDbcolAllFrom->set_sensitive( false );
+ }
+
+ // by default, select header button
+ m_xRbHeadlColnms->set_active(true);
+ m_xRbHeadlEmpty->set_active(false);
+
+ m_xRbAsTable->connect_toggled( LINK(this, SwInsertDBColAutoPilot, PageHdl ));
+ m_xRbAsField->connect_toggled( LINK(this, SwInsertDBColAutoPilot, PageHdl ));
+ m_xRbAsText->connect_toggled( LINK(this, SwInsertDBColAutoPilot, PageHdl ));
+
+ m_xRbDbFormatFromDb->connect_toggled( LINK(this, SwInsertDBColAutoPilot, DBFormatHdl ));
+ m_xRbDbFormatFromUsr->connect_toggled( LINK(this, SwInsertDBColAutoPilot, DBFormatHdl ));
+
+ m_xPbTableFormat->connect_clicked(LINK(this, SwInsertDBColAutoPilot, TableFormatHdl ));
+ m_xPbTableAutofmt->connect_clicked(LINK(this, SwInsertDBColAutoPilot, AutoFormatHdl ));
+
+ m_xIbDbcolAllTo->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl ));
+ m_xIbDbcolOneTo->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl ));
+ m_xIbDbcolOneFrom->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl ));
+ m_xIbDbcolAllFrom->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl ));
+ m_xIbDbcolToEdit->connect_clicked( LINK(this, SwInsertDBColAutoPilot, TableToFromHdl ));
+
+ m_xCbTableHeadon->connect_toggled( LINK(this, SwInsertDBColAutoPilot, HeaderHdl ));
+
+ m_xLbTextDbColumn->connect_changed( LINK( this, SwInsertDBColAutoPilot, TVSelectHdl ));
+ m_xLbTableDbColumn->connect_changed( LINK( this, SwInsertDBColAutoPilot, TVSelectHdl ));
+ m_xLbDbFormatFromUsr->connect_changed( LINK( this, SwInsertDBColAutoPilot, CBSelectHdl ));
+ m_xLbTableCol->connect_changed( LINK( this, SwInsertDBColAutoPilot, TVSelectHdl ));
+
+ m_xLbTextDbColumn->connect_row_activated( LINK( this, SwInsertDBColAutoPilot, DblClickHdl ));
+ m_xLbTableDbColumn->connect_row_activated( LINK( this, SwInsertDBColAutoPilot, DblClickHdl ));
+ m_xLbTableCol->connect_row_activated( LINK( this, SwInsertDBColAutoPilot, DblClickHdl ));
+
+ for( size_t n = 0; n < m_aDBColumns.size(); ++n )
+ {
+ const OUString& rS = m_aDBColumns[ n ]->sColumn;
+ m_xLbTableDbColumn->append_text(rS);
+ m_xLbTextDbColumn->append_text(rS);
+ }
+ m_xLbTextDbColumn->select(0);
+ m_xLbTableDbColumn->select(0);
+
+ // read configuration
+ Load();
+
+ // lock size to widest config
+ m_xHeadFrame->set_size_request(m_xHeadFrame->get_preferred_size().Width(), -1);
+ // initialise Controls:
+ PageHdl(m_xRbAsTable->get_active() ? *m_xRbAsTable : *m_xRbAsField);
+}
+
+SwInsertDBColAutoPilot::~SwInsertDBColAutoPilot()
+{
+}
+
+IMPL_LINK( SwInsertDBColAutoPilot, PageHdl, weld::Toggleable&, rButton, void )
+{
+ if (!rButton.get_active())
+ return;
+
+ bool bShowTable = m_xRbAsTable->get_active();
+
+ weld::RadioButton& rRadio = dynamic_cast<weld::RadioButton&>(rButton);
+ m_xHeadFrame->set_label(MnemonicGenerator::EraseAllMnemonicChars(rRadio.get_label().replace('_', '~')));
+
+ m_xLbTextDbColumn->set_visible( !bShowTable );
+ m_xIbDbcolToEdit->set_visible( !bShowTable );
+ m_xEdDbText->set_visible( !bShowTable );
+ m_xFtDbParaColl->set_visible( !bShowTable );
+ m_xLbDbParaColl->set_visible( !bShowTable );
+
+ m_xLbTableDbColumn->set_visible( bShowTable );
+ m_xIbDbcolAllTo->set_visible( bShowTable );
+ m_xIbDbcolOneTo->set_visible( bShowTable );
+ m_xIbDbcolOneFrom->set_visible( bShowTable );
+ m_xIbDbcolAllFrom->set_visible( bShowTable );
+ m_xFtTableCol->set_visible( bShowTable );
+ m_xLbTableCol->set_visible( bShowTable );
+ m_xCbTableHeadon->set_visible( bShowTable );
+ m_xRbHeadlColnms->set_visible( bShowTable );
+ m_xRbHeadlEmpty->set_visible( bShowTable );
+ m_xPbTableFormat->set_visible( bShowTable );
+ m_xPbTableAutofmt->set_visible( bShowTable );
+
+ if( bShowTable )
+ m_xPbTableFormat->set_sensitive( 0 != m_xLbTableCol->n_children() );
+
+ TVSelectHdl( bShowTable ? *m_xLbTableDbColumn : *m_xLbTextDbColumn );
+}
+
+IMPL_LINK( SwInsertDBColAutoPilot, DBFormatHdl, weld::Toggleable&, rButton, void )
+{
+ if (!rButton.get_active())
+ return;
+
+ weld::TreeView& rBox = m_xRbAsTable->get_active()
+ ? ( m_xLbTableCol->get_id(0).isEmpty()
+ ? *m_xLbTableDbColumn
+ : *m_xLbTableCol )
+ : *m_xLbTextDbColumn;
+
+ SwInsDBColumn aSrch(rBox.get_selected_text());
+ SwInsDBColumns::const_iterator it = m_aDBColumns.find( &aSrch );
+
+ bool bFromDB = m_xRbDbFormatFromDb->get_active();
+ (*it)->bIsDBFormat = bFromDB;
+ m_xLbDbFormatFromUsr->set_sensitive( !bFromDB );
+}
+
+IMPL_LINK( SwInsertDBColAutoPilot, TableToFromHdl, weld::Button&, rButton, void )
+{
+ bool bChgEnable = true, bEnableTo = true, bEnableFrom = true;
+
+ if( &rButton == m_xIbDbcolAllTo.get() )
+ {
+ bEnableTo = false;
+
+ sal_Int32 n, nInsPos = m_xLbTableCol->get_selected_index(),
+ nCnt = m_xLbTableDbColumn->n_children();
+
+ m_xLbTableDbColumn->unselect_all();
+
+ m_xLbTableDbColumn->freeze();
+ m_xLbTableCol->freeze();
+
+ if (nInsPos == -1)
+ for( n = 0; n < nCnt; ++n )
+ m_xLbTableCol->append_text(m_xLbTableDbColumn->get_text(n));
+ else
+ for( n = 0; n < nCnt; ++n, ++nInsPos )
+ m_xLbTableCol->insert_text(nInsPos, m_xLbTableDbColumn->get_text(n));
+ m_xLbTableDbColumn->clear();
+
+ m_xLbTableDbColumn->thaw();
+ m_xLbTableCol->thaw();
+
+ m_xLbTableCol->select(nInsPos);
+ }
+ else if( &rButton == m_xIbDbcolOneTo.get() &&
+ m_xLbTableDbColumn->get_selected_index() != -1 )
+ {
+ sal_Int32 nInsPos = m_xLbTableCol->get_selected_index(),
+ nDelPos = m_xLbTableDbColumn->get_selected_index();
+ m_xLbTableCol->insert_text(nInsPos, m_xLbTableDbColumn->get_text(nDelPos));
+ m_xLbTableDbColumn->remove(nDelPos);
+
+ m_xLbTableCol->select(nInsPos);
+ if (nDelPos >= m_xLbTableDbColumn->n_children())
+ nDelPos = m_xLbTableDbColumn->n_children() - 1;
+ m_xLbTableDbColumn->select(nDelPos);
+
+ bEnableTo = 0 != m_xLbTableDbColumn->n_children();
+ }
+ else if( &rButton == m_xIbDbcolOneFrom.get() )
+ {
+ if (m_xLbTableCol->get_selected_index() != -1)
+ {
+ sal_Int32 nInsPos,
+ nDelPos = m_xLbTableCol->get_selected_index();
+
+ // look for the right InsertPos!!
+ SwInsDBColumn aSrch(m_xLbTableCol->get_text(nDelPos));
+ SwInsDBColumns::const_iterator it = m_aDBColumns.find( &aSrch );
+ if( it == m_aDBColumns.begin() || (it+1) == m_aDBColumns.end() )
+ nInsPos = it - m_aDBColumns.begin();
+ else
+ {
+ nInsPos = -1;
+ while( ++it != m_aDBColumns.end() &&
+ -1 == (nInsPos = m_xLbTableDbColumn->
+ find_text( (*it)->sColumn )) )
+ ;
+ }
+
+ m_xLbTableDbColumn->insert_text(nInsPos, aSrch.sColumn);
+ m_xLbTableCol->remove( nDelPos );
+
+ if (nInsPos >= m_xLbTableDbColumn->n_children())
+ nInsPos = m_xLbTableDbColumn->n_children() - 1;
+ m_xLbTableDbColumn->select(nInsPos);
+
+ if (nDelPos >= m_xLbTableCol->n_children())
+ nDelPos = m_xLbTableCol->n_children() - 1;
+ m_xLbTableCol->select(nDelPos);
+ }
+ else
+ bEnableTo = 0 != m_xLbTableDbColumn->n_children();
+
+ bEnableFrom = 0 != m_xLbTableCol->n_children();
+ }
+ else if( &rButton == m_xIbDbcolAllFrom.get() )
+ {
+ bEnableFrom = false;
+
+ m_xLbTableDbColumn->freeze();
+ m_xLbTableCol->freeze();
+
+ m_xLbTableDbColumn->clear();
+ m_xLbTableCol->clear();
+ for (size_t n = 0; n < m_aDBColumns.size(); ++n)
+ m_xLbTableDbColumn->append_text(m_aDBColumns[n]->sColumn);
+
+ m_xLbTableDbColumn->thaw();
+ m_xLbTableCol->thaw();
+
+ m_xLbTableDbColumn->select(0);
+ }
+ else if( &rButton == m_xIbDbcolToEdit.get() )
+ {
+ bChgEnable = false;
+ // move data to Edit:
+ OUString aField(m_xLbTextDbColumn->get_selected_text());
+ if( !aField.isEmpty() )
+ {
+ OUString aStr( m_xEdDbText->get_text() );
+ int nStartPos, nEndPos;
+ m_xEdDbText->get_selection_bounds(nStartPos, nEndPos);
+ sal_Int32 nPos = std::min(nStartPos, nEndPos);
+ sal_Int32 nMax = std::max(nStartPos, nEndPos);
+ const sal_Int32 nSel = nMax - nPos;
+ if( nSel )
+ // first delete the existing selection
+ aStr = aStr.replaceAt( nPos, nSel, u"" );
+
+ aField = OUStringChar(cDBFieldStart) + aField + OUStringChar(cDBFieldEnd);
+ if( !aStr.isEmpty() )
+ {
+ if( nPos ) // one blank in front
+ {
+ sal_Unicode c = aStr[ nPos-1 ];
+ if( '\n' != c && '\r' != c )
+ aField = " " + aField;
+ }
+ if( nPos < aStr.getLength() ) // one blank behind
+ {
+ sal_Unicode c = aStr[ nPos ];
+ if( '\n' != c && '\r' != c )
+ aField += " ";
+ }
+ }
+
+ m_xEdDbText->set_text( aStr.replaceAt( nPos, 0, aField ) );
+ nPos += aField.getLength();
+ m_xEdDbText->select_region(nPos, nPos);
+ }
+ }
+
+ if( !bChgEnable )
+ return;
+
+ m_xIbDbcolOneTo->set_sensitive( bEnableTo );
+ m_xIbDbcolAllTo->set_sensitive( bEnableTo );
+ m_xIbDbcolOneFrom->set_sensitive( bEnableFrom );
+ m_xIbDbcolAllFrom->set_sensitive( bEnableFrom );
+
+ m_xRbDbFormatFromDb->set_sensitive( false );
+ m_xRbDbFormatFromUsr->set_sensitive( false );
+ m_xLbDbFormatFromUsr->set_sensitive( false );
+
+ m_xPbTableFormat->set_sensitive( bEnableFrom );
+}
+
+IMPL_LINK(SwInsertDBColAutoPilot, DblClickHdl, weld::TreeView&, rBox, bool)
+{
+ weld::Button* pButton = nullptr;
+ if( &rBox == m_xLbTextDbColumn.get() )
+ pButton = m_xIbDbcolToEdit.get();
+ else if( &rBox == m_xLbTableDbColumn.get() && m_xIbDbcolOneTo->get_sensitive() )
+ pButton = m_xIbDbcolOneTo.get();
+ else if( &rBox == m_xLbTableCol.get() && m_xIbDbcolOneFrom->get_sensitive() )
+ pButton = m_xIbDbcolOneFrom.get();
+
+ if (pButton)
+ TableToFromHdl(*pButton);
+
+ return true;
+}
+
+IMPL_LINK_NOARG(SwInsertDBColAutoPilot, TableFormatHdl, weld::Button&, void)
+{
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ bool bNewSet = false;
+ if( !m_pTableSet )
+ {
+ bNewSet = true;
+ m_pTableSet.reset(new SfxItemSet( rSh.GetAttrPool(), SwuiGetUITableAttrRange() ));
+
+ // At first acquire the simple attributes
+ m_pTableSet->Put( SfxStringItem( FN_PARAM_TABLE_NAME, rSh.GetUniqueTableName() ));
+ m_pTableSet->Put( SfxUInt16Item( FN_PARAM_TABLE_HEADLINE, 1 ) );
+
+ m_pTableSet->Put( SfxUInt16Item( SID_BACKGRND_DESTINATION,
+ rSh.GetViewOptions()->GetTableDest() ));
+
+ SvxBrushItem aBrush( RES_BACKGROUND );
+ m_pTableSet->Put( aBrush );
+ aBrush.SetWhich(SID_ATTR_BRUSH_ROW);
+ m_pTableSet->Put( aBrush );
+ aBrush.SetWhich(SID_ATTR_BRUSH_TABLE);
+ m_pTableSet->Put( aBrush );
+
+ SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
+ // table variant, when multiple table cells are selected
+ aBoxInfo.SetTable( true );
+ // always show gap field
+ aBoxInfo.SetDist( true);
+ // set minimum size in tables and paragraphs
+ aBoxInfo.SetMinDist( false );
+ // always set default-gap
+ aBoxInfo.SetDefDist( MIN_BORDER_DIST );
+ // Single lines can have DontCare-status only in tables
+ aBoxInfo.SetValid( SvxBoxInfoItemValidFlags::DISABLE );
+ m_pTableSet->Put( aBoxInfo );
+
+ SwGetCurColNumPara aPara;
+ const sal_uInt16 nNum = rSh.GetCurColNum( &aPara );
+ tools::Long nWidth;
+
+ if( nNum )
+ {
+ nWidth = aPara.pPrtRect->Width();
+ const SwFormatCol& rCol = aPara.pFrameFormat->GetCol();
+ const SwColumns& rCols = rCol.GetColumns();
+
+ // initialise nStart and nEnd for nNum == 0
+ tools::Long nWidth1 = 0,
+ nStart1 = 0,
+ nEnd1 = nWidth;
+ for( sal_uInt16 i = 0; i < nNum; ++i )
+ {
+ const SwColumn* pCol = &rCols[i];
+ nStart1 = pCol->GetLeft() + nWidth1;
+ nWidth1 += static_cast<tools::Long>(rCol.CalcColWidth( i, o3tl::narrowing<sal_uInt16>(nWidth) ));
+ nEnd1 = nWidth1 - pCol->GetRight();
+ }
+ if(nStart1 || nEnd1 != nWidth)
+ nWidth = nEnd1 - nStart1;
+ }
+ else
+ nWidth = rSh.GetAnyCurRect(
+ (FrameTypeFlags::FLY_ANY & rSh.GetFrameType( nullptr, true ))
+ ? CurRectType::FlyEmbeddedPrt
+ : CurRectType::PagePrt ).Width();
+
+ SwTabCols aTabCols;
+ aTabCols.SetRight( nWidth );
+ aTabCols.SetRightMax( nWidth );
+ m_pRep.reset(new SwTableRep( aTabCols ));
+ m_pRep->SetAlign( text::HoriOrientation::NONE );
+ m_pRep->SetSpace( nWidth );
+ m_pRep->SetWidth( nWidth );
+ m_pRep->SetWidthPercent( 100 );
+ m_pTableSet->Put( SwPtrItem( FN_TABLE_REP, m_pRep.get() ));
+
+ m_pTableSet->Put( SfxUInt16Item( SID_HTML_MODE,
+ ::GetHtmlMode( m_pView->GetDocShell() )));
+ }
+
+ sal_Int32 nCols = m_xLbTableCol->n_children();
+ if (nCols != m_pRep->GetAllColCount() && nCols > 0)
+ {
+ // Number of columns has changed: then the TabCols have to be adjusted
+ tools::Long nWidth = m_pRep->GetWidth();
+ --nCols;
+ SwTabCols aTabCols( nCols );
+ aTabCols.SetRight( nWidth );
+ aTabCols.SetRightMax( nWidth );
+ if( nCols )
+ {
+ const sal_Int32 nStep = nWidth / (nCols+1);
+ for( sal_Int32 n = 0; n < nCols; ++n )
+ {
+ aTabCols.Insert( nStep*(n+1), false, n );
+ }
+ }
+ m_pRep.reset(new SwTableRep( aTabCols ));
+ m_pRep->SetAlign( text::HoriOrientation::NONE );
+ m_pRep->SetSpace( nWidth );
+ m_pRep->SetWidth( nWidth );
+ m_pRep->SetWidthPercent( 100 );
+ m_pTableSet->Put( SwPtrItem( FN_TABLE_REP, m_pRep.get() ));
+ }
+
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(rFact.CreateSwTableTabDlg(m_xDialog.get(), m_pTableSet.get(), &rSh));
+ if( RET_OK == pDlg->Execute() )
+ m_pTableSet->Put( *pDlg->GetOutputItemSet() );
+ else if( bNewSet )
+ {
+ m_pTableSet.reset();
+ m_pRep.reset();
+ }
+}
+
+IMPL_LINK_NOARG(SwInsertDBColAutoPilot, AutoFormatHdl, weld::Button&, void)
+{
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+
+ ScopedVclPtr<AbstractSwAutoFormatDlg> pDlg(rFact.CreateSwAutoFormatDlg(m_xDialog.get(), m_pView->GetWrtShellPtr(), false, m_xTAutoFormat.get()));
+ if( RET_OK == pDlg->Execute())
+ m_xTAutoFormat = pDlg->FillAutoFormatOfIndex();
+}
+
+IMPL_LINK(SwInsertDBColAutoPilot, TVSelectHdl, weld::TreeView&, rBox, void)
+{
+ weld::TreeView* pGetBox = &rBox;
+
+ SwInsDBColumn aSrch(pGetBox->get_selected_text());
+ SwInsDBColumns::const_iterator it = m_aDBColumns.find( &aSrch );
+
+ // set the selected FieldName at the FormatGroupBox, so that
+ // it's clear what field is configured by the format!
+ OUString sText( m_xFormatFrame->get_label().copy( 0, m_nGBFormatLen ));
+ if( aSrch.sColumn.isEmpty() )
+ {
+ m_xRbDbFormatFromDb->set_sensitive( false );
+ m_xRbDbFormatFromUsr->set_sensitive( false );
+ m_xLbDbFormatFromUsr->set_sensitive( false );
+ }
+ else
+ {
+ bool bEnableFormat = (*it)->bHasFormat;
+ m_xRbDbFormatFromDb->set_sensitive( bEnableFormat );
+ m_xRbDbFormatFromUsr->set_sensitive( bEnableFormat );
+
+ if( bEnableFormat )
+ {
+ sText += " (" + aSrch.sColumn + ")";
+ }
+
+ bool bIsDBFormat = (*it)->bIsDBFormat;
+ m_xRbDbFormatFromDb->set_active( bIsDBFormat );
+ m_xRbDbFormatFromUsr->set_active( !bIsDBFormat );
+ m_xLbDbFormatFromUsr->set_sensitive( !bIsDBFormat );
+ if( !bIsDBFormat )
+ m_xLbDbFormatFromUsr->SetDefFormat( (*it)->nUsrNumFormat );
+ }
+
+ m_xFormatFrame->set_label(sText);
+
+ if (m_xLbTableCol->n_children())
+ {
+ // to know later on, what ListBox was the "active", a Flag
+ // is remembered in the 1st entry
+ if (&rBox == m_xLbTableCol.get())
+ m_xLbTableCol->set_id(0, "tablecols");
+ else
+ m_xLbTableCol->set_id(0, OUString());
+ }
+}
+
+IMPL_LINK_NOARG(SwInsertDBColAutoPilot, CBSelectHdl, weld::ComboBox&, void)
+{
+ weld::TreeView* pGetBox = m_xRbAsTable->get_active()
+ ? ( m_xLbTableCol->get_id(0).isEmpty()
+ ? m_xLbTableDbColumn.get()
+ : m_xLbTableCol.get() )
+ : m_xLbTextDbColumn.get();
+
+ SwInsDBColumn aSrch(pGetBox->get_selected_text());
+ SwInsDBColumns::const_iterator it = m_aDBColumns.find( &aSrch );
+
+ if( !aSrch.sColumn.isEmpty() )
+ {
+ m_xLbDbFormatFromUsr->CallSelectHdl();
+ (*it)->nUsrNumFormat = m_xLbDbFormatFromUsr->GetFormat();
+ }
+}
+
+IMPL_LINK_NOARG(SwInsertDBColAutoPilot, HeaderHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xCbTableHeadon->get_active();
+ m_xRbHeadlColnms->set_sensitive( bEnable );
+ m_xRbHeadlEmpty->set_sensitive( bEnable );
+}
+
+static void lcl_InsTextInArr( std::u16string_view aText, DB_Columns& rColArr )
+{
+ size_t nSttPos = 0;
+ size_t nFndPos;
+ while( std::u16string_view::npos != ( nFndPos = aText.find( '\x0A', nSttPos )) )
+ {
+ if( 1 < nFndPos )
+ {
+ rColArr.push_back(std::make_unique<DB_Column>(OUString(aText.substr(nSttPos, nFndPos -1))));
+ }
+ rColArr.push_back(std::make_unique<DB_Column>());
+ nSttPos = nFndPos + 1;
+ }
+ if( nSttPos < aText.size() )
+ {
+ rColArr.push_back(std::make_unique<DB_Column>(OUString(aText.substr(nSttPos))));
+ }
+}
+
+bool SwInsertDBColAutoPilot::SplitTextToColArr( const OUString& rText,
+ DB_Columns& rColArr,
+ bool bInsField )
+{
+ // create each of the database columns from the text again
+ // and then save in an array
+ // database columns are in <> and must be present in the columns' array:
+ OUString sText( rText );
+ sal_Int32 nFndPos, nEndPos, nSttPos = 0;
+
+ while( -1 != ( nFndPos = sText.indexOf( cDBFieldStart, nSttPos )))
+ {
+ nSttPos = nFndPos + 1;
+ nEndPos = sText.indexOf( cDBFieldEnd, nSttPos+1 );
+ if( -1 != nEndPos )
+ {
+ // Text in <> brackets found: what is it:
+ SwInsDBColumn aSrch( sText.copy( nSttPos, nEndPos - nSttPos ));
+ SwInsDBColumns::const_iterator it = m_aDBColumns.find( &aSrch );
+ if( it != m_aDBColumns.end() )
+ {
+ // that is a valid field
+ // so surely the text "before":
+ const SwInsDBColumn& rFndCol = **it;
+
+ DB_Column* pNew;
+
+ if( 1 < nSttPos )
+ {
+ ::lcl_InsTextInArr( sText.subView( 0, nSttPos-1 ), rColArr );
+ sText = sText.copy( nSttPos-1 );
+ }
+
+ sText = sText.copy( rFndCol.sColumn.getLength() + 2 );
+ nSttPos = 0;
+
+ sal_uInt16 nSubType = 0;
+ sal_uInt32 nFormat;
+ if( rFndCol.bHasFormat )
+ {
+ if( rFndCol.bIsDBFormat )
+ nFormat = static_cast<sal_uInt32>(rFndCol.nDBNumFormat);
+ else
+ {
+ nFormat = rFndCol.nUsrNumFormat;
+ nSubType = nsSwExtendedSubType::SUB_OWN_FMT;
+ }
+ }
+ else
+ nFormat = 0;
+
+ if( bInsField )
+ {
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ SwDBFieldType aFieldType( rSh.GetDoc(), aSrch.sColumn,
+ m_aDBData );
+ pNew = new DB_Column( rFndCol, *new SwDBField(
+ static_cast<SwDBFieldType*>(rSh.InsertFieldType( aFieldType )),
+ nFormat ) );
+ if( nSubType )
+ pNew->pField->SetSubType( nSubType );
+ }
+ else
+ pNew = new DB_Column( rFndCol, nFormat );
+
+ rColArr.push_back( std::unique_ptr<DB_Column>(pNew) );
+ }
+ }
+ }
+
+ // don't forget the last text
+ if( !sText.isEmpty() )
+ ::lcl_InsTextInArr( sText, rColArr );
+
+ return !rColArr.empty();
+}
+
+void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,
+ Reference< XDataSource> const & xSource,
+ Reference< XConnection> const & xConnection,
+ Reference< sdbc::XResultSet > const & xResultSet_in )
+{
+ auto xResultSet = xResultSet_in;
+
+ const Any* pSelection = rSelection.hasElements() ? rSelection.getConstArray() : nullptr;
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+
+ //with the drag and drop interface no result set is initially available
+ bool bDisposeResultSet = false;
+ // we don't have a cursor, so we have to create our own RowSet
+ if ( !xResultSet.is() )
+ {
+ xResultSet = SwDBManager::createCursor(m_aDBData.sDataSource,m_aDBData.sCommand,m_aDBData.nCommandType,xConnection,m_pView);
+ bDisposeResultSet = xResultSet.is();
+ }
+
+ Reference< sdbc::XRow > xRow(xResultSet, UNO_QUERY);
+ if ( !xRow.is() )
+ return;
+
+ rSh.StartAllAction();
+ bool bUndo = rSh.DoesUndo();
+ if( bUndo )
+ rSh.StartUndo();
+
+ bool bAsTable = m_xRbAsTable->get_active();
+ SvNumberFormatter& rNumFormatr = *rSh.GetNumberFormatter();
+
+ if( rSh.HasSelection() )
+ rSh.DelRight();
+
+ std::optional<SwWait> oWait;
+
+ Reference< XColumnsSupplier > xColsSupp( xResultSet, UNO_QUERY );
+ Reference <XNameAccess> xCols = xColsSupp->getColumns();
+
+ uno::Reference<sdbcx::XRowLocate> xRowLocate(xResultSet, uno::UNO_QUERY_THROW);
+
+ do{ // middle checked loop!!
+ if( bAsTable ) // fill in data as table
+ {
+ rSh.DoUndo( false );
+
+ sal_Int32 nCols = m_xLbTableCol->n_children();
+ sal_Int32 nRows = 0;
+ if( m_xCbTableHeadon->get_active() )
+ nRows++;
+
+ if( pSelection )
+ nRows += rSelection.getLength();
+ else
+ ++nRows;
+
+ // prepare the array for the selected columns
+ std::vector<SwInsDBColumn*> aColFields;
+ for( sal_Int32 n = 0; n < nCols; ++n )
+ {
+ SwInsDBColumn aSrch(m_xLbTableCol->get_text(n));
+ SwInsDBColumns::const_iterator it = m_aDBColumns.find( &aSrch );
+ if (it != m_aDBColumns.end())
+ aColFields.push_back(it->get());
+ else {
+ OSL_ENSURE( false, "database column not found" );
+ }
+ }
+
+ if( static_cast<size_t>(nCols) != aColFields.size() )
+ {
+ OSL_ENSURE( false, "not all database columns found" );
+ nCols = static_cast<sal_Int32>(aColFields.size());
+ }
+
+ if(!nRows || !nCols)
+ {
+ OSL_ENSURE( false, "wrong parameters" );
+ break;
+ }
+
+ const SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+
+ bool bHTML = 0 != (::GetHtmlMode( m_pView->GetDocShell() ) & HTMLMODE_ON);
+ rSh.InsertTable(
+ pModOpt->GetInsTableFlags(bHTML),
+ nRows, nCols, (pSelection ? m_xTAutoFormat.get(): nullptr) );
+ rSh.MoveTable( GotoPrevTable, fnTableStart );
+
+ if( pSelection && m_pTableSet )
+ SetTabSet();
+
+ SfxItemSetFixed<RES_BOXATR_FORMAT, RES_BOXATR_VALUE> aTableSet( rSh.GetAttrPool() );
+ bool bIsAutoUpdateCells = rSh.IsAutoUpdateCells();
+ rSh.SetAutoUpdateCells( false );
+
+ if( m_xCbTableHeadon->get_active() )
+ {
+ for( sal_Int32 n = 0; n < nCols; ++n )
+ {
+ if( m_xRbHeadlColnms->get_active() )
+ {
+ rSh.SwEditShell::Insert2( aColFields[ n ]->sColumn );
+ }
+ rSh.GoNextCell();
+ }
+ }
+ else
+ rSh.SetRowsToRepeat( 0 );
+
+ for( sal_Int32 i = 0 ; ; ++i )
+ {
+ bool bBreak = false;
+ try
+ {
+ if(pSelection)
+ {
+ bBreak = !xRowLocate->moveToBookmark(pSelection[i]);
+ }
+ else if(!i)
+ bBreak = !xResultSet->first();
+ }
+ catch (const Exception&)
+ {
+ bBreak = true;
+ }
+ if(bBreak)
+ break;
+
+ for( sal_Int32 n = 0; n < nCols; ++n )
+ {
+ // at the very first time, NO GoNextCell, because we're
+ // already in it. Also no GoNextCell after the Insert,
+ // because an empty line is added at the end.
+ if( i || n )
+ rSh.GoNextCell();
+
+ const SwInsDBColumn* pEntry = aColFields[ n ];
+
+ Reference< XColumn > xColumn;
+ xCols->getByName(pEntry->sColumn) >>= xColumn;
+ Reference< XPropertySet > xColumnProps( xColumn, UNO_QUERY );
+ sal_Int32 eDataType = 0;
+ if( xColumnProps.is() )
+ {
+ Any aType = xColumnProps->getPropertyValue("Type");
+ aType >>= eDataType;
+ }
+ try
+ {
+ if( pEntry->bHasFormat )
+ {
+ SwTableBoxNumFormat aNumFormat(
+ pEntry->bIsDBFormat ? static_cast<sal_uInt32>(pEntry->nDBNumFormat)
+ : pEntry->nUsrNumFormat );
+ aTableSet.Put(aNumFormat);
+ if( xColumn.is() )
+ {
+ double fVal = xColumn->getDouble();
+ if( xColumn->wasNull() )
+ aTableSet.ClearItem( RES_BOXATR_VALUE );
+ else
+ {
+ if(rNumFormatr.GetType(aNumFormat.GetValue()) & SvNumFormatType::DATE)
+ {
+ ::Date aStandard(1,1,1900);
+ if (rNumFormatr.GetNullDate() != aStandard)
+ fVal += (aStandard - rNumFormatr.GetNullDate());
+ }
+ aTableSet.Put( SwTableBoxValue( fVal ));
+ }
+ }
+ else
+ aTableSet.ClearItem( RES_BOXATR_VALUE );
+ rSh.SetTableBoxFormulaAttrs( aTableSet );
+ }
+ //#i60207# don't insert binary data as string - creates a loop
+ else if( DataType::BINARY == eDataType ||
+ DataType::VARBINARY == eDataType ||
+ DataType::LONGVARBINARY== eDataType ||
+ DataType::SQLNULL == eDataType ||
+ DataType::OTHER == eDataType ||
+ DataType::OBJECT == eDataType ||
+ DataType::DISTINCT == eDataType ||
+ DataType::STRUCT == eDataType ||
+ DataType::ARRAY == eDataType ||
+ DataType::BLOB == eDataType ||
+ DataType::CLOB == eDataType ||
+ DataType::REF == eDataType
+ )
+ {
+ // do nothing
+ }
+ else
+ {
+ const OUString sVal = xColumn->getString();
+ if(!xColumn->wasNull())
+ {
+ rSh.SwEditShell::Insert2( sVal );
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("sw", "");
+ }
+ }
+
+ if( !pSelection )
+ {
+ if ( !xResultSet->next() )
+ break;
+ }
+ else if( i+1 >= rSelection.getLength() )
+ break;
+
+ if( 10 == i )
+ oWait.emplace( *m_pView->GetDocShell(), true );
+ }
+
+ rSh.MoveTable( GotoCurrTable, fnTableStart );
+ if( !pSelection && ( m_pTableSet || m_xTAutoFormat ))
+ {
+ if( m_pTableSet )
+ SetTabSet();
+
+ if (m_xTAutoFormat)
+ rSh.SetTableStyle(*m_xTAutoFormat);
+ }
+ rSh.SetAutoUpdateCells( bIsAutoUpdateCells );
+ }
+ else // add data as fields/text
+ {
+ DB_Columns aColArr;
+ if( SplitTextToColArr( m_xEdDbText->get_text(), aColArr, m_xRbAsField->get_active() ) )
+ {
+ // now for each data set, we can iterate over the array
+ // and add the data
+
+ if( !rSh.IsSttPara() )
+ rSh.SwEditShell::SplitNode();
+ if( !rSh.IsEndPara() )
+ {
+ rSh.SwEditShell::SplitNode();
+ rSh.SwCursorShell::Left(1,SwCursorSkipMode::Chars);
+ }
+
+ rSh.DoUndo( false );
+
+ SwTextFormatColl* pColl = nullptr;
+ {
+ const OUString sTmplNm(m_xLbDbParaColl->get_active_text());
+ if( m_sNoTmpl != sTmplNm )
+ {
+ pColl = rSh.FindTextFormatCollByName( sTmplNm );
+ if( !pColl )
+ {
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
+ sTmplNm, SwGetPoolIdFromName::TxtColl );
+ if( USHRT_MAX != nId )
+ pColl = rSh.GetTextCollFromPool( nId );
+ else
+ pColl = rSh.MakeTextFormatColl( sTmplNm );
+ }
+ rSh.SetTextFormatColl( pColl );
+ }
+ }
+
+ // for adding as fields -> insert a "NextField" after
+ // every data set
+ SwDBFormatData aDBFormatData;
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ aDBFormatData.xFormatter.set(util::NumberFormatter::create(xContext), UNO_QUERY_THROW) ;
+
+ Reference<XPropertySet> xSourceProps(xSource, UNO_QUERY);
+ if(xSourceProps.is())
+ {
+ Any aFormats = xSourceProps->getPropertyValue("NumberFormatsSupplier");
+ if(aFormats.hasValue())
+ {
+ Reference< util::XNumberFormatsSupplier> xSuppl;
+ aFormats >>= xSuppl;
+ if(xSuppl.is())
+ {
+ Reference< XPropertySet > xSettings = xSuppl->getNumberFormatSettings();
+ Any aNull = xSettings->getPropertyValue("NullDate");
+ aNull >>= aDBFormatData.aNullDate;
+ if(aDBFormatData.xFormatter.is())
+ aDBFormatData.xFormatter->attachNumberFormatsSupplier(xSuppl);
+ }
+ }
+ }
+ aDBFormatData.aLocale = LanguageTag( rSh.GetCurLang() ).getLocale();
+ SwDBNextSetField aNxtDBField( static_cast<SwDBNextSetFieldType*>(rSh.
+ GetFieldType( 0, SwFieldIds::DbNextSet )),
+ "1", m_aDBData );
+
+ bool bSetCursor = true;
+ const size_t nCols = aColArr.size();
+ ::sw::mark::IMark* pMark = nullptr;
+ for( sal_Int32 i = 0 ; ; ++i )
+ {
+ bool bBreak = false;
+ try
+ {
+ if(pSelection)
+ {
+ bBreak = !xRowLocate->moveToBookmark(pSelection[i]);
+ }
+ else if(!i)
+ bBreak = !xResultSet->first();
+ }
+ catch (const Exception&)
+ {
+ bBreak = true;
+ }
+
+ if(bBreak)
+ break;
+
+ for( size_t n = 0; n < nCols; ++n )
+ {
+ DB_Column* pDBCol = aColArr[ n ].get();
+ OUString sIns;
+ switch( pDBCol->eColType )
+ {
+ case DB_Column::Type::FILLTEXT:
+ sIns = *pDBCol->pText;
+ break;
+
+ case DB_Column::Type::SPLITPARA:
+ rSh.SplitNode();
+ // when the template is not the same as the follow template,
+ // the selected has to be set newly
+ if( pColl && &pColl->GetNextTextFormatColl() != pColl )
+ rSh.SetTextFormatColl( pColl );
+ break;
+
+ case DB_Column::Type::COL_FIELD:
+ {
+ std::unique_ptr<SwDBField> pField(static_cast<SwDBField *>(
+ pDBCol->pField->CopyField().release()));
+ double nValue = DBL_MAX;
+
+ Reference< XPropertySet > xColumnProps;
+ xCols->getByName(pDBCol->pColInfo->sColumn) >>= xColumnProps;
+
+ pField->SetExpansion( SwDBManager::GetDBField(
+ xColumnProps,
+ aDBFormatData,
+ &nValue ) );
+ if( DBL_MAX != nValue )
+ {
+ Any aType = xColumnProps->getPropertyValue("Type");
+ sal_Int32 eDataType = 0;
+ aType >>= eDataType;
+ if( DataType::DATE == eDataType || DataType::TIME == eDataType ||
+ DataType::TIMESTAMP == eDataType)
+
+ {
+ ::Date aStandard(1,1,1900);
+ ::Date aCompare(aDBFormatData.aNullDate.Day ,
+ aDBFormatData.aNullDate.Month,
+ aDBFormatData.aNullDate.Year);
+ if(aStandard != aCompare)
+ nValue += (aStandard - aCompare);
+ }
+ pField->ChgValue( nValue, true );
+ }
+ pField->SetInitialized();
+
+ rSh.InsertField2( *pField );
+ }
+ break;
+
+ case DB_Column::Type::COL_TEXT:
+ {
+ double nValue = DBL_MAX;
+ Reference< XPropertySet > xColumnProps;
+ xCols->getByName(pDBCol->pColInfo->sColumn) >>= xColumnProps;
+ sIns = SwDBManager::GetDBField(
+ xColumnProps,
+ aDBFormatData,
+ &nValue );
+ if( pDBCol->nFormat &&
+ DBL_MAX != nValue )
+ {
+ const Color* pCol;
+ if(rNumFormatr.GetType(pDBCol->nFormat) & SvNumFormatType::DATE)
+ {
+ ::Date aStandard(1,1,1900);
+ if (rNumFormatr.GetNullDate() != aStandard)
+ nValue += (aStandard - rNumFormatr.GetNullDate());
+ }
+ rNumFormatr.GetOutputString( nValue,
+ pDBCol->nFormat,
+ sIns, &pCol );
+ }
+ }
+ break;
+ }
+
+ if( !sIns.isEmpty() )
+ {
+ rSh.Insert( sIns );
+
+ if( bSetCursor)
+ {
+ // to the beginning and set a mark, so that
+ // the cursor can be set to the initial position
+ // at the end.
+
+ rSh.SwCursorShell::MovePara(
+ GoCurrPara, fnParaStart );
+ pMark = rSh.SetBookmark(
+ vcl::KeyCode(),
+ OUString(),
+ IDocumentMarkAccess::MarkType::UNO_BOOKMARK );
+ rSh.SwCursorShell::MovePara(
+ GoCurrPara, fnParaEnd );
+ bSetCursor = false;
+ }
+ }
+ }
+
+ if( !pSelection )
+ {
+ bool bNext = xResultSet->next();
+ if(!bNext)
+ break;
+ }
+ else if( i+1 >= rSelection.getLength() )
+ break;
+
+ if( m_xRbAsField->get_active() )
+ rSh.InsertField2( aNxtDBField );
+
+ if( !rSh.IsSttPara() )
+ rSh.SwEditShell::SplitNode();
+
+ if( 10 == i )
+ oWait.emplace( *m_pView->GetDocShell(), true );
+ }
+
+ if( !bSetCursor && pMark != nullptr)
+ {
+ rSh.SetMark();
+ rSh.GotoMark( pMark );
+ rSh.getIDocumentMarkAccess()->deleteMark( pMark );
+ break;
+ }
+ }
+ }
+ // write configuration
+ Commit();
+ }while( false ); // middle checked loop
+
+ if( bUndo )
+ {
+ rSh.DoUndo();
+ rSh.AppendUndoForInsertFromDB( bAsTable );
+ rSh.EndUndo();
+ }
+ rSh.ClearMark();
+ rSh.EndAllAction();
+
+ if ( bDisposeResultSet )
+ ::comphelper::disposeComponent(xResultSet);
+}
+
+void SwInsertDBColAutoPilot::SetTabSet()
+{
+ SwWrtShell& rSh = m_pView->GetWrtShell();
+ const SfxPoolItem* pItem;
+
+ if (m_xTAutoFormat)
+ {
+ if (m_xTAutoFormat->IsFrame())
+ {
+ // border is from AutoFormat
+ m_pTableSet->ClearItem( RES_BOX );
+ m_pTableSet->ClearItem( SID_ATTR_BORDER_INNER );
+ }
+ if (m_xTAutoFormat->IsBackground())
+ {
+ m_pTableSet->ClearItem( RES_BACKGROUND );
+ m_pTableSet->ClearItem( SID_ATTR_BRUSH_ROW );
+ m_pTableSet->ClearItem( SID_ATTR_BRUSH_TABLE );
+ }
+ }
+ else
+ {
+ // remove the defaults again, it makes no sense to set them
+ SvxBrushItem aBrush( RES_BACKGROUND );
+ static const sal_uInt16 aIds[3] =
+ { RES_BACKGROUND, SID_ATTR_BRUSH_ROW, SID_ATTR_BRUSH_TABLE };
+ for(sal_uInt16 i : aIds)
+ if( SfxItemState::SET == m_pTableSet->GetItemState( i,
+ false, &pItem ) && *pItem == aBrush )
+ m_pTableSet->ClearItem( i );
+ }
+
+ const SfxStringItem* pTableNameItem = m_pTableSet->GetItemIfSet( FN_PARAM_TABLE_NAME, false);
+ if( pTableNameItem && pTableNameItem->GetValue() == rSh.GetTableFormat()->GetName() )
+ m_pTableSet->ClearItem( FN_PARAM_TABLE_NAME );
+
+ rSh.MoveTable( GotoCurrTable, fnTableStart );
+ rSh.SetMark();
+ rSh.MoveTable( GotoCurrTable, fnTableEnd );
+
+ ItemSetToTableParam( *m_pTableSet, rSh );
+
+ rSh.ClearMark();
+ rSh.MoveTable( GotoCurrTable, fnTableStart );
+}
+
+static Sequence<OUString> lcl_createSourceNames(std::u16string_view rNodeName)
+{
+ Sequence<OUString> aSourceNames(11);
+ OUString* pNames = aSourceNames.getArray();
+ pNames[0] = OUString::Concat(rNodeName) + "/DataSource";
+ pNames[1] = OUString::Concat(rNodeName) + "/Command";
+ pNames[2] = OUString::Concat(rNodeName) + "/CommandType";
+ pNames[3] = OUString::Concat(rNodeName) + "/ColumnsToText";
+ pNames[4] = OUString::Concat(rNodeName) + "/ColumnsToTable";
+ pNames[5] = OUString::Concat(rNodeName) + "/ParaStyle";
+ pNames[6] = OUString::Concat(rNodeName) + "/TableAutoFormat";
+ pNames[7] = OUString::Concat(rNodeName) + "/IsTable";
+ pNames[8] = OUString::Concat(rNodeName) + "/IsField";
+ pNames[9] = OUString::Concat(rNodeName) + "/IsHeadlineOn";
+ pNames[10] = OUString::Concat(rNodeName) + "/IsEmptyHeadline";
+ return aSourceNames;
+}
+
+static Sequence<OUString> lcl_CreateSubNames(std::u16string_view rSubNodeName)
+{
+ return
+ {
+ OUString::Concat(rSubNodeName) + "/ColumnName",
+ OUString::Concat(rSubNodeName) + "/ColumnIndex",
+ OUString::Concat(rSubNodeName) + "/IsNumberFormat",
+ OUString::Concat(rSubNodeName) + "/IsNumberFormatFromDataBase",
+ OUString::Concat(rSubNodeName) + "/NumberFormat",
+ OUString::Concat(rSubNodeName) + "/NumberFormatLocale"
+ };
+}
+
+static OUString lcl_CreateUniqueName(const Sequence<OUString>& aNames)
+{
+ sal_Int32 nIdx = aNames.getLength();
+ while(true)
+ {
+ const OUString sRet = "_" + OUString::number(nIdx++);
+ if ( comphelper::findValue(aNames, sRet) == -1 )
+ return sRet; // No match found, return unique name
+ }
+}
+
+void SwInsertDBColAutoPilot::Notify( const css::uno::Sequence< OUString >& ) {}
+
+void SwInsertDBColAutoPilot::ImplCommit()
+{
+ Sequence <OUString> aNames = GetNodeNames(OUString());
+ //remove entries that contain this data source + table at first
+ for(OUString const & nodeName : std::as_const(aNames))
+ {
+ Sequence<Any> aSourceProperties = GetProperties({ nodeName + "/DataSource", nodeName + "/Command" });
+ const Any* pSourceProps = aSourceProperties.getArray();
+ OUString sSource, sCommand;
+ pSourceProps[0] >>= sSource;
+ pSourceProps[1] >>= sCommand;
+ if(sSource==m_aDBData.sDataSource && sCommand==m_aDBData.sCommand)
+ {
+ ClearNodeElements(OUString(), { nodeName });
+ }
+ }
+
+ aNames = GetNodeNames(OUString());
+ OUString sNewNode = lcl_CreateUniqueName(aNames);
+ Sequence<OUString> aNodeNames = lcl_createSourceNames(sNewNode);
+ Sequence<PropertyValue> aValues(aNodeNames.getLength());
+ PropertyValue* pValues = aValues.getArray();
+ const OUString* pNodeNames = aNodeNames.getConstArray();
+ for(sal_Int32 i = 0; i < aNodeNames.getLength(); i++)
+ {
+ pValues[i].Name = "/" + pNodeNames[i];
+ }
+
+ pValues[0].Value <<= m_aDBData.sDataSource;
+ pValues[1].Value <<= m_aDBData.sCommand;
+ pValues[2].Value <<= m_aDBData.nCommandType;
+ pValues[3].Value <<= m_xEdDbText->get_text();
+
+ OUString sTmp;
+ const sal_Int32 nCnt = m_xLbTableCol->n_children();
+ for( sal_Int32 n = 0; n < nCnt; ++n )
+ sTmp += m_xLbTableCol->get_text(n) + "\x0a";
+
+ if (!sTmp.isEmpty())
+ pValues[4].Value <<= sTmp;
+
+ if( m_sNoTmpl != (sTmp = m_xLbDbParaColl->get_active_text()) )
+ pValues[5].Value <<= sTmp;
+
+ if (m_xTAutoFormat)
+ pValues[6].Value <<= m_xTAutoFormat->GetName();
+
+ pValues[7].Value <<= m_xRbAsTable->get_active();
+ pValues[8].Value <<= m_xRbAsField->get_active();
+ pValues[9].Value <<= m_xCbTableHeadon->get_active();
+ pValues[10].Value <<= m_xRbHeadlEmpty->get_active();
+
+ SetSetProperties(OUString(), aValues);
+
+ sNewNode += "/ColumnSet";
+
+ LanguageType ePrevLang(0xffff);
+
+ SvNumberFormatter& rNFormatr = *m_pView->GetWrtShell().GetNumberFormatter();
+ for(size_t nCol = 0; nCol < m_aDBColumns.size(); nCol++)
+ {
+ SwInsDBColumn* pColumn = m_aDBColumns[nCol].get();
+ OUString sColumnInsertNode(sNewNode + "/__");
+ if( nCol < 10 )
+ sColumnInsertNode += "00";
+ else if( nCol < 100 )
+ sColumnInsertNode += "0";
+ sColumnInsertNode += OUString::number( nCol );
+
+ const Sequence <OUString> aSubNodeNames = lcl_CreateSubNames(sColumnInsertNode);
+ Sequence<PropertyValue> aSubValues(aSubNodeNames.getLength());
+ PropertyValue* pSubValues = aSubValues.getArray();
+ sal_Int32 i = 0;
+
+ for( const OUString& rSubNodeName : aSubNodeNames)
+ pSubValues[i++].Name = rSubNodeName;
+ pSubValues[0].Value <<= pColumn->sColumn;
+ pSubValues[1].Value <<= i;
+ pSubValues[2].Value <<= pColumn->bHasFormat;
+ pSubValues[3].Value <<= pColumn->bIsDBFormat;
+
+ SwStyleNameMapper::FillUIName( RES_POOLCOLL_STANDARD, sTmp );
+ const SvNumberformat* pNF = rNFormatr.GetEntry( pColumn->nUsrNumFormat );
+ LanguageType eLang;
+ if( pNF )
+ {
+ pSubValues[4].Value <<= pNF->GetFormatstring();
+ eLang = pNF->GetLanguage();
+ }
+ else
+ {
+ pSubValues[4].Value <<= sTmp;
+ eLang = GetAppLanguage();
+ }
+
+ OUString sPrevLang;
+ if( eLang != ePrevLang )
+ {
+ sPrevLang = LanguageTag::convertToBcp47( eLang );
+ ePrevLang = eLang;
+ }
+
+ pSubValues[5].Value <<= sPrevLang;
+ SetSetProperties(sNewNode, aSubValues);
+ }
+}
+
+void SwInsertDBColAutoPilot::Load()
+{
+ const Sequence<OUString> aNames = GetNodeNames(OUString());
+ SvNumberFormatter& rNFormatr = *m_pView->GetWrtShell().GetNumberFormatter();
+ for(OUString const & nodeName : aNames)
+ {
+ //search for entries with the appropriate data source and table
+ Sequence<OUString> aSourceNames = lcl_createSourceNames(nodeName);
+
+ Sequence< Any> aDataSourceProps = GetProperties(aSourceNames);
+ const Any* pDataSourceProps = aDataSourceProps.getConstArray();
+ OUString sSource, sCommand;
+ sal_Int16 nCommandType;
+ pDataSourceProps[0] >>= sSource;
+ pDataSourceProps[1] >>= sCommand;
+ pDataSourceProps[2] >>= nCommandType;
+ if(sSource == m_aDBData.sDataSource && sCommand == m_aDBData.sCommand)
+ {
+ DB_ColumnConfigData aNewData;
+
+ pDataSourceProps[3] >>= aNewData.sEdit;
+ pDataSourceProps[4] >>= aNewData.sTableList;
+ pDataSourceProps[5] >>= aNewData.sTmplNm;
+ pDataSourceProps[6] >>= aNewData.sTAutoFormatNm;
+ if(pDataSourceProps[7].hasValue())
+ aNewData.bIsTable = *o3tl::doAccess<bool>(pDataSourceProps[7]);
+ if(pDataSourceProps[8].hasValue())
+ aNewData.bIsField = *o3tl::doAccess<bool>(pDataSourceProps[8]);
+ if(pDataSourceProps[9].hasValue())
+ aNewData.bIsHeadlineOn = *o3tl::doAccess<bool>(pDataSourceProps[9]);
+ if(pDataSourceProps[10].hasValue())
+ aNewData.bIsEmptyHeadln = *o3tl::doAccess<bool>(pDataSourceProps[10]);
+
+ const OUString sSubNodeName(nodeName + "/ColumnSet/");
+ const Sequence <OUString> aSubNames = GetNodeNames(sSubNodeName);
+ for(const OUString& rSubName : aSubNames)
+ {
+ Sequence <OUString> aSubNodeNames =
+ lcl_CreateSubNames(Concat2View(sSubNodeName + rSubName));
+ Sequence< Any> aSubProps = GetProperties(aSubNodeNames);
+ const Any* pSubProps = aSubProps.getConstArray();
+
+ OUString sColumn;
+ pSubProps[0] >>= sColumn;
+ // check for existence of the loaded column name
+ bool bFound = false;
+ for(size_t nRealColumn = 0; nRealColumn < m_aDBColumns.size(); ++nRealColumn)
+ {
+ if(m_aDBColumns[nRealColumn]->sColumn == sColumn)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ continue;
+ sal_Int16 nIndex = 0;
+ pSubProps[1] >>= nIndex;
+ std::unique_ptr<SwInsDBColumn> pInsDBColumn(new SwInsDBColumn(sColumn));
+ if(pSubProps[2].hasValue())
+ pInsDBColumn->bHasFormat = *o3tl::doAccess<bool>(pSubProps[2]);
+ if(pSubProps[3].hasValue())
+ pInsDBColumn->bIsDBFormat = *o3tl::doAccess<bool>(pSubProps[3]);
+
+ pSubProps[4] >>= pInsDBColumn->sUsrNumFormat;
+ OUString sNumberFormatLocale;
+ pSubProps[5] >>= sNumberFormatLocale;
+
+ /* XXX Earlier versions wrote a Country-Language string in
+ * SwInsertDBColAutoPilot::Commit() that here was read as
+ * Language-Country with 2 characters copied to language,
+ * 1 character separator and unconditionally 2 characters read
+ * as country. So for 'DE-de' and locales that have similar
+ * case-insensitive equal language/country combos that may have
+ * worked, for all others not. FIXME if you need to read old
+ * data that you were never able to read before. */
+ pInsDBColumn->eUsrNumFormatLng = LanguageTag::convertToLanguageType( sNumberFormatLocale );
+
+ pInsDBColumn->nUsrNumFormat = rNFormatr.GetEntryKey( pInsDBColumn->sUsrNumFormat,
+ pInsDBColumn->eUsrNumFormatLng );
+
+ aNewData.aDBColumns.insert(std::move(pInsDBColumn));
+ }
+ OUString sTmp( aNewData.sTableList );
+ if( !sTmp.isEmpty() )
+ {
+ sal_Int32 n = 0;
+ do {
+ const OUString sEntry( sTmp.getToken( 0, '\x0a', n ) );
+ //preselect column - if they still exist!
+ if (m_xLbTableDbColumn->find_text(sEntry) != -1)
+ {
+ m_xLbTableCol->append_text(sEntry);
+ m_xLbTableDbColumn->remove_text(sEntry);
+ }
+ } while( n>=0 );
+
+ if (!m_xLbTableDbColumn->n_children())
+ {
+ m_xIbDbcolAllTo->set_sensitive( false );
+ m_xIbDbcolOneTo->set_sensitive( false );
+ }
+ m_xIbDbcolOneFrom->set_sensitive(true);
+ m_xIbDbcolAllFrom->set_sensitive(true);
+ }
+ m_xEdDbText->set_text( aNewData.sEdit );
+
+ sTmp = aNewData.sTmplNm;
+ if( !sTmp.isEmpty() )
+ m_xLbDbParaColl->set_active_text(sTmp);
+ else
+ m_xLbDbParaColl->set_active(0);
+
+ m_xTAutoFormat.reset();
+ sTmp = aNewData.sTAutoFormatNm;
+ if( !sTmp.isEmpty() )
+ {
+ // then load the AutoFormat file and look for Autoformat first
+ SwTableAutoFormatTable aAutoFormatTable;
+ aAutoFormatTable.Load();
+ for( size_t nAutoFormat = aAutoFormatTable.size(); nAutoFormat; )
+ if( sTmp == aAutoFormatTable[ --nAutoFormat ].GetName() )
+ {
+ m_xTAutoFormat.reset(new SwTableAutoFormat(aAutoFormatTable[nAutoFormat]));
+ break;
+ }
+ }
+
+ m_xRbAsTable->set_active( aNewData.bIsTable );
+ m_xRbAsField->set_active( aNewData.bIsField );
+ m_xRbAsText->set_active( !aNewData.bIsTable && !aNewData.bIsField );
+
+ m_xCbTableHeadon->set_active( aNewData.bIsHeadlineOn );
+ m_xRbHeadlColnms->set_active( !aNewData.bIsEmptyHeadln );
+ m_xRbHeadlEmpty->set_active( aNewData.bIsEmptyHeadln );
+ HeaderHdl(*m_xCbTableHeadon);
+
+ // now copy the user defined Numberformat strings to the
+ // Shell. Then only these are available as ID
+ for( size_t n = 0; n < m_aDBColumns.size() ; ++n )
+ {
+ SwInsDBColumn& rSet = *m_aDBColumns[ n ];
+ for( size_t m = 0; m < aNewData.aDBColumns.size() ; ++m )
+ {
+ SwInsDBColumn& rGet = *aNewData.aDBColumns[ m ];
+ if(rGet.sColumn == rSet.sColumn)
+ {
+ if( rGet.bHasFormat && !rGet.bIsDBFormat )
+ {
+ rSet.bIsDBFormat = false;
+ rSet.nUsrNumFormat = rNFormatr.GetEntryKey( rGet.sUsrNumFormat,
+ rGet.eUsrNumFormatLng );
+ if( NUMBERFORMAT_ENTRY_NOT_FOUND == rSet.nUsrNumFormat )
+ {
+ sal_Int32 nCheckPos;
+ SvNumFormatType nType;
+ rNFormatr.PutEntry( rGet.sUsrNumFormat, nCheckPos, nType,
+ rSet.nUsrNumFormat, rGet.eUsrNumFormatLng );
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ // when the cursor is inside of a table, table must NEVER be selectable
+ if( !m_xRbAsTable->get_sensitive() && m_xRbAsTable->get_active() )
+ m_xRbAsField->set_active(true);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/dbtablepreviewdialog.cxx b/sw/source/ui/dbui/dbtablepreviewdialog.cxx
new file mode 100644
index 0000000000..ec530f9e3c
--- /dev/null
+++ b/sw/source/ui/dbui/dbtablepreviewdialog.cxx
@@ -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 .
+ */
+
+#include "dbtablepreviewdialog.hxx"
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/frame/Frame.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <utility>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+
+class DBTablePreviewFrame
+ : public cppu::WeakImplHelper<lang::XEventListener>
+{
+private:
+ css::uno::Reference<css::frame::XFrame2> m_xFrame;
+
+ virtual void SAL_CALL disposing(const lang::EventObject& /*Source*/) override
+ {
+ m_xFrame.clear();
+ }
+
+public:
+ DBTablePreviewFrame(css::uno::Reference<css::frame::XFrame2> xFrame)
+ : m_xFrame(std::move(xFrame))
+ {
+ }
+
+ void cleanup()
+ {
+ if (m_xFrame.is())
+ {
+ m_xFrame->setComponent(nullptr, nullptr);
+ m_xFrame->dispose();
+ m_xFrame.clear();
+ }
+ }
+};
+
+SwDBTablePreviewDialog::SwDBTablePreviewDialog(weld::Window* pParent, uno::Sequence< beans::PropertyValue> const & rValues)
+ : SfxDialogController(pParent, "modules/swriter/ui/tablepreviewdialog.ui", "TablePreviewDialog")
+ , m_xDescriptionFI(m_xBuilder->weld_label("description"))
+ , m_xBeamerWIN(m_xBuilder->weld_container("beamer"))
+{
+ Size aSize(m_xBeamerWIN->get_approximate_digit_width() * 80,
+ m_xBeamerWIN->get_text_height() * 18);
+ m_xBeamerWIN->set_size_request(aSize.Width(), aSize.Height());
+
+ auto pValue = std::find_if(rValues.begin(), rValues.end(),
+ [](const beans::PropertyValue& rValue) { return rValue.Name == "Command"; });
+ if (pValue != rValues.end())
+ {
+ OUString sDescription = m_xDescriptionFI->get_label();
+ OUString sTemp;
+ pValue->Value >>= sTemp;
+ m_xDescriptionFI->set_label(sDescription.replaceFirst("%1", sTemp));
+ }
+
+ css::uno::Reference<css::frame::XFrame2> xFrame;
+ try
+ {
+ // create a frame wrapper for myself
+ xFrame = frame::Frame::create( comphelper::getProcessComponentContext() );
+ xFrame->initialize(m_xBeamerWIN->CreateChildFrame());
+ }
+ catch (uno::Exception const &)
+ {
+ xFrame.clear();
+ }
+ if (!xFrame.is())
+ return;
+
+ m_xFrameListener.set(new DBTablePreviewFrame(xFrame));
+ xFrame->addEventListener(m_xFrameListener);
+
+ util::URL aURL;
+ aURL.Complete = ".component:DB/DataSourceBrowser";
+ uno::Reference<frame::XDispatch> xD = xFrame->queryDispatch(aURL, "",
+ css::frame::FrameSearchFlag::CHILDREN | css::frame::FrameSearchFlag::CREATE);
+ if (xD.is())
+ {
+ xD->dispatch(aURL, rValues);
+ m_xBeamerWIN->show();
+ }
+}
+
+SwDBTablePreviewDialog::~SwDBTablePreviewDialog()
+{
+ if (m_xFrameListener)
+ {
+ m_xFrameListener->cleanup();
+ m_xFrameListener.clear();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/dbtablepreviewdialog.hxx b/sw/source/ui/dbui/dbtablepreviewdialog.hxx
new file mode 100644
index 0000000000..99315fa017
--- /dev/null
+++ b/sw/source/ui/dbui/dbtablepreviewdialog.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_DBTABLEPREVIEWDIALOG_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_DBTABLEPREVIEWDIALOG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <com/sun/star/uno/Sequence.h>
+
+namespace com::sun::star{
+ namespace beans{ struct PropertyValue; }
+ namespace frame{ class XFrame2; }
+}
+
+class DBTablePreviewFrame;
+
+class SwDBTablePreviewDialog : public SfxDialogController
+{
+ std::unique_ptr<weld::Label> m_xDescriptionFI;
+ std::unique_ptr<weld::Container> m_xBeamerWIN;
+
+ rtl::Reference<DBTablePreviewFrame> m_xFrameListener;
+public:
+ SwDBTablePreviewDialog(weld::Window* pParent,
+ css::uno::Sequence< css::beans::PropertyValue> const & rValues );
+ virtual ~SwDBTablePreviewDialog() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mailmergewizard.cxx b/sw/source/ui/dbui/mailmergewizard.cxx
new file mode 100644
index 0000000000..7090d5c3e2
--- /dev/null
+++ b/sw/source/ui/dbui/mailmergewizard.cxx
@@ -0,0 +1,268 @@
+/* -*- 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 <mailmergewizard.hxx>
+#include "mmdocselectpage.hxx"
+#include "mmoutputtypepage.hxx"
+#include "mmaddressblockpage.hxx"
+#include "mmgreetingspage.hxx"
+#include "mmlayoutpage.hxx"
+#include <mmconfigitem.hxx>
+#include <swabstdlg.hxx>
+#include <strings.hrc>
+#include <utility>
+#include <view.hxx>
+
+#include <helpids.h>
+
+using namespace svt;
+using namespace ::com::sun::star;
+
+SwMailMergeWizard::SwMailMergeWizard(SwView& rView, std::shared_ptr<SwMailMergeConfigItem> xItem)
+ : RoadmapWizardMachine(rView.GetFrameWeld())
+ , m_pSwView(&rView)
+ , m_bDocumentLoad(false)
+ , m_xConfigItem(std::move(xItem))
+ , m_sStarting(SwResId(ST_STARTING))
+ , m_sDocumentType(SwResId(ST_DOCUMENTTYPE))
+ , m_sAddressBlock(SwResId(ST_ADDRESSBLOCK))
+ , m_sAddressList(SwResId(ST_ADDRESSLIST))
+ , m_sGreetingsLine(SwResId(ST_GREETINGSLINE))
+ , m_sLayout(SwResId(ST_LAYOUT))
+ , m_nRestartPage(MM_DOCUMENTSELECTPAGE)
+{
+ defaultButton(WizardButtonFlags::NEXT);
+ enableButtons(WizardButtonFlags::FINISH, false);
+
+ setTitleBase(SwResId(ST_MMWTITLE));
+
+ m_xFinish->set_label(SwResId( ST_FINISH ));
+ m_xNextPage->set_help_id(HID_MM_NEXT_PAGE);
+ m_xPrevPage->set_help_id(HID_MM_PREV_PAGE);
+
+ //#i51949# no output type page visible if e-Mail is not supported
+ if (m_xConfigItem->IsMailAvailable())
+ declarePath(
+ 0,
+ {MM_DOCUMENTSELECTPAGE,
+ MM_OUTPUTTYPETPAGE,
+ MM_ADDRESSBLOCKPAGE,
+ MM_GREETINGSPAGE,
+ MM_LAYOUTPAGE}
+ );
+ else
+ declarePath(
+ 0,
+ {MM_DOCUMENTSELECTPAGE,
+ MM_ADDRESSBLOCKPAGE,
+ MM_GREETINGSPAGE,
+ MM_LAYOUTPAGE}
+ );
+
+ ActivatePage();
+ m_xAssistant->set_current_page(0);
+ UpdateRoadmap();
+}
+
+SwMailMergeWizard::~SwMailMergeWizard()
+{
+}
+
+std::unique_ptr<BuilderPage> SwMailMergeWizard::createPage(WizardState _nState)
+{
+ OUString sIdent(OUString::number(_nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ std::unique_ptr<vcl::OWizardPage> xRet;
+ switch(_nState)
+ {
+ case MM_DOCUMENTSELECTPAGE :
+ xRet = std::make_unique<SwMailMergeDocSelectPage>(pPageContainer, this);
+
+ /* tdf#52986 Set help ID using SetRoadmapHelpId for all pages
+ so that when by default the focus is on the left side pane of
+ the wizard the relevant help page is displayed when hitting
+ the Help / F1 button */
+ SetRoadmapHelpId("modules/swriter/ui/mmselectpage/MMSelectPage");
+ break;
+ case MM_OUTPUTTYPETPAGE :
+ xRet = std::make_unique<SwMailMergeOutputTypePage>(pPageContainer, this);
+ SetRoadmapHelpId("modules/swriter/ui/mmoutputtypepage/MMOutputTypePage");
+ break;
+ case MM_ADDRESSBLOCKPAGE :
+ xRet = std::make_unique<SwMailMergeAddressBlockPage>(pPageContainer, this);
+ SetRoadmapHelpId("modules/swriter/ui/mmaddressblockpage/MMAddressBlockPage");
+ break;
+ case MM_GREETINGSPAGE :
+ xRet = std::make_unique<SwMailMergeGreetingsPage>(pPageContainer, this);
+ SetRoadmapHelpId("modules/swriter/ui/mmsalutationpage/MMSalutationPage");
+ break;
+ case MM_LAYOUTPAGE :
+ xRet = std::make_unique<SwMailMergeLayoutPage>(pPageContainer, this);
+ SetRoadmapHelpId("modules/swriter/ui/mmlayoutpage/MMLayoutPage");
+ break;
+ }
+
+ m_xAssistant->set_page_title(sIdent, getStateDisplayName(_nState));
+
+ OSL_ENSURE(xRet, "no page created in ::createPage");
+ return xRet;
+}
+
+void SwMailMergeWizard::enterState( WizardState _nState )
+{
+ ::vcl::RoadmapWizardMachine::enterState( _nState );
+
+ if (m_xConfigItem->GetTargetView())
+ {
+ //close the dialog, remove the target view, show the source view
+ m_nRestartPage = _nState;
+ //set ResultSet back to start
+ m_xConfigItem->MoveResultSet(1);
+ m_xAssistant->response(RET_REMOVE_TARGET);
+ return;
+ }
+ bool bEnablePrev = true;
+ bool bEnableNext = true;
+ switch(_nState)
+ {
+ case MM_DOCUMENTSELECTPAGE:
+ {
+ bEnablePrev = false; // the first page
+
+ OUString sDataSourceName = GetSwView()->GetDataSourceName();
+ if(!sDataSourceName.isEmpty() &&
+ !SwView::IsDataSourceAvailable(sDataSourceName))
+ {
+ bEnableNext = false;
+ }
+ }
+ break;
+ case MM_ADDRESSBLOCKPAGE :
+ bEnableNext = m_xConfigItem->GetResultSet().is();
+ break;
+ case MM_LAYOUTPAGE:
+ bEnableNext = false; // the last page
+ break;
+ }
+ enableButtons( WizardButtonFlags::PREVIOUS, bEnablePrev);
+ enableButtons( WizardButtonFlags::NEXT, bEnableNext);
+
+ UpdateRoadmap();
+}
+
+OUString SwMailMergeWizard::getStateDisplayName( WizardState _nState ) const
+{
+ switch(_nState)
+ {
+ case MM_DOCUMENTSELECTPAGE:
+ return m_sStarting;
+ case MM_OUTPUTTYPETPAGE:
+ return m_sDocumentType;
+ case MM_ADDRESSBLOCKPAGE:
+ return m_xConfigItem->IsOutputToLetter() ?
+ m_sAddressBlock : m_sAddressList;
+ case MM_GREETINGSPAGE:
+ return m_sGreetingsLine;
+ case MM_LAYOUTPAGE:
+ return m_sLayout;
+ }
+ return OUString();
+}
+
+// enables/disables pages in the roadmap depending on the current page and state
+void SwMailMergeWizard::UpdateRoadmap()
+{
+/*
+ MM_DOCUMENTSELECTPAGE > inactive after the layoutpage
+ MM_OUTPUTTYPETPAGE : > inactive after the layoutpage
+ MM_ADDRESSBLOCKPAGE > inactive after the layoutpage
+ MM_GREETINGSPAGE > inactive after the layoutpage
+ MM_LAYOUTPAGE > inactive after the layoutpage
+ inactive if address block and greeting are switched off
+ or are already inserted into the source document
+*/
+
+ // enableState( <page id>, false );
+ const sal_uInt16 nCurPage = m_xAssistant->get_current_page();
+ BuilderPage* pCurPage = GetPage( nCurPage );
+ if(!pCurPage)
+ return;
+ bool bAddressFieldsConfigured = !m_xConfigItem->IsOutputToLetter() ||
+ !m_xConfigItem->IsAddressBlock() ||
+ m_xConfigItem->IsAddressFieldsAssigned();
+ bool bGreetingFieldsConfigured = !m_xConfigItem->IsGreetingLine(false) ||
+ !m_xConfigItem->IsIndividualGreeting(false) ||
+ m_xConfigItem->IsGreetingFieldsAssigned();
+
+ //#i97436# if a document has to be loaded then enable output type page only
+ m_bDocumentLoad = false;
+ bool bEnableOutputTypePage = (nCurPage != MM_DOCUMENTSELECTPAGE) ||
+ static_cast<vcl::OWizardPage*>(pCurPage)->commitPage( ::vcl::WizardTypes::eValidate );
+
+ // handle the Finish button
+ bool bCanFinish = !m_bDocumentLoad && bEnableOutputTypePage &&
+ m_xConfigItem->GetResultSet().is() &&
+ bAddressFieldsConfigured &&
+ bGreetingFieldsConfigured;
+ enableButtons(WizardButtonFlags::FINISH, (nCurPage != MM_DOCUMENTSELECTPAGE) && bCanFinish);
+
+ for(sal_uInt16 nPage = MM_DOCUMENTSELECTPAGE; nPage <= MM_LAYOUTPAGE; ++nPage)
+ {
+ bool bEnable = true;
+ switch(nPage)
+ {
+ case MM_DOCUMENTSELECTPAGE:
+ bEnable = true;
+ break;
+ case MM_OUTPUTTYPETPAGE:
+ bEnable = bEnableOutputTypePage;
+ break;
+ case MM_ADDRESSBLOCKPAGE:
+ bEnable = !m_bDocumentLoad && bEnableOutputTypePage;
+ // update page title for email vs letter
+ m_xAssistant->set_page_title(OUString::number(MM_ADDRESSBLOCKPAGE), getStateDisplayName(MM_ADDRESSBLOCKPAGE));
+ break;
+ case MM_GREETINGSPAGE:
+ bEnable = !m_bDocumentLoad && bEnableOutputTypePage &&
+ m_xConfigItem->GetResultSet().is() &&
+ bAddressFieldsConfigured;
+ break;
+ case MM_LAYOUTPAGE:
+ bEnable = bCanFinish &&
+ ((m_xConfigItem->IsAddressBlock() && !m_xConfigItem->IsAddressInserted()) ||
+ (m_xConfigItem->IsGreetingLine(false) && !m_xConfigItem->IsGreetingInserted() ));
+ break;
+ }
+ enableState( nPage, bEnable );
+ }
+}
+
+short SwMailMergeWizard::run()
+{
+ OSL_FAIL("SwMailMergeWizard cannot be executed via Dialog::Execute!\n"
+ "It creates a thread (MailDispatcher instance) that will call"
+ "back to VCL apartment => deadlock!\n"
+ "Use Dialog::StartExecuteAsync to execute the dialog!" );
+ return RET_CANCEL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmaddressblockpage.cxx b/sw/source/ui/dbui/mmaddressblockpage.cxx
new file mode 100644
index 0000000000..73811cbf3e
--- /dev/null
+++ b/sw/source/ui/dbui/mmaddressblockpage.cxx
@@ -0,0 +1,1582 @@
+/* -*- 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 "mmaddressblockpage.hxx"
+#include <mailmergewizard.hxx>
+#include <swtypes.hxx>
+#include "addresslistdialog.hxx"
+#include <editeng/eeitem.hxx>
+#include <o3tl/safeint.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svl/itemset.hxx>
+#include <utility>
+#include <vcl/commandevent.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/transfer.hxx>
+#include <mmconfigitem.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <comphelper/sequence.hxx>
+#include <comphelper/string.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <vector>
+#include <strings.hrc>
+#include <mmaddressblockpage.hrc>
+#include <helpids.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+
+SwMailMergeAddressBlockPage::SwMailMergeAddressBlockPage(weld::Container* pPage, SwMailMergeWizard* pWizard)
+ : vcl::OWizardPage(pPage, pWizard, "modules/swriter/ui/mmaddressblockpage.ui", "MMAddressBlockPage")
+ , m_pWizard(pWizard)
+ , m_xAddressListPB(m_xBuilder->weld_button("addresslist"))
+ , m_xCurrentAddressFI(m_xBuilder->weld_label("currentaddress"))
+ , m_xStep2(m_xBuilder->weld_container("step2"))
+ , m_xStep3(m_xBuilder->weld_container("step3"))
+ , m_xStep4(m_xBuilder->weld_container("step4"))
+ , m_xSettingsFI(m_xBuilder->weld_label("settingsft"))
+ , m_xAddressCB(m_xBuilder->weld_check_button("address"))
+ , m_xSettingsPB(m_xBuilder->weld_button("settings"))
+ , m_xHideEmptyParagraphsCB(m_xBuilder->weld_check_button("hideempty"))
+ , m_xAssignPB(m_xBuilder->weld_button("assign"))
+ , m_xDocumentIndexFI(m_xBuilder->weld_label("documentindex"))
+ , m_xPrevSetIB(m_xBuilder->weld_button("prev"))
+ , m_xNextSetIB(m_xBuilder->weld_button("next"))
+ , m_xDifferentlist(m_xBuilder->weld_button("differentlist"))
+ , m_xSettings(new SwAddressPreview(m_xBuilder->weld_scrolled_window("settingspreviewwin", true)))
+ , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("addresspreviewwin", true)))
+ , m_xSettingsWIN(new weld::CustomWeld(*m_xBuilder, "settingspreview", *m_xSettings))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "addresspreview", *m_xPreview))
+{
+ m_xSettingsWIN->set_size_request(m_xDifferentlist->get_approximate_digit_width() * 40,
+ m_xDifferentlist->get_text_height() * 6);
+ m_xPreviewWIN->set_size_request(m_xDifferentlist->get_approximate_digit_width() * 44,
+ m_xDifferentlist->get_text_height() * 6);
+ m_sChangeAddress = m_xDifferentlist->get_label();
+ m_sDocument = m_xDocumentIndexFI->get_label();
+
+ m_sCurrentAddress = m_xCurrentAddressFI->get_label();
+ m_xAddressListPB->connect_clicked(LINK(this, SwMailMergeAddressBlockPage, AddressListHdl_Impl));
+ m_xSettingsPB->connect_clicked(LINK(this, SwMailMergeAddressBlockPage, SettingsHdl_Impl));
+ m_xAssignPB->connect_clicked(LINK(this, SwMailMergeAddressBlockPage, AssignHdl_Impl ));
+ m_xAddressCB->connect_toggled(LINK(this, SwMailMergeAddressBlockPage, AddressBlockHdl_Impl));
+ m_xSettings->SetSelectHdl(LINK(this, SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl));
+ m_xHideEmptyParagraphsCB->connect_toggled(LINK(this, SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl));
+
+ Link<weld::Button&,void> aLink = LINK(this, SwMailMergeAddressBlockPage, InsertDataHdl_Impl);
+ m_xPrevSetIB->connect_clicked(aLink);
+ m_xNextSetIB->connect_clicked(aLink);
+
+ // lock in preferred size including current address line
+ Size aSize1(m_xContainer->get_preferred_size());
+
+ OUString sOrigLabel = m_xAddressListPB->get_label();
+ m_xAddressListPB->set_label(m_sChangeAddress);
+ Size aSize2(m_xContainer->get_preferred_size());
+ m_xAddressListPB->set_label(sOrigLabel);
+
+ m_xCurrentAddressFI->hide();
+
+ m_xContainer->set_size_request(std::max(aSize1.Width(), aSize2.Width()),
+ std::max(aSize1.Height(), aSize2.Height()));
+}
+
+SwMailMergeAddressBlockPage::~SwMailMergeAddressBlockPage()
+{
+ m_xPreviewWIN.reset();
+ m_xSettingsWIN.reset();
+ m_xPreview.reset();
+ m_xSettings.reset();
+}
+
+bool SwMailMergeAddressBlockPage::canAdvance() const
+{
+ return m_pWizard->GetConfigItem().GetResultSet().is();
+}
+
+void SwMailMergeAddressBlockPage::Activate()
+{
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ bool bIsLetter = rConfigItem.IsOutputToLetter();
+
+ //no address block is created for e-Mail
+ m_xStep2->set_visible(bIsLetter);
+ m_xStep3->set_visible(bIsLetter);
+ m_xStep4->set_visible(bIsLetter);
+
+ if (!bIsLetter)
+ return;
+
+ m_xHideEmptyParagraphsCB->set_active( rConfigItem.IsHideEmptyParagraphs() );
+ m_xDocumentIndexFI->set_label(m_sDocument.replaceFirst("%1", "1"));
+
+ m_xSettings->Clear();
+ const uno::Sequence< OUString> aBlocks =
+ m_pWizard->GetConfigItem().GetAddressBlocks();
+ for(const auto& rAddress : aBlocks)
+ m_xSettings->AddAddress(rAddress);
+ m_xSettings->SelectAddress(o3tl::narrowing<sal_uInt16>(rConfigItem.GetCurrentAddressBlockIndex()));
+ m_xAddressCB->set_active(rConfigItem.IsAddressBlock());
+ AddressBlockHdl_Impl(*m_xAddressCB);
+ m_xSettings->SetLayout(1, 2);
+ InsertDataHdl(nullptr);
+}
+
+bool SwMailMergeAddressBlockPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+{
+ return ::vcl::WizardTypes::eTravelForward != _eReason || m_pWizard->GetConfigItem().GetResultSet().is();
+}
+
+IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressListHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ SwAddressListDialog aAddrDialog(this);
+ if (RET_OK == aAddrDialog.run())
+ {
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ rConfigItem.SetCurrentConnection(
+ aAddrDialog.GetSource(),
+ aAddrDialog.GetConnection(),
+ aAddrDialog.GetColumnsSupplier(),
+ aAddrDialog.GetDBData());
+ OUString sFilter = aAddrDialog.GetFilter();
+ rConfigItem.SetFilter( sFilter );
+ InsertDataHdl(nullptr);
+ GetWizard()->UpdateRoadmap();
+ GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
+ }
+ }
+ catch (const uno::Exception& e)
+ {
+ TOOLS_WARN_EXCEPTION("sw", "");
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_pWizard->getDialog(),
+ VclMessageType::Warning, VclButtonsType::Ok, e.Message));
+ xBox->run();
+ }
+}
+
+IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, SettingsHdl_Impl, weld::Button&, void)
+{
+ SwSelectAddressBlockDialog aDlg(m_pWizard->getDialog(), m_pWizard->GetConfigItem());
+ SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
+ aDlg.SetAddressBlocks(rConfig.GetAddressBlocks(), m_xSettings->GetSelectedAddress());
+ aDlg.SetSettings(rConfig.IsIncludeCountry(), rConfig.GetExcludeCountry());
+ if (aDlg.run() == RET_OK)
+ {
+ //the dialog provides the selected address at the first position!
+ const uno::Sequence< OUString> aBlocks = aDlg.GetAddressBlocks();
+ rConfig.SetAddressBlocks(aBlocks);
+ m_xSettings->Clear();
+ for(const auto& rAddress : aBlocks)
+ m_xSettings->AddAddress(rAddress);
+ m_xSettings->SelectAddress(0);
+ m_xSettings->Invalidate(); // #i40408
+ rConfig.SetCountrySettings(aDlg.IsIncludeCountry(), aDlg.GetCountry());
+ InsertDataHdl(nullptr);
+ }
+ GetWizard()->UpdateRoadmap();
+ GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
+}
+
+IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AssignHdl_Impl, weld::Button&, void)
+{
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ const sal_uInt16 nSel = m_xSettings->GetSelectedAddress();
+ const uno::Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
+ SwAssignFieldsDialog aDlg(m_pWizard->getDialog(), m_pWizard->GetConfigItem(), aBlocks[nSel], true);
+ if(RET_OK == aDlg.run())
+ {
+ //preview update
+ InsertDataHdl(nullptr);
+ GetWizard()->UpdateRoadmap();
+ GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
+ }
+}
+
+void SwMailMergeAddressBlockPage::EnableAddressBlock(bool bAll, bool bSelective)
+{
+ m_xSettingsFI->set_sensitive(bAll);
+ m_xAddressCB->set_sensitive(bAll);
+ bSelective &= bAll;
+ m_xHideEmptyParagraphsCB->set_sensitive(bSelective);
+ m_xSettingsWIN->set_sensitive(bSelective);
+ m_xSettingsPB->set_sensitive(bSelective);
+ m_xStep3->set_sensitive(bSelective);
+ m_xStep4->set_sensitive(bSelective);
+}
+
+IMPL_LINK(SwMailMergeAddressBlockPage, AddressBlockHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ EnableAddressBlock(rBox.get_sensitive(), rBox.get_active());
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ rConfigItem.SetAddressBlock(m_xAddressCB->get_active());
+ m_pWizard->UpdateRoadmap();
+ GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
+}
+
+IMPL_LINK_NOARG(SwMailMergeAddressBlockPage, AddressBlockSelectHdl_Impl, LinkParamNone*, void)
+{
+ const sal_uInt16 nSel = m_xSettings->GetSelectedAddress();
+ const uno::Sequence< OUString> aBlocks =
+ m_pWizard->GetConfigItem().GetAddressBlocks();
+ m_xPreview->SetAddress(SwAddressPreview::FillData(aBlocks[nSel],
+ m_pWizard->GetConfigItem()));
+ m_pWizard->GetConfigItem().SetCurrentAddressBlockIndex( nSel );
+ GetWizard()->UpdateRoadmap();
+ GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
+}
+
+IMPL_LINK(SwMailMergeAddressBlockPage, HideParagraphsHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ rConfigItem.SetHideEmptyParagraphs(rBox.get_active());
+}
+
+void SwMailMergeAddressBlockPage::InsertDataHdl(const weld::Button* pButton)
+{
+ //if no pButton is given, the first set has to be pre-set
+ SwMailMergeConfigItem& rConfig = m_pWizard->GetConfigItem();
+ std::unique_ptr<weld::WaitObject> xWaitObj(new weld::WaitObject(m_pWizard->getDialog()));
+ if(!pButton)
+ {
+ rConfig.GetResultSet();
+ }
+ else
+ {
+ bool bNext = pButton == m_xNextSetIB.get();
+ sal_Int32 nPos = rConfig.GetResultSetPosition();
+ rConfig.MoveResultSet( bNext ? ++nPos : --nPos);
+ }
+ xWaitObj.reset();
+ sal_Int32 nPos = rConfig.GetResultSetPosition();
+ bool bEnable = true;
+ if(nPos < 1)
+ {
+ bEnable = false;
+ nPos = 1;
+ }
+ else
+ {
+ //if output type is letter
+ if (m_xSettings->IsVisible())
+ {
+ //Fill data into preview
+ const sal_uInt16 nSel = m_xSettings->GetSelectedAddress();
+ const uno::Sequence< OUString> aBlocks =
+ m_pWizard->GetConfigItem().GetAddressBlocks();
+ m_xPreview->SetAddress(SwAddressPreview::FillData(aBlocks[nSel], rConfig));
+ }
+ }
+ m_xPrevSetIB->set_sensitive(bEnable);
+ m_xDocumentIndexFI->set_label(m_sDocument.replaceFirst("%1", OUString::number(nPos)));
+
+ GetWizard()->enableButtons(WizardButtonFlags::NEXT, GetWizard()->isStateEnabled(MM_GREETINGSPAGE));
+ bool bHasResultSet = rConfig.GetResultSet().is();
+ m_xCurrentAddressFI->set_visible(bHasResultSet);
+ if(bHasResultSet)
+ {
+ m_xCurrentAddressFI->set_label(m_sCurrentAddress.replaceFirst("%1", rConfig.GetCurrentDBData().sDataSource));
+ m_xAddressListPB->set_label(m_sChangeAddress);
+ }
+ EnableAddressBlock(bHasResultSet, m_xAddressCB->get_active());
+}
+
+IMPL_LINK(SwMailMergeAddressBlockPage, InsertDataHdl_Impl, weld::Button&, rButton, void)
+{
+ InsertDataHdl(&rButton);
+}
+
+SwSelectAddressBlockDialog::SwSelectAddressBlockDialog(weld::Window* pParent, SwMailMergeConfigItem& rConfig)
+ : SfxDialogController(pParent, "modules/swriter/ui/selectblockdialog.ui", "SelectBlockDialog")
+ , m_rConfig(rConfig)
+ , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
+ , m_xNewPB(m_xBuilder->weld_button("new"))
+ , m_xCustomizePB(m_xBuilder->weld_button("edit"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ , m_xNeverRB(m_xBuilder->weld_radio_button("never"))
+ , m_xAlwaysRB(m_xBuilder->weld_radio_button("always"))
+ , m_xDependentRB(m_xBuilder->weld_radio_button("dependent"))
+ , m_xCountryED(m_xBuilder->weld_entry("country"))
+ , m_xPreviewWin(new weld::CustomWeld(*m_xBuilder, "preview", *m_xPreview))
+{
+ m_xPreviewWin->set_size_request(m_xCountryED->get_approximate_digit_width() * 45,
+ m_xCountryED->get_text_height() * 12);
+
+ Link<weld::Button&,void> aCustomizeHdl = LINK(this, SwSelectAddressBlockDialog, NewCustomizeHdl_Impl);
+ m_xNewPB->connect_clicked(aCustomizeHdl);
+ m_xCustomizePB->connect_clicked(aCustomizeHdl);
+
+ m_xDeletePB->connect_clicked(LINK(this, SwSelectAddressBlockDialog, DeleteHdl_Impl));
+
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwSelectAddressBlockDialog, IncludeHdl_Impl);
+ m_xNeverRB->connect_toggled(aLk);
+ m_xAlwaysRB->connect_toggled(aLk);
+ m_xDependentRB->connect_toggled(aLk);
+ m_xPreview->SetLayout(2, 2);
+ m_xPreview->EnableScrollBar();
+}
+
+SwSelectAddressBlockDialog::~SwSelectAddressBlockDialog()
+{
+}
+
+void SwSelectAddressBlockDialog::SetAddressBlocks(const uno::Sequence< OUString>& rBlocks,
+ sal_uInt16 nSelectedAddress)
+{
+ m_aAddressBlocks = rBlocks;
+ for (const auto& rAddressBlock : std::as_const(m_aAddressBlocks))
+ m_xPreview->AddAddress(rAddressBlock);
+ m_xPreview->SelectAddress(nSelectedAddress);
+}
+
+// return the address blocks and put the selected one to the first position
+const uno::Sequence< OUString >& SwSelectAddressBlockDialog::GetAddressBlocks()
+{
+ //put the selected block to the first position
+ const sal_Int32 nSelect = static_cast<sal_Int32>(m_xPreview->GetSelectedAddress());
+ if(nSelect)
+ {
+ uno::Sequence< OUString >aTemp(m_aAddressBlocks.getLength());
+ auto it = aTemp.getArray();
+ *it = std::as_const(m_aAddressBlocks)[nSelect];
+ it = std::copy_n(std::cbegin(m_aAddressBlocks), nSelect - 1, std::next(it));
+ std::copy(std::next(std::cbegin(m_aAddressBlocks), nSelect + 1), std::cend(m_aAddressBlocks), it);
+ m_aAddressBlocks = aTemp;
+ }
+ return m_aAddressBlocks;
+}
+
+void SwSelectAddressBlockDialog::SetSettings(
+ bool bIsCountry, const OUString& rCountry)
+{
+ weld::RadioButton *pActive = m_xNeverRB.get();
+ if(bIsCountry)
+ {
+ pActive = !rCountry.isEmpty() ? m_xDependentRB.get() : m_xAlwaysRB.get();
+ m_xCountryED->set_text(rCountry);
+ }
+ pActive->set_active(true);
+ IncludeHdl_Impl(*pActive);
+ m_xDeletePB->set_sensitive(m_aAddressBlocks.getLength() > 1);
+}
+
+OUString SwSelectAddressBlockDialog::GetCountry() const
+{
+ if (m_xDependentRB->get_active())
+ return m_xCountryED->get_text();
+ return OUString();
+}
+
+IMPL_LINK(SwSelectAddressBlockDialog, DeleteHdl_Impl, weld::Button&, rButton, void)
+{
+ if (m_aAddressBlocks.getLength())
+ {
+ const sal_Int32 nSelected = static_cast<sal_Int32>(m_xPreview->GetSelectedAddress());
+ comphelper::removeElementAt(m_aAddressBlocks, nSelected);
+ if (m_aAddressBlocks.getLength() <= 1)
+ rButton.set_sensitive(false);
+ m_xPreview->RemoveSelectedAddress();
+ }
+}
+
+IMPL_LINK(SwSelectAddressBlockDialog, NewCustomizeHdl_Impl, weld::Button&, rButton, void)
+{
+ bool bCustomize = &rButton == m_xCustomizePB.get();
+ SwCustomizeAddressBlockDialog::DialogType nType = bCustomize ?
+ SwCustomizeAddressBlockDialog::ADDRESSBLOCK_EDIT :
+ SwCustomizeAddressBlockDialog::ADDRESSBLOCK_NEW;
+ std::unique_ptr<SwCustomizeAddressBlockDialog> xDlg(new SwCustomizeAddressBlockDialog(&rButton,
+ m_rConfig, nType));
+ if(bCustomize)
+ {
+ xDlg->SetAddress(m_aAddressBlocks[m_xPreview->GetSelectedAddress()]);
+ }
+ if (RET_OK != xDlg->run())
+ return;
+
+ const OUString sNew = xDlg->GetAddress();
+ if(bCustomize)
+ {
+ m_xPreview->ReplaceSelectedAddress(sNew);
+ m_aAddressBlocks.getArray()[m_xPreview->GetSelectedAddress()] = sNew;
+ }
+ else
+ {
+ m_xPreview->AddAddress(sNew);
+ m_aAddressBlocks.realloc(m_aAddressBlocks.getLength() + 1);
+ const sal_Int32 nSelect = m_aAddressBlocks.getLength() - 1;
+ m_aAddressBlocks.getArray()[nSelect] = sNew;
+ m_xPreview->SelectAddress(o3tl::narrowing<sal_uInt16>(nSelect));
+ }
+ m_xDeletePB->set_sensitive(m_aAddressBlocks.getLength() > 1);
+}
+
+IMPL_LINK_NOARG(SwSelectAddressBlockDialog, IncludeHdl_Impl, weld::Toggleable&, void)
+{
+ m_xCountryED->set_sensitive(m_xDependentRB->get_active());
+}
+
+#define USER_DATA_SALUTATION -1
+#define USER_DATA_PUNCTUATION -2
+#define USER_DATA_TEXT -3
+#define USER_DATA_NONE -4
+
+IMPL_LINK(SwCustomizeAddressBlockDialog, TextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = m_aTextFilter.filter(rTest);
+ return true;
+}
+
+SwCustomizeAddressBlockDialog::SwCustomizeAddressBlockDialog(
+ weld::Widget* pParent, SwMailMergeConfigItem& rConfig, DialogType eType)
+ : SfxDialogController(pParent, "modules/swriter/ui/addressblockdialog.ui",
+ "AddressBlockDialog")
+ , m_aTextFilter("<>")
+ , m_rConfigItem(rConfig)
+ , m_eType(eType)
+ , m_aSelectionChangedIdle("SwCustomizeAddressBlockDialog m_aSelectionChangedIdle")
+ , m_xAddressElementsFT(m_xBuilder->weld_label("addressesft"))
+ , m_xAddressElementsLB(m_xBuilder->weld_tree_view("addresses"))
+ , m_xInsertFieldIB(m_xBuilder->weld_button("toaddr"))
+ , m_xRemoveFieldIB(m_xBuilder->weld_button("fromaddr"))
+ , m_xDragFT(m_xBuilder->weld_label("addressdestft"))
+ , m_xUpIB(m_xBuilder->weld_button("up"))
+ , m_xLeftIB(m_xBuilder->weld_button("left"))
+ , m_xRightIB(m_xBuilder->weld_button("right"))
+ , m_xDownIB(m_xBuilder->weld_button("down"))
+ , m_xFieldFT(m_xBuilder->weld_label("customft"))
+ , m_xFieldCB(m_xBuilder->weld_combo_box("custom"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "addrpreview", *m_xPreview))
+ , m_xDragED(new AddressMultiLineEdit(this))
+ , m_xDragWIN(new weld::CustomWeld(*m_xBuilder, "addressdest", *m_xDragED))
+{
+ m_aSelectionChangedIdle.SetInvokeHandler( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedIdleHdl ) );
+
+ Size aSize(m_xDragED->GetDrawingArea()->get_size_request());
+ m_xPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xFieldCB->connect_entry_insert_text(LINK(this, SwCustomizeAddressBlockDialog, TextFilterHdl));
+ m_xAddressElementsLB->set_size_request(-1, m_xAddressElementsLB->get_height_rows(16));
+
+ if( eType >= GREETING_FEMALE )
+ {
+ m_xFieldFT->show();
+ m_xFieldCB->show();
+ m_xAddressElementsLB->append(OUString::number(USER_DATA_SALUTATION), SwResId(ST_SALUTATION));
+ m_xAddressElementsLB->append(OUString::number(USER_DATA_PUNCTUATION), SwResId(ST_PUNCTUATION));
+ m_xAddressElementsLB->append(OUString::number(USER_DATA_TEXT), SwResId(ST_TEXT));
+ for (auto const& aID : RA_SALUTATION)
+ m_aSalutations.push_back(SwResId(aID));
+ for (auto const& aID : RA_PUNCTUATION)
+ m_aPunctuations.push_back(SwResId(aID));
+ m_xDragED->SetText(" ");
+ m_xDialog->set_title(SwResId(eType == GREETING_MALE ? ST_TITLE_MALE : ST_TITLE_FEMALE));
+ m_xAddressElementsFT->set_label(SwResId(ST_SALUTATIONELEMENTS));
+ m_xInsertFieldIB->set_tooltip_text(SwResId(ST_INSERTSALUTATIONFIELD));
+ m_xRemoveFieldIB->set_tooltip_text(SwResId(ST_REMOVESALUTATIONFIELD));
+ m_xDragFT->set_label(SwResId(ST_DRAGSALUTATION));
+ }
+ else
+ {
+ if (eType == ADDRESSBLOCK_EDIT)
+ m_xDialog->set_title(SwResId(ST_TITLE_EDIT));
+ m_xDragED->SetText("\n\n\n\n\n");
+ /* Set custom HIDs for swriter/01/mm_newaddblo.xhp */
+ m_xAddressElementsLB->set_help_id( HID_MM_ADDBLOCK_ELEMENTS );
+ m_xInsertFieldIB->set_help_id( HID_MM_ADDBLOCK_INSERT );
+ m_xRemoveFieldIB->set_help_id( HID_MM_ADDBLOCK_REMOVE );
+ m_xDragWIN->set_help_id( HID_MM_ADDBLOCK_DRAG );
+ m_xPreviewWIN->set_help_id( HID_MM_ADDBLOCK_PREVIEW );
+ m_xRightIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
+ m_xLeftIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
+ m_xDownIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
+ m_xUpIB->set_help_id( HID_MM_ADDBLOCK_MOVEBUTTONS );
+ }
+
+ const std::vector<std::pair<OUString, int>>& rHeaders = m_rConfigItem.GetDefaultAddressHeaders();
+ for (size_t i = 0; i < rHeaders.size(); ++i)
+ m_xAddressElementsLB->append(OUString::number(i), rHeaders[i].first);
+ m_xOK->connect_clicked(LINK(this, SwCustomizeAddressBlockDialog, OKHdl_Impl));
+ m_xAddressElementsLB->connect_changed(LINK(this, SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl));
+ if (m_xAddressElementsLB->n_children())
+ m_xAddressElementsLB->select(0);
+ m_xDragED->SetModifyHdl(LINK(this, SwCustomizeAddressBlockDialog, EditModifyHdl_Impl));
+ m_xDragED->SetSelectionChangedHdl( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl));
+ m_xFieldCB->connect_changed(LINK(this, SwCustomizeAddressBlockDialog, FieldChangeComboBoxHdl_Impl));
+ Link<weld::Button&,void> aImgButtonHdl = LINK(this, SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl);
+ m_xInsertFieldIB->connect_clicked(aImgButtonHdl);
+ m_xRemoveFieldIB->connect_clicked(aImgButtonHdl);
+ m_xUpIB->connect_clicked(aImgButtonHdl);
+ m_xLeftIB->connect_clicked(aImgButtonHdl);
+ m_xRightIB->connect_clicked(aImgButtonHdl);
+ m_xDownIB->connect_clicked(aImgButtonHdl);
+ UpdateImageButtons_Impl();
+}
+
+bool SwCustomizeAddressBlockDialog::SetCursorLogicPosition(const Point& rPosition)
+{
+ return m_xDragED->SetCursorLogicPosition(rPosition);
+}
+
+void SwCustomizeAddressBlockDialog::UpdateFields()
+{
+ m_xDragED->UpdateFields();
+}
+
+SwCustomizeAddressBlockDialog::~SwCustomizeAddressBlockDialog()
+{
+ m_xDragED->EndDropTarget();
+}
+
+IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, OKHdl_Impl, weld::Button&, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwCustomizeAddressBlockDialog, ListBoxSelectHdl_Impl, weld::TreeView&, rBox, void)
+{
+ sal_Int32 nUserData = rBox.get_selected_id().toInt32();
+ // Check if the selected entry is already in the address and then forbid inserting
+ m_xInsertFieldIB->set_sensitive(nUserData >= 0 || !HasItem(nUserData));
+}
+
+IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, EditModifyHdl_Impl, AddressMultiLineEdit&, void)
+{
+ m_xPreview->SetAddress(SwAddressPreview::FillData(GetAddress(), m_rConfigItem));
+ UpdateImageButtons_Impl();
+}
+
+IMPL_LINK(SwCustomizeAddressBlockDialog, ImageButtonHdl_Impl, weld::Button&, rButton, void)
+{
+ if (m_xInsertFieldIB.get() == &rButton)
+ {
+ int nEntry = m_xAddressElementsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ m_xDragED->InsertNewEntry("<" + m_xAddressElementsLB->get_text(nEntry) + ">");
+ }
+ }
+ else if (m_xRemoveFieldIB.get() == &rButton)
+ {
+ m_xDragED->RemoveCurrentEntry();
+ }
+ else
+ {
+ MoveItemFlags nMove = MoveItemFlags::Down;
+ if (m_xUpIB.get() == &rButton)
+ nMove = MoveItemFlags::Up;
+ else if (m_xLeftIB.get() == &rButton)
+ nMove = MoveItemFlags::Left;
+ else if (m_xRightIB.get() == &rButton)
+ nMove = MoveItemFlags::Right;
+ m_xDragED->MoveCurrentItem(nMove);
+ }
+ UpdateImageButtons_Impl();
+}
+
+sal_Int32 SwCustomizeAddressBlockDialog::GetSelectedItem_Impl() const
+{
+ sal_Int32 nRet = USER_DATA_NONE;
+ const OUString sSelected = m_xDragED->GetCurrentItem();
+ if(!sSelected.isEmpty())
+ {
+ for (int i = 0, nEntryCount = m_xAddressElementsLB->n_children(); i < nEntryCount; ++i)
+ {
+ const OUString sEntry = m_xAddressElementsLB->get_text(i);
+ if( sEntry == sSelected.subView( 1, sSelected.getLength() - 2 ) )
+ {
+ nRet = m_xAddressElementsLB->get_id(i).toInt32();
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+
+bool SwCustomizeAddressBlockDialog::HasItem(sal_Int32 nUserData)
+{
+ //get the entry from the ListBox
+ OUString sEntry;
+ for (int i = 0, nEntryCount = m_xAddressElementsLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (m_xAddressElementsLB->get_id(i).toInt32() == nUserData)
+ {
+ sEntry = m_xAddressElementsLB->get_text(i);
+ break;
+ }
+ }
+ //search for this entry in the content
+ return m_xDragED->GetText().indexOf(Concat2View("<" + sEntry + ">")) >= 0;
+}
+
+IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, SelectionChangedIdleHdl, Timer*, void)
+{
+ // called in case the selection of the edit field changes.
+ // determine selection - if it's one of the editable fields then
+ // enable the related ComboBox and fill it
+
+ // don't trigger outself again
+ m_xDragED->SetSelectionChangedHdl(Link<bool, void>());
+
+ sal_Int32 nSelected = GetSelectedItem_Impl();
+ if (USER_DATA_NONE != nSelected)
+ m_xDragED->SelectCurrentItem();
+
+ if(m_xFieldCB->get_visible() && (USER_DATA_NONE != nSelected) && (nSelected < 0))
+ {
+ //search in ListBox if it's one of the first entries
+ OUString sSelect;
+ std::vector<OUString>* pVector = nullptr;
+ switch(nSelected) {
+ case USER_DATA_SALUTATION:
+ sSelect = m_sCurrentSalutation;
+ pVector = &m_aSalutations;
+ break;
+ case USER_DATA_PUNCTUATION:
+ sSelect = m_sCurrentPunctuation;
+ pVector = &m_aPunctuations;
+ break;
+ case USER_DATA_TEXT:
+ sSelect = m_sCurrentText;
+ break;
+ }
+ m_xFieldCB->clear();
+ if(pVector) {
+ for (const auto& rItem : *pVector)
+ m_xFieldCB->append_text(rItem);
+ }
+ m_xFieldCB->set_entry_text(sSelect);
+ m_xFieldCB->set_sensitive(true);
+ m_xFieldFT->set_sensitive(true);
+ }
+ else
+ {
+ m_xFieldCB->set_sensitive(false);
+ m_xFieldFT->set_sensitive(false);
+ }
+
+ UpdateImageButtons_Impl();
+ m_xDragED->SetSelectionChangedHdl( LINK( this, SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl));
+}
+
+IMPL_LINK(SwCustomizeAddressBlockDialog, SelectionChangedHdl_Impl, bool, bIdle, void)
+{
+ if (bIdle)
+ m_aSelectionChangedIdle.Start();
+ else
+ {
+ m_aSelectionChangedIdle.Stop();
+ SelectionChangedIdleHdl(nullptr);
+ }
+}
+
+IMPL_LINK_NOARG(SwCustomizeAddressBlockDialog, FieldChangeComboBoxHdl_Impl, weld::ComboBox&, void)
+{
+ //changing the field content changes the related members, too
+ sal_Int32 nSelected = GetSelectedItem_Impl();
+ const OUString sContent = m_xFieldCB->get_active_text();
+ switch(nSelected) {
+ case USER_DATA_SALUTATION:
+ m_sCurrentSalutation = sContent;
+ break;
+ case USER_DATA_PUNCTUATION:
+ m_sCurrentPunctuation = sContent;
+ break;
+ case USER_DATA_TEXT:
+ m_sCurrentText = sContent;
+ break;
+ }
+ UpdateImageButtons_Impl();
+ m_xPreview->SetAddress(GetAddress());
+ EditModifyHdl_Impl(*m_xDragED);
+}
+
+void SwCustomizeAddressBlockDialog::UpdateImageButtons_Impl()
+{
+ MoveItemFlags nMove = m_xDragED->IsCurrentItemMoveable();
+ m_xUpIB->set_sensitive( bool(nMove & MoveItemFlags::Up) );
+ m_xLeftIB->set_sensitive( bool(nMove & MoveItemFlags::Left) );
+ m_xRightIB->set_sensitive( bool(nMove & MoveItemFlags::Right) );
+ m_xDownIB->set_sensitive( bool(nMove & MoveItemFlags::Down) );
+ m_xRemoveFieldIB->set_sensitive(m_xDragED->HasCurrentItem());
+ int nEntry = m_xAddressElementsLB->get_selected_index();
+ m_xInsertFieldIB->set_sensitive( nEntry != -1 &&
+ (m_xAddressElementsLB->get_id(nEntry).toInt32() >= 0 || !m_xFieldCB->get_active_text().isEmpty()));
+}
+
+void SwCustomizeAddressBlockDialog::SetAddress(const OUString& rAddress)
+{
+ m_xDragED->SetText(rAddress);
+ UpdateImageButtons_Impl();
+ EditModifyHdl_Impl(*m_xDragED);
+}
+
+OUString SwCustomizeAddressBlockDialog::GetAddress() const
+{
+ OUString sAddress(m_xDragED->GetAddress());
+ //remove placeholders by the actual content
+ if (m_xFieldFT->get_visible())
+ {
+ for (int i = 0, nEntryCount = m_xAddressElementsLB->n_children(); i < nEntryCount; ++i)
+ {
+ const OUString sEntry = "<" + m_xAddressElementsLB->get_text(i) + ">";
+ sal_Int32 nUserData = m_xAddressElementsLB->get_id(i).toInt32();
+ switch(nUserData)
+ {
+ case USER_DATA_SALUTATION:
+ sAddress = sAddress.replaceFirst(sEntry, m_sCurrentSalutation);
+ break;
+ case USER_DATA_PUNCTUATION:
+ sAddress = sAddress.replaceFirst(sEntry, m_sCurrentPunctuation);
+ break;
+ case USER_DATA_TEXT:
+ sAddress = sAddress.replaceFirst(sEntry, m_sCurrentText);
+ break;
+ }
+ }
+ }
+ return sAddress;
+}
+
+namespace {
+
+struct SwAssignFragment
+{
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Label> m_xLabel;
+ std::unique_ptr<weld::ComboBox> m_xComboBox;
+ std::unique_ptr<weld::Label> m_xPreview;
+
+ SwAssignFragment(weld::Container* pGrid, int nLine)
+ : m_xBuilder(Application::CreateBuilder(pGrid, "modules/swriter/ui/assignfragment.ui"))
+ , m_xLabel(m_xBuilder->weld_label("label"))
+ , m_xComboBox(m_xBuilder->weld_combo_box("combobox"))
+ , m_xPreview(m_xBuilder->weld_label("preview"))
+ {
+ m_xLabel->set_grid_left_attach(0);
+ m_xLabel->set_grid_top_attach(nLine);
+
+ m_xComboBox->set_grid_left_attach(1);
+ m_xComboBox->set_grid_top_attach(nLine);
+
+ m_xPreview->set_grid_left_attach(2);
+ m_xPreview->set_grid_top_attach(nLine);
+ }
+};
+
+}
+
+class SwAssignFieldsControl
+{
+ friend class SwAssignFieldsDialog;
+ std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
+ std::unique_ptr<weld::Container> m_xGrid;
+
+ std::vector<SwAssignFragment> m_aFields;
+
+ SwMailMergeConfigItem* m_rConfigItem;
+
+ Link<LinkParamNone*,void> m_aModifyHdl;
+
+ DECL_LINK(MatchHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(GotFocusHdl_Impl, weld::Widget&, void);
+
+ void MakeVisible(const tools::Rectangle & rRect);
+public:
+ SwAssignFieldsControl(std::unique_ptr<weld::ScrolledWindow> xWindow,
+ std::unique_ptr<weld::Container> xGrid);
+
+ void Init(SwAssignFieldsDialog* pDialog, SwMailMergeConfigItem& rConfigItem);
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rModifyHdl)
+ {
+ m_aModifyHdl = rModifyHdl;
+ m_aModifyHdl.Call(nullptr);
+ }
+};
+
+SwAssignFieldsControl::SwAssignFieldsControl(std::unique_ptr<weld::ScrolledWindow> xWindow,
+ std::unique_ptr<weld::Container> xGrid)
+ : m_xVScroll(std::move(xWindow))
+ , m_xGrid(std::move(xGrid))
+ , m_rConfigItem(nullptr)
+{
+}
+
+void SwAssignFieldsControl::Init(SwAssignFieldsDialog* pDialog, SwMailMergeConfigItem& rConfigItem)
+{
+ m_rConfigItem = &rConfigItem;
+
+ //get the name of the default headers
+ const std::vector<std::pair<OUString, int>>& rHeaders = rConfigItem.GetDefaultAddressHeaders();
+ //get the actual data
+ uno::Reference< XColumnsSupplier > xColsSupp( rConfigItem.GetResultSet(), uno::UNO_QUERY);
+ //get the name of the actual columns
+ uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
+ uno::Sequence< OUString > aFields;
+ if(xColAccess.is())
+ aFields = xColAccess->getElementNames();
+
+ //get the current assignment list
+ //each position in this sequence matches the position in the header array rHeaders
+ //if no assignment is available an empty sequence will be returned
+ uno::Sequence< OUString> aAssignments = rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
+ Link<weld::ComboBox&,void> aMatchHdl = LINK(this, SwAssignFieldsControl, MatchHdl_Impl);
+ Link<weld::Widget&,void> aFocusHdl = LINK(this, SwAssignFieldsControl, GotFocusHdl_Impl);
+
+ int nLabelWidth(0), nComboBoxWidth(0), nPreviewWidth(0);
+
+ //fill the controls
+ for (size_t i = 0; i < rHeaders.size(); ++i)
+ {
+ m_aFields.emplace_back(m_xGrid.get(), i);
+
+ const OUString rHeader = rHeaders[i].first;
+ weld::ComboBox& rNewLB = *m_aFields.back().m_xComboBox;
+ rNewLB.append_text(SwResId(SW_STR_NONE));
+ rNewLB.set_active(0);
+
+ for (const OUString& rField : std::as_const(aFields))
+ rNewLB.append_text(rField);
+ //select the ListBox
+ //if there is an assignment
+ if(o3tl::make_unsigned(aAssignments.getLength()) > i && !aAssignments[i].isEmpty())
+ rNewLB.set_active_text(aAssignments[i]);
+ else //otherwise the current column name may match one of the db columns
+ rNewLB.set_active_text(rHeader);
+
+ weld::Label& rNewText = *m_aFields.back().m_xLabel;
+ rNewText.set_label("<" + rHeader + ">");
+
+ weld::Label& rNewPreview = *m_aFields.back().m_xPreview;
+ //then the preview can be filled accordingly
+ if (xColAccess.is() && rNewLB.get_active() > 0 &&
+ xColAccess->hasByName(rNewLB.get_active_text()))
+ {
+ uno::Any aCol = xColAccess->getByName(rNewLB.get_active_text());
+ uno::Reference< XColumn > xColumn;
+ aCol >>= xColumn;
+ if(xColumn.is())
+ {
+ try
+ {
+ rNewPreview.set_label(xColumn->getString());
+ }
+ catch (const SQLException&)
+ {
+ }
+ }
+ }
+
+ if (i == 0)
+ {
+ auto nLineHeight = m_xGrid->get_preferred_size().Height();
+ m_xVScroll->set_size_request(m_xVScroll->get_approximate_digit_width() * 65,
+ nLineHeight * 6);
+ nComboBoxWidth = rNewLB.get_preferred_size().Width();
+ }
+
+ nLabelWidth = std::max<int>(nLabelWidth, rNewText.get_preferred_size().Width());
+ nPreviewWidth = std::max<int>(nPreviewWidth, rNewPreview.get_preferred_size().Width());
+
+ rNewLB.connect_changed(aMatchHdl);
+ rNewLB.connect_focus_in(aFocusHdl);
+ rNewText.show();
+ rNewLB.show();
+ rNewPreview.show();
+ }
+ pDialog->ConnectSizeGroups(nLabelWidth, nComboBoxWidth, nPreviewWidth);
+}
+
+void SwAssignFieldsControl::MakeVisible(const tools::Rectangle & rRect)
+{
+ //determine range of visible positions
+ auto nMinVisiblePos = m_xVScroll->vadjustment_get_value();
+ auto nMaxVisiblePos = nMinVisiblePos + m_xVScroll->vadjustment_get_page_size();
+ if (rRect.Top() < nMinVisiblePos || rRect.Bottom() > nMaxVisiblePos)
+ m_xVScroll->vadjustment_set_value(rRect.Top());
+}
+
+IMPL_LINK(SwAssignFieldsControl, MatchHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ const OUString sColumn = rBox.get_active_text();
+ uno::Reference< XColumnsSupplier > xColsSupp( m_rConfigItem->GetResultSet(), uno::UNO_QUERY);
+ uno::Reference <XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
+ OUString sPreview;
+ if(xColAccess.is() && xColAccess->hasByName(sColumn))
+ {
+ uno::Any aCol = xColAccess->getByName(sColumn);
+ uno::Reference< XColumn > xColumn;
+ aCol >>= xColumn;
+ if(xColumn.is())
+ {
+ try
+ {
+ sPreview = xColumn->getString();
+ }
+ catch (const sdbc::SQLException&)
+ {
+ }
+ }
+ }
+ auto aLBIter = std::find_if(m_aFields.begin(), m_aFields.end(), [&rBox](const SwAssignFragment& rFragment){
+ return &rBox == rFragment.m_xComboBox.get(); });
+ if (aLBIter != m_aFields.end())
+ {
+ auto nIndex = static_cast<sal_Int32>(std::distance(m_aFields.begin(), aLBIter));
+ m_aFields[nIndex].m_xPreview->set_label(sPreview);
+ }
+ m_aModifyHdl.Call(nullptr);
+}
+
+IMPL_LINK(SwAssignFieldsControl, GotFocusHdl_Impl, weld::Widget&, rBox, void)
+{
+ int x, y, width, height;
+ rBox.get_extents_relative_to(*m_xGrid, x, y, width, height);
+ // the container has a border of 3 in the .ui
+ tools::Rectangle aRect(Point(x - 3, y - 3), Size(width + 6, height + 6));
+ MakeVisible(aRect);
+}
+
+SwAssignFieldsDialog::SwAssignFieldsDialog(
+ weld::Window* pParent, SwMailMergeConfigItem& rConfigItem,
+ OUString aPreview,
+ bool bIsAddressBlock)
+ : SfxDialogController(pParent, "modules/swriter/ui/assignfieldsdialog.ui", "AssignFieldsDialog")
+ , m_sNone(SwResId(SW_STR_NONE))
+ , m_rPreviewString(std::move(aPreview))
+ , m_rConfigItem(rConfigItem)
+ , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
+ , m_xMatchingFI(m_xBuilder->weld_label("MATCHING_LABEL"))
+ , m_xAddressTitle(m_xBuilder->weld_label("addresselem"))
+ , m_xMatchTitle(m_xBuilder->weld_label("matchelem"))
+ , m_xPreviewTitle(m_xBuilder->weld_label("previewelem"))
+ , m_xPreviewFI(m_xBuilder->weld_label("PREVIEW_LABEL"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xPreviewWin(new weld::CustomWeld(*m_xBuilder, "PREVIEW", *m_xPreview))
+ , m_xFieldsControl(new SwAssignFieldsControl(m_xBuilder->weld_scrolled_window("scroll"),
+ m_xBuilder->weld_container("FIELDS")))
+{
+ m_xPreviewWin->set_size_request(m_xMatchingFI->get_approximate_digit_width() * 45,
+ m_xMatchingFI->get_text_height() * 5);
+ m_xFieldsControl->Init(this, rConfigItem);
+
+ const OUString sMatchesTo( SwResId(ST_MATCHESTO) );
+ if (!bIsAddressBlock)
+ {
+ m_xPreviewFI->set_label(SwResId(ST_SALUTATIONPREVIEW));
+ m_xMatchingFI->set_label(SwResId(ST_SALUTATIONMATCHING));
+ m_xAddressTitle->set_label(SwResId(ST_SALUTATIONELEMENT));
+ }
+
+ m_xFieldsControl->SetModifyHdl(LINK(this, SwAssignFieldsDialog, AssignmentModifyHdl_Impl ));
+ m_xMatchingFI->set_label(m_xMatchingFI->get_label().replaceAll("%1", sMatchesTo));
+ m_xOK->connect_clicked(LINK(this, SwAssignFieldsDialog, OkHdl_Impl));
+}
+
+SwAssignFieldsDialog::~SwAssignFieldsDialog()
+{
+}
+
+uno::Sequence< OUString > SwAssignFieldsDialog::CreateAssignments()
+{
+ uno::Sequence< OUString > aAssignments(
+ m_rConfigItem.GetDefaultAddressHeaders().size());
+ OUString* pAssignments = aAssignments.getArray();
+ sal_Int32 nIndex = 0;
+ for (const auto& rLBItem : m_xFieldsControl->m_aFields)
+ {
+ const OUString sSelect = rLBItem.m_xComboBox->get_active_text();
+ pAssignments[nIndex] = (m_sNone != sSelect) ? sSelect : OUString();
+ ++nIndex;
+ }
+ return aAssignments;
+}
+
+IMPL_LINK_NOARG(SwAssignFieldsDialog, OkHdl_Impl, weld::Button&, void)
+{
+ m_rConfigItem.SetColumnAssignment(
+ m_rConfigItem.GetCurrentDBData(),
+ CreateAssignments() );
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwAssignFieldsDialog, AssignmentModifyHdl_Impl, LinkParamNone*, void)
+{
+ uno::Sequence< OUString > aAssignments = CreateAssignments();
+ const OUString sPreview = SwAddressPreview::FillData(
+ m_rPreviewString, m_rConfigItem, &aAssignments);
+ m_xPreview->SetAddress(sPreview);
+}
+
+void SwAssignFieldsDialog::ConnectSizeGroups(int nLabelWidth, int nComboBoxWidth, int nPreviewWidth)
+{
+ m_xAddressTitle->set_size_request(nLabelWidth, -1);
+ m_xMatchTitle->set_size_request(nComboBoxWidth, -1);
+ m_xPreviewTitle->set_size_request(nPreviewWidth, -1);
+}
+
+namespace
+{
+ const EECharAttrib* FindCharAttrib(int nStartPosition, std::vector<EECharAttrib>& rAttribList)
+ {
+ for (auto it = rAttribList.rbegin(); it != rAttribList.rend(); ++it)
+ {
+ const auto& rTextAtr = *it;
+ if (rTextAtr.pAttr->Which() != EE_CHAR_GRABBAG)
+ continue;
+ if (rTextAtr.nStart <= nStartPosition && rTextAtr.nEnd >= nStartPosition)
+ {
+ return &rTextAtr;
+ }
+ }
+
+ return nullptr;
+ }
+}
+
+AddressMultiLineEdit::AddressMultiLineEdit(SwCustomizeAddressBlockDialog *pParent)
+ : m_pParentDialog(pParent)
+{
+}
+
+void AddressMultiLineEdit::EndDropTarget()
+{
+ if (m_xDropTarget.is())
+ {
+ m_xEditEngine->RemoveView(m_xEditView.get());
+ auto xRealDropTarget = GetDrawingArea()->get_drop_target();
+ uno::Reference<css::datatransfer::dnd::XDropTargetListener> xListener(m_xDropTarget, uno::UNO_QUERY);
+ xRealDropTarget->removeDropTargetListener(xListener);
+ m_xDropTarget.clear();
+ }
+}
+
+AddressMultiLineEdit::~AddressMultiLineEdit()
+{
+ assert(!m_xDropTarget.is());
+}
+
+void AddressMultiLineEdit::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(160, 60), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+ WeldEditView::SetDrawingArea(pDrawingArea);
+}
+
+bool AddressMultiLineEdit::KeyInput(const KeyEvent& rKEvt)
+{
+ if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
+ return false; // we want default esc behaviour
+ if (rKEvt.GetCharCode())
+ return true; // handled
+ return WeldEditView::KeyInput(rKEvt);
+}
+
+bool AddressMultiLineEdit::Command(const CommandEvent& rCEvt)
+{
+ if (rCEvt.GetCommand() == CommandEventId::StartExtTextInput ||
+ rCEvt.GetCommand() == CommandEventId::EndExtTextInput ||
+ rCEvt.GetCommand() == CommandEventId::ExtTextInput)
+ {
+ return true;
+ }
+ return WeldEditView::Command(rCEvt);
+}
+
+bool AddressMultiLineEdit::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ if (rMEvt.GetClicks() >= 2)
+ return true; // handled
+ return WeldEditView::MouseButtonDown(rMEvt);
+}
+
+OUString AddressMultiLineEdit::GetText() const
+{
+ return m_xEditEngine->GetText();
+}
+
+void AddressMultiLineEdit::SetText( const OUString& rStr )
+{
+ m_xEditEngine->SetText(rStr);
+ //set attributes to all address tokens
+
+ sal_Int32 nSequence(0);
+ SfxGrabBagItem aProtectAttr(EE_CHAR_GRABBAG);
+ const sal_uInt32 nParaCount = m_xEditEngine->GetParagraphCount();
+ for(sal_uInt32 nPara = 0; nPara < nParaCount; ++nPara)
+ {
+ sal_Int32 nIndex = 0;
+ const OUString sPara = m_xEditEngine->GetText( nPara );
+ if (!sPara.isEmpty() && !sPara.endsWith(" "))
+ {
+ ESelection aPaM(nPara, sPara.getLength(), nPara, sPara.getLength());
+ m_xEditEngine->QuickInsertText(" ", aPaM);
+ }
+ for(;;)
+ {
+ const sal_Int32 nStart = sPara.indexOf( '<', nIndex );
+ if (nStart < 0)
+ break;
+ const sal_Int32 nEnd = sPara.indexOf( '>', nStart );
+ if (nEnd < 0)
+ break;
+ nIndex = nEnd;
+ SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
+ // make each one different, so they are not collapsed together
+ // as one attribute
+ aProtectAttr.GetGrabBag()["Index"] <<= nSequence++;
+ aSet.Put(aProtectAttr);
+ m_xEditEngine->QuickSetAttribs(aSet, ESelection(nPara, nStart, nPara, nEnd + 1));
+ }
+
+ }
+ // add two empty paragraphs at the end
+ if(m_pParentDialog->m_eType == SwCustomizeAddressBlockDialog::ADDRESSBLOCK_NEW ||
+ m_pParentDialog->m_eType == SwCustomizeAddressBlockDialog::ADDRESSBLOCK_EDIT)
+ {
+ sal_Int32 nLastLen = m_xEditEngine->GetText(nParaCount - 1).getLength();
+ if(nLastLen)
+ {
+ int nPara = nParaCount ? nParaCount - 1 : 0;
+ ESelection aPaM(nPara, nLastLen, nPara, nLastLen);
+ m_xEditEngine->QuickInsertText("\n \n ", aPaM);
+ }
+ }
+
+ m_xEditView->SetSelection(ESelection(0, 0, 0, 0));
+}
+
+// Insert the new entry in front of the entry at the beginning of the selection
+void AddressMultiLineEdit::InsertNewEntry( const OUString& rStr )
+{
+ // insert new entry after current selected one.
+ ESelection aSelection = m_xEditView->GetSelection();
+ const sal_uInt32 nPara = aSelection.nStartPara;
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(nPara, aAttribList);
+
+ sal_Int32 nIndex = aSelection.nEndPara;
+ const EECharAttrib* pAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if(nullptr != pAttrib)
+ nIndex = pAttrib->nEnd;
+ InsertNewEntryAtPosition( rStr, nPara, nIndex );
+
+ // select the new entry
+ m_xEditEngine->GetCharAttribs(nPara, aAttribList);
+ pAttrib = FindCharAttrib(nIndex, aAttribList);
+ const sal_Int32 nEnd = pAttrib ? pAttrib->nEnd : nIndex;
+ ESelection aEntrySel(nPara, nIndex, nPara, nEnd);
+ m_xEditView->SetSelection(aEntrySel);
+ Invalidate();
+ m_aModifyLink.Call(*this);
+}
+
+void AddressMultiLineEdit::InsertNewEntryAtPosition( const OUString& rStr, sal_uLong nPara, sal_uInt16 nIndex )
+{
+ ESelection aInsertPos(nPara, nIndex, nPara, nIndex);
+ m_xEditEngine->QuickInsertText(rStr, aInsertPos);
+
+ //restore the attributes
+ SetText( GetAddress() );
+
+ //select the newly inserted/moved element
+ m_xEditView->SetSelection(aInsertPos);
+ m_aSelectionLink.Call(false);
+}
+
+void AddressMultiLineEdit::RemoveCurrentEntry()
+{
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+
+ const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if(pBeginAttrib &&
+ (pBeginAttrib->nStart <= aSelection.nStartPos
+ && pBeginAttrib->nEnd >= aSelection.nEndPos))
+ {
+ const sal_uInt32 nPara = aSelection.nStartPara;
+ ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
+ m_xEditEngine->QuickInsertText(OUString(), aEntrySel);
+ //restore the attributes
+ SetText( GetAddress() );
+ m_aModifyLink.Call(*this);
+ }
+}
+
+void AddressMultiLineEdit::MoveCurrentItem(MoveItemFlags nMove)
+{
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+
+ const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if(!pBeginAttrib ||
+ pBeginAttrib->nStart > aSelection.nStartPos ||
+ pBeginAttrib->nEnd < aSelection.nEndPos)
+ return;
+
+ //current item has been found
+ sal_Int32 nPara = aSelection.nStartPara;
+ sal_Int32 nIndex = pBeginAttrib->nStart;
+ ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
+ const OUString sCurrentItem = m_xEditEngine->GetText(aEntrySel);
+ m_xEditEngine->RemoveAttribs(aEntrySel, false, EE_CHAR_GRABBAG);
+ m_xEditEngine->QuickInsertText(OUString(), aEntrySel);
+ m_xEditEngine->GetCharAttribs(nPara, aAttribList);
+ switch (nMove)
+ {
+ case MoveItemFlags::Left :
+ if(nIndex)
+ {
+ //go left to find a predecessor or simple text
+ --nIndex;
+ const OUString sPara = m_xEditEngine->GetText( nPara );
+ sal_Int32 nSearchIndex = sPara.lastIndexOf( '>', nIndex+1 );
+ if( nSearchIndex != -1 && nSearchIndex == nIndex )
+ {
+ nSearchIndex = sPara.lastIndexOf( '<', nIndex );
+ if( nSearchIndex != -1 )
+ nIndex = nSearchIndex;
+ }
+ }
+ break;
+ case MoveItemFlags::Right:
+ {
+ //go right to find a successor or simple text
+ ++nIndex;
+ const EECharAttrib* pEndAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if(pEndAttrib && pEndAttrib->nEnd >= nIndex)
+ {
+ nIndex = pEndAttrib->nEnd;
+ }
+ }
+ break;
+ case MoveItemFlags::Up :
+ --nPara;
+ nIndex = 0;
+ break;
+ case MoveItemFlags::Down :
+ ++nPara;
+ nIndex = 0;
+ break;
+ default: break;
+ }
+ //add a new paragraph if there is none yet
+ if (nPara >= m_xEditEngine->GetParagraphCount())
+ {
+ auto nInsPara = nPara - 1;
+ auto nInsPos = m_xEditEngine->GetTextLen( nPara - 1 );
+ ESelection aTemp(nInsPara, nInsPos, nInsPara, nInsPos);
+ m_xEditEngine->QuickInsertText("\n", aTemp);
+ }
+ InsertNewEntryAtPosition( sCurrentItem, nPara, nIndex );
+
+ // select the new entry [#i40817]
+ m_xEditEngine->GetCharAttribs(nPara, aAttribList);
+ const EECharAttrib* pAttrib = FindCharAttrib(nIndex, aAttribList);
+ if (pAttrib)
+ aEntrySel = ESelection(nPara, nIndex, nPara, pAttrib->nEnd);
+ m_xEditView->SetSelection(aEntrySel);
+ Invalidate();
+ m_aModifyLink.Call(*this);
+}
+
+MoveItemFlags AddressMultiLineEdit::IsCurrentItemMoveable() const
+{
+ MoveItemFlags nRet = MoveItemFlags::NONE;
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+
+ const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if (pBeginAttrib &&
+ (pBeginAttrib->nStart <= aSelection.nStartPos
+ && pBeginAttrib->nEnd >= aSelection.nEndPos))
+ {
+ if (pBeginAttrib->nStart)
+ nRet |= MoveItemFlags::Left;
+ //if there is an entry it can always be move to the right and down
+ nRet |= MoveItemFlags::Right | MoveItemFlags::Down;
+ if (aSelection.nStartPara > 0)
+ nRet |= MoveItemFlags::Up;
+ }
+ return nRet;
+}
+
+bool AddressMultiLineEdit::HasCurrentItem() const
+{
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+
+ const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ return (pBeginAttrib &&
+ (pBeginAttrib->nStart <= aSelection.nStartPos
+ && pBeginAttrib->nEnd >= aSelection.nEndPos));
+}
+
+OUString AddressMultiLineEdit::GetCurrentItem() const
+{
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+
+ const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if (pBeginAttrib &&
+ (pBeginAttrib->nStart <= aSelection.nStartPos
+ && pBeginAttrib->nEnd >= aSelection.nEndPos))
+ {
+ const sal_uInt32 nPara = aSelection.nStartPara;
+ ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
+ return m_xEditEngine->GetText( aEntrySel );
+ }
+ return OUString();
+}
+
+void AddressMultiLineEdit::SelectCurrentItem()
+{
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+
+ const EECharAttrib* pBeginAttrib = FindCharAttrib(aSelection.nStartPos, aAttribList);
+ if (pBeginAttrib &&
+ (pBeginAttrib->nStart <= aSelection.nStartPos
+ && pBeginAttrib->nEnd >= aSelection.nEndPos))
+ {
+ const sal_uInt32 nPara = aSelection.nStartPara;
+ ESelection aEntrySel(nPara, pBeginAttrib->nStart, nPara, pBeginAttrib->nEnd);
+ m_xEditView->SetSelection(aEntrySel);
+ Invalidate();
+ }
+}
+
+OUString AddressMultiLineEdit::GetAddress() const
+{
+ OUString sRet;
+ const sal_uInt32 nParaCount = m_xEditEngine->GetParagraphCount();
+ for(sal_uInt32 nPara = nParaCount; nPara; --nPara)
+ {
+ const OUString sPara = comphelper::string::stripEnd(m_xEditEngine->GetText(nPara - 1), ' ');
+ //don't add empty trailing paragraphs
+ if(!sRet.isEmpty() || !sPara.isEmpty())
+ {
+ sRet = sPara + sRet;
+ //insert the para break
+ if(nPara > 1)
+ sRet = "\n" + sRet;
+ }
+ }
+ return sRet;
+}
+
+void AddressMultiLineEdit::UpdateFields()
+{
+ ESelection aSelection = m_xEditView->GetSelection();
+
+ //restore the attributes
+ SetText( GetAddress() );
+
+ //reselect the element
+ m_xEditView->SetSelection(aSelection);
+ m_aSelectionLink.Call(false);
+}
+
+void AddressMultiLineEdit::EditViewSelectionChange()
+{
+ WeldEditView::EditViewSelectionChange();
+ m_aSelectionLink.Call(true);
+}
+
+namespace
+{
+ // sit between the tree as drag source and the editview as drop target and translate
+ // the tree dnd data to the simple string the editview wants
+ class DropTargetListener : public cppu::WeakImplHelper< css::datatransfer::dnd::XDropTargetListener,
+ css::datatransfer::dnd::XDropTarget >
+ {
+ private:
+ css::uno::Reference<css::datatransfer::dnd::XDropTarget> m_xRealDropTarget;
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> m_aListeners;
+ SwCustomizeAddressBlockDialog* m_pParentDialog;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& ) override
+ {
+ m_xRealDropTarget.clear();
+ m_aListeners.clear();
+ }
+
+ // XDropTargetListener
+ virtual void SAL_CALL drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) override
+ {
+ SolarMutexGuard aGuard;
+
+ auto aReplacement(dtde);
+
+ Point aMousePos(dtde.LocationX, dtde.LocationY);
+ bool bAllowed = m_pParentDialog->SetCursorLogicPosition(aMousePos);
+ if (bAllowed)
+ {
+ if (weld::TreeView* pTree = m_pParentDialog->get_drag_source())
+ {
+ int nEntry = pTree->get_selected_index();
+ if (nEntry != -1)
+ {
+ sal_Int32 nUserData = pTree->get_id(nEntry).toInt32();
+ //special entries can only be once in the address / greeting
+ if (nUserData >= 0 || !m_pParentDialog->HasItem(nUserData))
+ {
+ rtl::Reference<TransferDataContainer> xContainer = new TransferDataContainer;
+ xContainer->CopyString( "<" + pTree->get_text(nEntry) + ">" );
+
+ // replace what the treeview is offering with what ImpEditView::drop wants
+ aReplacement.Transferable = xContainer.get();
+ }
+ }
+ }
+ }
+
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
+ for (auto const& listener : aListeners)
+ listener->drop(aReplacement);
+
+ if (bAllowed)
+ m_pParentDialog->UpdateFields();
+ }
+
+ virtual void SAL_CALL dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) override
+ {
+ auto aReplacement(dtdee);
+ // replace what the treeview is offering with what ImpEditView::dragEnter wants
+ aReplacement.SupportedDataFlavors.realloc(1);
+ SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aReplacement.SupportedDataFlavors.getArray()[0]);
+
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
+ for (auto const& listener : aListeners)
+ listener->dragEnter(aReplacement);
+ }
+
+ virtual void SAL_CALL dragExit( const css::datatransfer::dnd::DropTargetEvent& dte ) override
+ {
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
+ for (auto const& listener : aListeners)
+ listener->dragExit( dte );
+ }
+
+ virtual void SAL_CALL dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) override
+ {
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
+ for (auto const& listener : aListeners)
+ listener->dragOver( dtde );
+ }
+
+ virtual void SAL_CALL dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) override
+ {
+ std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(m_aListeners);
+ for (auto const& listener : aListeners)
+ listener->dropActionChanged( dtde );
+ }
+
+ // XDropTarget
+ virtual void SAL_CALL addDropTargetListener(const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener) override
+ {
+ m_aListeners.push_back(xListener);
+ }
+
+ virtual void SAL_CALL removeDropTargetListener(const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener) override
+ {
+ std::erase(m_aListeners, xListener);
+ }
+
+ virtual sal_Bool SAL_CALL isActive() override
+ {
+ return m_xRealDropTarget->isActive();
+ }
+
+ virtual void SAL_CALL setActive(sal_Bool active) override
+ {
+ m_xRealDropTarget->setActive(active);
+ }
+
+ virtual sal_Int8 SAL_CALL getDefaultActions() override
+ {
+ return m_xRealDropTarget->getDefaultActions();
+ }
+
+ virtual void SAL_CALL setDefaultActions(sal_Int8 actions) override
+ {
+ m_xRealDropTarget->setDefaultActions(actions);
+ }
+
+ public:
+ DropTargetListener(css::uno::Reference<css::datatransfer::dnd::XDropTarget> xRealDropTarget,
+ SwCustomizeAddressBlockDialog* pParentDialog)
+ : m_xRealDropTarget(std::move(xRealDropTarget))
+ , m_pParentDialog(pParentDialog)
+ {
+ }
+ };
+}
+
+css::uno::Reference<css::datatransfer::dnd::XDropTarget> AddressMultiLineEdit::GetDropTarget()
+{
+ if (!m_xDropTarget.is())
+ {
+ auto xRealDropTarget = GetDrawingArea()->get_drop_target();
+ rtl::Reference<DropTargetListener> pProxy = new DropTargetListener(xRealDropTarget, m_pParentDialog);
+ xRealDropTarget->addDropTargetListener(pProxy);
+ m_xDropTarget = pProxy;
+ }
+ return m_xDropTarget;
+}
+
+bool AddressMultiLineEdit::SetCursorLogicPosition(const Point& rPosition)
+{
+ Point aMousePos = EditViewOutputDevice().PixelToLogic(rPosition);
+ m_xEditView->SetCursorLogicPosition(aMousePos, false, true);
+
+ ESelection aSelection = m_xEditView->GetSelection();
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(aSelection.nStartPara, aAttribList);
+ return FindCharAttrib(aSelection.nStartPos, aAttribList) == nullptr;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmaddressblockpage.hxx b/sw/source/ui/dbui/mmaddressblockpage.hxx
new file mode 100644
index 0000000000..f69b446169
--- /dev/null
+++ b/sw/source/ui/dbui/mmaddressblockpage.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_MMADDRESSBLOCKPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_MMADDRESSBLOCKPAGE_HXX
+
+#include <svx/weldeditview.hxx>
+#include <vcl/wizardmachine.hxx>
+#include <mailmergehelper.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <vcl/textfilter.hxx>
+#include <svl/lstner.hxx>
+#include <vcl/idle.hxx>
+#include <o3tl/typed_flags_set.hxx>
+
+class SwMailMergeWizard;
+class SwMailMergeConfigItem;
+
+class SwMailMergeAddressBlockPage : public vcl::OWizardPage
+{
+ OUString m_sDocument;
+ OUString m_sCurrentAddress;
+ OUString m_sChangeAddress;
+
+ SwMailMergeWizard* m_pWizard;
+
+ std::unique_ptr<weld::Button> m_xAddressListPB;
+ std::unique_ptr<weld::Label> m_xCurrentAddressFI;
+
+ std::unique_ptr<weld::Container> m_xStep2;
+ std::unique_ptr<weld::Container> m_xStep3;
+ std::unique_ptr<weld::Container> m_xStep4;
+
+ std::unique_ptr<weld::Label> m_xSettingsFI;
+ std::unique_ptr<weld::CheckButton> m_xAddressCB;
+ std::unique_ptr<weld::Button> m_xSettingsPB;
+ std::unique_ptr<weld::CheckButton> m_xHideEmptyParagraphsCB;
+
+ std::unique_ptr<weld::Button> m_xAssignPB;
+
+ std::unique_ptr<weld::Label> m_xDocumentIndexFI;
+ std::unique_ptr<weld::Button> m_xPrevSetIB;
+ std::unique_ptr<weld::Button> m_xNextSetIB;
+
+ std::unique_ptr<weld::Button> m_xDifferentlist;
+
+ std::unique_ptr<SwAddressPreview> m_xSettings;
+ std::unique_ptr<SwAddressPreview> m_xPreview;
+ std::unique_ptr<weld::CustomWeld> m_xSettingsWIN;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+
+ void InsertDataHdl(const weld::Button* pButton);
+
+ DECL_LINK(AddressListHdl_Impl, weld::Button&, void);
+ DECL_LINK(SettingsHdl_Impl, weld::Button&, void);
+ DECL_LINK(AssignHdl_Impl, weld::Button&, void);
+ DECL_LINK(AddressBlockHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(InsertDataHdl_Impl, weld::Button&, void);
+ DECL_LINK(AddressBlockSelectHdl_Impl, LinkParamNone*, void);
+ DECL_LINK(HideParagraphsHdl_Impl, weld::Toggleable&, void);
+
+ void EnableAddressBlock(bool bAll, bool bSelective);
+
+ virtual void Activate() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason _eReason ) override;
+ virtual bool canAdvance() const override;
+
+public:
+ SwMailMergeAddressBlockPage(weld::Container* pPage, SwMailMergeWizard* pWizard);
+ virtual ~SwMailMergeAddressBlockPage() override;
+ SwMailMergeWizard* GetWizard() { return m_pWizard; }
+};
+
+class SwSelectAddressBlockDialog : public SfxDialogController
+{
+ css::uno::Sequence< OUString> m_aAddressBlocks;
+ SwMailMergeConfigItem& m_rConfig;
+
+ std::unique_ptr<SwAddressPreview> m_xPreview;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xCustomizePB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<weld::RadioButton> m_xNeverRB;
+ std::unique_ptr<weld::RadioButton> m_xAlwaysRB;
+ std::unique_ptr<weld::RadioButton> m_xDependentRB;
+ std::unique_ptr<weld::Entry> m_xCountryED;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWin;
+
+ DECL_LINK(NewCustomizeHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(IncludeHdl_Impl, weld::Toggleable&, void);
+
+public:
+ SwSelectAddressBlockDialog(weld::Window* pParent, SwMailMergeConfigItem& rConfig);
+ virtual ~SwSelectAddressBlockDialog() override;
+
+ void SetAddressBlocks(const css::uno::Sequence< OUString>& rBlocks,
+ sal_uInt16 nSelected);
+ const css::uno::Sequence< OUString>& GetAddressBlocks();
+
+ void SetSettings(bool bIsCountry, const OUString& sCountry);
+ bool IsIncludeCountry() const {return !m_xNeverRB->get_active();}
+ OUString GetCountry() const;
+};
+
+class SwCustomizeAddressBlockDialog;
+
+enum class MoveItemFlags {
+ NONE = 0,
+ Left = 1,
+ Right = 2,
+ Up = 4,
+ Down = 8,
+};
+namespace o3tl {
+ template<> struct typed_flags<MoveItemFlags> : is_typed_flags<MoveItemFlags, 0x0f> {};
+}
+
+class AddressMultiLineEdit;
+
+class AddressMultiLineEdit : public WeldEditView
+ , public SfxListener
+{
+ Link<bool,void> m_aSelectionLink;
+ Link<AddressMultiLineEdit&,void> m_aModifyLink;
+ SwCustomizeAddressBlockDialog* m_pParentDialog;
+
+ virtual void EditViewSelectionChange() override;
+ virtual css::uno::Reference<css::datatransfer::dnd::XDropTarget> GetDropTarget() override;
+
+ virtual bool KeyInput(const KeyEvent& rKEvt) override;
+ virtual bool Command(const CommandEvent& rCEvt) override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+
+public:
+ AddressMultiLineEdit(SwCustomizeAddressBlockDialog *pParent);
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ void EndDropTarget();
+ bool SetCursorLogicPosition(const Point& rPosition);
+ void UpdateFields();
+ virtual ~AddressMultiLineEdit() override;
+
+ void SetSelectionChangedHdl( const Link<bool,void>& rLink ) { m_aSelectionLink = rLink; }
+ void SetModifyHdl( const Link<AddressMultiLineEdit&,void>& rLink ) { m_aModifyLink = rLink; }
+
+ void SetText( const OUString& rStr );
+ OUString GetText() const;
+ OUString GetAddress() const;
+
+ void InsertNewEntry( const OUString& rStr );
+ void InsertNewEntryAtPosition( const OUString& rStr, sal_uLong nPara, sal_uInt16 nIndex );
+ void RemoveCurrentEntry();
+
+ void MoveCurrentItem(MoveItemFlags nMove);
+ MoveItemFlags IsCurrentItemMoveable() const;
+ bool HasCurrentItem() const;
+ OUString GetCurrentItem() const;
+ void SelectCurrentItem();
+};
+
+class SwCustomizeAddressBlockDialog : public SfxDialogController
+{
+ friend class AddressMultiLineEdit;
+public:
+ enum DialogType
+ {
+ ADDRESSBLOCK_NEW,
+ ADDRESSBLOCK_EDIT,
+ GREETING_FEMALE,
+ GREETING_MALE
+ };
+private:
+ TextFilter m_aTextFilter;
+
+ std::vector<OUString> m_aSalutations;
+ std::vector<OUString> m_aPunctuations;
+
+ OUString m_sCurrentSalutation;
+ OUString m_sCurrentPunctuation;
+ OUString m_sCurrentText;
+
+ SwMailMergeConfigItem& m_rConfigItem;
+ DialogType m_eType;
+
+ Idle m_aSelectionChangedIdle;
+
+ std::unique_ptr<weld::Label> m_xAddressElementsFT;
+ std::unique_ptr<weld::TreeView> m_xAddressElementsLB;
+ std::unique_ptr<weld::Button> m_xInsertFieldIB;
+ std::unique_ptr<weld::Button> m_xRemoveFieldIB;
+ std::unique_ptr<weld::Label> m_xDragFT;
+ std::unique_ptr<weld::Button> m_xUpIB;
+ std::unique_ptr<weld::Button> m_xLeftIB;
+ std::unique_ptr<weld::Button> m_xRightIB;
+ std::unique_ptr<weld::Button> m_xDownIB;
+ std::unique_ptr<weld::Label> m_xFieldFT;
+ std::unique_ptr<weld::ComboBox> m_xFieldCB;
+ std::unique_ptr<weld::Button> m_xOK;
+ std::unique_ptr<SwAddressPreview> m_xPreview;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+ std::unique_ptr<AddressMultiLineEdit> m_xDragED;
+ std::unique_ptr<weld::CustomWeld> m_xDragWIN;
+
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ DECL_LINK(ListBoxSelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(EditModifyHdl_Impl, AddressMultiLineEdit&, void);
+ DECL_LINK(ImageButtonHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectionChangedHdl_Impl, bool, void);
+ DECL_LINK(FieldChangeComboBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(TextFilterHdl, OUString&, bool);
+ DECL_LINK(SelectionChangedIdleHdl, Timer*, void);
+
+ sal_Int32 GetSelectedItem_Impl() const;
+ void UpdateImageButtons_Impl();
+
+public:
+ SwCustomizeAddressBlockDialog(weld::Widget* pParent, SwMailMergeConfigItem& rConfig, DialogType);
+ virtual ~SwCustomizeAddressBlockDialog() override;
+
+ bool SetCursorLogicPosition(const Point& rPosition);
+ void UpdateFields();
+
+ // for dragging from the TreeViews, return the active source
+ weld::TreeView* get_drag_source() const { return m_xAddressElementsLB->get_drag_source(); }
+ bool HasItem(sal_Int32 nUserData);
+
+ void SetAddress(const OUString& rAddress);
+ OUString GetAddress() const;
+};
+
+class SwAssignFieldsControl;
+class SwAssignFieldsDialog : public SfxDialogController
+{
+ OUString m_sNone;
+ OUString m_rPreviewString;
+
+ SwMailMergeConfigItem& m_rConfigItem;
+
+ std::unique_ptr<SwAddressPreview> m_xPreview;
+ std::unique_ptr<weld::Label> m_xMatchingFI;
+ std::unique_ptr<weld::Label> m_xAddressTitle;
+ std::unique_ptr<weld::Label> m_xMatchTitle;
+ std::unique_ptr<weld::Label> m_xPreviewTitle;
+ std::unique_ptr<weld::Label> m_xPreviewFI;
+ std::unique_ptr<weld::Button> m_xOK;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWin;
+ std::unique_ptr<SwAssignFieldsControl> m_xFieldsControl;
+
+ css::uno::Sequence< OUString > CreateAssignments();
+ DECL_LINK(OkHdl_Impl, weld::Button&, void);
+ DECL_LINK(AssignmentModifyHdl_Impl, LinkParamNone*, void);
+
+public:
+ SwAssignFieldsDialog(weld::Window* pParent,
+ SwMailMergeConfigItem& rConfigItem,
+ OUString aPreview,
+ bool bIsAddressBlock);
+
+ void ConnectSizeGroups(int nLabelWidth, int nComboBoxWidth, int nPreviewWidth);
+
+ virtual ~SwAssignFieldsDialog() override;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmdocselectpage.cxx b/sw/source/ui/dbui/mmdocselectpage.cxx
new file mode 100644
index 0000000000..180a6d0441
--- /dev/null
+++ b/sw/source/ui/dbui/mmdocselectpage.cxx
@@ -0,0 +1,226 @@
+/* -*- 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/filedlghelper.hxx>
+#include <sfx2/new.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/docfac.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include "mmdocselectpage.hxx"
+#include <mailmergewizard.hxx>
+#include <swabstdlg.hxx>
+#include <mmconfigitem.hxx>
+#include <swuiexp.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace svt;
+
+SwMailMergeDocSelectPage::SwMailMergeDocSelectPage(weld::Container* pPage, SwMailMergeWizard* pWizard)
+ : vcl::OWizardPage(pPage, pWizard, "modules/swriter/ui/mmselectpage.ui", "MMSelectPage")
+ , m_pWizard(pWizard)
+ , m_xCurrentDocRB(m_xBuilder->weld_radio_button("currentdoc"))
+ , m_xNewDocRB(m_xBuilder->weld_radio_button("newdoc"))
+ , m_xLoadDocRB(m_xBuilder->weld_radio_button("loaddoc"))
+ , m_xLoadTemplateRB(m_xBuilder->weld_radio_button("template"))
+ , m_xRecentDocRB(m_xBuilder->weld_radio_button("recentdoc"))
+ , m_xBrowseDocPB(m_xBuilder->weld_button("browsedoc"))
+ , m_xBrowseTemplatePB(m_xBuilder->weld_button("browsetemplate"))
+ , m_xRecentDocLB(m_xBuilder->weld_combo_box("recentdoclb"))
+ , m_xDataSourceWarningFT(m_xBuilder->weld_label("datasourcewarning"))
+ , m_xExchangeDatabasePB(m_xBuilder->weld_button("exchangedatabase"))
+{
+ m_xDataSourceWarningFT->set_label_type(weld::LabelType::Warning);
+ m_xCurrentDocRB->set_active(true);
+ DocSelectHdl(*m_xNewDocRB);
+
+ Link<weld::Toggleable&,void> aDocSelectLink = LINK(this, SwMailMergeDocSelectPage, DocSelectHdl);
+ m_xCurrentDocRB->connect_toggled(aDocSelectLink);
+ m_xNewDocRB->connect_toggled(aDocSelectLink);
+ m_xLoadDocRB->connect_toggled(aDocSelectLink);
+ m_xLoadTemplateRB->connect_toggled(aDocSelectLink);
+ m_xRecentDocRB->connect_toggled(aDocSelectLink);
+
+ Link<weld::Button&,void> aFileSelectHdl = LINK(this, SwMailMergeDocSelectPage, FileSelectHdl);
+ m_xBrowseDocPB->connect_clicked(aFileSelectHdl);
+ m_xBrowseTemplatePB->connect_clicked(aFileSelectHdl);
+
+ Link<weld::Button&,void> aExchangeDatabaseHdl = LINK(this, SwMailMergeDocSelectPage, ExchangeDatabaseHdl);
+ m_xExchangeDatabasePB->connect_clicked(aExchangeDatabaseHdl);
+
+ const uno::Sequence< OUString >& rDocs =
+ m_pWizard->GetConfigItem().GetSavedDocuments();
+ for(const auto& rDoc : rDocs)
+ {
+ //insert in reverse order
+ m_xRecentDocLB->insert_text(0, rDoc);
+ }
+ if (!rDocs.hasElements())
+ m_xRecentDocRB->set_sensitive(false);
+ else
+ m_xRecentDocLB->set_active(0);
+}
+
+SwMailMergeDocSelectPage::~SwMailMergeDocSelectPage()
+{
+}
+
+IMPL_LINK_NOARG(SwMailMergeDocSelectPage, DocSelectHdl, weld::Toggleable&, void)
+{
+ m_xRecentDocLB->set_sensitive(m_xRecentDocRB->get_active());
+ m_pWizard->UpdateRoadmap();
+ OUString sDataSourceName = m_pWizard->GetSwView()->GetDataSourceName();
+
+ if(m_xCurrentDocRB->get_active() &&
+ !sDataSourceName.isEmpty() &&
+ !SwView::IsDataSourceAvailable(sDataSourceName))
+ {
+ m_xDataSourceWarningFT->show();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, false);
+ }
+ else
+ {
+ m_xDataSourceWarningFT->hide();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_OUTPUTTYPETPAGE));
+ }
+
+ if(m_xCurrentDocRB->get_active())
+ m_xExchangeDatabasePB->set_sensitive(true);
+ else
+ m_xExchangeDatabasePB->set_sensitive(false);
+}
+
+IMPL_LINK(SwMailMergeDocSelectPage, FileSelectHdl, weld::Button&, rButton, void)
+{
+ bool bTemplate = m_xBrowseTemplatePB.get() == &rButton;
+
+ if(bTemplate)
+ {
+ m_xLoadTemplateRB->set_active(true);
+ SfxNewFileDialog aNewFileDlg(m_pWizard->getDialog(), SfxNewFileDialogMode::NONE);
+ sal_uInt16 nRet = aNewFileDlg.run();
+ if(RET_TEMPLATE_LOAD == nRet)
+ bTemplate = false;
+ else if(RET_CANCEL != nRet)
+ m_sLoadTemplateName = aNewFileDlg.GetTemplateFileName();
+ }
+ else
+ m_xLoadDocRB->set_active(true);
+
+ if(!bTemplate)
+ {
+ sfx2::FileDialogHelper aDlgHelper(TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, m_pWizard->getDialog());
+ aDlgHelper.SetContext(sfx2::FileDialogHelper::WriterMailMerge);
+ Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+
+ SfxObjectFactory &rFact = m_pWizard->GetSwView()->GetDocShell()->GetFactory();
+ SfxFilterMatcher aMatcher( rFact.GetFactoryName() );
+ SfxFilterMatcherIter aIter( aMatcher );
+ std::shared_ptr<const SfxFilter> pFlt = aIter.First();
+ while( pFlt )
+ {
+ if( pFlt && pFlt->IsAllowedAsTemplate() )
+ {
+ const OUString sWild = pFlt->GetWildcard().getGlob();
+ xFP->appendFilter( pFlt->GetUIName(), sWild );
+
+ // #i40125
+ if(pFlt->GetFilterFlags() & SfxFilterFlags::DEFAULT)
+ xFP->setCurrentFilter( pFlt->GetUIName() ) ;
+ }
+
+ pFlt = aIter.Next();
+ }
+
+ if( ERRCODE_NONE == aDlgHelper.Execute() )
+ {
+ m_sLoadFileName = xFP->getSelectedFiles().getConstArray()[0];
+ }
+ }
+ m_pWizard->UpdateRoadmap();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_OUTPUTTYPETPAGE));
+}
+
+IMPL_LINK_NOARG(SwMailMergeDocSelectPage, ExchangeDatabaseHdl, weld::Button&, void)
+{
+
+ SwAbstractDialogFactory& rFact = ::swui::GetFactory();
+ ScopedVclPtr<VclAbstractDialog> pDlg(rFact.CreateSwChangeDBDlg(*m_pWizard->GetSwView()));
+ pDlg->Execute();
+
+ OUString sDataSourceName = m_pWizard->GetSwView()->GetDataSourceName();
+
+ if(m_xCurrentDocRB->get_active() &&
+ !sDataSourceName.isEmpty() &&
+ SwView::IsDataSourceAvailable(sDataSourceName))
+ {
+ m_xDataSourceWarningFT->hide();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, true);
+ }
+}
+
+bool SwMailMergeDocSelectPage::commitPage( ::vcl::WizardTypes::CommitPageReason _eReason )
+{
+ bool bReturn = false;
+ bool bNext = _eReason == ::vcl::WizardTypes::eTravelForward;
+ if(bNext || _eReason == ::vcl::WizardTypes::eValidate )
+ {
+ OUString sReloadDocument;
+ bReturn = m_xCurrentDocRB->get_active() ||
+ m_xNewDocRB->get_active();
+ if (!bReturn)
+ {
+ sReloadDocument = m_sLoadFileName;
+ bReturn = !sReloadDocument.isEmpty() && m_xLoadDocRB->get_active();
+ }
+ if (!bReturn)
+ {
+ sReloadDocument = m_sLoadTemplateName;
+ bReturn = !sReloadDocument.isEmpty() && m_xLoadTemplateRB->get_active();
+ }
+ if (!bReturn)
+ {
+ bReturn = m_xRecentDocRB->get_active();
+ if (bReturn)
+ {
+ sReloadDocument = m_xRecentDocLB->get_active_text();
+ bReturn = !sReloadDocument.isEmpty();
+ }
+ }
+ if( _eReason == ::vcl::WizardTypes::eValidate )
+ m_pWizard->SetDocumentLoad(!m_xCurrentDocRB->get_active());
+
+ if(bNext && !m_xCurrentDocRB->get_active())
+ {
+ if(!sReloadDocument.isEmpty())
+ m_pWizard->SetReloadDocument( sReloadDocument );
+ m_pWizard->SetRestartPage(MM_OUTPUTTYPETPAGE);
+ m_pWizard->response(RET_LOAD_DOC);
+ }
+ }
+ return bReturn;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmdocselectpage.hxx b/sw/source/ui/dbui/mmdocselectpage.hxx
new file mode 100644
index 0000000000..d1cdca67d3
--- /dev/null
+++ b/sw/source/ui/dbui/mmdocselectpage.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_MMDOCSELECTPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_MMDOCSELECTPAGE_HXX
+
+#include <vcl/wizardmachine.hxx>
+#include <vcl/weld.hxx>
+
+class SwMailMergeWizard;
+
+class SwMailMergeDocSelectPage : public vcl::OWizardPage
+{
+ OUString m_sLoadFileName;
+ OUString m_sLoadTemplateName;
+
+ SwMailMergeWizard* m_pWizard;
+
+ std::unique_ptr<weld::RadioButton> m_xCurrentDocRB;
+ std::unique_ptr<weld::RadioButton> m_xNewDocRB;
+ std::unique_ptr<weld::RadioButton> m_xLoadDocRB;
+ std::unique_ptr<weld::RadioButton> m_xLoadTemplateRB;
+ std::unique_ptr<weld::RadioButton> m_xRecentDocRB;
+ std::unique_ptr<weld::Button> m_xBrowseDocPB;
+ std::unique_ptr<weld::Button> m_xBrowseTemplatePB;
+ std::unique_ptr<weld::ComboBox> m_xRecentDocLB;
+ std::unique_ptr<weld::Label> m_xDataSourceWarningFT;
+ std::unique_ptr<weld::Button> m_xExchangeDatabasePB;
+
+ DECL_LINK(DocSelectHdl, weld::Toggleable&, void);
+ DECL_LINK(FileSelectHdl, weld::Button&, void);
+ DECL_LINK(ExchangeDatabaseHdl, weld::Button&, void);
+
+ virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override;
+
+public:
+ SwMailMergeDocSelectPage(weld::Container* pPage, SwMailMergeWizard* pWizard);
+ virtual ~SwMailMergeDocSelectPage() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmgreetingspage.cxx b/sw/source/ui/dbui/mmgreetingspage.cxx
new file mode 100644
index 0000000000..c75a01ee8d
--- /dev/null
+++ b/sw/source/ui/dbui/mmgreetingspage.cxx
@@ -0,0 +1,421 @@
+/* -*- 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 "mmgreetingspage.hxx"
+#include <mailmergewizard.hxx>
+#include <mmconfigitem.hxx>
+#include "mmaddressblockpage.hxx"
+#include <dbui.hrc>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/sdbc/SQLException.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+
+using namespace svt;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+static void lcl_FillGreetingsBox(weld::ComboBox& rBox,
+ SwMailMergeConfigItem const & rConfig,
+ SwMailMergeConfigItem::Gender eType)
+{
+ const Sequence< OUString> rEntries = rConfig.GetGreetings(eType);
+ for(const auto& rEntry : rEntries)
+ rBox.append_text(rEntry);
+ rBox.set_active(rConfig.GetCurrentGreeting(eType));
+}
+
+static void lcl_StoreGreetingsBox(const weld::ComboBox& rBox,
+ SwMailMergeConfigItem& rConfig,
+ SwMailMergeConfigItem::Gender eType)
+{
+ Sequence< OUString> aEntries(rBox.get_count());
+ OUString* pEntries = aEntries.getArray();
+ for(sal_Int32 nEntry = 0; nEntry < rBox.get_count(); ++nEntry)
+ pEntries[nEntry] = rBox.get_text(nEntry);
+ rConfig.SetGreetings(eType, aEntries);
+ rConfig.SetCurrentGreeting(eType, rBox.get_active());
+}
+
+IMPL_LINK_NOARG(SwGreetingsHandler, IndividualHdl_Impl, weld::Toggleable&, void)
+{
+ bool bIndividual = m_xPersonalizedCB->get_sensitive() && m_xPersonalizedCB->get_active();
+ m_xFemaleFT->set_sensitive(bIndividual);
+ m_xFemaleLB->set_sensitive(bIndividual);
+ m_xFemalePB->set_sensitive(bIndividual);
+ m_xMaleFT->set_sensitive(bIndividual);
+ m_xMaleLB->set_sensitive(bIndividual);
+ m_xMalePB->set_sensitive(bIndividual);
+ m_xFemaleFI->set_sensitive(bIndividual);
+ m_xFemaleColumnFT->set_sensitive(bIndividual);
+ m_xFemaleColumnLB->set_sensitive(bIndividual);
+ m_xFemaleFieldFT->set_sensitive(bIndividual);
+ m_xFemaleFieldCB->set_sensitive(bIndividual);
+
+ if( m_bIsTabPage )
+ {
+ m_rConfigItem.SetIndividualGreeting(bIndividual, false);
+ m_pWizard->UpdateRoadmap();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_LAYOUTPAGE));
+ }
+ UpdatePreview();
+}
+
+IMPL_LINK(SwGreetingsHandler, GreetingHdl_Impl, weld::Button&, rButton, void)
+{
+ std::unique_ptr<SwCustomizeAddressBlockDialog> xDlg(new SwCustomizeAddressBlockDialog(&rButton, m_rConfigItem,
+ &rButton == m_xMalePB.get() ?
+ SwCustomizeAddressBlockDialog::GREETING_MALE :
+ SwCustomizeAddressBlockDialog::GREETING_FEMALE ));
+ if (RET_OK == xDlg->run())
+ {
+ weld::ComboBox* pToInsert = &rButton == m_xMalePB.get() ? m_xMaleLB.get() : m_xFemaleLB.get();
+ pToInsert->append_text(xDlg->GetAddress());
+ pToInsert->set_active(pToInsert->get_count() - 1);
+ if(m_bIsTabPage)
+ {
+ m_pWizard->UpdateRoadmap();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_LAYOUTPAGE));
+ }
+ UpdatePreview();
+ }
+}
+
+void SwGreetingsHandler::UpdatePreview()
+{
+ //the base class does nothing
+}
+
+IMPL_LINK_NOARG(SwMailMergeGreetingsPage, AssignHdl_Impl, weld::Button&, void)
+{
+ const OUString sPreview(m_xFemaleLB->get_active_text() + "\n" + m_xMaleLB->get_active_text());
+ SwAssignFieldsDialog aDlg(m_pWizard->getDialog(), m_rConfigItem, sPreview, false);
+ if (RET_OK == aDlg.run())
+ {
+ UpdatePreview();
+ m_pWizard->UpdateRoadmap();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_LAYOUTPAGE));
+ }
+}
+
+IMPL_LINK_NOARG(SwMailMergeGreetingsPage, GreetingSelectListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ UpdatePreview();
+}
+
+IMPL_LINK_NOARG(SwMailMergeGreetingsPage, GreetingSelectComboBoxHdl_Impl, weld::ComboBox&, void)
+{
+ UpdatePreview();
+}
+
+void SwMailMergeGreetingsPage::UpdatePreview()
+{
+ //find out which type of greeting should be selected:
+ bool bFemale = false;
+ bool bNoValue = !m_xFemaleColumnLB->get_sensitive();
+ if( !bNoValue )
+ {
+ const OUString sFemaleValue = m_xFemaleFieldCB->get_active_text();
+ const OUString sFemaleColumn = m_xFemaleColumnLB->get_active_text();
+ Reference< sdbcx::XColumnsSupplier > xColsSupp( m_rConfigItem.GetResultSet(), UNO_QUERY);
+ Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
+ if(!sFemaleValue.isEmpty() && !sFemaleColumn.isEmpty() &&
+ xColAccess.is() &&
+ xColAccess->hasByName(sFemaleColumn))
+ {
+ //get the content and exchange it in the address string
+ Any aCol = xColAccess->getByName(sFemaleColumn);
+ Reference< sdb::XColumn > xColumn;
+ aCol >>= xColumn;
+ if(xColumn.is())
+ {
+ try
+ {
+ bFemale = xColumn->getString() == sFemaleValue;
+
+ //no last name value marks the greeting also as neutral
+ const OUString sLastNameColumn =
+ m_rConfigItem.GetAssignedColumn(MM_PART_LASTNAME);
+ if ( xColAccess->hasByName(sLastNameColumn) )
+ {
+ aCol = xColAccess->getByName(sLastNameColumn);
+ aCol >>= xColumn;
+ bNoValue = xColumn->getString().isEmpty();
+ }
+ }
+ catch (const sdbc::SQLException&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "");
+ }
+ }
+ }
+ }
+
+ OUString sPreview = bFemale ? m_xFemaleLB->get_active_text() :
+ bNoValue ? m_xNeutralCB->get_active_text() : m_xMaleLB->get_active_text();
+
+ sPreview = SwAddressPreview::FillData(sPreview, m_rConfigItem);
+ m_xPreview->SetAddress(sPreview);
+}
+
+void SwGreetingsHandler::Contains(bool bContainsGreeting)
+{
+ m_xPersonalizedCB->set_sensitive(bContainsGreeting);
+ bool bEnablePersonal = bContainsGreeting && m_xPersonalizedCB->get_active();
+ m_xFemaleFT->set_sensitive(bEnablePersonal);
+ m_xFemaleLB->set_sensitive(bEnablePersonal);
+ m_xFemalePB->set_sensitive(bEnablePersonal);
+ m_xMaleFT->set_sensitive(bEnablePersonal);
+ m_xMaleLB->set_sensitive(bEnablePersonal);
+ m_xMalePB->set_sensitive(bEnablePersonal);
+ m_xFemaleFI->set_sensitive(bEnablePersonal);
+ m_xFemaleColumnFT->set_sensitive(bEnablePersonal);
+ m_xFemaleColumnLB->set_sensitive(bEnablePersonal);
+ m_xFemaleFieldFT->set_sensitive(bEnablePersonal);
+ m_xFemaleFieldCB->set_sensitive(bEnablePersonal);
+ m_xNeutralFT->set_sensitive(bContainsGreeting);
+ m_xNeutralCB->set_sensitive(bContainsGreeting);
+}
+
+SwMailMergeGreetingsPage::SwMailMergeGreetingsPage(weld::Container* pPage, SwMailMergeWizard* pWizard)
+ : vcl::OWizardPage(pPage, pWizard, "modules/swriter/ui/mmsalutationpage.ui", "MMSalutationPage")
+ , SwGreetingsHandler(pWizard->GetConfigItem(), *m_xBuilder)
+ , m_xPreview(new SwAddressPreview(m_xBuilder->weld_scrolled_window("previewwin", true)))
+ , m_xPreviewFI(m_xBuilder->weld_label("previewft"))
+ , m_xAssignPB(m_xBuilder->weld_button("assign"))
+ , m_xDocumentIndexFI(m_xBuilder->weld_label("documentindex"))
+ , m_xPrevSetIB(m_xBuilder->weld_button("prev"))
+ , m_xNextSetIB(m_xBuilder->weld_button("next"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", *m_xPreview))
+{
+ m_pWizard = pWizard;
+
+ Size aSize(m_xPreview->GetDrawingArea()->get_ref_device().LogicToPixel(Size(186, 21), MapMode(MapUnit::MapAppFont)));
+ m_xPreviewWIN->set_size_request(aSize.Width(), aSize.Height());
+ m_sDocument = m_xDocumentIndexFI->get_label();
+
+ m_bIsTabPage = true;
+
+ m_xGreetingLineCB->connect_toggled(LINK(this, SwMailMergeGreetingsPage, ContainsHdl_Impl));
+ Link<weld::Toggleable&,void> aIndividualLink = LINK(this, SwGreetingsHandler, IndividualHdl_Impl);
+ m_xPersonalizedCB->connect_toggled(aIndividualLink);
+ Link<weld::Button&,void> aGreetingLink = LINK(this, SwGreetingsHandler, GreetingHdl_Impl);
+ m_xFemalePB->connect_clicked(aGreetingLink);
+ m_xMalePB->connect_clicked(aGreetingLink);
+ m_xAssignPB->connect_clicked(LINK(this, SwMailMergeGreetingsPage, AssignHdl_Impl));
+ Link<weld::ComboBox&,void> aLBoxLink2 = LINK(this, SwMailMergeGreetingsPage, GreetingSelectListBoxHdl_Impl);
+ m_xFemaleLB->connect_changed(aLBoxLink2);
+ m_xMaleLB->connect_changed(aLBoxLink2);
+ m_xFemaleColumnLB->connect_changed(aLBoxLink2);
+ m_xFemaleFieldCB->connect_changed(LINK(this, SwMailMergeGreetingsPage, GreetingSelectComboBoxHdl_Impl));
+ m_xNeutralCB->connect_changed(LINK(this, SwMailMergeGreetingsPage, GreetingSelectComboBoxHdl_Impl));
+
+ Link<weld::Button&,void> aDataLink = LINK(this, SwMailMergeGreetingsPage, InsertDataHdl_Impl);
+ m_xPrevSetIB->connect_clicked(aDataLink);
+ m_xNextSetIB->connect_clicked(aDataLink);
+
+ m_xGreetingLineCB->set_active(m_rConfigItem.IsGreetingLine(false));
+ m_xPersonalizedCB->set_active(m_rConfigItem.IsIndividualGreeting(false));
+ ContainsHdl_Impl(*m_xGreetingLineCB);
+ aIndividualLink.Call(*m_xPersonalizedCB);
+
+ lcl_FillGreetingsBox(*m_xFemaleLB, m_rConfigItem, SwMailMergeConfigItem::FEMALE);
+ lcl_FillGreetingsBox(*m_xMaleLB, m_rConfigItem, SwMailMergeConfigItem::MALE);
+ lcl_FillGreetingsBox(*m_xNeutralCB, m_rConfigItem, SwMailMergeConfigItem::NEUTRAL);
+
+ m_xDocumentIndexFI->set_label(m_sDocument.replaceFirst("%1", "1"));
+}
+
+SwMailMergeGreetingsPage::~SwMailMergeGreetingsPage()
+{
+ m_xPreviewWIN.reset();
+ m_xPreview.reset();
+}
+
+void SwMailMergeGreetingsPage::Activate()
+{
+ //try to find the gender setting
+ m_xFemaleColumnLB->clear();
+ Reference< sdbcx::XColumnsSupplier > xColsSupp = m_rConfigItem.GetColumnsSupplier();
+ if(xColsSupp.is())
+ {
+ Reference < container::XNameAccess> xColAccess = xColsSupp->getColumns();
+ const Sequence< OUString > aColumns = xColAccess->getElementNames();
+ for(const auto& rColumn : aColumns)
+ m_xFemaleColumnLB->append_text(rColumn);
+ }
+
+ m_xFemaleColumnLB->set_active_text(m_rConfigItem.GetAssignedColumn(MM_PART_GENDER));
+ m_xFemaleColumnLB->save_value();
+
+ m_xFemaleFieldCB->set_entry_text(m_rConfigItem.GetFemaleGenderValue());
+ m_xFemaleFieldCB->save_value();
+
+ UpdatePreview();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_LAYOUTPAGE));
+}
+
+bool SwMailMergeGreetingsPage::commitPage( ::vcl::WizardTypes::CommitPageReason )
+{
+ if (m_xFemaleColumnLB->get_value_changed_from_saved())
+ {
+ const SwDBData& rDBData = m_rConfigItem.GetCurrentDBData();
+ Sequence< OUString> aAssignment = m_rConfigItem.GetColumnAssignment( rDBData );
+ if(aAssignment.getLength() <= MM_PART_GENDER)
+ aAssignment.realloc(MM_PART_GENDER + 1);
+ aAssignment.getArray()[MM_PART_GENDER] = m_xFemaleColumnLB->get_active_text();
+ m_rConfigItem.SetColumnAssignment( rDBData, aAssignment );
+ }
+ if (m_xFemaleFieldCB->get_value_changed_from_saved())
+ m_rConfigItem.SetFemaleGenderValue(m_xFemaleFieldCB->get_active_text());
+
+ lcl_StoreGreetingsBox(*m_xFemaleLB, m_rConfigItem, SwMailMergeConfigItem::FEMALE);
+ lcl_StoreGreetingsBox(*m_xMaleLB, m_rConfigItem, SwMailMergeConfigItem::MALE);
+
+ sal_Int32 nCurrentTextPos = m_xNeutralCB->find_text(m_xNeutralCB->get_active_text());
+ if (nCurrentTextPos == -1)
+ {
+ m_xNeutralCB->append_text(m_xNeutralCB->get_active_text());
+ m_xNeutralCB->set_active(m_xNeutralCB->get_count() - 1);
+ }
+ lcl_StoreGreetingsBox(*m_xNeutralCB, m_rConfigItem, SwMailMergeConfigItem::NEUTRAL);
+ m_rConfigItem.SetGreetingLine(m_xGreetingLineCB->get_active(), false);
+ m_rConfigItem.SetIndividualGreeting(m_xPersonalizedCB->get_active(), false);
+ return true;
+}
+
+IMPL_LINK(SwMailMergeGreetingsPage, ContainsHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bContainsGreeting = rBox.get_active();
+ SwGreetingsHandler::Contains(bContainsGreeting);
+ m_xPreviewFI->set_sensitive(bContainsGreeting);
+ m_xPreviewWIN->set_sensitive(bContainsGreeting);
+ m_xAssignPB->set_sensitive(bContainsGreeting);
+ m_xDocumentIndexFI->set_sensitive(bContainsGreeting);
+ m_xPrevSetIB->set_sensitive(bContainsGreeting);
+ m_xNextSetIB->set_sensitive(bContainsGreeting);
+ m_rConfigItem.SetGreetingLine(m_xGreetingLineCB->get_active(), false);
+ m_pWizard->UpdateRoadmap();
+ m_pWizard->enableButtons(WizardButtonFlags::NEXT, m_pWizard->isStateEnabled(MM_LAYOUTPAGE));
+}
+
+IMPL_LINK(SwMailMergeGreetingsPage, InsertDataHdl_Impl, weld::Button&, rButton, void)
+{
+ bool bNext = &rButton == m_xNextSetIB.get();
+ sal_Int32 nPos = m_rConfigItem.GetResultSetPosition();
+ m_rConfigItem.MoveResultSet( bNext ? ++nPos : --nPos);
+ nPos = m_rConfigItem.GetResultSetPosition();
+ bool bEnable = true;
+ if(nPos < 1)
+ {
+ bEnable = false;
+ nPos = 1;
+ }
+ else
+ UpdatePreview();
+ m_xPrevSetIB->set_sensitive(bEnable);
+ m_xNextSetIB->set_sensitive(bEnable);
+ m_xDocumentIndexFI->set_sensitive(bEnable);
+ m_xDocumentIndexFI->set_label(m_sDocument.replaceFirst("%1", OUString::number(nPos)));
+}
+
+SwMailBodyDialog::SwMailBodyDialog(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/mmmailbody.ui", "MailBodyDialog")
+ , SwGreetingsHandler(*GetActiveView()->GetMailMergeConfigItem(), *m_xBuilder)
+ , m_xBodyMLE(m_xBuilder->weld_text_view("bodymle"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+{
+ m_bIsTabPage = false;
+ m_xBodyMLE->set_size_request(m_xBodyMLE->get_approximate_digit_width() * 45,
+ m_xBodyMLE->get_height_rows(6));
+ m_xGreetingLineCB->connect_toggled(LINK(this, SwMailBodyDialog, ContainsHdl_Impl));
+ Link<weld::Toggleable&,void> aIndividualLink = LINK(this, SwGreetingsHandler, IndividualHdl_Impl);
+ m_xPersonalizedCB->connect_toggled(aIndividualLink);
+ Link<weld::Button&,void> aGreetingLink = LINK(this, SwGreetingsHandler, GreetingHdl_Impl);
+ m_xFemalePB->connect_clicked(aGreetingLink);
+ m_xMalePB->connect_clicked(aGreetingLink);
+ m_xOK->connect_clicked(LINK(this, SwMailBodyDialog, OKHdl));
+
+ m_xGreetingLineCB->set_active(m_rConfigItem.IsGreetingLine(true));
+ m_xPersonalizedCB->set_active(m_rConfigItem.IsIndividualGreeting(true));
+ ContainsHdl_Impl(*m_xGreetingLineCB);
+ aIndividualLink.Call(*m_xPersonalizedCB);
+
+ lcl_FillGreetingsBox(*m_xFemaleLB, m_rConfigItem, SwMailMergeConfigItem::FEMALE);
+ lcl_FillGreetingsBox(*m_xMaleLB, m_rConfigItem, SwMailMergeConfigItem::MALE);
+ lcl_FillGreetingsBox(*m_xNeutralCB, m_rConfigItem, SwMailMergeConfigItem::NEUTRAL);
+
+ //try to find the gender setting
+ m_xFemaleColumnLB->clear();
+ Reference< sdbcx::XColumnsSupplier > xColsSupp = m_rConfigItem.GetColumnsSupplier();
+ if(xColsSupp.is())
+ {
+ Reference < container::XNameAccess> xColAccess = xColsSupp->getColumns();
+ const Sequence< OUString > aColumns = xColAccess->getElementNames();
+ for(const auto& rColumn : aColumns)
+ m_xFemaleColumnLB->append_text(rColumn);
+ }
+
+ m_xFemaleColumnLB->set_active_text(m_rConfigItem.GetAssignedColumn(MM_PART_GENDER));
+ m_xFemaleColumnLB->save_value();
+
+ m_xFemaleFieldCB->set_entry_text(m_rConfigItem.GetFemaleGenderValue());
+ m_xFemaleFieldCB->save_value();
+}
+
+SwMailBodyDialog::~SwMailBodyDialog()
+{
+}
+
+IMPL_LINK(SwMailBodyDialog, ContainsHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ SwGreetingsHandler::Contains(rBox.get_active());
+ m_rConfigItem.SetGreetingLine(rBox.get_active(), true);
+}
+
+IMPL_LINK_NOARG(SwMailBodyDialog, OKHdl, weld::Button&, void)
+{
+ m_rConfigItem.SetGreetingLine(
+ m_xGreetingLineCB->get_active(), false);
+ m_rConfigItem.SetIndividualGreeting(
+ m_xPersonalizedCB->get_active(), false);
+
+ if (m_xFemaleColumnLB->get_value_changed_from_saved())
+ {
+ const SwDBData& rDBData = m_rConfigItem.GetCurrentDBData();
+ Sequence< OUString> aAssignment = m_rConfigItem.GetColumnAssignment( rDBData );
+ sal_Int32 nPos = m_xFemaleColumnLB->get_active();
+ if(aAssignment.getLength() < MM_PART_GENDER)
+ aAssignment.realloc(MM_PART_GENDER);
+ if( nPos > 0 )
+ aAssignment.getArray()[MM_PART_GENDER] = m_xFemaleColumnLB->get_active_text();
+ else
+ aAssignment.getArray()[MM_PART_GENDER].clear();
+ m_rConfigItem.SetColumnAssignment( rDBData, aAssignment );
+ }
+ if (m_xFemaleFieldCB->get_value_changed_from_saved())
+ m_rConfigItem.SetFemaleGenderValue(m_xFemaleFieldCB->get_active_text());
+
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmgreetingspage.hxx b/sw/source/ui/dbui/mmgreetingspage.hxx
new file mode 100644
index 0000000000..cce99a0ffb
--- /dev/null
+++ b/sw/source/ui/dbui/mmgreetingspage.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_MMGREETINGSPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_MMGREETINGSPAGE_HXX
+
+#include <vcl/wizardmachine.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <mailmergehelper.hxx>
+#include <vcl/weld.hxx>
+
+#include <mailmergewizard.hxx>
+
+class SwMailMergeWizard;
+
+class SwGreetingsHandler
+{
+protected:
+ SwMailMergeWizard* m_pWizard;
+ /// The mail merge state, available even when m_pWizard is nullptr.
+ SwMailMergeConfigItem& m_rConfigItem;
+ bool m_bIsTabPage;
+
+ std::unique_ptr<weld::CheckButton> m_xGreetingLineCB;
+ std::unique_ptr<weld::CheckButton> m_xPersonalizedCB;
+ std::unique_ptr<weld::Label> m_xFemaleFT;
+ std::unique_ptr<weld::ComboBox> m_xFemaleLB;
+ std::unique_ptr<weld::Button> m_xFemalePB;
+ std::unique_ptr<weld::Label> m_xMaleFT;
+ std::unique_ptr<weld::ComboBox> m_xMaleLB;
+ std::unique_ptr<weld::Button> m_xMalePB;
+ std::unique_ptr<weld::Label> m_xFemaleFI;
+ std::unique_ptr<weld::Label> m_xFemaleColumnFT;
+ std::unique_ptr<weld::ComboBox> m_xFemaleColumnLB;
+ std::unique_ptr<weld::Label> m_xFemaleFieldFT;
+ std::unique_ptr<weld::ComboBox> m_xFemaleFieldCB;
+ std::unique_ptr<weld::Label> m_xNeutralFT;
+ std::unique_ptr<weld::ComboBox> m_xNeutralCB;
+
+ SwGreetingsHandler(SwMailMergeConfigItem& rConfigItem, weld::Builder& rBuilder)
+ : m_pWizard(nullptr)
+ , m_rConfigItem(rConfigItem)
+ , m_bIsTabPage(false)
+ , m_xGreetingLineCB(rBuilder.weld_check_button("greeting"))
+ , m_xPersonalizedCB(rBuilder.weld_check_button("personalized"))
+ , m_xFemaleFT(rBuilder.weld_label("femaleft"))
+ , m_xFemaleLB(rBuilder.weld_combo_box("female"))
+ , m_xFemalePB(rBuilder.weld_button("newfemale"))
+ , m_xMaleFT(rBuilder.weld_label("maleft"))
+ , m_xMaleLB(rBuilder.weld_combo_box("male"))
+ , m_xMalePB(rBuilder.weld_button("newmale"))
+ , m_xFemaleFI(rBuilder.weld_label("femalefi"))
+ , m_xFemaleColumnFT(rBuilder.weld_label("femalecolft"))
+ , m_xFemaleColumnLB(rBuilder.weld_combo_box("femalecol"))
+ , m_xFemaleFieldFT(rBuilder.weld_label("femalefieldft"))
+ , m_xFemaleFieldCB(rBuilder.weld_combo_box("femalefield"))
+ , m_xNeutralFT(rBuilder.weld_label("generalft"))
+ , m_xNeutralCB(rBuilder.weld_combo_box("general"))
+ {
+ }
+
+ ~SwGreetingsHandler() {}
+
+ DECL_LINK(IndividualHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(GreetingHdl_Impl, weld::Button&, void);
+
+ void Contains(bool bContainsGreeting);
+ virtual void UpdatePreview();
+};
+
+class SwMailMergeGreetingsPage : public vcl::OWizardPage, public SwGreetingsHandler
+{
+ std::unique_ptr<SwAddressPreview> m_xPreview;
+ std::unique_ptr<weld::Label> m_xPreviewFI;
+ std::unique_ptr<weld::Button> m_xAssignPB;
+ std::unique_ptr<weld::Label> m_xDocumentIndexFI;
+ std::unique_ptr<weld::Button> m_xPrevSetIB;
+ std::unique_ptr<weld::Button> m_xNextSetIB;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+
+ OUString m_sDocument;
+
+ DECL_LINK(ContainsHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(InsertDataHdl_Impl, weld::Button&, void);
+ DECL_LINK(GreetingSelectComboBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(GreetingSelectListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(AssignHdl_Impl, weld::Button&, void);
+
+ virtual void UpdatePreview() override;
+ virtual void Activate() override;
+ virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override;
+
+public:
+ SwMailMergeGreetingsPage(weld::Container* pPage, SwMailMergeWizard* pWizard);
+ virtual ~SwMailMergeGreetingsPage() override;
+};
+
+class SwMailBodyDialog : public SfxDialogController, public SwGreetingsHandler
+{
+ std::unique_ptr<weld::TextView> m_xBodyMLE;
+ std::unique_ptr<weld::Button> m_xOK;
+
+ DECL_LINK(ContainsHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(OKHdl, weld::Button&, void);
+
+public:
+ SwMailBodyDialog(weld::Window* pParent);
+ virtual ~SwMailBodyDialog() override;
+
+ void SetBody(const OUString& rBody) { m_xBodyMLE->set_text(rBody); }
+ OUString GetBody() const { return m_xBodyMLE->get_text(); }
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmlayoutpage.cxx b/sw/source/ui/dbui/mmlayoutpage.cxx
new file mode 100644
index 0000000000..2e01e49ec9
--- /dev/null
+++ b/sw/source/ui/dbui/mmlayoutpage.cxx
@@ -0,0 +1,692 @@
+/* -*- 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 <swtypes.hxx>
+#include "mmlayoutpage.hxx"
+#include <mailmergewizard.hxx>
+#include <mmconfigitem.hxx>
+#include <mailmergehelper.hxx>
+#include <unotools.hxx>
+#include <comphelper/string.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <i18nutil/unicode.hxx>
+#include <unotools/tempfile.hxx>
+#include <uitool.hxx>
+#include <view.hxx>
+#include <swundo.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <svtools/unitconv.hxx>
+#include <com/sun/star/view/XViewSettingsSupplier.hpp>
+#include <com/sun/star/view/DocumentZoomType.hpp>
+#include <fldmgr.hxx>
+#include <fldbas.hxx>
+#include <unotxdoc.hxx>
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <wrtsh.hxx>
+#include <fmtsrnd.hxx>
+#include <pagedesc.hxx>
+#include <fmtanchr.hxx>
+#include <fmtornt.hxx>
+#include <fmtfsize.hxx>
+#include <editeng/boxitem.hxx>
+#include <osl/file.hxx>
+#include <vcl/settings.hxx>
+#include <unoprnms.hxx>
+
+#include <dbui.hrc>
+
+using namespace osl;
+using namespace svt;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::view;
+
+constexpr tools::Long DEFAULT_LEFT_DISTANCE = o3tl::toTwips(25, o3tl::Length::mm); // 2,5 cm
+constexpr tools::Long DEFAULT_TOP_DISTANCE = o3tl::toTwips(55, o3tl::Length::mm); // 5,5 cm
+constexpr tools::Long GREETING_TOP_DISTANCE = o3tl::toTwips(125, o3tl::Length::mm); //12,5 cm
+constexpr tools::Long DEFAULT_ADDRESS_WIDTH = o3tl::toTwips(75, o3tl::Length::mm); // 7,5 cm
+constexpr tools::Long DEFAULT_ADDRESS_HEIGHT = o3tl::toTwips(35, o3tl::Length::mm); // 3,5cm
+
+SwMailMergeLayoutPage::SwMailMergeLayoutPage(weld::Container* pPage, SwMailMergeWizard* pWizard)
+ : vcl::OWizardPage(pPage, pWizard, "modules/swriter/ui/mmlayoutpage.ui", "MMLayoutPage")
+ , m_pExampleWrtShell(nullptr)
+ , m_pAddressBlockFormat(nullptr)
+ , m_bIsGreetingInserted(false)
+ , m_pWizard(pWizard)
+ , m_xPosition(m_xBuilder->weld_container("addresspos"))
+ , m_xAlignToBodyCB(m_xBuilder->weld_check_button("align"))
+ , m_xLeftFT(m_xBuilder->weld_label("leftft"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
+ , m_xGreetingLine(m_xBuilder->weld_container("greetingspos"))
+ , m_xUpPB(m_xBuilder->weld_button("up"))
+ , m_xDownPB(m_xBuilder->weld_button("down"))
+ , m_xZoomLB(m_xBuilder->weld_combo_box("zoom"))
+{
+ std::shared_ptr<const SfxFilter> pSfxFlt =
+ SwDocShell::Factory().GetFilterContainer()->
+ GetFilter4FilterName("writer8", SfxFilterFlags::EXPORT);
+
+ //save the current document into a temporary file
+ {
+ //temp file needs its own block
+ //creating with extension is not supported by a static method :-(
+ OUString const sExt(
+ comphelper::string::stripStart(pSfxFlt->GetDefaultExtension(),'*'));
+ utl::TempFileNamed aTempFile( u"", true, sExt );
+ aTempFile.EnableKillingFile();
+ m_sExampleURL = aTempFile.GetURL();
+ }
+ SwView* pView = m_pWizard->GetSwView();
+ // Don't save embedded data set! It would steal it from current document.
+ uno::Sequence< beans::PropertyValue > aValues =
+ {
+ comphelper::makePropertyValue("FilterName", pSfxFlt->GetFilterName()),
+ comphelper::makePropertyValue("NoEmbDataSet", true)
+ };
+
+ uno::Reference< frame::XStorable > xStore( pView->GetDocShell()->GetModel(), uno::UNO_QUERY);
+ xStore->storeToURL( m_sExampleURL, aValues );
+
+ Link<SwOneExampleFrame&,void> aLink(LINK(this, SwMailMergeLayoutPage, PreviewLoadedHdl_Impl));
+ m_xExampleFrame.reset(new SwOneExampleFrame(EX_SHOW_DEFAULT_PAGE, &aLink, &m_sExampleURL));
+ m_xExampleContainerWIN.reset(new weld::CustomWeld(*m_xBuilder, "example", *m_xExampleFrame));
+
+ Size aSize = m_xExampleFrame->GetDrawingArea()->get_ref_device().LogicToPixel(
+ Size(124, 159), MapMode(MapUnit::MapAppFont));
+ m_xExampleFrame->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xExampleContainerWIN->hide();
+
+ m_xLeftMF->set_value(m_xLeftMF->normalize(DEFAULT_LEFT_DISTANCE), FieldUnit::TWIP);
+ m_xTopMF->set_value(m_xTopMF->normalize(DEFAULT_TOP_DISTANCE), FieldUnit::TWIP);
+
+ const LanguageTag& rLang = Application::GetSettings().GetUILanguageTag();
+ m_xZoomLB->append_text(unicode::formatPercent(50, rLang));
+ m_xZoomLB->append_text(unicode::formatPercent(75, rLang));
+ m_xZoomLB->append_text(unicode::formatPercent(100, rLang));
+ m_xZoomLB->set_active(0); //page size
+ m_xZoomLB->connect_changed(LINK(this, SwMailMergeLayoutPage, ZoomHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aFrameHdl = LINK(this, SwMailMergeLayoutPage, ChangeAddressHdl_Impl);
+ m_xLeftMF->connect_value_changed(aFrameHdl);
+ m_xTopMF->connect_value_changed(aFrameHdl);
+
+ FieldUnit eFieldUnit = ::GetDfltMetric(false);
+ ::SetFieldUnit( *m_xLeftMF, eFieldUnit );
+ ::SetFieldUnit( *m_xTopMF, eFieldUnit );
+
+ Link<weld::Button&,void> aUpDownHdl = LINK(this, SwMailMergeLayoutPage, GreetingsHdl_Impl );
+ m_xUpPB->connect_clicked(aUpDownHdl);
+ m_xDownPB->connect_clicked(aUpDownHdl);
+ m_xAlignToBodyCB->connect_toggled(LINK(this, SwMailMergeLayoutPage, AlignToTextHdl_Impl));
+ m_xAlignToBodyCB->set_active(true);
+}
+
+SwMailMergeLayoutPage::~SwMailMergeLayoutPage()
+{
+ File::remove( m_sExampleURL );
+}
+
+void SwMailMergeLayoutPage::Activate()
+{
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ bool bGreetingLine = rConfigItem.IsGreetingLine(false) && !rConfigItem.IsGreetingInserted();
+ bool bAddressBlock = rConfigItem.IsAddressBlock() && !rConfigItem.IsAddressInserted();
+
+ m_xPosition->set_sensitive(bAddressBlock);
+ AlignToTextHdl_Impl(*m_xAlignToBodyCB);
+
+ m_xGreetingLine->set_sensitive(bGreetingLine);
+
+ //check if greeting and/or address frame have to be inserted/removed
+ if(!m_pExampleWrtShell) // initially there's nothing to check
+ return;
+
+ if(!rConfigItem.IsGreetingInserted() &&
+ m_bIsGreetingInserted != bGreetingLine )
+ {
+ if( m_bIsGreetingInserted )
+ {
+ m_pExampleWrtShell->DelFullPara();
+ m_bIsGreetingInserted = false;
+ }
+ else
+ {
+ InsertGreeting(*m_pExampleWrtShell, m_pWizard->GetConfigItem(), true);
+ m_bIsGreetingInserted = true;
+ }
+ }
+ if(!rConfigItem.IsAddressInserted() &&
+ rConfigItem.IsAddressBlock() != ( nullptr != m_pAddressBlockFormat ))
+ {
+ if( m_pAddressBlockFormat )
+ {
+ m_pExampleWrtShell->Push();
+ m_pExampleWrtShell->GotoFly( m_pAddressBlockFormat->GetName() );
+ m_pExampleWrtShell->DelRight();
+ m_pAddressBlockFormat = nullptr;
+ m_pExampleWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+ else
+ {
+ tools::Long nLeft = static_cast< tools::Long >(m_xLeftMF->denormalize(m_xLeftMF->get_value(FieldUnit::TWIP)));
+ tools::Long nTop = static_cast< tools::Long >(m_xTopMF->denormalize(m_xTopMF->get_value(FieldUnit::TWIP)));
+ m_pAddressBlockFormat = InsertAddressFrame(
+ *m_pExampleWrtShell, m_pWizard->GetConfigItem(),
+ Point(nLeft, nTop),
+ m_xAlignToBodyCB->get_active(), true);
+ }
+ }
+ m_xExampleFrame->Invalidate();
+}
+
+bool SwMailMergeLayoutPage::commitPage(::vcl::WizardTypes::CommitPageReason eReason)
+{
+ //now insert the frame and the greeting
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ if (eReason == ::vcl::WizardTypes::eTravelForward || eReason == ::vcl::WizardTypes::eFinish)
+ {
+ tools::Long nLeft = static_cast< tools::Long >(m_xLeftMF->denormalize(m_xLeftMF->get_value(FieldUnit::TWIP)));
+ tools::Long nTop = static_cast< tools::Long >(m_xTopMF->denormalize(m_xTopMF->get_value(FieldUnit::TWIP)));
+ InsertAddressAndGreeting(
+ m_pWizard->GetSwView(),
+ rConfigItem,
+ Point(nLeft, nTop),
+ m_xAlignToBodyCB->get_active());
+ }
+ return true;
+}
+
+SwFrameFormat* SwMailMergeLayoutPage::InsertAddressAndGreeting(SwView const * pView,
+ SwMailMergeConfigItem& rConfigItem,
+ const Point& rAddressPosition,
+ bool bAlignToBody)
+{
+ SwFrameFormat* pAddressBlockFormat = nullptr;
+ pView->GetWrtShell().StartUndo(SwUndoId::INSERT);
+ if(rConfigItem.IsAddressBlock() && !rConfigItem.IsAddressInserted())
+ {
+ //insert the frame
+ Point aAddressPosition(DEFAULT_LEFT_DISTANCE, DEFAULT_TOP_DISTANCE);
+ if(rAddressPosition.X() > 0 && rAddressPosition.Y() > 0)
+ aAddressPosition = rAddressPosition;
+ pAddressBlockFormat = InsertAddressFrame( pView->GetWrtShell(),
+ rConfigItem,
+ aAddressPosition, bAlignToBody, false);
+ rConfigItem.SetAddressInserted();
+ }
+ //now the greeting
+ if(rConfigItem.IsGreetingLine(false) && !rConfigItem.IsGreetingInserted())
+ {
+ InsertGreeting( pView->GetWrtShell(), rConfigItem, false);
+ rConfigItem.SetGreetingInserted();
+ }
+ pView->GetWrtShell().EndUndo(SwUndoId::INSERT);
+ return pAddressBlockFormat;
+}
+
+SwFrameFormat* SwMailMergeLayoutPage::InsertAddressFrame(
+ SwWrtShell& rShell,
+ SwMailMergeConfigItem const & rConfigItem,
+ const Point& rDestination,
+ bool bAlignLeft,
+ bool bExample)
+{
+ // insert the address block and the greeting line
+ SfxItemSetFixed<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_SURROUND, RES_ANCHOR,
+ RES_BOX, RES_BOX> aSet( rShell.GetAttrPool() );
+ aSet.Put(SwFormatAnchor(RndStdIds::FLY_AT_PAGE, 1));
+ if(bAlignLeft)
+ aSet.Put(SwFormatHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ));
+ else
+ aSet.Put(SwFormatHoriOrient( rDestination.X(), text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
+ aSet.Put(SwFormatVertOrient( rDestination.Y(), text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
+ aSet.Put(SwFormatFrameSize( SwFrameSize::Minimum, DEFAULT_ADDRESS_WIDTH, DEFAULT_ADDRESS_HEIGHT ));
+ // the example gets a border around the frame, the real document doesn't get one
+ if(!bExample)
+ aSet.Put(SvxBoxItem( RES_BOX ));
+ aSet.Put(SwFormatSurround( css::text::WrapTextMode_NONE ));
+
+ rShell.NewFlyFrame(aSet, true );
+ SwFrameFormat* pRet = rShell.GetFlyFrameFormat();
+ OSL_ENSURE( pRet, "Fly not inserted" );
+
+ rShell.UnSelectFrame();
+ const Sequence< OUString> aBlocks = rConfigItem.GetAddressBlocks();
+ if(bExample)
+ {
+ rShell.Insert(aBlocks[0]);
+ }
+ else
+ {
+ //the placeholders should be replaced by the appropriate fields
+ SwFieldMgr aFieldMgr(&rShell);
+ //create a database string source.command.commandtype.column
+ const SwDBData& rData = rConfigItem.GetCurrentDBData();
+ OUString sDBName(rData.sDataSource + OUStringChar(DB_DELIM)
+ + rData.sCommand + OUStringChar(DB_DELIM));
+ const OUString sDatabaseConditionPrefix(sDBName.replace(DB_DELIM, '.'));
+ sDBName += OUString::number(rData.nCommandType) + OUStringChar(DB_DELIM);
+
+ // if only the country is in an address line the
+ // paragraph has to be hidden depending on the
+ // IsIncludeCountry()/GetExcludeCountry() settings
+
+ bool bIncludeCountry = rConfigItem.IsIncludeCountry();
+ bool bHideEmptyParagraphs = rConfigItem.IsHideEmptyParagraphs();
+ const OUString rExcludeCountry = rConfigItem.GetExcludeCountry();
+ bool bSpecialReplacementForCountry = (!bIncludeCountry || !rExcludeCountry.isEmpty());
+
+ const std::vector<std::pair<OUString, int>>& rHeaders = rConfigItem.GetDefaultAddressHeaders();
+ Sequence< OUString> aAssignment =
+ rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
+ const OUString* pAssignment = aAssignment.getConstArray();
+ const OUString sCountryColumn(
+ (aAssignment.getLength() > MM_PART_COUNTRY && !aAssignment[MM_PART_COUNTRY].isEmpty())
+ ? aAssignment[MM_PART_COUNTRY]
+ : rHeaders[MM_PART_COUNTRY].first);
+
+ OUString sHideParagraphsExpression;
+ SwAddressIterator aIter(aBlocks[0]);
+ while(aIter.HasMore())
+ {
+ SwMergeAddressItem aItem = aIter.Next();
+ if(aItem.bIsColumn)
+ {
+ OUString sConvertedColumn = aItem.sText;
+ auto nSize = std::min(static_cast<sal_uInt32>(rHeaders.size()),
+ static_cast<sal_uInt32>(aAssignment.getLength()));
+ for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
+ {
+ if (rHeaders[nColumn].first == aItem.sText &&
+ !pAssignment[nColumn].isEmpty())
+ {
+ sConvertedColumn = pAssignment[nColumn];
+ break;
+ }
+ }
+ const OUString sDB(sDBName + sConvertedColumn);
+
+ if(!sHideParagraphsExpression.isEmpty())
+ sHideParagraphsExpression += " AND ";
+ sHideParagraphsExpression += "![" + sDatabaseConditionPrefix + sConvertedColumn + "]";
+
+ if( bSpecialReplacementForCountry && sCountryColumn == sConvertedColumn )
+ {
+ // now insert a hidden paragraph field
+ if( !rExcludeCountry.isEmpty() )
+ {
+ const OUString sExpression("[" + sDatabaseConditionPrefix + sCountryColumn + "]");
+ SwInsertField_Data aData(SwFieldTypesEnum::ConditionalText, 0,
+ sExpression + " != \"" + rExcludeCountry + "\"",
+ sExpression,
+ 0, &rShell );
+ aFieldMgr.InsertField( aData );
+ }
+ else
+ {
+ SwInsertField_Data aData(SwFieldTypesEnum::HiddenParagraph, 0, "", "", 0, &rShell );
+ aFieldMgr.InsertField( aData );
+ }
+ }
+ else
+ {
+ SwInsertField_Data aData(SwFieldTypesEnum::Database, 0, sDB, OUString(), 0, &rShell);
+ aFieldMgr.InsertField( aData );
+ }
+ }
+ else if(!aItem.bIsReturn)
+ {
+ rShell.Insert(aItem.sText);
+ }
+ else
+ {
+ if(bHideEmptyParagraphs)
+ {
+ SwInsertField_Data aData(SwFieldTypesEnum::HiddenParagraph, 0, sHideParagraphsExpression, OUString(), 0, &rShell);
+ aFieldMgr.InsertField( aData );
+ }
+ sHideParagraphsExpression.clear();
+ //now add a new paragraph
+ rShell.SplitNode();
+ }
+ }
+ if(bHideEmptyParagraphs && !sHideParagraphsExpression.isEmpty())
+ {
+ SwInsertField_Data aData(SwFieldTypesEnum::HiddenParagraph, 0, sHideParagraphsExpression, OUString(), 0, &rShell);
+ aFieldMgr.InsertField( aData );
+ }
+ }
+ return pRet;
+}
+
+void SwMailMergeLayoutPage::InsertGreeting(SwWrtShell& rShell, SwMailMergeConfigItem const & rConfigItem, bool bExample)
+{
+ //set the cursor to the desired position - if no text content is here then
+ //new paragraphs are inserted
+ const SwRect& rPageRect = rShell.GetAnyCurRect(CurRectType::Page);
+ const Point aGreetingPos( DEFAULT_LEFT_DISTANCE + rPageRect.Left(), GREETING_TOP_DISTANCE );
+
+ const bool bRet = rShell.SetShadowCursorPos( aGreetingPos, SwFillMode::TabSpace );
+
+ if(!bRet)
+ {
+ //there's already text at the desired position
+ //go to start of the doc, directly!
+ rShell.SttEndDoc(true);
+ //and go by paragraph until the position is reached
+ tools::Long nYPos = rShell.GetCharRect().Top();
+ while(nYPos < GREETING_TOP_DISTANCE)
+ {
+ if(!rShell.FwdPara())
+ break;
+ nYPos = rShell.GetCharRect().Top();
+ }
+ //text needs to be appended
+ while(nYPos < GREETING_TOP_DISTANCE)
+ {
+ if(!rShell.AppendTextNode())
+ break;
+ nYPos = rShell.GetCharRect().Top();
+ }
+ }
+ else
+ {
+ //we may end up inside of a paragraph if the left margin is not at DEFAULT_LEFT_DISTANCE
+ rShell.MovePara(GoCurrPara, fnParaStart);
+ }
+ bool bSplitNode = !rShell.IsEndPara();
+ SwNodeOffset nMoves(rConfigItem.GetGreetingMoves());
+ if( !bExample && SwNodeOffset(0) != nMoves )
+ {
+ if(nMoves < SwNodeOffset(0))
+ {
+ rShell.MoveParagraph( nMoves );
+ }
+ else
+ while(nMoves)
+ {
+ bool bMoved = rShell.MoveParagraph();
+ if(!bMoved)
+ {
+ //insert a new paragraph before the greeting line
+ rShell.SplitNode();
+ }
+ --nMoves;
+ }
+ }
+ //now insert the greeting text - if we have any?
+ const bool bIndividual = rConfigItem.IsIndividualGreeting(false);
+ if(bIndividual)
+ {
+ //lock expression fields - prevents hiding of the paragraph to insert into
+ rShell.LockExpFields();
+ if(bExample)
+ {
+ for(sal_Int8 eGender = SwMailMergeConfigItem::FEMALE;
+ eGender <= SwMailMergeConfigItem::NEUTRAL; ++eGender)
+ {
+ Sequence< OUString > aEntries =
+ rConfigItem.GetGreetings(static_cast<SwMailMergeConfigItem::Gender>(eGender));
+ sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting(static_cast<SwMailMergeConfigItem::Gender>(eGender));
+ if( nCurrent >= 0 && nCurrent < aEntries.getLength())
+ {
+ // Greeting
+ rShell.Insert(aEntries[nCurrent]);
+ break;
+ }
+ }
+ }
+ else
+ {
+ SwFieldMgr aFieldMgr(&rShell);
+ //three paragraphs, each with an appropriate hidden paragraph field
+ //are to be inserted
+
+ //name of the gender column
+ const OUString sGenderColumn = rConfigItem.GetAssignedColumn(MM_PART_GENDER);
+ const OUString sNameColumn = rConfigItem.GetAssignedColumn(MM_PART_LASTNAME);
+
+ const OUString& rFemaleGenderValue = rConfigItem.GetFemaleGenderValue();
+ bool bHideEmptyParagraphs = rConfigItem.IsHideEmptyParagraphs();
+ const SwDBData& rData = rConfigItem.GetCurrentDBData();
+ const OUString sCommonBase(rData.sDataSource + "." + rData.sCommand + ".");
+ const OUString sConditionBase("[" + sCommonBase + sGenderColumn + "]");
+ const OUString sNameColumnBase("[" + sCommonBase + sNameColumn + "]");
+
+ const OUString sDBName(rData.sDataSource + OUStringChar(DB_DELIM)
+ + rData.sCommand + OUStringChar(DB_DELIM)
+ + OUString::number(rData.nCommandType) + OUStringChar(DB_DELIM));
+
+// Female: [database.sGenderColumn] != "rFemaleGenderValue" && [database.NameColumn]
+// Male: [database.sGenderColumn] == "rFemaleGenderValue" && [database.rGenderColumn]
+// Neutral: [database.sNameColumn]
+ OSL_ENSURE(!sGenderColumn.isEmpty() && !rFemaleGenderValue.isEmpty(),
+ "gender settings not available - how to form the condition?");
+ //column used as lastname
+ for(sal_Int8 eGender = SwMailMergeConfigItem::FEMALE;
+ eGender <= SwMailMergeConfigItem::NEUTRAL; ++eGender)
+ {
+ Sequence< OUString> aEntries = rConfigItem.GetGreetings(static_cast<SwMailMergeConfigItem::Gender>(eGender));
+ sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting(static_cast<SwMailMergeConfigItem::Gender>(eGender));
+ if( nCurrent >= 0 && nCurrent < aEntries.getLength())
+ {
+ const OUString sGreeting = aEntries[nCurrent];
+ OUString sCondition;
+ OUString sHideParagraphsExpression;
+ switch(eGender)
+ {
+ case SwMailMergeConfigItem::FEMALE:
+ sCondition = sConditionBase + " != \"" + rFemaleGenderValue
+ + "\" OR NOT " + sNameColumnBase;
+ sHideParagraphsExpression = "!" + sNameColumnBase;
+ break;
+ case SwMailMergeConfigItem::MALE:
+ sCondition = sConditionBase + " == \"" + rFemaleGenderValue
+ + "\" OR NOT " + sNameColumnBase;
+ break;
+ case SwMailMergeConfigItem::NEUTRAL:
+ sCondition = sNameColumnBase;
+ break;
+ }
+
+ if(bHideEmptyParagraphs && !sHideParagraphsExpression.isEmpty())
+ {
+ OUString sComplete = "(" + sCondition + ") OR (" + sHideParagraphsExpression + ")";
+ SwInsertField_Data aData(SwFieldTypesEnum::HiddenParagraph, 0, sComplete, OUString(), 0, &rShell);
+ aFieldMgr.InsertField( aData );
+ }
+ else
+ {
+ SwInsertField_Data aData(SwFieldTypesEnum::HiddenParagraph, 0, sCondition, OUString(), 0, &rShell);
+ aFieldMgr.InsertField( aData );
+ }
+ //now the text has to be inserted
+ const std::vector<std::pair<OUString, int>>& rHeaders = rConfigItem.GetDefaultAddressHeaders();
+ Sequence< OUString> aAssignment =
+ rConfigItem.GetColumnAssignment( rConfigItem.GetCurrentDBData() );
+ const OUString* pAssignment = aAssignment.getConstArray();
+ SwAddressIterator aIter(sGreeting);
+ while(aIter.HasMore())
+ {
+ SwMergeAddressItem aItem = aIter.Next();
+ if(aItem.bIsColumn)
+ {
+ OUString sConvertedColumn = aItem.sText;
+ auto nSize = std::min(static_cast<sal_uInt32>(rHeaders.size()),
+ static_cast<sal_uInt32>(aAssignment.getLength()));
+ for(sal_uInt32 nColumn = 0; nColumn < nSize; ++nColumn)
+ {
+ if (rHeaders[nColumn].first == aItem.sText &&
+ !pAssignment[nColumn].isEmpty())
+ {
+ sConvertedColumn = pAssignment[nColumn];
+ break;
+ }
+ }
+ SwInsertField_Data aData(SwFieldTypesEnum::Database, 0,
+ sDBName + sConvertedColumn,
+ OUString(), 0, &rShell);
+ aFieldMgr.InsertField( aData );
+ }
+ else
+ {
+ rShell.Insert(aItem.sText);
+ }
+ }
+ //now add a new paragraph
+ rShell.SplitNode();
+ }
+ }
+
+ }
+ rShell.UnlockExpFields();
+ }
+ else
+ {
+ Sequence< OUString> aEntries = rConfigItem.GetGreetings(SwMailMergeConfigItem::NEUTRAL);
+ sal_Int32 nCurrent = rConfigItem.GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL);
+ // Greeting
+ rShell.Insert(( nCurrent >= 0 && nCurrent < aEntries.getLength() )
+ ? aEntries[nCurrent] : OUString());
+ }
+ // now insert a new paragraph here if necessary
+ if(bSplitNode)
+ {
+ rShell.Push();
+ rShell.SplitNode();
+ rShell.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ }
+ //put the cursor to the start of the paragraph
+ rShell.SttPara();
+
+ OSL_ENSURE(nullptr == rShell.GetTableFormat(), "What to do with a table here?");
+}
+
+IMPL_LINK_NOARG(SwMailMergeLayoutPage, PreviewLoadedHdl_Impl, SwOneExampleFrame&, void)
+{
+ m_xExampleContainerWIN->show();
+
+ Reference< XModel > & xModel = m_xExampleFrame->GetModel();
+ //now the ViewOptions should be set properly
+ Reference< XViewSettingsSupplier > xSettings(xModel->getCurrentController(), UNO_QUERY);
+ m_xViewProperties = xSettings->getViewSettings();
+ auto pXDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xModel);
+ SwDocShell* pDocShell = pXDoc->GetDocShell();
+ m_pExampleWrtShell = pDocShell->GetWrtShell();
+ OSL_ENSURE(m_pExampleWrtShell, "No SwWrtShell found!");
+ if(!m_pExampleWrtShell)
+ return;
+
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ if(rConfigItem.IsAddressBlock())
+ {
+ m_pAddressBlockFormat = InsertAddressFrame(
+ *m_pExampleWrtShell, rConfigItem,
+ Point(DEFAULT_LEFT_DISTANCE, DEFAULT_TOP_DISTANCE),
+ m_xAlignToBodyCB->get_active(), true);
+ }
+ if(rConfigItem.IsGreetingLine(false))
+ {
+ InsertGreeting(*m_pExampleWrtShell, rConfigItem, true);
+ m_bIsGreetingInserted = true;
+ }
+
+ ZoomHdl_Impl(*m_xZoomLB);
+
+ const SwFormatFrameSize& rPageSize = m_pExampleWrtShell->GetPageDesc(
+ m_pExampleWrtShell->GetCurPageDesc()).GetMaster().GetFrameSize();
+ m_xLeftMF->set_max(rPageSize.GetWidth() - DEFAULT_LEFT_DISTANCE, FieldUnit::NONE);
+ m_xTopMF->set_max(rPageSize.GetHeight() - DEFAULT_TOP_DISTANCE, FieldUnit::NONE);
+}
+
+IMPL_LINK(SwMailMergeLayoutPage, ZoomHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ if (!m_pExampleWrtShell)
+ return;
+
+ sal_Int16 eType = DocumentZoomType::BY_VALUE;
+ short nZoom = 50;
+ switch (rBox.get_active())
+ {
+ case 0 : eType = DocumentZoomType::ENTIRE_PAGE; break;
+ case 1 : nZoom = 50; break;
+ case 2 : nZoom = 75; break;
+ case 3 : nZoom = 100; break;
+ }
+ Any aZoom;
+ aZoom <<= eType;
+ m_xViewProperties->setPropertyValue(UNO_NAME_ZOOM_TYPE, aZoom);
+ aZoom <<= nZoom;
+ m_xViewProperties->setPropertyValue(UNO_NAME_ZOOM_VALUE, aZoom);
+
+ m_xExampleFrame->Invalidate();
+}
+
+IMPL_LINK_NOARG(SwMailMergeLayoutPage, ChangeAddressHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if(!(m_pExampleWrtShell && m_pAddressBlockFormat))
+ return;
+
+ tools::Long nLeft = static_cast< tools::Long >(m_xLeftMF->denormalize(m_xLeftMF->get_value(FieldUnit::TWIP)));
+ tools::Long nTop = static_cast< tools::Long >(m_xTopMF->denormalize(m_xTopMF->get_value(FieldUnit::TWIP)));
+
+ SfxItemSetFixed<RES_VERT_ORIENT, RES_ANCHOR> aSet(
+ m_pExampleWrtShell->GetAttrPool());
+ if (m_xAlignToBodyCB->get_active())
+ aSet.Put(SwFormatHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ));
+ else
+ aSet.Put(SwFormatHoriOrient( nLeft, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
+ aSet.Put(SwFormatVertOrient( nTop, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ));
+ m_pExampleWrtShell->GetDoc()->SetFlyFrameAttr( *m_pAddressBlockFormat, aSet );
+ m_xExampleFrame->Invalidate();
+}
+
+IMPL_LINK(SwMailMergeLayoutPage, GreetingsHdl_Impl, weld::Button&, rButton, void)
+{
+ bool bDown = &rButton == m_xDownPB.get();
+ bool bMoved = m_pExampleWrtShell->MoveParagraph( SwNodeOffset(bDown ? 1 : -1) );
+ if (bMoved || bDown)
+ m_pWizard->GetConfigItem().MoveGreeting(bDown ? 1 : -1 );
+ if(!bMoved && bDown)
+ {
+ //insert a new paragraph before the greeting line
+ m_pExampleWrtShell->SplitNode();
+ }
+ m_xExampleFrame->Invalidate();
+}
+
+IMPL_LINK(SwMailMergeLayoutPage, AlignToTextHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bCheck = rBox.get_active() && rBox.get_sensitive();
+ m_xLeftFT->set_sensitive(!bCheck);
+ m_xLeftMF->set_sensitive(!bCheck);
+ ChangeAddressHdl_Impl( *m_xLeftMF );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmlayoutpage.hxx b/sw/source/ui/dbui/mmlayoutpage.hxx
new file mode 100644
index 0000000000..abec12bb2c
--- /dev/null
+++ b/sw/source/ui/dbui/mmlayoutpage.hxx
@@ -0,0 +1,87 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_MMLAYOUTPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_MMLAYOUTPAGE_HXX
+
+#include <vcl/wizardmachine.hxx>
+#include <mailmergehelper.hxx>
+#include <com/sun/star/uno/Reference.h>
+
+class SwMailMergeWizard;
+class SwFrameFormat;
+class SwOneExampleFrame;
+class SwWrtShell;
+class SwView;
+
+namespace com::sun::star::beans{ class XPropertySet;}
+
+class SwMailMergeLayoutPage : public vcl::OWizardPage
+{
+ SwWrtShell* m_pExampleWrtShell;
+
+ OUString m_sExampleURL;
+ SwFrameFormat* m_pAddressBlockFormat;
+
+ bool m_bIsGreetingInserted;
+
+ SwMailMergeWizard* m_pWizard;
+
+ css::uno::Reference< css::beans::XPropertySet > m_xViewProperties;
+
+ std::unique_ptr<weld::Container> m_xPosition;
+ std::unique_ptr<weld::CheckButton> m_xAlignToBodyCB;
+ std::unique_ptr<weld::Label> m_xLeftFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMF;
+ std::unique_ptr<weld::Container> m_xGreetingLine;
+ std::unique_ptr<weld::Button> m_xUpPB;
+ std::unique_ptr<weld::Button> m_xDownPB;
+ std::unique_ptr<weld::ComboBox> m_xZoomLB;
+ std::unique_ptr<SwOneExampleFrame> m_xExampleFrame;
+ std::unique_ptr<weld::CustomWeld> m_xExampleContainerWIN;
+
+ DECL_LINK(PreviewLoadedHdl_Impl, SwOneExampleFrame&, void);
+ DECL_LINK(ZoomHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeAddressHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(GreetingsHdl_Impl, weld::Button&, void);
+ DECL_LINK(AlignToTextHdl_Impl, weld::Toggleable&, void);
+
+ static SwFrameFormat* InsertAddressFrame(
+ SwWrtShell& rShell,
+ SwMailMergeConfigItem const & rConfigItem,
+ const Point& rDestination,
+ bool bAlignToBody,
+ bool bExample);
+ static void InsertGreeting(SwWrtShell& rShell, SwMailMergeConfigItem const & rConfigItem, bool bExample);
+
+ virtual void Activate() override;
+ virtual bool commitPage(::vcl::WizardTypes::CommitPageReason _eReason) override;
+public:
+ SwMailMergeLayoutPage(weld::Container* pPage, SwMailMergeWizard* pWizard);
+ virtual ~SwMailMergeLayoutPage() override;
+
+ static SwFrameFormat* InsertAddressAndGreeting(SwView const * pView,
+ SwMailMergeConfigItem& rConfigItem,
+ const Point& rAddressPos,
+ bool bAlignToBody);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmoutputtypepage.cxx b/sw/source/ui/dbui/mmoutputtypepage.cxx
new file mode 100644
index 0000000000..0110c0e5d0
--- /dev/null
+++ b/sw/source/ui/dbui/mmoutputtypepage.cxx
@@ -0,0 +1,532 @@
+/* -*- 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 "mmoutputtypepage.hxx"
+#include <mailmergewizard.hxx>
+#include <mmconfigitem.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <swtypes.hxx>
+
+#include <osl/diagnose.h>
+#include <rtl/ref.hxx>
+#include <com/sun/star/mail/XSmtpService.hpp>
+#include <vcl/idle.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <swunohelper.hxx>
+#include <mmresultdialogs.hxx>
+#include <maildispatcher.hxx>
+#include <imaildsplistener.hxx>
+#include <mutex>
+
+using namespace ::com::sun::star;
+
+SwMailMergeOutputTypePage::SwMailMergeOutputTypePage(weld::Container* pPage, SwMailMergeWizard* pWizard)
+ : vcl::OWizardPage(pPage, pWizard, "modules/swriter/ui/mmoutputtypepage.ui", "MMOutputTypePage")
+ , m_pWizard(pWizard)
+ , m_xLetterRB(m_xBuilder->weld_radio_button("letter"))
+ , m_xMailRB(m_xBuilder->weld_radio_button("email"))
+ , m_xLetterHint(m_xBuilder->weld_label("letterft"))
+ , m_xMailHint(m_xBuilder->weld_label("emailft"))
+{
+ Link<weld::Toggleable&,void> aLink = LINK(this, SwMailMergeOutputTypePage, TypeHdl_Impl);
+ m_xLetterRB->connect_toggled(aLink);
+ m_xMailRB->connect_toggled(aLink);
+
+ SwMailMergeConfigItem& rConfigItem = m_pWizard->GetConfigItem();
+ if(rConfigItem.IsOutputToLetter())
+ m_xLetterRB->set_active(true);
+ else
+ m_xMailRB->set_active(true);
+ TypeHdl_Impl(*m_xLetterRB);
+}
+
+SwMailMergeOutputTypePage::~SwMailMergeOutputTypePage()
+{
+}
+
+IMPL_LINK_NOARG(SwMailMergeOutputTypePage, TypeHdl_Impl, weld::Toggleable&, void)
+{
+ bool bLetter = m_xLetterRB->get_active();
+ m_xLetterHint->set_visible(bLetter);
+ m_xMailHint->set_visible(!bLetter);
+ m_pWizard->GetConfigItem().SetOutputToLetter(bLetter);
+ m_pWizard->UpdateRoadmap();
+}
+
+struct SwSendMailDialog_Impl
+{
+ friend class SwSendMailDialog;
+ // The mutex is locked in SwSendMailDialog_Impl::GetNextDescriptor, which may be called
+ // both with mutex unlocked (inside SwSendMailDialog::SendMails), and with mutex locked
+ // (inside SwSendMailDialog::AddDocument).
+ std::recursive_mutex aDescriptorMutex;
+
+ std::vector< SwMailDescriptor > aDescriptors;
+ sal_uInt32 nCurrentDescriptor;
+ ::rtl::Reference< MailDispatcher > xMailDispatcher;
+ ::rtl::Reference< IMailDispatcherListener> xMailListener;
+ uno::Reference< mail::XMailService > xConnectedInMailService;
+ Idle aRemoveIdle;
+
+ SwSendMailDialog_Impl() :
+ nCurrentDescriptor(0), aRemoveIdle("SwSendMailDialog_Impl aRemoveIdle")
+ {
+ aRemoveIdle.SetPriority(TaskPriority::LOWEST);
+ }
+
+ ~SwSendMailDialog_Impl()
+ {
+ // Shutdown must be called when the last reference to the
+ // mail dispatcher will be released in order to force a
+ // shutdown of the mail dispatcher thread.
+ // 'join' with the mail dispatcher thread leads to a
+ // deadlock (SolarMutex).
+ if( xMailDispatcher.is() && !xMailDispatcher->isShutdownRequested() )
+ xMailDispatcher->shutdown();
+ }
+ const SwMailDescriptor* GetNextDescriptor();
+};
+
+const SwMailDescriptor* SwSendMailDialog_Impl::GetNextDescriptor()
+{
+ std::scoped_lock aGuard(aDescriptorMutex);
+ if(nCurrentDescriptor < aDescriptors.size())
+ {
+ ++nCurrentDescriptor;
+ return &aDescriptors[nCurrentDescriptor - 1];
+ }
+ return nullptr;
+}
+
+namespace {
+
+class SwMailDispatcherListener_Impl : public IMailDispatcherListener
+{
+ SwSendMailDialog& m_rSendMailDialog;
+
+public:
+ explicit SwMailDispatcherListener_Impl(SwSendMailDialog& rParentDlg);
+
+ virtual void idle() override;
+ virtual void mailDelivered(uno::Reference< mail::XMailMessage> xMailMessage) override;
+ virtual void mailDeliveryError(::rtl::Reference<MailDispatcher> xMailDispatcher,
+ uno::Reference< mail::XMailMessage> xMailMessage, const OUString& sErrorMessage) override;
+
+ static void DeleteAttachments( uno::Reference< mail::XMailMessage > const & xMessage );
+};
+
+}
+
+SwMailDispatcherListener_Impl::SwMailDispatcherListener_Impl(SwSendMailDialog& rParentDlg)
+ : m_rSendMailDialog(rParentDlg)
+{
+}
+
+void SwMailDispatcherListener_Impl::idle()
+{
+ SolarMutexGuard aGuard;
+ m_rSendMailDialog.AllMailsSent();
+}
+
+void SwMailDispatcherListener_Impl::mailDelivered(
+ uno::Reference< mail::XMailMessage> xMailMessage)
+{
+ SolarMutexGuard aGuard;
+ m_rSendMailDialog.DocumentSent( xMailMessage, true, nullptr );
+ DeleteAttachments( xMailMessage );
+}
+
+void SwMailDispatcherListener_Impl::mailDeliveryError(
+ ::rtl::Reference<MailDispatcher> /*xMailDispatcher*/,
+ uno::Reference< mail::XMailMessage> xMailMessage,
+ const OUString& sErrorMessage)
+{
+ SolarMutexGuard aGuard;
+ m_rSendMailDialog.DocumentSent( xMailMessage, false, &sErrorMessage );
+ DeleteAttachments( xMailMessage );
+}
+
+void SwMailDispatcherListener_Impl::DeleteAttachments( uno::Reference< mail::XMailMessage > const & xMessage )
+{
+ const uno::Sequence< mail::MailAttachment > aAttachments = xMessage->getAttachments();
+
+ for(const auto& rAttachment : aAttachments)
+ {
+ try
+ {
+ uno::Reference< beans::XPropertySet > xTransferableProperties( rAttachment.Data, uno::UNO_QUERY_THROW);
+ OUString sURL;
+ xTransferableProperties->getPropertyValue("URL") >>= sURL;
+ if(!sURL.isEmpty())
+ SWUnoHelper::UCB_DeleteFile( sURL );
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+}
+
+namespace {
+
+class SwSendWarningBox_Impl : public weld::MessageDialogController
+{
+ std::unique_ptr<weld::TextView> m_xDetailED;
+public:
+ SwSendWarningBox_Impl(weld::Window* pParent, const OUString& rDetails)
+ : MessageDialogController(pParent, "modules/swriter/ui/warnemaildialog.ui", "WarnEmailDialog", "grid")
+ , m_xDetailED(m_xBuilder->weld_text_view("errors"))
+ {
+ m_xDetailED->set_size_request(80 * m_xDetailED->get_approximate_digit_width(),
+ 8 * m_xDetailED->get_text_height());
+ m_xDetailED->set_text(rDetails);
+ }
+};
+
+}
+
+SwSendMailDialog::SwSendMailDialog(weld::Window *pParent, SwMailMergeConfigItem& rConfigItem)
+ : GenericDialogController(pParent, "modules/swriter/ui/mmsendmails.ui", "SendMailsDialog")
+ , m_sContinue(SwResId( ST_CONTINUE ))
+ , m_sClose(SwResId(ST_CLOSE_DIALOG))
+ , m_sSendingTo( SwResId(ST_SENDINGTO ))
+ , m_sCompleted( SwResId(ST_COMPLETED ))
+ , m_sFailed( SwResId(ST_FAILED ))
+ , m_sAddressInvalid(SwResId(ST_ADDRESS_INVALID))
+ , m_bCancel(false)
+ , m_bDestructionEnabled(false)
+ , m_pImpl(new SwSendMailDialog_Impl)
+ , m_pConfigItem(&rConfigItem)
+ , m_nExpectedCount(0)
+ , m_nProcessedCount(0)
+ , m_nErrorCount(0)
+ , m_xTransferStatus(m_xBuilder->weld_label("transferstatus"))
+ , m_xPaused(m_xBuilder->weld_label("paused"))
+ , m_xProgressBar(m_xBuilder->weld_progress_bar("progress"))
+ , m_xErrorStatus(m_xBuilder->weld_label("errorstatus"))
+ , m_xStatus(m_xBuilder->weld_tree_view("container"))
+ , m_xStop(m_xBuilder->weld_button("stop"))
+ , m_xCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_sStop = m_xStop->get_label();
+ m_sTransferStatus = m_xTransferStatus->get_label();
+ m_sErrorStatus = m_xErrorStatus->get_label();
+
+ Size aSize(m_xStatus->get_approximate_digit_width() * 28,
+ m_xStatus->get_height_rows(20));
+ m_xStatus->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xStop->connect_clicked(LINK( this, SwSendMailDialog, StopHdl_Impl));
+ m_xCancel->connect_clicked(LINK( this, SwSendMailDialog, CancelHdl_Impl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xStatus->get_checkbox_column_width()),
+ o3tl::narrowing<int>(aSize.Width()/3 * 2)
+ };
+ m_xStatus->set_column_fixed_widths(aWidths);
+
+ m_xPaused->set_visible(false);
+ UpdateTransferStatus();
+}
+
+SwSendMailDialog::~SwSendMailDialog()
+{
+ if(!m_pImpl->xMailDispatcher.is())
+ return;
+
+ try
+ {
+ if(m_pImpl->xMailDispatcher->isStarted())
+ m_pImpl->xMailDispatcher->stop();
+ if(m_pImpl->xConnectedInMailService.is() && m_pImpl->xConnectedInMailService->isConnected())
+ m_pImpl->xConnectedInMailService->disconnect();
+
+ uno::Reference<mail::XMailMessage> xMessage =
+ m_pImpl->xMailDispatcher->dequeueMailMessage();
+ while(xMessage.is())
+ {
+ SwMailDispatcherListener_Impl::DeleteAttachments( xMessage );
+ xMessage = m_pImpl->xMailDispatcher->dequeueMailMessage();
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+void SwSendMailDialog::AddDocument( SwMailDescriptor const & rDesc )
+{
+ std::scoped_lock aGuard(m_pImpl->aDescriptorMutex);
+ m_pImpl->aDescriptors.push_back(rDesc);
+ // if the dialog is already running then continue sending of documents
+ if(m_pImpl->xMailDispatcher.is())
+ {
+ IterateMails();
+ }
+}
+
+IMPL_LINK( SwSendMailDialog, StopHdl_Impl, weld::Button&, rButton, void )
+{
+ m_bCancel = true;
+ if(!m_pImpl->xMailDispatcher.is())
+ return;
+
+ if(m_pImpl->xMailDispatcher->isStarted())
+ {
+ m_pImpl->xMailDispatcher->stop();
+ rButton.set_label(m_sContinue);
+ m_xPaused->show();
+ }
+ else
+ {
+ m_pImpl->xMailDispatcher->start();
+ rButton.set_label(m_sStop);
+ m_xPaused->hide();
+ }
+}
+
+IMPL_LINK_NOARG(SwSendMailDialog, CancelHdl_Impl, weld::Button&, void)
+{
+ m_xDialog->hide();
+
+ if (m_bDestructionEnabled)
+ m_xDialog->response(RET_CANCEL);
+ else
+ {
+ m_pImpl->aRemoveIdle.SetInvokeHandler( LINK( this, SwSendMailDialog, RemoveThis ) );
+ m_pImpl->aRemoveIdle.Start();
+ }
+}
+
+IMPL_STATIC_LINK( SwSendMailDialog, StartSendMails, void*, pDialog, void )
+{
+ static_cast<SwSendMailDialog*>(pDialog)->SendMails();
+}
+
+IMPL_LINK( SwSendMailDialog, RemoveThis, Timer*, pTimer, void )
+{
+ if( m_pImpl->xMailDispatcher.is() )
+ {
+ if(m_pImpl->xMailDispatcher->isStarted())
+ m_pImpl->xMailDispatcher->stop();
+ if(!m_pImpl->xMailDispatcher->isShutdownRequested())
+ m_pImpl->xMailDispatcher->shutdown();
+ }
+
+ if( m_bDestructionEnabled &&
+ (!m_pImpl->xMailDispatcher.is() ||
+ !m_pImpl->xMailDispatcher->isRunning()))
+ {
+ m_xDialog->response(RET_CANCEL);
+ }
+ else
+ {
+ pTimer->Start();
+ }
+}
+
+IMPL_STATIC_LINK( SwSendMailDialog, StopSendMails, void*, p, void )
+{
+ SwSendMailDialog* pDialog = static_cast<SwSendMailDialog*>(p);
+ if(pDialog->m_pImpl->xMailDispatcher.is() &&
+ pDialog->m_pImpl->xMailDispatcher->isStarted())
+ {
+ pDialog->m_pImpl->xMailDispatcher->stop();
+ pDialog->m_xStop->set_label(pDialog->m_sContinue);
+ pDialog->m_xPaused->show();
+ }
+}
+
+void SwSendMailDialog::SendMails()
+{
+ if(!m_pConfigItem)
+ {
+ OSL_FAIL("config item not set");
+ return;
+ }
+ auto xWait(std::make_unique<weld::WaitObject>(m_xDialog.get()));
+ //get a mail server connection
+ uno::Reference< mail::XSmtpService > xSmtpServer =
+ SwMailMergeHelper::ConnectToSmtpServer( *m_pConfigItem,
+ m_pImpl->xConnectedInMailService,
+ OUString(), OUString(), m_xDialog.get());
+ bool bIsLoggedIn = xSmtpServer.is() && xSmtpServer->isConnected();
+ xWait.reset();
+ if(!bIsLoggedIn)
+ {
+ OSL_FAIL("create error message");
+ return;
+ }
+ m_pImpl->xMailDispatcher.set( new MailDispatcher(xSmtpServer));
+ IterateMails();
+ m_pImpl->xMailListener = new SwMailDispatcherListener_Impl(*this);
+ m_pImpl->xMailDispatcher->addListener(m_pImpl->xMailListener);
+ if(!m_bCancel)
+ {
+ m_pImpl->xMailDispatcher->start();
+ }
+}
+
+void SwSendMailDialog::IterateMails()
+{
+ const SwMailDescriptor* pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
+ while( pCurrentMailDescriptor )
+ {
+ if (!SwMailMergeHelper::CheckMailAddress( pCurrentMailDescriptor->sEMail))
+ {
+ OUString sMessage = m_sSendingTo;
+ m_xStatus->append();
+ m_xStatus->set_image(m_nProcessedCount, RID_BMP_FORMULA_CANCEL, 0);
+ m_xStatus->set_text(m_nProcessedCount, sMessage.replaceFirst("%1", pCurrentMailDescriptor->sEMail), 1);
+ m_xStatus->set_text(m_nProcessedCount, m_sAddressInvalid, 2);
+ ++m_nProcessedCount;
+ ++m_nErrorCount;
+ UpdateTransferStatus( );
+ pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
+ continue;
+ }
+ rtl::Reference<SwMailMessage> pMessage = new SwMailMessage;
+ if(m_pConfigItem->IsMailReplyTo())
+ pMessage->setReplyToAddress(m_pConfigItem->GetMailReplyTo());
+ pMessage->addRecipient( pCurrentMailDescriptor->sEMail );
+ pMessage->SetSenderName( m_pConfigItem->GetMailDisplayName() );
+ pMessage->SetSenderAddress( m_pConfigItem->GetMailAddress() );
+ if(!pCurrentMailDescriptor->sAttachmentURL.isEmpty())
+ {
+ mail::MailAttachment aAttach;
+ aAttach.Data =
+ new SwMailTransferable(
+ pCurrentMailDescriptor->sAttachmentURL,
+ pCurrentMailDescriptor->sAttachmentName,
+ pCurrentMailDescriptor->sMimeType );
+ aAttach.ReadableName = pCurrentMailDescriptor->sAttachmentName;
+ pMessage->addAttachment( aAttach );
+ }
+ pMessage->setSubject( pCurrentMailDescriptor->sSubject );
+ uno::Reference< datatransfer::XTransferable> xBody =
+ new SwMailTransferable(
+ pCurrentMailDescriptor->sBodyContent,
+ pCurrentMailDescriptor->sBodyMimeType);
+ pMessage->setBody( xBody );
+
+ //CC and BCC are tokenized by ';'
+ if(!pCurrentMailDescriptor->sCC.isEmpty())
+ {
+ sal_Int32 nPos = 0;
+ do
+ {
+ OUString sTmp = pCurrentMailDescriptor->sCC.getToken( 0, ';', nPos );
+ if( !sTmp.isEmpty() )
+ pMessage->addCcRecipient( sTmp );
+ }
+ while (nPos >= 0);
+ }
+ if(!pCurrentMailDescriptor->sBCC.isEmpty())
+ {
+ sal_Int32 nPos = 0;
+ do
+ {
+ OUString sTmp = pCurrentMailDescriptor->sBCC.getToken( 0, ';', nPos );
+ if( !sTmp.isEmpty() )
+ pMessage->addBccRecipient( sTmp );
+ }
+ while (nPos >= 0);
+ }
+ m_pImpl->xMailDispatcher->enqueueMailMessage( pMessage );
+ pCurrentMailDescriptor = m_pImpl->GetNextDescriptor();
+ }
+ UpdateTransferStatus();
+}
+
+void SwSendMailDialog::StartSend(sal_Int32 nExpectedCount)
+{
+ Application::PostUserEvent( LINK( this, SwSendMailDialog,
+ StartSendMails ), this );
+ m_nExpectedCount = nExpectedCount > 0 ? nExpectedCount : 1;
+}
+
+void SwSendMailDialog::DocumentSent( uno::Reference< mail::XMailMessage> const & xMessage,
+ bool bResult,
+ const OUString* pError )
+{
+ //sending should stop on send errors, except after last error - it will stop in AllMailsSent
+ if (pError && m_nProcessedCount + 1 < m_nExpectedCount &&
+ m_pImpl->xMailDispatcher.is() && m_pImpl->xMailDispatcher->isStarted())
+ {
+ Application::PostUserEvent( LINK( this, SwSendMailDialog,
+ StopSendMails ), this );
+ }
+ OUString sInsertImg(bResult ? RID_BMP_FORMULA_APPLY : RID_BMP_FORMULA_CANCEL);
+
+ OUString sMessage = m_sSendingTo;
+ m_xStatus->append();
+ m_xStatus->set_image(m_nProcessedCount, sInsertImg, 0);
+ m_xStatus->set_text(m_nProcessedCount, sMessage.replaceFirst("%1", xMessage->getRecipients()[0]), 1);
+ m_xStatus->set_text(m_nProcessedCount, bResult ? m_sCompleted : m_sFailed, 2);
+ ++m_nProcessedCount;
+ if(!bResult)
+ ++m_nErrorCount;
+
+ UpdateTransferStatus( );
+
+ if (pError)
+ {
+ SwSendWarningBox_Impl aDlg(m_xDialog.get(), *pError);
+ aDlg.run();
+ }
+}
+
+void SwSendMailDialog::UpdateTransferStatus()
+{
+ OUString sStatus( m_sTransferStatus );
+ sStatus = sStatus.replaceFirst("%1", OUString::number(m_nProcessedCount) );
+ sStatus = sStatus.replaceFirst("%2", OUString::number(m_nExpectedCount));
+ m_xTransferStatus->set_label(sStatus);
+
+ sStatus = m_sErrorStatus.replaceFirst("%1", OUString::number(m_nErrorCount) );
+ m_xErrorStatus->set_label(sStatus);
+
+ if (!m_pImpl->aDescriptors.empty())
+ {
+ assert(m_nExpectedCount && "div-by-zero");
+ m_xProgressBar->set_percentage(m_nProcessedCount * 100 / m_nExpectedCount);
+ }
+ else
+ m_xProgressBar->set_percentage(0);
+}
+
+void SwSendMailDialog::AllMailsSent()
+{
+ if (m_nProcessedCount == m_nExpectedCount)
+ {
+ m_xStop->set_sensitive(false);
+ m_xCancel->set_label(m_sClose);
+ // Leave open if some kind of error occurred
+ if (m_nErrorCount == 0)
+ {
+ m_xDialog->hide();
+ m_xDialog->response(RET_CANCEL);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmoutputtypepage.hxx b/sw/source/ui/dbui/mmoutputtypepage.hxx
new file mode 100644
index 0000000000..0fa6c00d0f
--- /dev/null
+++ b/sw/source/ui/dbui/mmoutputtypepage.hxx
@@ -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/.
+ *
+ * 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_MMOUTPUTTYPEPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_MMOUTPUTTYPEPAGE_HXX
+
+#include <vcl/wizardmachine.hxx>
+#include <vcl/weld.hxx>
+class SwMailMergeWizard;
+
+class SwMailMergeOutputTypePage : public vcl::OWizardPage
+{
+ SwMailMergeWizard* m_pWizard;
+
+ std::unique_ptr<weld::RadioButton> m_xLetterRB;
+ std::unique_ptr<weld::RadioButton> m_xMailRB;
+ std::unique_ptr<weld::Label> m_xLetterHint;
+ std::unique_ptr<weld::Label> m_xMailHint;
+
+ DECL_LINK(TypeHdl_Impl, weld::Toggleable&, void);
+
+public:
+ SwMailMergeOutputTypePage(weld::Container* pPage, SwMailMergeWizard* pWizard);
+ virtual ~SwMailMergeOutputTypePage() override;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/mmresultdialogs.cxx b/sw/source/ui/dbui/mmresultdialogs.cxx
new file mode 100644
index 0000000000..d53085c912
--- /dev/null
+++ b/sw/source/ui/dbui/mmresultdialogs.cxx
@@ -0,0 +1,1296 @@
+/* -*- 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 <mmresultdialogs.hxx>
+#include <mmconfigitem.hxx>
+#include <mailconfigpage.hxx>
+#include "mmgreetingspage.hxx"
+#include <printdata.hxx>
+#include <swmessdialog.hxx>
+#include <cmdid.h>
+#include <swtypes.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <hintids.hxx>
+#include <swmodule.hxx>
+
+#include <vcl/QueueInfo.hxx>
+#include <editeng/langitem.hxx>
+#include <o3tl/temporary.hxx>
+#include <svl/itemset.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/scheduler.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/urihelper.hxx>
+#include <vcl/print.hxx>
+#include <rtl/tencinfo.h>
+#include <sal/log.hxx>
+
+#include <unotools/tempfile.hxx>
+#include <osl/file.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdb/XColumn.hpp>
+#include <com/sun/star/task/ErrorCodeIOException.hpp>
+#include <dbmgr.hxx>
+#include <swunohelper.hxx>
+#include <shellio.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <sfx2/event.hxx>
+#include <swevent.hxx>
+#include <dbui.hxx>
+#include <dbui.hrc>
+#include <doc.hxx>
+#include <sfx2/app.hxx>
+#include <strings.hrc>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/string.hxx>
+#include <iodetect.hxx>
+
+using namespace svt;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+#define MM_DOCTYPE_OOO 1
+#define MM_DOCTYPE_PDF 2
+#define MM_DOCTYPE_WORD 3
+#define MM_DOCTYPE_HTML 4
+#define MM_DOCTYPE_TEXT 5
+
+static OUString lcl_GetExtensionForDocType(sal_uLong nDocType)
+{
+ OUString sExtension;
+ switch( nDocType )
+ {
+ case MM_DOCTYPE_OOO : sExtension = "odt"; break;
+ case MM_DOCTYPE_PDF : sExtension = "pdf"; break;
+ case MM_DOCTYPE_WORD: sExtension = "doc"; break;
+ case MM_DOCTYPE_HTML: sExtension = "html"; break;
+ case MM_DOCTYPE_TEXT: sExtension = "txt"; break;
+ }
+ return sExtension;
+}
+
+static OUString lcl_GetColumnValueOf(const OUString& rColumn, Reference < container::XNameAccess> const & rxColAccess )
+{
+ OUString sRet;
+ try
+ {
+ if (rxColAccess->hasByName(rColumn))
+ {
+ Any aCol = rxColAccess->getByName(rColumn);
+ Reference< sdb::XColumn > xColumn;
+ aCol >>= xColumn;
+ if(xColumn.is())
+ sRet = xColumn->getString();
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ return sRet;
+}
+
+/**
+ * Replace email server settings in rConfigItem with those set in Writer's global
+ * mail merge config settings.
+ */
+static void lcl_UpdateEmailSettingsFromGlobalConfig(SwMailMergeConfigItem& rConfigItem)
+{
+ // newly created SwMailMergeConfigItem is initialized with values from (global) config
+ SwMailMergeConfigItem aConfigItem;
+
+ // take over email-related settings
+ rConfigItem.SetMailDisplayName(aConfigItem.GetMailDisplayName());
+ rConfigItem.SetMailAddress(aConfigItem.GetMailAddress());
+ rConfigItem.SetMailReplyTo(aConfigItem.GetMailReplyTo());
+ rConfigItem.SetMailReplyTo(aConfigItem.IsMailReplyTo());
+ rConfigItem.SetMailServer(aConfigItem.GetMailServer());
+ rConfigItem.SetMailPort(aConfigItem.GetMailPort());
+ rConfigItem.SetSecureConnection(aConfigItem.IsSecureConnection());
+ // authentication settings
+ rConfigItem.SetAuthentication(aConfigItem.IsAuthentication());
+ rConfigItem.SetSMTPAfterPOP(aConfigItem.IsSMTPAfterPOP());
+ rConfigItem.SetMailUserName(aConfigItem.GetMailUserName());
+ rConfigItem.SetMailPassword(aConfigItem.GetMailPassword());
+ rConfigItem.SetInServerName(aConfigItem.GetInServerName());
+ rConfigItem.SetInServerPort(aConfigItem.GetInServerPort());
+ rConfigItem.SetInServerPOP(aConfigItem.IsInServerPOP());
+ rConfigItem.SetInServerUserName(aConfigItem.GetInServerUserName());
+ rConfigItem.SetInServerPassword(aConfigItem.GetInServerPassword());
+}
+
+namespace {
+
+class SwSaveWarningBox_Impl : public SwMessageAndEditDialog
+{
+ DECL_LINK( ModifyHdl, weld::Entry&, void);
+public:
+ SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName);
+
+ OUString GetFileName() const
+ {
+ return m_xEdit->get_text();
+ }
+};
+
+class SwSendQueryBox_Impl : public SwMessageAndEditDialog
+{
+ bool m_bIsEmptyAllowed;
+ DECL_LINK( ModifyHdl, weld::Entry&, void);
+public:
+ SwSendQueryBox_Impl(weld::Window* pParent, const OUString& rID,
+ const OUString& rUIXMLDescription);
+
+ void SetValue(const OUString& rSet)
+ {
+ m_xEdit->set_text(rSet);
+ ModifyHdl(*m_xEdit);
+ }
+
+ OUString GetValue() const
+ {
+ return m_xEdit->get_text();
+ }
+
+ void SetIsEmptyTextAllowed(bool bSet)
+ {
+ m_bIsEmptyAllowed = bSet;
+ ModifyHdl(*m_xEdit);
+ }
+};
+
+}
+
+SwSaveWarningBox_Impl::SwSaveWarningBox_Impl(weld::Window* pParent, const OUString& rFileName)
+ : SwMessageAndEditDialog(pParent, "AlreadyExistsDialog",
+ "modules/swriter/ui/alreadyexistsdialog.ui")
+{
+ m_xEdit->set_text(rFileName);
+ m_xEdit->connect_changed(LINK(this, SwSaveWarningBox_Impl, ModifyHdl));
+
+ INetURLObject aTmp(rFileName);
+ m_xDialog->set_primary_text(m_xDialog->get_primary_text().replaceAll("%1", aTmp.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset)));
+
+ ModifyHdl(*m_xEdit);
+}
+
+IMPL_LINK( SwSaveWarningBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ m_xOKPB->set_sensitive(!rEdit.get_text().isEmpty());
+}
+
+SwSendQueryBox_Impl::SwSendQueryBox_Impl(weld::Window* pParent, const OUString& rID,
+ const OUString& rUIXMLDescription)
+ : SwMessageAndEditDialog(pParent, rID, rUIXMLDescription)
+ , m_bIsEmptyAllowed(true)
+{
+ m_xEdit->connect_changed(LINK(this, SwSendQueryBox_Impl, ModifyHdl));
+ ModifyHdl(*m_xEdit);
+}
+
+IMPL_LINK( SwSendQueryBox_Impl, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ m_xOKPB->set_sensitive(m_bIsEmptyAllowed || !rEdit.get_text().isEmpty());
+}
+
+namespace {
+
+class SwCopyToDialog : public SfxDialogController
+{
+ std::unique_ptr<weld::Entry> m_xCCED;
+ std::unique_ptr<weld::Entry> m_xBCCED;
+
+public:
+ explicit SwCopyToDialog(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/ccdialog.ui", "CCDialog")
+ , m_xCCED(m_xBuilder->weld_entry("cc"))
+ , m_xBCCED(m_xBuilder->weld_entry("bcc"))
+ {
+ }
+
+ OUString GetCC() const {return m_xCCED->get_text();}
+ void SetCC(const OUString& rSet) {m_xCCED->set_text(rSet);}
+
+ OUString GetBCC() const {return m_xBCCED->get_text();}
+ void SetBCC(const OUString& rSet) {m_xBCCED->set_text(rSet);}
+};
+
+}
+
+SwMMResultSaveDialog::SwMMResultSaveDialog(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/mmresultsavedialog.ui", "MMResultSaveDialog")
+ , m_bCancelSaving(false)
+ , m_xSaveAsOneRB(m_xBuilder->weld_radio_button("singlerb"))
+ , m_xSaveIndividualRB(m_xBuilder->weld_radio_button("individualrb"))
+ , m_xFromRB(m_xBuilder->weld_check_button("fromrb"))
+ , m_xFromNF(m_xBuilder->weld_spin_button("from"))
+ , m_xToFT(m_xBuilder->weld_label("toft"))
+ , m_xToNF(m_xBuilder->weld_spin_button("to"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+{
+ Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultSaveDialog, DocumentSelectionHdl_Impl);
+ m_xSaveAsOneRB->connect_toggled(aLink);
+ m_xSaveIndividualRB->connect_toggled(aLink);
+ m_xFromRB->connect_toggled(aLink);
+ // m_pSaveAsOneRB is the default, so disable m_xFromNF and m_xToNF initially.
+ aLink.Call(*m_xSaveAsOneRB);
+ if (SwView* pView = GetActiveView())
+ {
+ const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+ sal_Int32 nCount = xConfigItem->GetMergedDocumentCount();
+ m_xFromNF->set_max(nCount);
+ m_xToNF->set_max(nCount);
+ m_xToNF->set_value(nCount);
+ }
+
+ m_xOKButton->connect_clicked(LINK(this, SwMMResultSaveDialog, SaveOutputHdl_Impl));
+}
+
+SwMMResultSaveDialog::~SwMMResultSaveDialog()
+{
+}
+
+SwMMResultPrintDialog::SwMMResultPrintDialog(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/mmresultprintdialog.ui", "MMResultPrintDialog")
+ , m_xPrinterLB(m_xBuilder->weld_combo_box("printers"))
+ , m_xPrinterSettingsPB(m_xBuilder->weld_button("printersettings"))
+ , m_xPrintAllRB(m_xBuilder->weld_radio_button("printallrb"))
+ , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
+ , m_xFromNF(m_xBuilder->weld_spin_button("from"))
+ , m_xToFT(m_xBuilder->weld_label("toft"))
+ , m_xToNF(m_xBuilder->weld_spin_button("to"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+{
+ m_xPrinterLB->make_sorted();
+
+ m_xPrinterLB->connect_changed(LINK(this, SwMMResultPrintDialog, PrinterChangeHdl_Impl));
+ m_xPrinterSettingsPB->connect_clicked(LINK(this, SwMMResultPrintDialog, PrinterSetupHdl_Impl));
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultPrintDialog, DocumentSelectionHdl_Impl);
+ m_xPrintAllRB->connect_toggled(aLink);
+ m_xFromRB->connect_toggled(aLink);
+ // m_pPrintAllRB is the default, so disable m_xFromNF and m_xToNF initially.
+ aLink.Call(*m_xPrintAllRB);
+
+ m_xOKButton->connect_clicked(LINK(this, SwMMResultPrintDialog, PrintHdl_Impl));
+
+ FillInPrinterSettings();
+}
+
+SwMMResultPrintDialog::~SwMMResultPrintDialog()
+{
+}
+
+SwMMResultEmailDialog::SwMMResultEmailDialog(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/mmresultemaildialog.ui", "MMResultEmailDialog")
+ , m_sConfigureMail(SwResId(ST_CONFIGUREMAIL))
+ , m_xMailToLB(m_xBuilder->weld_combo_box("mailto"))
+ , m_xCopyToPB(m_xBuilder->weld_button("copyto"))
+ , m_xSubjectED(m_xBuilder->weld_entry("subject"))
+ , m_xSendAsLB(m_xBuilder->weld_combo_box("sendas"))
+ , m_xSendAsPB(m_xBuilder->weld_button("sendassettings"))
+ , m_xAttachmentGroup(m_xBuilder->weld_widget("attachgroup"))
+ , m_xAttachmentED(m_xBuilder->weld_entry("attach"))
+ , m_xPasswordFT(m_xBuilder->weld_label("passwordft"))
+ , m_xPasswordLB(m_xBuilder->weld_combo_box("password"))
+ , m_xPasswordCB(m_xBuilder->weld_check_button("passwordcb"))
+ , m_xSendAllRB(m_xBuilder->weld_radio_button("sendallrb"))
+ , m_xFromRB(m_xBuilder->weld_radio_button("fromrb"))
+ , m_xFromNF(m_xBuilder->weld_spin_button("from"))
+ , m_xToFT(m_xBuilder->weld_label("toft"))
+ , m_xToNF(m_xBuilder->weld_spin_button("to"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+{
+ m_xCopyToPB->connect_clicked(LINK(this, SwMMResultEmailDialog, CopyToHdl_Impl));
+ m_xSendAsPB->connect_clicked(LINK(this, SwMMResultEmailDialog, SendAsHdl_Impl));
+ m_xSendAsLB->connect_changed(LINK(this, SwMMResultEmailDialog, SendTypeHdl_Impl));
+ m_xPasswordCB->connect_toggled( LINK( this, SwMMResultEmailDialog, CheckHdl ));
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, SwMMResultEmailDialog, DocumentSelectionHdl_Impl);
+ m_xSendAllRB->connect_toggled(aLink);
+ m_xFromRB->connect_toggled(aLink);
+ // m_xSendAllRB is the default, so disable m_xFromNF and m_xToNF initially.
+ aLink.Call(*m_xSendAllRB);
+
+ m_xOKButton->connect_clicked(LINK(this, SwMMResultEmailDialog, SendDocumentsHdl_Impl));
+
+ m_xPasswordCB->set_sensitive(false);
+ m_xPasswordFT->set_sensitive(false);
+ m_xPasswordLB->set_sensitive(false);
+
+ FillInEmailSettings();
+}
+
+SwMMResultEmailDialog::~SwMMResultEmailDialog()
+{
+}
+
+void SwMMResultPrintDialog::FillInPrinterSettings()
+{
+ //fill printer ListBox
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
+ const std::vector<OUString>& rPrinters = Printer::GetPrinterQueues();
+ unsigned int nCount = rPrinters.size();
+ bool bMergePrinterExists = false;
+
+ for (unsigned int i = 0; i < nCount; ++i)
+ {
+ m_xPrinterLB->append_text( rPrinters[i] );
+ if( !bMergePrinterExists && rPrinters[i] == xConfigItem->GetSelectedPrinter() )
+ bMergePrinterExists = true;
+ }
+
+ assert(xConfigItem);
+ if(!bMergePrinterExists)
+ {
+ SfxPrinter* pPrinter = pView->GetWrtShell().getIDocumentDeviceAccess().getPrinter( true );
+ m_xPrinterLB->set_active_text(pPrinter->GetName());
+ }
+ else
+ {
+ m_xPrinterLB->set_active_text(xConfigItem->GetSelectedPrinter());
+ }
+ PrinterChangeHdl_Impl(*m_xPrinterLB);
+
+ sal_Int32 count = xConfigItem->GetMergedDocumentCount();
+ m_xFromNF->set_max(count);
+ m_xToNF->set_value(count);
+ m_xToNF->set_max(count);
+}
+
+void SwMMResultEmailDialog::FillInEmailSettings()
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+
+ SwView* pSourceView = xConfigItem->GetSourceView();
+ OSL_ENSURE(pSourceView, "no source view exists");
+ if (pSourceView)
+ {
+ SwDocShell* pDocShell = pSourceView->GetDocShell();
+ if (pDocShell->HasName())
+ {
+ INetURLObject aTmp(pDocShell->GetMedium()->GetName());
+ m_xAttachmentED->set_text(aTmp.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ));
+ }
+ }
+
+ if (m_xAttachmentED->get_text().isEmpty())
+ {
+ OUString sAttach = "." + lcl_GetExtensionForDocType(m_xSendAsLB->get_active_id().toUInt32());
+ m_xAttachmentED->set_text(sAttach);
+
+ }
+
+ //select first column
+ uno::Reference< sdbcx::XColumnsSupplier > xColsSupp(xConfigItem->GetResultSet(), uno::UNO_QUERY);
+ //get the name of the actual columns
+ uno::Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
+ uno::Sequence< OUString > aFields;
+ if (xColAccess.is())
+ aFields = xColAccess->getElementNames();
+
+ // fill mail address and password ListBox
+ assert(m_xMailToLB->get_count() == 0);
+ assert(m_xPasswordLB->get_count() == 0);
+ for (const OUString& rField : std::as_const(aFields))
+ {
+ m_xMailToLB->append_text(rField);
+ m_xPasswordLB->append_text(rField);
+ }
+
+ m_xMailToLB->set_active(0);
+ m_xPasswordLB->set_active(0);
+
+ // then select the right one - may not be available
+ const std::vector<std::pair<OUString, int>>& rHeaders = xConfigItem->GetDefaultAddressHeaders();
+ OUString sEMailColumn = rHeaders[MM_PART_E_MAIL].first;
+ Sequence< OUString> aAssignment = xConfigItem->GetColumnAssignment(xConfigItem->GetCurrentDBData());
+ if (aAssignment.getLength() > MM_PART_E_MAIL && !aAssignment[MM_PART_E_MAIL].isEmpty())
+ sEMailColumn = aAssignment[MM_PART_E_MAIL];
+ if (int pos = m_xMailToLB->find_text(sEMailColumn); pos >= 0)
+ m_xMailToLB->set_active(pos);
+
+ // HTML format pre-selected
+ m_xSendAsLB->set_active(3);
+ SendTypeHdl_Impl(*m_xSendAsLB);
+
+ const sal_Int32 nCount = xConfigItem->GetMergedDocumentCount();
+ m_xFromNF->set_max(nCount);
+ m_xToNF->set_max(nCount);
+ m_xToNF->set_value(nCount);
+}
+
+IMPL_LINK_NOARG(SwMMResultSaveDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnableFromTo = m_xFromRB->get_active();
+ m_xFromNF->set_sensitive(bEnableFromTo);
+ m_xToFT->set_sensitive(bEnableFromTo);
+ m_xToNF->set_sensitive(bEnableFromTo);
+}
+
+IMPL_LINK_NOARG(SwMMResultEmailDialog, CheckHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xPasswordCB->get_active();
+
+ m_xPasswordFT->set_sensitive(bEnable);
+ m_xPasswordLB->set_sensitive(bEnable);
+}
+
+IMPL_LINK_NOARG(SwMMResultPrintDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnableFromTo = m_xFromRB->get_active();
+ m_xFromNF->set_sensitive(bEnableFromTo);
+ m_xToFT->set_sensitive(bEnableFromTo);
+ m_xToNF->set_sensitive(bEnableFromTo);
+}
+
+IMPL_LINK_NOARG(SwMMResultEmailDialog, DocumentSelectionHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnableFromTo = m_xFromRB->get_active();
+ m_xFromNF->set_sensitive(bEnableFromTo);
+ m_xToFT->set_sensitive(bEnableFromTo);
+ m_xToNF->set_sensitive(bEnableFromTo);
+}
+
+IMPL_LINK_NOARG(SwMMResultEmailDialog, CopyToHdl_Impl, weld::Button&, void)
+{
+ SwCopyToDialog aDlg(m_xDialog.get());
+ aDlg.SetCC(m_sCC );
+ aDlg.SetBCC(m_sBCC);
+ if (aDlg.run() == RET_OK)
+ {
+ m_sCC = aDlg.GetCC() ;
+ m_sBCC = aDlg.GetBCC();
+ }
+}
+
+namespace {
+
+int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
+{
+ SwView* pTargetView = pConfigItem->GetTargetView();
+ assert( pTargetView );
+ SwCursorShell& shell = pTargetView->GetWrtShell();
+ const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo(document);
+ sal_uInt16 page;
+ shell.Push();
+ shell.GotoMark( info.startPageInTarget );
+ if (!bIgnoreEmpty)
+ shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
+ else
+ page = shell.GetPageNumSeqNonEmpty();
+ shell.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ return page;
+}
+
+int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty)
+{
+ SwView* pTargetView = pConfigItem->GetTargetView();
+ assert( pTargetView );
+ SwWrtShell& shell = pTargetView->GetWrtShell();
+ shell.Push();
+ if (document < int(pConfigItem->GetMergedDocumentCount()) - 1)
+ {
+ // Go to the page before the starting page of the next merged document.
+ const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo( document + 1 );
+ shell.GotoMark( info.startPageInTarget );
+ shell.EndPrvPg();
+ }
+ else
+ { // This is the last merged document, so it ends on the page at which the document ends.
+ shell.SttEndDoc( false ); // go to doc end
+ }
+ sal_uInt16 page;
+ if (!bIgnoreEmpty)
+ shell.GetPageNum(page, o3tl::temporary(sal_uInt16()));
+ else
+ page = shell.GetPageNumSeqNonEmpty();
+ shell.Pop(SwCursorShell::PopMode::DeleteCurrent);
+ return page;
+}
+
+} // anonymous namespace
+
+IMPL_LINK_NOARG(SwMMResultSaveDialog, SaveOutputHdl_Impl, weld::Button&, void)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+
+ const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
+ sal_uInt32 nBegin = 0;
+ sal_uInt32 nEnd = nDocumentCount;
+
+ if (m_xFromRB->get_active())
+ {
+ nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1);
+ nEnd = static_cast<sal_Int32>(m_xToNF->get_value());
+ if (nEnd > nDocumentCount)
+ nEnd = nDocumentCount;
+ }
+
+ xConfigItem->SetBeginEnd(nBegin, nEnd);
+
+ if (!xConfigItem->GetTargetView())
+ SwDBManager::PerformMailMerge(pView);
+
+ SwView* pTargetView = xConfigItem->GetTargetView();
+ assert(pTargetView);
+
+ OUString sFilter;
+ OUString sPath = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
+ if (sPath.isEmpty())
+ {
+ // just return back to the dialog
+ return;
+ }
+
+ if (m_xSaveAsOneRB->get_active())
+ {
+ uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", sFilter) };
+
+ uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
+ ErrCode nErrorCode = ERRCODE_NONE;
+ try
+ {
+ xStore->storeToURL( sPath, aValues );
+ }
+ catch (const task::ErrorCodeIOException& rErrorEx)
+ {
+ nErrorCode = ErrCode(rErrorEx.ErrCode);
+ }
+ catch (const Exception&)
+ {
+ nErrorCode = ERRCODE_IO_GENERAL;
+ }
+ if( nErrorCode != ERRCODE_NONE )
+ {
+ SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, pTargetView->GetDocShell()->GetTitle());
+ ErrorHandler::HandleError( nErrorCode );
+ }
+ }
+ else
+ {
+ OUString sTargetTempURL = URIHelper::SmartRel2Abs(
+ INetURLObject(), utl::CreateTempName(),
+ URIHelper::GetMaybeFileHdl());
+ std::shared_ptr<const SfxFilter> pSfxFlt = SwIoSystem::GetFilterOfFormat(
+ FILTER_XML,
+ SwDocShell::Factory().GetFilterContainer() );
+
+ uno::Sequence< beans::PropertyValue > aValues(1);
+ beans::PropertyValue* pValues = aValues.getArray();
+ pValues[0].Name = "FilterName";
+ pValues[0].Value <<= pSfxFlt->GetFilterName();
+
+ uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
+ ErrCode nErrorCode = ERRCODE_NONE;
+ try
+ {
+ xStore->storeToURL( sTargetTempURL, aValues );
+ }
+ catch (const task::ErrorCodeIOException& rErrorEx)
+ {
+ nErrorCode = ErrCode(rErrorEx.ErrCode);
+ }
+ catch (const Exception&)
+ {
+ nErrorCode = ERRCODE_IO_GENERAL;
+ }
+ if( nErrorCode != ERRCODE_NONE )
+ {
+ SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, pTargetView->GetDocShell()->GetTitle());
+ ErrorHandler::HandleError( nErrorCode );
+ }
+
+ SwView* pSourceView = xConfigItem->GetSourceView();
+ auto xSaveMonitor = std::make_shared<SaveMonitor>(m_xDialog.get());
+ xSaveMonitor->m_xDocName->set_label(pSourceView->GetDocShell()->GetTitle(22));
+ xSaveMonitor->m_xPrinter->set_label( INetURLObject( sPath ).getFSysPath( FSysStyle::Detect ) );
+ m_bCancelSaving = false;
+ weld::DialogController::runAsync(xSaveMonitor, [this, &xSaveMonitor](sal_Int32 nResult){
+ if (nResult == RET_CANCEL)
+ m_bCancelSaving = true;
+ xSaveMonitor.reset();
+ });
+
+ for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin && !m_bCancelSaving; ++nDoc)
+ {
+ INetURLObject aURL(sPath);
+ OUString sExtension = aURL.getExtension();
+ if (sExtension.isEmpty())
+ {
+ sExtension = pSfxFlt->GetWildcard().getGlob().getToken(1, '.');
+ sPath += "." + sExtension;
+ }
+ OUString sStat = SwResId(STR_STATSTR_LETTER) + " " + OUString::number(nDoc + 1);
+ xSaveMonitor->m_xPrintInfo->set_label(sStat);
+
+ //now extract a document from the target document
+ // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
+ SfxObjectShellLock xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
+ xTempDocShell->DoInitNew();
+ SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE );
+ SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
+ pTargetView->GetWrtShell().StartAction();
+ SwgReaderOption aOpt;
+ aOpt.SetTextFormats( true );
+ aOpt.SetFrameFormats( true );
+ aOpt.SetPageDescs( true );
+ aOpt.SetNumRules( true );
+ aOpt.SetMerge( false );
+ pTempView->GetDocShell()->LoadStylesFromFile(
+ sTargetTempURL, aOpt, true );
+ pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc());
+ pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
+ pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
+
+ uno::Reference<beans::XPropertySet> const xThisSet(
+ pTargetView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> const xRetSet(
+ pTempView->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aInteropGrabBag;
+ xThisSet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
+ xRetSet->setPropertyValue("InteropGrabBag", uno::Any(aInteropGrabBag));
+
+ pTargetView->GetWrtShell().PastePages(
+ pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
+ documentEndPageNumber(xConfigItem.get(), nDoc, false));
+ pTargetView->GetWrtShell().EndAction();
+ //then save it
+ OUString sOutPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
+ OUString sCounter = "_" + OUString::number(nDoc + 1);
+ sOutPath = sOutPath.replaceAt( sOutPath.getLength() - sExtension.getLength() - 1, 0, sCounter);
+
+ while(true)
+ {
+ //time for other slots is needed
+ Scheduler::ProcessEventsToIdle();
+
+ bool bFailed = false;
+ try
+ {
+ pValues[0].Value <<= sFilter;
+ uno::Reference< frame::XStorable > xTempStore( xTempDocShell->GetModel(), uno::UNO_QUERY);
+ xTempStore->storeToURL( sOutPath, aValues );
+ }
+ catch (const uno::Exception&)
+ {
+ bFailed = true;
+ }
+
+ if(bFailed)
+ {
+ std::unique_ptr<SwSaveWarningBox_Impl> xWarning(new SwSaveWarningBox_Impl(m_xDialog.get(), sOutPath));
+ if (RET_OK == xWarning->run())
+ sOutPath = xWarning->GetFileName();
+ else
+ {
+ xTempDocShell->DoClose();
+ m_xDialog->response(RET_OK);
+ return;
+ }
+ }
+ else
+ {
+ xTempDocShell->DoClose();
+ m_xDialog->response(RET_OK);
+ break;
+ }
+ }
+ }
+ if (xSaveMonitor)
+ xSaveMonitor->response(RET_OK);
+ ::osl::File::remove( sTargetTempURL );
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwMMResultPrintDialog, PrinterChangeHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ const std::shared_ptr<SwMailMergeConfigItem>& xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+ if (rBox.get_active() != -1)
+ {
+ const QueueInfo* pInfo = Printer::GetQueueInfo( rBox.get_active_text(), false );
+
+ if( pInfo )
+ {
+ if ( !m_pTempPrinter )
+ {
+ m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
+ }
+ else
+ {
+ if( (m_pTempPrinter->GetName() != pInfo->GetPrinterName()) ||
+ (m_pTempPrinter->GetDriverName() != pInfo->GetDriver()) )
+ {
+ m_pTempPrinter.disposeAndClear();
+ m_pTempPrinter = VclPtr<Printer>::Create( *pInfo );
+ }
+ }
+ }
+ else if( ! m_pTempPrinter )
+ m_pTempPrinter = VclPtr<Printer>::Create();
+
+ m_xPrinterSettingsPB->set_sensitive(m_pTempPrinter->HasSupport(PrinterSupport::SetupDialog));
+ }
+ else
+ m_xPrinterSettingsPB->set_sensitive(false);
+
+ xConfigItem->SetSelectedPrinter(rBox.get_active_text());
+}
+
+IMPL_LINK_NOARG(SwMMResultPrintDialog, PrintHdl_Impl, weld::Button&, void)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+
+ const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
+ sal_uInt32 nBegin = 0;
+ sal_uInt32 nEnd = nDocumentCount;
+
+ if (m_xFromRB->get_active())
+ {
+ nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1);
+ nEnd = static_cast<sal_Int32>(m_xToNF->get_value());
+ if (nEnd > nDocumentCount)
+ nEnd = nDocumentCount;
+ }
+
+ xConfigItem->SetBeginEnd(nBegin, nEnd);
+
+ if(!xConfigItem->GetTargetView())
+ SwDBManager::PerformMailMerge(pView);
+
+ SwView* pTargetView = xConfigItem->GetTargetView();
+ assert(pTargetView);
+
+ // If we skip autoinserted blanks, then the page numbers used in the print range string
+ // refer to the non-blank pages as they appear in the document (see tdf#89708).
+ const bool bIgnoreEmptyPages =
+ !pTargetView->GetDocShell()->GetDoc()->getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages();
+ const int nStartPage = documentStartPageNumber(xConfigItem.get(), 0, bIgnoreEmptyPages);
+ const int nEndPage = documentEndPageNumber(xConfigItem.get(), nEnd - nBegin - 1, bIgnoreEmptyPages);
+
+ const OUString sPages(OUString::number(nStartPage) + "-" + OUString::number(nEndPage));
+
+ pTargetView->SetMailMergeConfigItem(xConfigItem);
+ if(m_pTempPrinter)
+ {
+ SfxPrinter *const pDocumentPrinter = pTargetView->GetWrtShell()
+ .getIDocumentDeviceAccess().getPrinter(true);
+ pDocumentPrinter->SetPrinterProps(m_pTempPrinter);
+ // this should be able to handle setting its own printer
+ pTargetView->SetPrinter(pDocumentPrinter);
+ }
+
+ SfxObjectShell* pObjSh = pTargetView->GetViewFrame().GetObjectShell();
+ SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMerge, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), pObjSh));
+
+ uno::Sequence aProps{ comphelper::makePropertyValue("MonitorVisible", true),
+ comphelper::makePropertyValue("Pages", sPages) };
+
+ pTargetView->ExecPrint( aProps, false, true );
+ SfxGetpApp()->NotifyEvent(SfxEventHint(SfxEventHintId::SwMailMergeEnd, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), pObjSh));
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwMMResultPrintDialog, PrinterSetupHdl_Impl, weld::Button&, void)
+{
+ if (m_pTempPrinter)
+ m_pTempPrinter->Setup(m_xDialog.get());
+}
+
+IMPL_LINK(SwMMResultEmailDialog, SendTypeHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ auto nDocType = rBox.get_active_id().toUInt32();
+ bool bEnable = MM_DOCTYPE_HTML != nDocType && MM_DOCTYPE_TEXT != nDocType;
+ bool bIsPDF = nDocType == MM_DOCTYPE_PDF;
+ m_xSendAsPB->set_sensitive(bEnable);
+ m_xAttachmentGroup->set_sensitive(bEnable);
+ if(bEnable)
+ {
+ //add the correct extension
+ OUString sAttach(m_xAttachmentED->get_text());
+ //do nothing if the user has removed the name - the warning will come early enough
+ if (!sAttach.isEmpty())
+ {
+ sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
+ if( 2 > nTokenCount)
+ {
+ sAttach += ".";
+ ++nTokenCount;
+ }
+ sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType( nDocType ));
+ m_xAttachmentED->set_text(sAttach);
+ }
+ }
+
+ if(bIsPDF)
+ {
+ m_xPasswordCB->set_sensitive(true);
+ m_xPasswordFT->set_sensitive(true);
+ m_xPasswordLB->set_sensitive(true);
+ CheckHdl(*m_xPasswordCB);
+ }
+ else
+ {
+ m_xPasswordCB->set_sensitive(false);
+ m_xPasswordFT->set_sensitive(false);
+ m_xPasswordLB->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SwMMResultEmailDialog, SendAsHdl_Impl, weld::Button&, void)
+{
+ // work around crash when calling constructor with no active view
+ if (!GetActiveView())
+ {
+ SAL_WARN("sw", "ignoring SendAs button click, because no active view");
+ return;
+ }
+ SwMailBodyDialog aDlg(m_xDialog.get());
+ aDlg.SetBody(m_sBody);
+ if (RET_OK == aDlg.run())
+ {
+ m_sBody = aDlg.GetBody();
+ }
+}
+
+// Send documents as e-mail
+IMPL_LINK_NOARG(SwMMResultEmailDialog, SendDocumentsHdl_Impl, weld::Button&, void)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ std::shared_ptr<SwMailMergeConfigItem> xConfigItem = pView->GetMailMergeConfigItem();
+ assert(xConfigItem);
+
+ const sal_uInt32 nDocumentCount = xConfigItem->GetMergedDocumentCount();
+ sal_uInt32 nBegin = 0;
+ sal_uInt32 nEnd = nDocumentCount;
+
+ if (m_xFromRB->get_active())
+ {
+ nBegin = static_cast<sal_Int32>(m_xFromNF->get_value() - 1);
+ nEnd = static_cast<sal_Int32>(m_xToNF->get_value());
+ if (nEnd > nDocumentCount)
+ nEnd = nDocumentCount;
+ }
+
+ xConfigItem->SetBeginEnd(nBegin, nEnd);
+
+ if (!xConfigItem->GetTargetView())
+ SwDBManager::PerformMailMerge(pView);
+
+ //get the composed document
+ SwView* pTargetView = xConfigItem->GetTargetView();
+ SAL_WARN_IF(!pTargetView, "sw.ui", "No TargetView in SwMailMergeConfigItem");
+
+ if (xConfigItem->GetMailServer().isEmpty() ||
+ !SwMailMergeHelper::CheckMailAddress(xConfigItem->GetMailAddress()) )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_sConfigureMail));
+ xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), RET_CANCEL);
+ sal_uInt16 nRet = xQueryBox->run();
+ if (RET_YES == nRet )
+ {
+ SwView* pConfigView = pTargetView ? pTargetView : pView;
+ SfxAllItemSet aSet(pConfigView->GetPool());
+ SwMailConfigDlg aDlg(m_xDialog.get(), aSet);
+ nRet = aDlg.run();
+ }
+
+ if(nRet != RET_OK && nRet != RET_YES)
+ return; // back to the dialog
+
+ // SwMailConfigDlg writes mail merge email settings only to (global) config,
+ // so copy them to the existing config item
+ lcl_UpdateEmailSettingsFromGlobalConfig(*xConfigItem);
+ }
+ //add the documents
+ bool bAsBody = false;
+ rtl_TextEncoding eEncoding = ::osl_getThreadTextEncoding();
+ SfxFilterContainer* pFilterContainer = SwDocShell::Factory().GetFilterContainer();
+ std::shared_ptr<const SfxFilter> pSfxFlt;
+ auto nDocType = m_xSendAsLB->get_active_id().toUInt32();
+ OUString sExtension = lcl_GetExtensionForDocType(nDocType);
+ switch( nDocType )
+ {
+ case MM_DOCTYPE_OOO:
+ {
+ //Make sure we don't pick e.g. the flat xml filter
+ //for this format
+ pSfxFlt = pFilterContainer->GetFilter4FilterName(
+ "writer8",
+ SfxFilterFlags::EXPORT);
+ }
+ break;
+ case MM_DOCTYPE_PDF:
+ {
+ pSfxFlt = pFilterContainer->GetFilter4FilterName(
+ "writer_pdf_Export",
+ SfxFilterFlags::EXPORT);
+ }
+ break;
+ case MM_DOCTYPE_WORD:
+ {
+ //the method SwIOSystemGetFilterOfFormat( ) returns the template filter
+ //because it uses the same user data :-(
+ SfxFilterMatcher aMatcher( pFilterContainer->GetName() );
+ SfxFilterMatcherIter aIter( aMatcher );
+ std::shared_ptr<const SfxFilter> pFilter = aIter.First();
+ while ( pFilter )
+ {
+ if( pFilter->GetUserData() == FILTER_WW8 && pFilter->CanExport() )
+ {
+ pSfxFlt = pFilter;
+ break;
+ }
+ pFilter = aIter.Next();
+ }
+
+ }
+ break;
+ case MM_DOCTYPE_HTML:
+ {
+ bAsBody = true;
+ eEncoding = RTL_TEXTENCODING_UTF8;
+ }
+ break;
+ case MM_DOCTYPE_TEXT:
+ {
+ bAsBody = true;
+ pSfxFlt = pFilterContainer->GetFilter4FilterName(
+ "Text (encoded)", SfxFilterFlags::EXPORT);
+ }
+ break;
+ }
+ if(!pSfxFlt)
+ pSfxFlt = pFilterContainer->GetFilter4Extension(sExtension, SfxFilterFlags::EXPORT);
+
+ if(!pSfxFlt)
+ {
+ m_xDialog->response(RET_OK);
+ return;
+ }
+ OUString sMimeType = pSfxFlt->GetMimeType();
+
+ if (m_xSubjectED->get_text().isEmpty())
+ {
+ std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "SubjectDialog",
+ "modules/swriter/ui/subjectdialog.ui"));
+ xQuery->SetIsEmptyTextAllowed(true);
+ xQuery->SetValue("");
+ if(RET_OK == xQuery->run())
+ {
+ if (!xQuery->GetValue().isEmpty())
+ m_xSubjectED->set_text(xQuery->GetValue());
+ }
+ else
+ return; // back to the dialog
+ }
+ if(!bAsBody && m_xAttachmentED->get_text().isEmpty())
+ {
+ std::unique_ptr<SwSendQueryBox_Impl> xQuery(new SwSendQueryBox_Impl(m_xDialog.get(), "AttachNameDialog",
+ "modules/swriter/ui/attachnamedialog.ui"));
+ xQuery->SetIsEmptyTextAllowed(false);
+ if (RET_OK == xQuery->run())
+ {
+ OUString sAttach(xQuery->GetValue());
+ sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttach, '.');
+ if (2 > nTokenCount)
+ {
+ sAttach += ".";
+ ++nTokenCount;
+ }
+ sAttach = comphelper::string::setToken(sAttach, nTokenCount - 1, '.', lcl_GetExtensionForDocType(
+ m_xSendAsLB->get_active_id().toUInt32()));
+ m_xAttachmentED->set_text(sAttach);
+ }
+ else
+ return; // back to the dialog
+ }
+
+ OUString sEMailColumn = m_xMailToLB->get_active_text();
+ OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected");
+ Reference< sdbcx::XColumnsSupplier > xColsSupp( xConfigItem->GetResultSet(), UNO_QUERY);
+ Reference < container::XNameAccess> xColAccess = xColsSupp.is() ? xColsSupp->getColumns() : nullptr;
+ if(sEMailColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sEMailColumn))
+ {
+ m_xDialog->response(RET_OK);
+ return;
+ }
+
+ OUString sPasswordColumn = m_xPasswordLB->get_active_text();
+ OSL_ENSURE( !sPasswordColumn.isEmpty(), "No password column selected");
+ if(sPasswordColumn.isEmpty() || !xColAccess.is() || !xColAccess->hasByName(sPasswordColumn))
+ {
+ m_xDialog->response(RET_OK);
+ return;
+ }
+
+ OUString sFilterOptions;
+ if(MM_DOCTYPE_TEXT == nDocType)
+ {
+ SwAsciiOptions aOpt;
+ sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
+ TypedWhichId<SvxLanguageItem> nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
+ const SvxLanguageItem& rDefLangItem = pTargetView->GetWrtShell().GetDefault( nWhich );
+ aOpt.SetLanguage( rDefLangItem.GetLanguage() );
+ aOpt.SetParaFlags( LINEEND_CR );
+ aOpt.WriteUserData( sFilterOptions );
+ }
+ else if(MM_DOCTYPE_HTML == nDocType)
+ {
+ sFilterOptions = "EmbedImages";
+ }
+ OUString sTargetTempURL = URIHelper::SmartRel2Abs(
+ INetURLObject(), utl::CreateTempName(),
+ URIHelper::GetMaybeFileHdl());
+ std::shared_ptr<const SfxFilter> pTargetSfxFlt = SwIoSystem::GetFilterOfFormat(
+ FILTER_XML,
+ SwDocShell::Factory().GetFilterContainer() );
+
+ uno::Sequence< beans::PropertyValue > aValues { comphelper::makePropertyValue("FilterName", pTargetSfxFlt->GetFilterName()) };
+
+ uno::Reference< frame::XStorable > xStore( pTargetView->GetDocShell()->GetModel(), uno::UNO_QUERY);
+ xStore->storeToURL( sTargetTempURL, aValues );
+
+ //create the send dialog
+ std::shared_ptr<SwSendMailDialog> xDlg = std::make_shared<SwSendMailDialog>(Application::GetDefDialogParent(), *xConfigItem);
+
+ xDlg->StartSend(nEnd - nBegin);
+ weld::DialogController::runAsync(xDlg, [](sal_Int32 /*nResult*/){});
+
+ //help to force painting the dialog
+ //TODO/CLEANUP
+ //predetermined breaking point
+ Application::Reschedule( true );
+ m_xDialog->response(RET_OK);
+ for(sal_uInt32 nDoc = 0; nDoc < nEnd - nBegin; ++nDoc)
+ {
+ SwDocMergeInfo& rInfo = xConfigItem->GetDocumentMergeInfo(nDoc);
+
+ //now extract a document from the target document
+ // the shell will be closed at the end, but it is more safe to use SfxObjectShellLock here
+ SfxObjectShellLock xTempDocShell( new SwDocShell( SfxObjectCreateMode::STANDARD ) );
+ xTempDocShell->DoInitNew();
+ SfxViewFrame* pTempFrame = SfxViewFrame::LoadHiddenDocument( *xTempDocShell, SFX_INTERFACE_NONE );
+ SwView* pTempView = static_cast<SwView*>( pTempFrame->GetViewShell() );
+ pTargetView->GetWrtShell().StartAction();
+ SwgReaderOption aOpt;
+ aOpt.SetTextFormats( true );
+ aOpt.SetFrameFormats( true );
+ aOpt.SetPageDescs( true );
+ aOpt.SetNumRules( true );
+ aOpt.SetMerge( false );
+ pTempView->GetDocShell()->LoadStylesFromFile(
+ sTargetTempURL, aOpt, true );
+ pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc());
+ pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc());
+ pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true );
+ pTargetView->GetWrtShell().PastePages(
+ pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false),
+ documentEndPageNumber(xConfigItem.get(), nDoc, false));
+ pTargetView->GetWrtShell().EndAction();
+
+ //then save it
+ SfxStringItem aName(SID_FILE_NAME,
+ URIHelper::SmartRel2Abs(
+ INetURLObject(), utl::CreateTempName(),
+ URIHelper::GetMaybeFileHdl()) );
+
+ {
+ bool withFilterOptions = MM_DOCTYPE_TEXT == nDocType || MM_DOCTYPE_HTML == nDocType;
+ bool withPasswordOptions = m_xPasswordCB->get_active();
+
+ sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow);
+ OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected");
+ OUString sPassword = lcl_GetColumnValueOf(sPasswordColumn, xColAccess);
+
+ sal_Int32 nOptionCount = (withFilterOptions && withPasswordOptions) ? 4 : withPasswordOptions ? 3 : withFilterOptions ? 2 : 1;
+ sal_Int32 nOpt = 0;
+ uno::Sequence< beans::PropertyValue > aFilterValues(nOptionCount);
+ beans::PropertyValue* pFilterValues = aFilterValues.getArray();
+
+ pFilterValues[nOpt].Name = "FilterName";
+ pFilterValues[nOpt].Value <<= pSfxFlt->GetFilterName();
+
+ if(withFilterOptions)
+ {
+ nOpt++;
+ pFilterValues[nOpt].Name = "FilterOptions";
+ pFilterValues[nOpt].Value <<= sFilterOptions;
+ }
+
+ if(withPasswordOptions)
+ {
+ nOpt++;
+ pFilterValues[nOpt].Name = "EncryptFile";
+ pFilterValues[nOpt].Value <<= true;
+ nOpt++;
+ pFilterValues[nOpt].Name = "DocumentOpenPassword";
+ pFilterValues[nOpt].Value <<= sPassword;
+ }
+
+ uno::Reference< frame::XStorable > xTempStore( pTempView->GetDocShell()->GetModel(), uno::UNO_QUERY);
+ xTempStore->storeToURL( aName.GetValue(), aFilterValues );
+ }
+ xTempDocShell->DoClose();
+
+ sal_Int32 nTarget = xConfigItem->MoveResultSet(rInfo.nDBRow);
+ OSL_ENSURE( nTarget == rInfo.nDBRow, "row of current document could not be selected");
+ OSL_ENSURE( !sEMailColumn.isEmpty(), "No email column selected");
+ OUString sEMail = lcl_GetColumnValueOf(sEMailColumn, xColAccess);
+ SwMailDescriptor aDesc;
+ aDesc.sEMail = sEMail;
+ OUStringBuffer sBody;
+ if(bAsBody)
+ {
+ {
+ //read in the temporary file and use it as mail body
+ SfxMedium aMedium( aName.GetValue(), StreamMode::READ);
+ SvStream* pInStream = aMedium.GetInStream();
+ if(pInStream)
+ pInStream->SetStreamCharSet( eEncoding );
+ else
+ {
+ OSL_FAIL("no output file created?");
+ continue;
+ }
+ OStringBuffer sLine;
+ bool bDone = pInStream->ReadLine( sLine );
+ while ( bDone )
+ {
+ sBody.append( OStringToOUString(sLine, eEncoding) + "\n");
+ bDone = pInStream->ReadLine( sLine );
+ }
+ }
+ //remove the temporary file
+ SWUnoHelper::UCB_DeleteFile( aName.GetValue() );
+ }
+ else
+ {
+ sBody = m_sBody;
+ aDesc.sAttachmentURL = aName.GetValue();
+ OUString sAttachment(m_xAttachmentED->get_text());
+ sal_Int32 nTokenCount = comphelper::string::getTokenCount(sAttachment, '.');
+ if (2 > nTokenCount)
+ {
+ sAttachment += ".";
+ sAttachment = comphelper::string::setToken(sAttachment, nTokenCount, '.', sExtension);
+ }
+ else if (o3tl::getToken(sAttachment, nTokenCount - 1, '.') != sExtension)
+ sAttachment += sExtension;
+ aDesc.sAttachmentName = sAttachment;
+ aDesc.sMimeType = sMimeType;
+
+ if (xConfigItem->IsGreetingLine(true))
+ {
+ OUString sNameColumn = xConfigItem->GetAssignedColumn(MM_PART_LASTNAME);
+ OUString sName = lcl_GetColumnValueOf(sNameColumn, xColAccess);
+ OUString sGreeting;
+ if(!sName.isEmpty() && xConfigItem->IsIndividualGreeting(true))
+ {
+ OUString sGenderColumn = xConfigItem->GetAssignedColumn(MM_PART_GENDER);
+ const OUString& sFemaleValue = xConfigItem->GetFemaleGenderValue();
+ OUString sGenderValue = lcl_GetColumnValueOf(sGenderColumn, xColAccess);
+ SwMailMergeConfigItem::Gender eGenderType = sGenderValue == sFemaleValue ?
+ SwMailMergeConfigItem::FEMALE :
+ SwMailMergeConfigItem::MALE;
+
+ sGreeting = SwAddressPreview::FillData(
+ xConfigItem->GetGreetings(eGenderType)
+ [xConfigItem->GetCurrentGreeting(eGenderType)],
+ *xConfigItem);
+ }
+ else
+ {
+ sGreeting =
+ xConfigItem->GetGreetings(SwMailMergeConfigItem::NEUTRAL)
+ [xConfigItem->GetCurrentGreeting(SwMailMergeConfigItem::NEUTRAL)];
+
+ }
+ sGreeting += "\n";
+ sBody.insert(0, sGreeting);
+ }
+ }
+ aDesc.sBodyContent = sBody.makeStringAndClear();
+ if(MM_DOCTYPE_HTML == nDocType)
+ {
+ aDesc.sBodyMimeType = "text/html; charset=" +
+ OUString::createFromAscii(rtl_getBestMimeCharsetFromTextEncoding( eEncoding ));
+ }
+ else
+ aDesc.sBodyMimeType = "text/plain; charset=UTF-8; format=flowed";
+
+ aDesc.sSubject = m_xSubjectED->get_text();
+ aDesc.sCC = m_sCC;
+ aDesc.sBCC = m_sBCC;
+ xDlg->AddDocument( aDesc );
+ //help to force painting the dialog
+ Application::Reschedule( true );
+ //stop creating of data when dialog has been closed
+ if (!xDlg->getDialog()->get_visible())
+ {
+ break;
+ }
+ }
+ xDlg->EnableDestruction();
+ ::osl::File::remove( sTargetTempURL );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/selectdbtabledialog.cxx b/sw/source/ui/dbui/selectdbtabledialog.cxx
new file mode 100644
index 0000000000..be5faf3ada
--- /dev/null
+++ b/sw/source/ui/dbui/selectdbtabledialog.cxx
@@ -0,0 +1,144 @@
+/* -*- 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 <comphelper/propertyvalue.hxx>
+#include <swtypes.hxx>
+#include "selectdbtabledialog.hxx"
+#include "dbtablepreviewdialog.hxx"
+#include <osl/diagnose.h>
+#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
+#include <com/sun/star/sdb/XQueriesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/sdbc/XDataSource.hpp>
+
+#include <strings.hrc>
+#include <utility>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+
+SwSelectDBTableDialog::SwSelectDBTableDialog(weld::Window* pParent,
+ uno::Reference<sdbc::XConnection> xConnection)
+ : SfxDialogController(pParent, "modules/swriter/ui/selecttabledialog.ui", "SelectTableDialog")
+ , m_xConnection(std::move(xConnection))
+ , m_xTable(m_xBuilder->weld_tree_view("table"))
+ , m_xPreviewPB(m_xBuilder->weld_button("preview"))
+{
+ m_xTable->set_size_request(m_xTable->get_approximate_digit_width() * 60,
+ m_xTable->get_height_rows(6));
+
+ std::vector<int> aWidths{ o3tl::narrowing<int>(m_xTable->get_approximate_digit_width() * 30) };
+ m_xTable->set_column_fixed_widths(aWidths);
+
+ m_xPreviewPB->connect_clicked(LINK(this, SwSelectDBTableDialog, PreviewHdl));
+
+ Reference<XTablesSupplier> xTSupplier(m_xConnection, UNO_QUERY);
+ if (xTSupplier.is())
+ {
+ Reference<XNameAccess> xTables = xTSupplier->getTables();
+ Sequence<OUString> aTables = xTables->getElementNames();
+ const OUString* pTables = aTables.getConstArray();
+ for (int i = 0; i < aTables.getLength(); i++)
+ {
+ OUString sEntry = pTables[i];
+ m_xTable->append_text(sEntry);
+ m_xTable->set_text(i, SwResId(ST_TABLE), 1);
+ }
+ }
+ Reference<XQueriesSupplier> xQSupplier(m_xConnection, UNO_QUERY);
+ if (!xQSupplier.is())
+ return;
+
+ Reference<XNameAccess> xQueries = xQSupplier->getQueries();
+ const Sequence<OUString> aQueries = xQueries->getElementNames();
+ int nPos = m_xTable->n_children();
+ for (const OUString& rQuery : aQueries)
+ {
+ m_xTable->append_text(rQuery);
+ m_xTable->set_text(nPos, SwResId(ST_QUERY), 1);
+ m_xTable->set_id(nPos, OUString::number(1));
+ ++nPos;
+ }
+}
+
+SwSelectDBTableDialog::~SwSelectDBTableDialog() {}
+
+IMPL_LINK_NOARG(SwSelectDBTableDialog, PreviewHdl, weld::Button&, void)
+{
+ int nEntry = m_xTable->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ OUString sTableOrQuery = m_xTable->get_text(nEntry, 0);
+ sal_Int32 nCommandType = m_xTable->get_id(nEntry).isEmpty() ? 0 : 1;
+
+ OUString sDataSourceName;
+ Reference<XChild> xChild(m_xConnection, UNO_QUERY);
+ if (xChild.is())
+ {
+ Reference<XDataSource> xSource(xChild->getParent(), UNO_QUERY);
+ Reference<XPropertySet> xPrSet(xSource, UNO_QUERY);
+ xPrSet->getPropertyValue("Name") >>= sDataSourceName;
+ }
+ OSL_ENSURE(!sDataSourceName.isEmpty(), "no data source found");
+ Sequence<PropertyValue> aProperties{
+ comphelper::makePropertyValue("DataSourceName", sDataSourceName),
+ comphelper::makePropertyValue("Command", sTableOrQuery),
+ comphelper::makePropertyValue("CommandType", nCommandType),
+ comphelper::makePropertyValue("ShowTreeView", false),
+ comphelper::makePropertyValue("ShowTreeViewButton", false)
+ };
+
+ SwDBTablePreviewDialog aDlg(m_xDialog.get(), aProperties);
+ aDlg.run();
+}
+
+OUString SwSelectDBTableDialog::GetSelectedTable(bool& bIsTable)
+{
+ int nEntry = m_xTable->get_selected_index();
+ if (nEntry != -1)
+ {
+ bIsTable = m_xTable->get_id(nEntry).isEmpty();
+ return m_xTable->get_text(nEntry, 0);
+ }
+ bIsTable = false;
+ return OUString();
+}
+
+void SwSelectDBTableDialog::SetSelectedTable(std::u16string_view rTable, bool bIsTable)
+{
+ for (int i = 0, nCount = m_xTable->n_children(); i < nCount; ++i)
+ {
+ if (m_xTable->get_text(i, 0) == rTable && m_xTable->get_id(i).isEmpty() == bIsTable)
+ {
+ m_xTable->select(i);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dbui/selectdbtabledialog.hxx b/sw/source/ui/dbui/selectdbtabledialog.hxx
new file mode 100644
index 0000000000..aa0bbddea8
--- /dev/null
+++ b/sw/source/ui/dbui/selectdbtabledialog.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DBUI_SELECTDBTABLEDIALOG_HXX
+#define INCLUDED_SW_SOURCE_UI_DBUI_SELECTDBTABLEDIALOG_HXX
+
+#include <sfx2/basedlgs.hxx>
+
+namespace com::sun::star::sdbc { class XConnection; }
+
+class SwSelectDBTableDialog : public SfxDialogController
+{
+ css::uno::Reference<css::sdbc::XConnection> m_xConnection;
+
+ std::unique_ptr<weld::TreeView> m_xTable;
+ std::unique_ptr<weld::Button> m_xPreviewPB;
+
+ DECL_LINK(PreviewHdl, weld::Button&, void);
+public:
+ SwSelectDBTableDialog(weld::Window* pParent,
+ css::uno::Reference<css::sdbc::XConnection> xConnection);
+ virtual ~SwSelectDBTableDialog() override;
+
+ OUString GetSelectedTable(bool& bIsTable);
+ void SetSelectedTable(std::u16string_view rTable, bool bIsTable);
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/abstract.cxx b/sw/source/ui/dialog/abstract.cxx
new file mode 100644
index 0000000000..01e0138955
--- /dev/null
+++ b/sw/source/ui/dialog/abstract.cxx
@@ -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 .
+ */
+
+#include <abstract.hxx>
+
+SwInsertAbstractDlg::SwInsertAbstractDlg(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/abstractdialog.ui", "AbstractDialog")
+ , m_xLevelNF(m_xBuilder->weld_spin_button("outlines"))
+ , m_xParaNF(m_xBuilder->weld_spin_button("paras"))
+{
+}
+
+SwInsertAbstractDlg::~SwInsertAbstractDlg() {}
+
+sal_uInt8 SwInsertAbstractDlg::GetLevel() const
+{
+ return static_cast<sal_uInt8>(m_xLevelNF->get_value() - 1);
+}
+
+sal_uInt8 SwInsertAbstractDlg::GetPara() const
+{
+ return static_cast<sal_uInt8>(m_xParaNF->get_value());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/addrdlg.cxx b/sw/source/ui/dialog/addrdlg.cxx
new file mode 100644
index 0000000000..0dde165fc0
--- /dev/null
+++ b/sw/source/ui/dialog/addrdlg.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 <addrdlg.hxx>
+#include <sfx2/pageids.hxx>
+#include <sfx2/sfxdlg.hxx>
+
+SwAddrDlg::SwAddrDlg(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc(RID_SFXPAGE_GENERAL);
+ if (fnCreatePage)
+ {
+ // create TabPage
+ SetTabPage(fnCreatePage(get_content_area(), this, &rSet));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/ascfldlg.cxx b/sw/source/ui/dialog/ascfldlg.cxx
new file mode 100644
index 0000000000..43a3249823
--- /dev/null
+++ b/sw/source/ui/dialog/ascfldlg.cxx
@@ -0,0 +1,448 @@
+/* -*- 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 <optional>
+#include <utility>
+
+#include <hintids.hxx>
+#include <rtl/textenc.h>
+#include <i18nlangtag/mslangid.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <unotools/lingucfg.hxx>
+#include <unotools/viewoptions.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/printer.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/languageoptions.hxx>
+#include <editeng/langitem.hxx>
+#include <swtypes.hxx>
+#include <ascfldlg.hxx>
+#include <shellio.hxx>
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <IDocumentDeviceAccess.hxx>
+
+#include <vcl/metric.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+
+const sal_Unicode cDialogExtraDataClose = '}';
+const char sDialogImpExtraData[] = "EncImpDlg:{";
+const char sDialogExpExtraData[] = "EncExpDlg:{";
+const sal_Int32 nDialogExtraDataLen = 11; // 12345678901
+
+}
+
+SwAsciiFilterDlg::SwAsciiFilterDlg( weld::Window* pParent, SwDocShell& rDocSh,
+ SvStream* pStream )
+ : SfxDialogController(pParent, "modules/swriter/ui/asciifilterdialog.ui", "AsciiFilterDialog")
+ , m_bSaveLineStatus(true)
+ , m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder->weld_combo_box("charset")))
+ , m_xFontFT(m_xBuilder->weld_label("fontft"))
+ , m_xFontLB(m_xBuilder->weld_combo_box("font"))
+ , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xCRLF_RB(m_xBuilder->weld_radio_button("crlf"))
+ , m_xCR_RB(m_xBuilder->weld_radio_button("cr"))
+ , m_xLF_RB(m_xBuilder->weld_radio_button("lf"))
+ , m_xIncludeBOM_CB(m_xBuilder->weld_check_button("includebom"))
+{
+ m_xFontLB->make_sorted();
+
+ SwAsciiOptions aOpt;
+ {
+ SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
+ if (aDlgOpt.Exists())
+ {
+ css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem");
+ aUserItem >>= m_sExtraData;
+ }
+
+ const SfxStringItem* pItem;
+ OUString sAsciiOptions;
+ if( rDocSh.GetMedium() != nullptr &&
+ (pItem = rDocSh.GetMedium()->GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS )))
+ {
+ sAsciiOptions = pItem->GetValue();
+ }
+
+ const OUString sFindNm = OUString::createFromAscii(
+ pStream ? sDialogImpExtraData
+ : sDialogExpExtraData);
+ sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
+ if( -1 != nStt )
+ {
+ nStt += nDialogExtraDataLen;
+ sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose, nStt );
+ if( -1 != nEnd )
+ {
+ if(sAsciiOptions.isEmpty())
+ sAsciiOptions = m_sExtraData.copy(nStt, nEnd - nStt);
+ nStt -= nDialogExtraDataLen;
+ m_sExtraData = m_sExtraData.replaceAt(nStt, nEnd - nStt + 1, u"");
+ }
+ }
+ if(!sAsciiOptions.isEmpty())
+ aOpt.ReadUserData(sAsciiOptions);
+ }
+
+ // read the first chars and check the charset, (language - with L&H)
+ if( pStream )
+ {
+ char aBuffer[ 4098 ];
+ const sal_uInt64 nOldPos = pStream->Tell();
+ const size_t nBytesRead = pStream->ReadBytes(aBuffer, 4096);
+ pStream->Seek( nOldPos );
+
+ if( nBytesRead <= 4096 )
+ {
+ aBuffer[ nBytesRead ] = '0';
+ aBuffer[ nBytesRead+1 ] = '0';
+ }
+
+ bool bCR = false, bLF = false, bNullChar = false;
+ for( sal_uInt64 nCnt = 0; nCnt < nBytesRead; ++nCnt )
+ switch( aBuffer[ nCnt ] )
+ {
+ case 0x0: bNullChar = true; break;
+ case 0xA: bLF = true; break;
+ case 0xD: bCR = true; break;
+ case 0xC:
+ case 0x1A:
+ case 0x9: break;
+ default: break;
+ }
+
+ if( !bNullChar )
+ {
+ if( bCR )
+ {
+ if( bLF )
+ {
+ aOpt.SetParaFlags( LINEEND_CRLF );
+ }
+ else
+ {
+ aOpt.SetParaFlags( LINEEND_CR );
+ }
+ }
+ else if( bLF )
+ {
+ aOpt.SetParaFlags( LINEEND_LF );
+ }
+ }
+
+ const sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
+ SwDoc* pDoc = rDocSh.GetDoc();
+
+ // initialize language
+ {
+ if( !aOpt.GetLanguage() )
+ {
+ if(pDoc)
+ {
+ const TypedWhichId<SvxLanguageItem> nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
+ const SvxLanguageItem& rLangItem = pDoc->GetDefault( nWhich );
+ aOpt.SetLanguage( rLangItem.GetLanguage() );
+ }
+ else
+ {
+ SvtLinguOptions aLinguOpt;
+ SvtLinguConfig().GetOptions( aLinguOpt );
+ switch(nAppScriptType)
+ {
+ case css::i18n::ScriptType::ASIAN:
+ aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN));
+ break;
+ case css::i18n::ScriptType::COMPLEX:
+ aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX));
+ break;
+ //SvtScriptType::LATIN:
+ default:
+ aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN));
+ }
+ }
+ }
+
+ m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL, true );
+ m_xLanguageLB->set_active_id(aOpt.GetLanguage());
+ }
+
+ {
+ bool bDelPrinter = false;
+ VclPtr<SfxPrinter> pPrt = pDoc ? pDoc->getIDocumentDeviceAccess().getPrinter(false) : nullptr;
+ if( !pPrt )
+ {
+ auto pSet = std::make_unique<SfxItemSetFixed
+ <SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
+ SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC>>( rDocSh.GetPool() );
+ pPrt = VclPtr<SfxPrinter>::Create( std::move(pSet) );
+ bDelPrinter = true;
+ }
+
+ // get the set of distinct available family names
+ std::set< OUString > aFontNames;
+ int nFontNames = pPrt->GetFontFaceCollectionCount();
+ for( int i = 0; i < nFontNames; i++ )
+ {
+ FontMetric aFontMetric( pPrt->GetFontMetricFromCollection( i ) );
+ aFontNames.insert( aFontMetric.GetFamilyName() );
+ }
+
+ // insert into listbox
+ for( const auto& rFontName : aFontNames )
+ {
+ m_xFontLB->append_text(rFontName);
+ }
+
+ if( aOpt.GetFontName().isEmpty() )
+ {
+ LanguageType eLang = aOpt.GetLanguage();
+ vcl::Font aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED, eLang, GetDefaultFontFlags::OnlyOne, pPrt));
+ aOpt.SetFontName(aTmpFont.GetFamilyName());
+ }
+
+ m_xFontLB->set_active_text(aOpt.GetFontName());
+
+ if( bDelPrinter )
+ pPrt.disposeAndClear();
+ }
+
+ // hide the unused Controls for Export
+ m_xIncludeBOM_CB->hide();
+ }
+ else
+ {
+ // hide the unused Controls for Export
+ m_xFontFT->hide();
+ m_xFontLB->hide();
+ m_xLanguageFT->hide();
+ m_xLanguageLB->hide();
+
+
+ SetIncludeBOM(aOpt.GetIncludeBOM());
+ m_xIncludeBOM_CB->save_state();
+ }
+
+ // initialize character set
+ m_xCharSetLB->FillFromTextEncodingTable( pStream != nullptr );
+ m_xCharSetLB->SelectTextEncoding( aOpt.GetCharSet() );
+
+ m_xCharSetLB->connect_changed( LINK( this, SwAsciiFilterDlg, CharSetSelHdl ));
+ m_xCRLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
+ m_xLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
+ m_xCR_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
+
+ SetCRLF( aOpt.GetParaFlags() );
+
+ m_xCRLF_RB->save_state();
+ m_xLF_RB->save_state();
+ m_xCR_RB->save_state();
+
+ UpdateIncludeBOMSensitiveState();
+}
+
+SwAsciiFilterDlg::~SwAsciiFilterDlg()
+{
+ SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
+ aDlgOpt.SetUserItem("UserItem", uno::Any(m_sExtraData));
+}
+
+void SwAsciiFilterDlg::FillOptions( SwAsciiOptions& rOptions )
+{
+ sal_uLong nCCode = m_xCharSetLB->GetSelectTextEncoding();
+ OUString sFont;
+ LanguageType nLng = LANGUAGE_SYSTEM;
+ if (m_xFontLB->get_visible())
+ {
+ sFont = m_xFontLB->get_active_text();
+ nLng = m_xLanguageLB->get_active_id();
+ }
+
+ rOptions.SetFontName( sFont );
+ rOptions.SetCharSet( rtl_TextEncoding( nCCode ) );
+ rOptions.SetLanguage( nLng );
+ rOptions.SetParaFlags( GetCRLF() );
+ rOptions.SetIncludeBOM( GetIncludeBOM() );
+
+ // save the user settings
+ OUString sData;
+ rOptions.WriteUserData( sData );
+ if (sData.isEmpty())
+ return;
+
+ const OUString sFindNm = OUString::createFromAscii(
+ m_xFontLB->get_visible() ? sDialogImpExtraData
+ : sDialogExpExtraData);
+ sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
+ if( -1 != nStt )
+ {
+ // called twice, so remove "old" settings
+ sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose,
+ nStt + nDialogExtraDataLen );
+ if( -1 != nEnd )
+ m_sExtraData = m_sExtraData.replaceAt( nStt, nEnd - nStt + 1, u"" );
+ }
+ m_sExtraData += sFindNm + sData + OUStringChar(cDialogExtraDataClose);
+}
+
+void SwAsciiFilterDlg::SetCRLF( LineEnd eEnd )
+{
+ switch (eEnd)
+ {
+ case LINEEND_CR:
+ m_xCR_RB->set_active(true);
+ break;
+ case LINEEND_CRLF:
+ m_xCRLF_RB->set_active(true);
+ break;
+ case LINEEND_LF:
+ m_xLF_RB->set_active(true);
+ break;
+ }
+}
+
+LineEnd SwAsciiFilterDlg::GetCRLF() const
+{
+ LineEnd eEnd;
+ if(m_xCR_RB->get_active())
+ eEnd = LINEEND_CR;
+ else if (m_xLF_RB->get_active())
+ eEnd = LINEEND_LF;
+ else
+ eEnd = LINEEND_CRLF;
+ return eEnd;
+}
+
+void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM )
+{
+ m_xIncludeBOM_CB->set_state(bIncludeBOM ? TRISTATE_TRUE : TRISTATE_FALSE);
+}
+
+bool SwAsciiFilterDlg::GetIncludeBOM() const
+{
+ return m_xIncludeBOM_CB->get_state() != TRISTATE_FALSE;
+}
+
+void SwAsciiFilterDlg::UpdateIncludeBOMSensitiveState()
+{
+ if (!m_xIncludeBOM_CB->get_visible())
+ return;
+
+ switch (m_xCharSetLB->GetSelectTextEncoding())
+ {
+ case RTL_TEXTENCODING_UTF8:
+ case RTL_TEXTENCODING_UCS2:
+ m_xIncludeBOM_CB->set_sensitive(true);
+ break;
+ default:
+ m_xIncludeBOM_CB->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox&, void)
+{
+ LineEnd eOldEnd = GetCRLF();
+ std::optional<LineEnd> eEnd;
+ LanguageType nLng = m_xFontLB->get_visible()
+ ? m_xLanguageLB->get_active_id()
+ : LANGUAGE_SYSTEM,
+ nOldLng = nLng;
+
+ rtl_TextEncoding nChrSet = m_xCharSetLB->GetSelectTextEncoding();
+ if( nChrSet == osl_getThreadTextEncoding() )
+ eEnd = GetSystemLineEnd();
+ else
+ {
+ switch( nChrSet )
+ {
+ case RTL_TEXTENCODING_MS_1252:
+#ifdef UNX
+ eEnd = LINEEND_LF;
+#else
+ eEnd = LINEEND_CRLF; // ANSI
+#endif
+ break;
+
+ case RTL_TEXTENCODING_APPLE_ROMAN: // MAC
+ eEnd = LINEEND_CR;
+ break;
+
+ case RTL_TEXTENCODING_IBM_850: // DOS
+ eEnd = LINEEND_CRLF;
+ break;
+
+ case RTL_TEXTENCODING_APPLE_ARABIC:
+ case RTL_TEXTENCODING_APPLE_CENTEURO:
+ case RTL_TEXTENCODING_APPLE_CROATIAN:
+ case RTL_TEXTENCODING_APPLE_CYRILLIC:
+ case RTL_TEXTENCODING_APPLE_DEVANAGARI:
+ case RTL_TEXTENCODING_APPLE_FARSI:
+ case RTL_TEXTENCODING_APPLE_GREEK:
+ case RTL_TEXTENCODING_APPLE_GUJARATI:
+ case RTL_TEXTENCODING_APPLE_GURMUKHI:
+ case RTL_TEXTENCODING_APPLE_HEBREW:
+ case RTL_TEXTENCODING_APPLE_ICELAND:
+ case RTL_TEXTENCODING_APPLE_ROMANIAN:
+ case RTL_TEXTENCODING_APPLE_THAI:
+ case RTL_TEXTENCODING_APPLE_TURKISH:
+ case RTL_TEXTENCODING_APPLE_UKRAINIAN:
+ case RTL_TEXTENCODING_APPLE_CHINSIMP:
+ case RTL_TEXTENCODING_APPLE_CHINTRAD:
+ case RTL_TEXTENCODING_APPLE_JAPANESE:
+ case RTL_TEXTENCODING_APPLE_KOREAN:
+ eEnd = LINEEND_CR;
+ break;
+ }
+ }
+
+ m_bSaveLineStatus = false;
+ if( eEnd ) // changed?
+ {
+ if( eOldEnd != *eEnd )
+ SetCRLF( *eEnd );
+ }
+ else
+ {
+ // restore old user choice (not the automatic!)
+ m_xCRLF_RB->set_state(m_xCRLF_RB->get_saved_state());
+ m_xCR_RB->set_state(m_xCR_RB->get_saved_state());
+ m_xLF_RB->set_state(m_xLF_RB->get_saved_state());
+ }
+ m_bSaveLineStatus = true;
+
+ if (nOldLng != nLng && m_xFontLB->get_visible())
+ m_xLanguageLB->set_active_id(nLng);
+
+ UpdateIncludeBOMSensitiveState();
+}
+
+IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::Toggleable&, rBtn, void)
+{
+ if (m_bSaveLineStatus)
+ rBtn.save_state();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/docstdlg.cxx b/sw/source/ui/dialog/docstdlg.cxx
new file mode 100644
index 0000000000..1b300206fc
--- /dev/null
+++ b/sw/source/ui/dialog/docstdlg.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 <swwait.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <pview.hxx>
+#include <doc.hxx>
+#include <docstdlg.hxx>
+#include <IDocumentStatistics.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/diagnose.h>
+
+std::unique_ptr<SfxTabPage> SwDocStatPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwDocStatPage>(pPage, pController, *rSet);
+}
+
+SwDocStatPage::SwDocStatPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/statisticsinfopage.ui", "StatisticsInfoPage", &rSet)
+ , m_xPageNo(m_xBuilder->weld_label("nopages"))
+ , m_xTableNo(m_xBuilder->weld_label("notables"))
+ , m_xGrfNo(m_xBuilder->weld_label("nogrfs"))
+ , m_xOLENo(m_xBuilder->weld_label("nooles"))
+ , m_xParaNo(m_xBuilder->weld_label("noparas"))
+ , m_xWordNo(m_xBuilder->weld_label("nowords"))
+ , m_xCharNo(m_xBuilder->weld_label("nochars"))
+ , m_xCharExclSpacesNo(m_xBuilder->weld_label("nocharsexspaces"))
+ , m_xLineLbl(m_xBuilder->weld_label("lineft"))
+ , m_xLineNo(m_xBuilder->weld_label("nolines"))
+ , m_xUpdatePB(m_xBuilder->weld_button("update"))
+{
+ Update();
+ m_xUpdatePB->connect_clicked(LINK(this, SwDocStatPage, UpdateHdl));
+ //#111684# is the current view a page preview no SwFEShell can be found -> hide the update button
+ SwDocShell* pDocShell = static_cast<SwDocShell*>( SfxObjectShell::Current() );
+ SwFEShell* pFEShell = pDocShell ? pDocShell->GetFEShell() : nullptr;
+ if(!pFEShell)
+ {
+ m_xUpdatePB->hide();
+ m_xLineLbl->hide();
+ m_xLineNo->hide();
+ }
+}
+
+SwDocStatPage::~SwDocStatPage()
+{
+}
+
+// Description: fill ItemSet when changed
+bool SwDocStatPage::FillItemSet(SfxItemSet * /*rSet*/)
+{
+ return false;
+}
+
+void SwDocStatPage::Reset(const SfxItemSet *)
+{
+}
+
+// Description: update / set data
+void SwDocStatPage::SetData(const SwDocStat &rStat)
+{
+ const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper();
+ m_xTableNo->set_label(rLocaleData.getNum(rStat.nTable, 0));
+ m_xGrfNo->set_label(rLocaleData.getNum(rStat.nGrf, 0));
+ m_xOLENo->set_label(rLocaleData.getNum(rStat.nOLE, 0));
+ m_xPageNo->set_label(rLocaleData.getNum(rStat.nPage, 0));
+ m_xParaNo->set_label(rLocaleData.getNum(rStat.nPara, 0));
+ m_xWordNo->set_label(rLocaleData.getNum(rStat.nWord, 0));
+ m_xCharNo->set_label(rLocaleData.getNum(rStat.nChar, 0));
+ m_xCharExclSpacesNo->set_label(rLocaleData.getNum(rStat.nCharExcludingSpaces, 0));
+}
+
+// Description: update statistics
+void SwDocStatPage::Update()
+{
+ SfxViewShell *pVSh = SfxViewShell::Current();
+ SwViewShell *pSh = nullptr;
+ if ( auto pSwView = dynamic_cast<SwView *>( pVSh ) )
+ pSh = pSwView->GetWrtShellPtr();
+ else if ( auto pPagePreview = dynamic_cast<SwPagePreview *>( pVSh ) )
+ pSh = pPagePreview->GetViewShell();
+
+ OSL_ENSURE( pSh, "Shell not found" );
+
+ if (!pSh)
+ return;
+
+ SwWait aWait( *pSh->GetDoc()->GetDocShell(), true );
+ pSh->StartAction();
+ m_aDocStat = pSh->GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( false, true );
+ pSh->EndAction();
+
+ SetData(m_aDocStat);
+}
+
+IMPL_LINK_NOARG(SwDocStatPage, UpdateHdl, weld::Button&, void)
+{
+ Update();
+ SwDocShell* pDocShell = static_cast<SwDocShell*>( SfxObjectShell::Current());
+ SwFEShell* pFEShell = pDocShell ? pDocShell->GetFEShell() : nullptr;
+ if (pFEShell)
+ {
+ const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper();
+ OUString sLineCount = rLocaleData.getNum(pFEShell->GetLineCount(), 0);
+ m_xLineNo->set_label(sLineCount);
+ m_xLineNo->set_size_request(m_xLineNo->get_approximate_digit_width() * sLineCount.getLength(), -1);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/macassgn.cxx b/sw/source/ui/dialog/macassgn.cxx
new file mode 100644
index 0000000000..375b1aca4f
--- /dev/null
+++ b/sw/source/ui/dialog/macassgn.cxx
@@ -0,0 +1,132 @@
+/* -*- 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 <hintids.hxx>
+
+#include <sfx2/htmlmode.hxx>
+#include <svx/svxids.hrc>
+#include <svl/macitem.hxx>
+
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <viewopt.hxx>
+#include <macassgn.hxx>
+#include <docsh.hxx>
+#include <strings.hrc>
+#include <view.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <svx/svxdlg.hxx>
+
+
+SfxEventNamesItem SwMacroAssignDlg::AddEvents( DlgEventType eType )
+{
+ SfxEventNamesItem aItem(SID_EVENTCONFIG);
+
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ bool bHtmlMode = nHtmlMode & HTMLMODE_ON;
+
+ switch( eType )
+ {
+ case MACASSGN_AUTOTEXT:
+ aItem.AddEvent( SwResId(STR_EVENT_START_INS_GLOSSARY), OUString(),
+ SvMacroItemId::SwStartInsGlossary );
+ aItem.AddEvent( SwResId(STR_EVENT_END_INS_GLOSSARY), OUString(),
+ SvMacroItemId::SwEndInsGlossary);
+ // in order for the new handler to become active!
+ break;
+ case MACASSGN_ALLFRM:
+ case MACASSGN_GRAPHIC: // graphics
+ {
+ aItem.AddEvent( SwResId(STR_EVENT_IMAGE_ERROR), OUString(),
+ SvMacroItemId::OnImageLoadError);
+ aItem.AddEvent( SwResId(STR_EVENT_IMAGE_ABORT), OUString(),
+ SvMacroItemId::OnImageLoadCancel);
+ aItem.AddEvent( SwResId(STR_EVENT_IMAGE_LOAD), OUString(),
+ SvMacroItemId::OnImageLoadDone);
+ }
+ [[fallthrough]];
+ case MACASSGN_FRMURL: // Frame - URL-Attributes
+ {
+ if( !bHtmlMode &&
+ (MACASSGN_FRMURL == eType || MACASSGN_ALLFRM == eType))
+ {
+ aItem.AddEvent( SwResId( STR_EVENT_FRM_KEYINPUT_A ), OUString(),
+ SvMacroItemId::SwFrmKeyInputAlpha );
+ aItem.AddEvent( SwResId( STR_EVENT_FRM_KEYINPUT_NOA ), OUString(),
+ SvMacroItemId::SwFrmKeyInputNoAlpha );
+ aItem.AddEvent( SwResId( STR_EVENT_FRM_RESIZE ), OUString(),
+ SvMacroItemId::SwFrmResize );
+ aItem.AddEvent( SwResId( STR_EVENT_FRM_MOVE ), OUString(),
+ SvMacroItemId::SwFrmMove );
+ }
+ }
+ [[fallthrough]];
+ case MACASSGN_OLE: // OLE
+ {
+ if( !bHtmlMode )
+ aItem.AddEvent( SwResId(STR_EVENT_OBJECT_SELECT), OUString(),
+ SvMacroItemId::SwObjectSelect );
+ }
+ [[fallthrough]];
+ case MACASSGN_INETFMT: // INetFormat-Attributes
+ {
+ aItem.AddEvent( SwResId(STR_EVENT_MOUSEOVER_OBJECT), OUString(),
+ SvMacroItemId::OnMouseOver );
+ aItem.AddEvent( SwResId(STR_EVENT_MOUSECLICK_OBJECT), OUString(),
+ SvMacroItemId::OnClick);
+ aItem.AddEvent( SwResId(STR_EVENT_MOUSEOUT_OBJECT), OUString(),
+ SvMacroItemId::OnMouseOut);
+ }
+ break;
+ }
+
+ return aItem;
+}
+
+bool SwMacroAssignDlg::INetFormatDlg(weld::Window* pParent, SwWrtShell& rSh,
+ std::optional<SvxMacroTableDtor>& rpINetItem )
+{
+ bool bRet = false;
+ SfxItemSetFixed<RES_FRMMACRO, RES_FRMMACRO, SID_EVENTCONFIG, SID_EVENTCONFIG> aSet( rSh.GetAttrPool() );
+ SvxMacroItem aItem( RES_FRMMACRO );
+ if( !rpINetItem )
+ rpINetItem.emplace();
+ else
+ aItem.SetMacroTable( *rpINetItem );
+
+ aSet.Put( aItem );
+ aSet.Put( AddEvents( MACASSGN_INETFMT ) );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pMacroDlg( pFact->CreateEventConfigDialog(pParent, aSet,
+ rSh.GetView().GetViewFrame().GetFrame().GetFrameInterface() ) );
+ if ( pMacroDlg && pMacroDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pMacroDlg->GetOutputItemSet();
+ if( const SvxMacroItem* pItem = pOutSet->GetItemIfSet( RES_FRMMACRO, false ))
+ {
+ rpINetItem.emplace(pItem->GetMacroTable());
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx
new file mode 100644
index 0000000000..daf0dd6ff3
--- /dev/null
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -0,0 +1,1430 @@
+/* -*- 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 <config_fuzzers.h>
+#include <config_wasm_strip.h>
+
+#include "swdlgfact.hxx"
+#include <svl/style.hxx>
+#include <globals.hrc>
+
+#include <wordcountdialog.hxx>
+#include <abstract.hxx>
+#include <addrdlg.hxx>
+#include <ascfldlg.hxx>
+#include <bookmark.hxx>
+#include <break.hxx>
+#include <changedb.hxx>
+#include <chrdlg.hxx>
+#include <colwd.hxx>
+#include <contentcontroldlg.hxx>
+#include <contentcontrollistitemdlg.hxx>
+#include <pagenumberdlg.hxx>
+#include <convert.hxx>
+#include <cption.hxx>
+#include <dbinsdlg.hxx>
+#include <docfnote.hxx>
+#include <docstdlg.hxx>
+#include <DateFormFieldDialog.hxx>
+#include <DropDownFieldDialog.hxx>
+#include <DropDownFormFieldDialog.hxx>
+#include <envlop.hxx>
+#include <label.hxx>
+#include <drpcps.hxx>
+#include <swuipardlg.hxx>
+#include <pattern.hxx>
+#include <pardlg.hxx>
+#include <rowht.hxx>
+#include <selglos.hxx>
+#include <splittbl.hxx>
+#include <srtdlg.hxx>
+#include <tautofmt.hxx>
+#include <tblnumfm.hxx>
+#include <wrap.hxx>
+#include <tabledlg.hxx>
+#include <fldtdlg.hxx>
+#include <fldedt.hxx>
+#include <swrenamexnameddlg.hxx>
+#include <swmodalredlineacceptdlg.hxx>
+#include <frmdlg.hxx>
+#include <tmpdlg.hxx>
+#include <glossary.hxx>
+#include <inpdlg.hxx>
+#include <insfnote.hxx>
+#include <instable.hxx>
+#include <javaedit.hxx>
+#include <linenum.hxx>
+#include <titlepage.hxx>
+#include <mailmrge.hxx>
+#include <mergetbl.hxx>
+#include <multmrk.hxx>
+#include <num.hxx>
+#include <outline.hxx>
+#include <column.hxx>
+#include <cnttab.hxx>
+#include <swuicnttab.hxx>
+#include <regionsw.hxx>
+#include <optcomp.hxx>
+#include <optload.hxx>
+#include <optpage.hxx>
+#include <swuiidxmrk.hxx>
+#include <svx/dialogs.hrc>
+#include <mailmergewizard.hxx>
+#include <mailconfigpage.hxx>
+#include <uiborder.hxx>
+#include <mmresultdialogs.hxx>
+#include <formatlinebreak.hxx>
+#include <translatelangselect.hxx>
+
+using namespace ::com::sun::star;
+using namespace css::frame;
+using namespace css::uno;
+
+short AbstractSwWordCountFloatDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwInsertAbstractDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short SwAbstractSfxController_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractNumFormatDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractNumFormatDlg_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxSingleTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSwAsciiFilterDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSplitTableDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSplitTableDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return weld::GenericDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSwTableWidthDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwTableHeightDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwMergeTableDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwPageNumberDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSwPageNumberDlg_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return weld::GenericDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractGenericDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractGenericDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return weld::GenericDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSwSortDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractMultiTOXMarkDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractTabController_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractNumBulletDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwConvertTableDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwInsertDBColAutoPilot_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractDropDownFieldDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractDropDownFormFieldDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractDateFormFieldDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwLabDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwSelGlossaryDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwAutoFormatDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwFieldDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwRenameXNamedDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSwContentControlListItemDlg_Impl::StartExecuteAsync(VclAbstractDialog::AsyncContext& rCtx)
+{
+ return weld::DialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSwContentControlListItemDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSwModalRedlineAcceptDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractGlossaryDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractFieldInputDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractInsFootNoteDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractJavaEditDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractMailMergeDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractMailMergeCreateFromDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractMailMergeFieldConnectionsDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractMultiTOXTabDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractMultiTOXTabDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractEditRegionDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractInsertSectionTabDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractInsertSectionTabDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractIndexMarkFloatDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractAuthMarkFloatDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+void AbstractTabController_Impl::SetCurPageId( const OUString &rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractTabController_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer AbstractTabController_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractTabController_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+bool AbstractTabController_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+//From class Window.
+void AbstractTabController_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractNumBulletDialog_Impl::SetCurPageId( const OUString &rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractNumBulletDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+const SfxItemSet* AbstractNumBulletDialog_Impl::GetInputItemSet() const
+{
+ return m_xDlg->GetInputItemSet();
+}
+
+WhichRangesContainer AbstractNumBulletDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractNumBulletDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+bool AbstractNumBulletDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+//From class Window.
+void AbstractNumBulletDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+IMPL_LINK_NOARG(AbstractApplyTabController_Impl, ApplyHdl, weld::Button&, void)
+{
+ if (m_xDlg->Apply())
+ {
+ m_aHandler.Call(nullptr);
+ m_xDlg->Applied();
+ }
+}
+
+void AbstractApplyTabController_Impl::SetApplyHdl( const Link<LinkParamNone*,void>& rLink )
+{
+ m_aHandler = rLink;
+ m_xDlg->SetApplyHandler(LINK(this, AbstractApplyTabController_Impl, ApplyHdl));
+}
+
+sal_uInt8 AbstractSwInsertAbstractDlg_Impl::GetLevel() const
+{
+ return m_xDlg->GetLevel();
+}
+
+sal_uInt8 AbstractSwInsertAbstractDlg_Impl::GetPara() const
+{
+ return m_xDlg->GetPara();
+}
+
+const SfxItemSet* SwAbstractSfxController_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+const SfxItemSet* AbstractNumFormatDlg_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void SwAbstractSfxController_Impl::SetText(const OUString& rStr)
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractNumFormatDlg_Impl::SetText(const OUString& rStr)
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSwAsciiFilterDlg_Impl::FillOptions( SwAsciiOptions& rOptions )
+{
+ m_xDlg->FillOptions(rOptions);
+}
+
+SplitTable_HeadlineOption AbstractSplitTableDialog_Impl::GetSplitMode()
+{
+ return m_xDlg->GetSplitMode();
+}
+
+OUString AbstractSwBreakDlg_Impl::GetTemplateName()
+{
+ SwBreakDlg* pDlg = dynamic_cast<SwBreakDlg*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->GetTemplateName();
+
+ return "";
+}
+
+sal_uInt16 AbstractSwBreakDlg_Impl:: GetKind()
+{
+ SwBreakDlg* pDlg = dynamic_cast<SwBreakDlg*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->GetKind();
+
+ return 0;
+}
+
+::std::optional<sal_uInt16> AbstractSwBreakDlg_Impl:: GetPageNumber()
+{
+ SwBreakDlg* pDlg = dynamic_cast<SwBreakDlg*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->GetPageNumber();
+
+ return 0;
+}
+
+std::optional<SwLineBreakClear> AbstractSwBreakDlg_Impl::GetClear()
+{
+ SwBreakDlg* pDlg = dynamic_cast<SwBreakDlg*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->GetClear();
+
+ return SwLineBreakClear::NONE;
+}
+
+void AbstractSwConvertTableDlg_Impl::GetValues( sal_Unicode& rDelim,SwInsertTableOptions& rInsTableFlags,
+ SwTableAutoFormat const*& prTAFormat)
+{
+ m_xDlg->GetValues(rDelim,rInsTableFlags, prTAFormat);
+}
+
+void AbstractSwInsertDBColAutoPilot_Impl::DataToDoc( const uno::Sequence< uno::Any >& rSelection,
+ uno::Reference< sdbc::XDataSource> rxSource,
+ uno::Reference< sdbc::XConnection> xConnection,
+ uno::Reference< sdbc::XResultSet > xResultSet)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ m_xDlg->DataToDoc(rSelection, rxSource, xConnection, xResultSet);
+#else
+ (void) rSelection;
+ (void) rxSource;
+ (void) xConnection;
+ (void) xResultSet;
+#endif
+}
+
+bool AbstractDropDownFieldDialog_Impl::PrevButtonPressed() const
+{
+ return m_xDlg->PrevButtonPressed();
+}
+
+bool AbstractDropDownFieldDialog_Impl::NextButtonPressed() const
+{
+ return m_xDlg->NextButtonPressed();
+}
+
+void AbstractSwLabDlg_Impl::SetCurPageId( const OUString &rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractSwLabDlg_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer AbstractSwLabDlg_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSwLabDlg_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+void AbstractSwLabDlg_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+const OUString& AbstractSwLabDlg_Impl::GetBusinessCardStr() const
+{
+ return m_xDlg->GetBusinessCardStr();
+}
+
+Printer * AbstractSwLabDlg_Impl::GetPrt()
+{
+ return m_xDlg->GetPrt();
+}
+
+void AbstractSwSelGlossaryDlg_Impl::InsertGlos(const OUString &rRegion, const OUString &rGlosName)
+{
+ m_xDlg->InsertGlos( rRegion, rGlosName );
+}
+
+sal_Int32 AbstractSwSelGlossaryDlg_Impl::GetSelectedIdx() const
+{
+ return m_xDlg->GetSelectedIdx();
+}
+
+void AbstractSwSelGlossaryDlg_Impl::SelectEntryPos(sal_Int32 nIdx)
+{
+ m_xDlg->SelectEntryPos( nIdx );
+}
+
+std::unique_ptr<SwTableAutoFormat> AbstractSwAutoFormatDlg_Impl::FillAutoFormatOfIndex() const
+{
+ return m_xDlg->FillAutoFormatOfIndex();
+}
+
+void AbstractSwFieldDlg_Impl::SetCurPageId( const OUString &rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractSwFieldDlg_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+WhichRangesContainer AbstractSwFieldDlg_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSwFieldDlg_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+void AbstractSwFieldDlg_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+bool AbstractSwFieldDlg_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ auto xDlg = m_xDlg;
+ return SfxTabDialogController::runAsync(m_xDlg, [=](sal_Int32 nResult){
+ xDlg->Close();
+ if (rCtx.isSet())
+ rCtx.maEndDialogFn(nResult);
+ });
+}
+
+void AbstractSwFieldDlg_Impl::Initialize(SfxChildWinInfo *pInfo)
+{
+ m_xDlg->Initialize( pInfo );
+}
+
+void AbstractSwFieldDlg_Impl::ReInitDlg()
+{
+ m_xDlg->ReInitDlg();
+}
+
+void AbstractSwFieldDlg_Impl::ActivateDatabasePage()
+{
+ m_xDlg->ActivateDatabasePage();
+}
+
+void AbstractSwFieldDlg_Impl::ShowReferencePage()
+{
+ m_xDlg->ShowReferencePage();
+}
+
+std::shared_ptr<SfxDialogController> AbstractSwFieldDlg_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+void AbstractSwRenameXNamedDlg_Impl::SetForbiddenChars( const OUString& rSet )
+{
+ m_xDlg->SetForbiddenChars( rSet );
+}
+
+void AbstractSwRenameXNamedDlg_Impl::SetAlternativeAccess(
+ css::uno::Reference< css::container::XNameAccess > & xSecond,
+ css::uno::Reference< css::container::XNameAccess > & xThird )
+{
+ m_xDlg->SetAlternativeAccess( xSecond, xThird);
+}
+
+OUString AbstractGlossaryDlg_Impl::GetCurrGrpName() const
+{
+ return m_xDlg->GetCurrGrpName();
+}
+
+OUString AbstractGlossaryDlg_Impl::GetCurrShortName() const
+{
+ return m_xDlg->GetCurrShortName();
+}
+
+void AbstractFieldInputDlg_Impl::EndDialog(sal_Int32 n)
+{
+ m_xDlg->response(n);
+}
+
+bool AbstractFieldInputDlg_Impl::PrevButtonPressed() const
+{
+ return m_xDlg->PrevButtonPressed();
+}
+
+bool AbstractFieldInputDlg_Impl::NextButtonPressed() const
+{
+ return m_xDlg->NextButtonPressed();
+}
+
+OUString AbstractInsFootNoteDlg_Impl::GetFontName()
+{
+ return m_xDlg->GetFontName();
+}
+
+int AbstractSwPageNumberDlg_Impl::GetPageNumberPosition() const
+{
+ return m_xDlg->GetPageNumberPosition();
+}
+
+int AbstractSwPageNumberDlg_Impl::GetPageNumberAlignment() const
+{
+ return m_xDlg->GetPageNumberAlignment();
+}
+
+bool AbstractSwPageNumberDlg_Impl::GetMirrorOnEvenPages() const
+{
+ return m_xDlg->GetMirrorOnEvenPages();
+}
+
+bool AbstractSwPageNumberDlg_Impl::GetIncludePageTotal() const
+{
+ return m_xDlg->GetIncludePageTotal();
+}
+
+SvxNumType AbstractSwPageNumberDlg_Impl::GetPageNumberType() const
+{
+ return m_xDlg->GetPageNumberType();
+}
+
+void AbstractSwPageNumberDlg_Impl::SetPageNumberType(SvxNumType nSet)
+{
+ m_xDlg->SetPageNumberType(nSet);
+}
+
+bool AbstractInsFootNoteDlg_Impl::IsEndNote()
+{
+ return m_xDlg->IsEndNote();
+}
+
+OUString AbstractInsFootNoteDlg_Impl::GetStr()
+{
+ return m_xDlg->GetStr();
+}
+
+void AbstractInsFootNoteDlg_Impl::SetHelpId(const OUString& rHelpId)
+{
+ m_xDlg->set_help_id(rHelpId);
+}
+
+void AbstractInsFootNoteDlg_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractInsTableDlg_Impl::GetValues( OUString& rName, sal_uInt16& rRow, sal_uInt16& rCol,
+ SwInsertTableOptions& rInsTableFlags, OUString& rTableAutoFormatName,
+ std::unique_ptr<SwTableAutoFormat>& prTAFormat )
+{
+ SwInsTableDlg* pDlg = dynamic_cast<SwInsTableDlg*>(m_xDlg.get());
+ if (pDlg)
+ pDlg->GetValues(rName, rRow, rCol, rInsTableFlags, rTableAutoFormatName, prTAFormat);
+}
+
+OUString AbstractJavaEditDialog_Impl::GetScriptText() const
+{
+ return m_xDlg->GetScriptText();
+}
+
+OUString AbstractJavaEditDialog_Impl::GetScriptType() const
+{
+ return m_xDlg->GetScriptType();
+}
+
+bool AbstractJavaEditDialog_Impl::IsUrl() const
+{
+ return m_xDlg->IsUrl();
+}
+
+bool AbstractJavaEditDialog_Impl::IsNew() const
+{
+ return m_xDlg->IsNew();
+}
+
+bool AbstractJavaEditDialog_Impl::IsUpdate() const
+{
+ return m_xDlg->IsUpdate();
+}
+
+DBManagerOptions AbstractMailMergeDlg_Impl::GetMergeType()
+{
+ return m_xDlg->GetMergeType();
+}
+
+const OUString& AbstractMailMergeDlg_Impl::GetSaveFilter() const
+{
+ return m_xDlg->GetSaveFilter();
+}
+
+css::uno::Sequence< css::uno::Any > AbstractMailMergeDlg_Impl::GetSelection() const
+{
+ return m_xDlg->GetSelection();
+}
+
+uno::Reference< sdbc::XResultSet> AbstractMailMergeDlg_Impl::GetResultSet() const
+{
+ return m_xDlg->GetResultSet();
+}
+
+bool AbstractMailMergeDlg_Impl::IsSaveSingleDoc() const
+{
+ return m_xDlg->IsSaveSingleDoc();
+}
+
+bool AbstractMailMergeDlg_Impl::IsGenerateFromDataBase() const
+{
+ return m_xDlg->IsGenerateFromDataBase();
+}
+
+bool AbstractMailMergeDlg_Impl::IsFileEncryptedFromDataBase() const
+{
+ return m_xDlg->IsFileEncryptedFromDataBase();
+}
+
+OUString AbstractMailMergeDlg_Impl::GetColumnName() const
+{
+ return m_xDlg->GetColumnName();
+}
+
+OUString AbstractMailMergeDlg_Impl::GetPasswordColumnName() const
+{
+ return m_xDlg->GetPasswordColumnName();
+}
+
+OUString AbstractMailMergeDlg_Impl::GetTargetURL() const
+{
+ return m_xDlg->GetTargetURL();
+}
+
+bool AbstractMailMergeCreateFromDlg_Impl::IsThisDocument() const
+{
+ return m_xDlg->IsThisDocument();
+}
+
+bool AbstractMailMergeFieldConnectionsDlg_Impl::IsUseExistingConnections() const
+{
+ return m_xDlg->IsUseExistingConnections();
+}
+
+CurTOXType AbstractMultiTOXTabDialog_Impl::GetCurrentTOXType() const
+{
+ return m_xDlg->GetCurrentTOXType();
+}
+
+SwTOXDescription& AbstractMultiTOXTabDialog_Impl::GetTOXDescription(CurTOXType eTOXTypes)
+{
+ return m_xDlg->GetTOXDescription(eTOXTypes);
+}
+
+const SfxItemSet* AbstractMultiTOXTabDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractEditRegionDlg_Impl::SelectSection(const OUString& rSectionName)
+{
+ m_xDlg->SelectSection(rSectionName);
+}
+
+void
+AbstractInsertSectionTabDialog_Impl::SetSectionData(SwSectionData const& rSect)
+{
+ m_xDlg->SetSectionData(rSect);
+}
+
+void AbstractIndexMarkFloatDlg_Impl::ReInitDlg(SwWrtShell& rWrtShell)
+{
+ m_xDlg->ReInitDlg( rWrtShell);
+}
+
+std::shared_ptr<SfxDialogController> AbstractIndexMarkFloatDlg_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+void AbstractAuthMarkFloatDlg_Impl::ReInitDlg(SwWrtShell& rWrtShell)
+{
+ m_xDlg->ReInitDlg(rWrtShell);
+}
+
+std::shared_ptr<SfxDialogController> AbstractAuthMarkFloatDlg_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+std::shared_ptr<SfxDialogController> AbstractSwWordCountFloatDlg_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+void AbstractSwWordCountFloatDlg_Impl::UpdateCounts()
+{
+ m_xDlg->UpdateCounts();
+}
+
+void AbstractSwWordCountFloatDlg_Impl::SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat)
+{
+ m_xDlg->SetCounts(rCurrCnt, rDocStat);
+}
+
+AbstractMailMergeWizard_Impl::~AbstractMailMergeWizard_Impl()
+{
+}
+
+bool AbstractMailMergeWizard_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ // SwMailMergeWizardExecutor wants to run the lifecycle of this dialog
+ // so clear mxOwner here and leave it up to SwMailMergeWizardExecutor
+ rCtx.mxOwner.clear();
+ return weld::GenericDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractMailMergeWizard_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+OUString AbstractMailMergeWizard_Impl::GetReloadDocument() const
+{
+ return m_xDlg->GetReloadDocument();
+}
+
+void AbstractMailMergeWizard_Impl::ShowPage( sal_uInt16 nLevel )
+{
+ m_xDlg->skipUntil(nLevel);
+}
+
+sal_uInt16 AbstractMailMergeWizard_Impl::GetRestartPage() const
+{
+ return m_xDlg->GetRestartPage();
+}
+
+std::optional<SwLanguageListItem> AbstractSwTranslateLangSelectDlg_Impl::GetSelectedLanguage()
+{
+#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+ return SwTranslateLangSelectDlg::GetSelectedLanguage();
+#else
+ return {};
+#endif
+}
+
+VclPtr<AbstractSwInsertAbstractDlg> SwAbstractDialogFactory_Impl::CreateSwInsertAbstractDlg(weld::Window* pParent)
+{
+ return VclPtr<AbstractSwInsertAbstractDlg_Impl>::Create(std::make_unique<SwInsertAbstractDlg>(pParent));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwAddressAbstractDlg(weld::Window* pParent,
+ const SfxItemSet& rSet)
+{
+ return VclPtr<SwAbstractSfxController_Impl>::Create(std::make_unique<SwAddrDlg>(pParent, rSet));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwDropCapsDialog(weld::Window* pParent,
+ const SfxItemSet& rSet)
+{
+ return VclPtr<SwAbstractSfxController_Impl>::Create(std::make_unique<SwDropCapsDlg>(pParent, rSet));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwBackgroundDialog(weld::Window* pParent,
+ const SfxItemSet& rSet)
+{
+ return VclPtr<SwAbstractSfxController_Impl>::Create(std::make_unique<SwBackgroundDlg>(pParent, rSet));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateNumFormatDialog(weld::Widget* pParent, const SfxItemSet& rSet)
+{
+ return VclPtr<AbstractNumFormatDlg_Impl>::Create(std::make_shared<SwNumFormatDlg>(pParent, rSet));
+}
+
+VclPtr<AbstractSwAsciiFilterDlg> SwAbstractDialogFactory_Impl::CreateSwAsciiFilterDlg(weld::Window* pParent,
+ SwDocShell& rDocSh, SvStream* pStream)
+{
+ return VclPtr<AbstractSwAsciiFilterDlg_Impl>::Create(std::make_unique<SwAsciiFilterDlg>(pParent, rDocSh, pStream));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwInsertBookmarkDlg(weld::Window *pParent,
+ SwWrtShell &rSh, OUString const*const pSelected)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwInsertBookmarkDlg>(pParent, rSh, pSelected));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwContentControlDlg(weld::Window* pParent,
+ SwWrtShell &rSh)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwContentControlDlg>(pParent, rSh));
+}
+
+VclPtr<AbstractSwContentControlListItemDlg>
+SwAbstractDialogFactory_Impl::CreateSwContentControlListItemDlg(weld::Window* pParent,
+ SwContentControlListItem& rItem)
+{
+ return VclPtr<AbstractSwContentControlListItemDlg_Impl>::Create(
+ std::make_shared<SwContentControlListItemDlg>(pParent, rItem));
+}
+
+std::shared_ptr<AbstractSwBreakDlg> SwAbstractDialogFactory_Impl::CreateSwBreakDlg(weld::Window* pParent, SwWrtShell &rSh)
+{
+ return std::make_shared<AbstractSwBreakDlg_Impl>(std::make_unique<SwBreakDlg>(pParent, rSh));
+}
+
+std::shared_ptr<AbstractSwTranslateLangSelectDlg> SwAbstractDialogFactory_Impl::CreateSwTranslateLangSelectDlg(weld::Window* pParent, SwWrtShell &rSh)
+{
+#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
+ return std::make_shared<AbstractSwTranslateLangSelectDlg_Impl>(std::make_unique<SwTranslateLangSelectDlg>(pParent, rSh));
+#else
+ (void) pParent;
+ (void) rSh;
+ return nullptr;
+#endif
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwChangeDBDlg(SwView& rVw)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwChangeDBDlg>(rVw));
+#else
+ (void) rVw;
+ return nullptr;
+#endif
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateSwCharDlg(weld::Window* pParent, SwView& pVw,
+ const SfxItemSet& rCoreSet, SwCharDlgMode nDialogMode, const OUString* pFormatStr)
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwCharDlg>(pParent, pVw, rCoreSet, nDialogMode, pFormatStr));
+}
+
+VclPtr<AbstractSwConvertTableDlg> SwAbstractDialogFactory_Impl::CreateSwConvertTableDlg(SwView& rView, bool bToTable)
+{
+ return VclPtr<AbstractSwConvertTableDlg_Impl>::Create(std::make_unique<SwConvertTableDlg>(rView, bToTable));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwCaptionDialog(weld::Window *pParent, SwView &rV)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwCaptionDialog>(pParent, rV));
+}
+
+VclPtr<AbstractSwInsertDBColAutoPilot> SwAbstractDialogFactory_Impl::CreateSwInsertDBColAutoPilot( SwView& rView,
+ uno::Reference< sdbc::XDataSource> rxSource,
+ uno::Reference<sdbcx::XColumnsSupplier> xColSupp,
+ const SwDBData& rData)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ return VclPtr<AbstractSwInsertDBColAutoPilot_Impl>::Create(std::make_unique<SwInsertDBColAutoPilot>(rView, rxSource, xColSupp, rData));
+#else
+ (void) rView;
+ (void) rxSource;
+ (void) xColSupp;
+ (void) rData;
+ return nullptr;
+#endif
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateSwFootNoteOptionDlg(weld::Window *pParent, SwWrtShell &rSh)
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwFootNoteOptionDlg>(pParent, rSh));
+}
+
+VclPtr<AbstractDropDownFieldDialog> SwAbstractDialogFactory_Impl::CreateDropDownFieldDialog(weld::Widget *pParent,
+ SwWrtShell &rSh, SwField* pField, bool bPrevButton, bool bNextButton)
+{
+ return VclPtr<AbstractDropDownFieldDialog_Impl>::Create(std::make_unique<sw::DropDownFieldDialog>(pParent, rSh, pField, bPrevButton, bNextButton));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDropDownFormFieldDialog(weld::Widget *pParent, sw::mark::IFieldmark* pDropDownField)
+{
+ return VclPtr<AbstractDropDownFormFieldDialog_Impl>::Create(std::make_unique<sw::DropDownFormFieldDialog>(pParent, pDropDownField));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDateFormFieldDialog(weld::Widget *pParent, sw::mark::IDateFieldmark* pDateField, SwDoc& rDoc)
+{
+ return VclPtr<AbstractDateFormFieldDialog_Impl>::Create(std::make_unique<sw::DateFormFieldDialog>(pParent, pDateField, rDoc));
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateSwEnvDlg(weld::Window* pParent, const SfxItemSet& rSet,
+ SwWrtShell* pWrtSh, Printer* pPrt,
+ bool bInsert)
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwEnvDlg>(pParent, rSet, pWrtSh,pPrt, bInsert));
+}
+
+VclPtr<AbstractSwLabDlg> SwAbstractDialogFactory_Impl::CreateSwLabDlg(weld::Window* pParent, const SfxItemSet& rSet,
+ SwDBManager* pDBManager, bool bLabel)
+{
+ return VclPtr<AbstractSwLabDlg_Impl>::Create(std::make_unique<SwLabDlg>(pParent, rSet, pDBManager, bLabel));
+}
+
+SwLabDlgMethod SwAbstractDialogFactory_Impl::GetSwLabDlgStaticMethod ()
+{
+ return SwLabDlg::UpdateFieldInformation;
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateSwParaDlg(weld::Window *pParent, SwView& rVw,
+ const SfxItemSet& rCoreSet,
+ bool bDraw ,
+ const OUString& sDefPage)
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwParaDlg>(pParent, rVw, rCoreSet, DLG_STD, nullptr, bDraw, sDefPage));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwAutoMarkDialog(weld::Window *pParent, SwWrtShell &rSh)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwAuthMarkModalDlg>(pParent, rSh));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwColumnDialog(weld::Window *pParent, SwWrtShell &rSh)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwColumnDlg>(pParent, rSh));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwTableHeightDialog(weld::Window *pParent, SwWrtShell &rSh)
+{
+ return VclPtr<AbstractSwTableHeightDlg_Impl>::Create(std::make_unique<SwTableHeightDlg>(pParent, rSh));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwSortingDialog(weld::Window *pParent, SwWrtShell &rSh)
+{
+ return VclPtr<AbstractSwSortDlg_Impl>::Create(std::make_unique<SwSortDlg>(pParent, rSh));
+}
+
+VclPtr<AbstractSplitTableDialog> SwAbstractDialogFactory_Impl::CreateSplitTableDialog(weld::Window *pParent, SwWrtShell &rSh)
+{
+ return VclPtr<AbstractSplitTableDialog_Impl>::Create(std::make_shared<SwSplitTableDlg>(pParent, rSh));
+}
+
+VclPtr<AbstractSwSelGlossaryDlg> SwAbstractDialogFactory_Impl::CreateSwSelGlossaryDlg(weld::Window *pParent, const OUString &rShortName)
+{
+ return VclPtr<AbstractSwSelGlossaryDlg_Impl>::Create(std::make_unique<SwSelGlossaryDlg>(pParent, rShortName));
+}
+
+VclPtr<AbstractSwAutoFormatDlg> SwAbstractDialogFactory_Impl::CreateSwAutoFormatDlg(weld::Window* pParent,
+ SwWrtShell* pShell, bool bSetAutoFormat, const SwTableAutoFormat* pSelFormat)
+{
+ return VclPtr<AbstractSwAutoFormatDlg_Impl>::Create(
+ std::unique_ptr<SwAutoFormatDlg, o3tl::default_delete<SwAutoFormatDlg>>(
+ new SwAutoFormatDlg(pParent, pShell, bSetAutoFormat, pSelFormat)));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwBorderDlg(weld::Window* pParent, SfxItemSet& rSet, SwBorderModes nType )
+{
+ return VclPtr<SwAbstractSfxController_Impl>::Create(std::make_unique<SwBorderDlg>(pParent, rSet, nType));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwWrapDlg(weld::Window* pParent, SfxItemSet& rSet, SwWrtShell* pSh)
+{
+ return VclPtr<SwAbstractSfxController_Impl>::Create(std::make_unique<SwWrapDlg>(pParent, rSet, pSh, true/*bDrawMode*/));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwTableWidthDlg(weld::Window *pParent, SwTableFUNC &rFnc)
+{
+ return VclPtr<AbstractSwTableWidthDlg_Impl>::Create(std::make_unique<SwTableWidthDlg>(pParent, rFnc));
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateSwTableTabDlg(weld::Window* pParent,
+ const SfxItemSet* pItemSet, SwWrtShell* pSh)
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwTableTabDlg>(pParent, pItemSet, pSh));
+}
+
+VclPtr<AbstractSwFieldDlg> SwAbstractDialogFactory_Impl::CreateSwFieldDlg(SfxBindings* pB, SwChildWinWrapper* pCW, weld::Window *pParent)
+{
+ return VclPtr<AbstractSwFieldDlg_Impl>::Create(std::make_shared<SwFieldDlg>(pB, pCW, pParent));
+}
+
+VclPtr<SfxAbstractDialog> SwAbstractDialogFactory_Impl::CreateSwFieldEditDlg(SwView& rVw)
+{
+ return VclPtr<SwAbstractSfxController_Impl>::Create(std::make_unique<SwFieldEditDlg>(rVw));
+}
+
+VclPtr<AbstractSwRenameXNamedDlg> SwAbstractDialogFactory_Impl::CreateSwRenameXNamedDlg(weld::Widget* pParent,
+ css::uno::Reference< css::container::XNamed > & xNamed,
+ css::uno::Reference< css::container::XNameAccess > & xNameAccess)
+{
+ return VclPtr<AbstractSwRenameXNamedDlg_Impl>::Create(std::make_unique<SwRenameXNamedDlg>(pParent,xNamed, xNameAccess));
+}
+
+VclPtr<AbstractSwModalRedlineAcceptDlg> SwAbstractDialogFactory_Impl::CreateSwModalRedlineAcceptDlg(weld::Window *pParent)
+{
+ return VclPtr<AbstractSwModalRedlineAcceptDlg_Impl>::Create(std::make_unique<SwModalRedlineAcceptDlg>(pParent));
+}
+
+VclPtr<AbstractSwPageNumberDlg> SwAbstractDialogFactory_Impl::CreateSwPageNumberDlg(weld::Window *pParent)
+{
+ return VclPtr<AbstractSwPageNumberDlg_Impl>::Create(std::make_shared<SwPageNumberDlg>(pParent));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateTableMergeDialog(weld::Window* pParent, bool& rWithPrev)
+{
+ return VclPtr<AbstractSwMergeTableDlg_Impl>::Create(std::make_unique<SwMergeTableDlg>(pParent, rWithPrev));
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateFrameTabDialog(const OUString &rDialogType,
+ SfxViewFrame& rFrame, weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bNewFrame,
+ const OUString& sDefPage )
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwFrameDlg>(rFrame, pParent, rCoreSet, bNewFrame, rDialogType, false/*bFormat*/, sDefPage, nullptr));
+}
+
+VclPtr<SfxAbstractApplyTabDialog> SwAbstractDialogFactory_Impl::CreateTemplateDialog(
+ weld::Window *pParent,
+ SfxStyleSheetBase& rBase,
+ SfxStyleFamily nRegion,
+ const OUString& sPage,
+ SwWrtShell* pActShell,
+ bool bNew )
+{
+ return VclPtr<AbstractApplyTabController_Impl>::Create(std::make_shared<SwTemplateDlgController>(pParent, rBase, nRegion,
+ sPage, pActShell, bNew));
+}
+
+VclPtr<AbstractGlossaryDlg> SwAbstractDialogFactory_Impl::CreateGlossaryDlg(SfxViewFrame& rViewFrame, SwGlossaryHdl* pGlosHdl,
+ SwWrtShell *pWrtShell)
+{
+ return VclPtr<AbstractGlossaryDlg_Impl>::Create(std::make_unique<SwGlossaryDlg>(rViewFrame, pGlosHdl, pWrtShell));
+}
+
+VclPtr<AbstractFieldInputDlg> SwAbstractDialogFactory_Impl::CreateFieldInputDlg(weld::Widget *pParent,
+ SwWrtShell &rSh, SwField* pField, bool bPrevButton, bool bNextButton)
+{
+ return VclPtr<AbstractFieldInputDlg_Impl>::Create(std::make_unique<SwFieldInputDlg>(pParent, rSh, pField, bPrevButton, bNextButton));
+}
+
+VclPtr<AbstractInsFootNoteDlg> SwAbstractDialogFactory_Impl::CreateInsFootNoteDlg(
+ weld::Window * pParent, SwWrtShell &rSh, bool bEd )
+{
+ return VclPtr<AbstractInsFootNoteDlg_Impl>::Create(std::make_unique<SwInsFootNoteDlg>(pParent, rSh, bEd));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateTitlePageDlg(weld::Window *pParent)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwTitlePageDlg>(pParent));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateVclSwViewDialog(SwView& rView)
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwLineNumberingDlg>(rView));
+}
+
+std::shared_ptr<AbstractInsTableDlg> SwAbstractDialogFactory_Impl::CreateInsTableDlg(SwView& rView)
+{
+ return std::make_shared<AbstractInsTableDlg_Impl>(std::make_shared<SwInsTableDlg>(rView));
+}
+
+VclPtr<AbstractJavaEditDialog> SwAbstractDialogFactory_Impl::CreateJavaEditDialog(
+ weld::Window* pParent, SwWrtShell* pWrtSh)
+{
+ return VclPtr<AbstractJavaEditDialog_Impl>::Create(std::make_unique<SwJavaEditDialog>(pParent, pWrtSh));
+}
+
+VclPtr<AbstractMailMergeDlg> SwAbstractDialogFactory_Impl::CreateMailMergeDlg(
+ weld::Window* pParent, SwWrtShell& rSh,
+ const OUString& rSourceName,
+ const OUString& rTableName,
+ sal_Int32 nCommandType,
+ const uno::Reference< sdbc::XConnection>& xConnection )
+{
+ return VclPtr<AbstractMailMergeDlg_Impl>::Create(std::make_unique<SwMailMergeDlg>(pParent, rSh, rSourceName, rTableName, nCommandType, xConnection, nullptr));
+}
+
+VclPtr<AbstractMailMergeCreateFromDlg> SwAbstractDialogFactory_Impl::CreateMailMergeCreateFromDlg(weld::Window* pParent)
+{
+ return VclPtr<AbstractMailMergeCreateFromDlg_Impl>::Create(std::make_unique<SwMailMergeCreateFromDlg>(pParent));
+}
+
+VclPtr<AbstractMailMergeFieldConnectionsDlg> SwAbstractDialogFactory_Impl::CreateMailMergeFieldConnectionsDlg(weld::Window* pParent)
+{
+ return VclPtr<AbstractMailMergeFieldConnectionsDlg_Impl>::Create(std::make_unique<SwMailMergeFieldConnectionsDlg>(pParent));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateMultiTOXMarkDlg(weld::Window* pParent, SwTOXMgr &rTOXMgr)
+{
+ return VclPtr<AbstractMultiTOXMarkDlg_Impl>::Create(std::make_unique<SwMultiTOXMarkDlg>(pParent, rTOXMgr));
+}
+
+VclPtr<AbstractNumBulletDialog> SwAbstractDialogFactory_Impl::CreateSvxNumBulletTabDialog(weld::Window* pParent,
+ const SfxItemSet& rSwItemSet,
+ SwWrtShell & rWrtSh)
+{
+ return VclPtr<AbstractNumBulletDialog_Impl>::Create(std::make_shared<SwSvxNumBulletTabDialog>(pParent, rSwItemSet, rWrtSh));
+}
+
+VclPtr<SfxAbstractTabDialog> SwAbstractDialogFactory_Impl::CreateOutlineTabDialog(weld::Window* pParent,
+ const SfxItemSet* pSwItemSet,
+ SwWrtShell & rWrtSh )
+{
+ return VclPtr<AbstractTabController_Impl>::Create(std::make_shared<SwOutlineTabDialog>(pParent, pSwItemSet, rWrtSh));
+}
+
+VclPtr<AbstractMultiTOXTabDialog> SwAbstractDialogFactory_Impl::CreateMultiTOXTabDialog(weld::Widget* pParent, const SfxItemSet& rSet,
+ SwWrtShell &rShell, SwTOXBase* pCurTOX, bool bGlobal)
+{
+ return VclPtr<AbstractMultiTOXTabDialog_Impl>::Create(std::make_shared<SwMultiTOXTabDialog>(pParent, rSet, rShell, pCurTOX, USHRT_MAX, bGlobal));
+}
+
+VclPtr<AbstractEditRegionDlg> SwAbstractDialogFactory_Impl::CreateEditRegionDlg(weld::Window* pParent, SwWrtShell& rWrtSh)
+{
+ return VclPtr<AbstractEditRegionDlg_Impl>::Create(std::make_shared<SwEditRegionDlg>(pParent, rWrtSh));
+}
+
+VclPtr<AbstractInsertSectionTabDialog> SwAbstractDialogFactory_Impl::CreateInsertSectionTabDialog(weld::Window* pParent,
+ const SfxItemSet& rSet, SwWrtShell& rSh)
+{
+ return VclPtr<AbstractInsertSectionTabDialog_Impl>::Create(std::make_shared<SwInsertSectionTabDialog>(pParent, rSet, rSh));
+}
+
+VclPtr<AbstractMarkFloatDlg> SwAbstractDialogFactory_Impl::CreateIndexMarkFloatDlg(
+ SfxBindings* pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo* pInfo )
+{
+ return VclPtr<AbstractIndexMarkFloatDlg_Impl>::Create(std::make_shared<SwIndexMarkFloatDlg>(pBindings, pChild, pParent, pInfo, true/*bNew*/));
+}
+
+VclPtr<AbstractMarkFloatDlg> SwAbstractDialogFactory_Impl::CreateAuthMarkFloatDlg(
+ SfxBindings* pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo* pInfo)
+{
+ return VclPtr<AbstractAuthMarkFloatDlg_Impl>::Create(std::make_shared<SwAuthMarkFloatDlg>(pBindings, pChild, pParent, pInfo, true/*bNew*/));
+}
+
+VclPtr<AbstractSwWordCountFloatDlg> SwAbstractDialogFactory_Impl::CreateSwWordCountDialog(
+ SfxBindings* pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo* pInfo)
+{
+ return VclPtr<AbstractSwWordCountFloatDlg_Impl>::Create(std::make_shared<SwWordCountFloatDlg>(pBindings, pChild, pParent, pInfo));
+}
+
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateIndexMarkModalDlg(weld::Window *pParent, SwWrtShell& rSh, SwTOXMark* pCurTOXMark )
+{
+ return VclPtr<AbstractGenericDialog_Impl>::Create(std::make_shared<SwIndexMarkModalDlg>(pParent, rSh, pCurTOXMark));
+}
+
+VclPtr<AbstractMailMergeWizard> SwAbstractDialogFactory_Impl::CreateMailMergeWizard(
+ SwView& rView, std::shared_ptr<SwMailMergeConfigItem>& rConfigItem)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ return VclPtr<AbstractMailMergeWizard_Impl>::Create(std::make_shared<SwMailMergeWizard>(rView, rConfigItem));
+#else
+ (void) rView;
+ (void) rConfigItem;
+ return nullptr;
+#endif
+}
+
+GlossaryGetCurrGroup SwAbstractDialogFactory_Impl::GetGlossaryCurrGroupFunc()
+{
+ return SwGlossaryDlg::GetCurrGroup;
+}
+
+GlossarySetActGroup SwAbstractDialogFactory_Impl::SetGlossaryActGroupFunc()
+{
+ return SwGlossaryDlg::SetActGroup;
+}
+
+// Factories for TabPages
+CreateTabPage SwAbstractDialogFactory_Impl::GetTabPageCreatorFunc( sal_uInt16 nId )
+{
+ CreateTabPage pRet = nullptr;
+ switch ( nId )
+ {
+ case RID_SW_TP_OPTCOMPATIBILITY_PAGE :
+ pRet = SwCompatibilityOptPage::Create;
+ break;
+ case RID_SW_TP_OPTLOAD_PAGE :
+ pRet = SwLoadOptPage::Create;
+ break;
+ case RID_SW_TP_OPTCAPTION_PAGE:
+ return SwCaptionOptPage::Create;
+ case RID_SW_TP_CONTENT_OPT:
+ case RID_SW_TP_HTML_CONTENT_OPT:
+ pRet = SwContentOptPage::Create;
+ break;
+ case RID_SW_TP_OPTSHDWCRSR:
+ case RID_SW_TP_HTML_OPTSHDWCRSR:
+ pRet = SwShdwCursorOptionsTabPage::Create;
+ break;
+ case RID_SW_TP_REDLINE_OPT :
+ pRet = SwRedlineOptionsTabPage::Create;
+ break;
+ case RID_SW_TP_OPTTEST_PAGE :
+#ifdef DBG_UTIL
+ pRet = SwTestTabPage::Create;
+#endif
+ break;
+ case TP_OPTPRINT_PAGE :
+ case RID_SW_TP_HTML_OPTPRINT_PAGE:
+ case RID_SW_TP_OPTPRINT_PAGE:
+ pRet = SwAddPrinterTabPage::Create;
+ break;
+ case RID_SW_TP_STD_FONT:
+ case RID_SW_TP_STD_FONT_CJK:
+ case RID_SW_TP_STD_FONT_CTL:
+ pRet = SwStdFontTabPage::Create;
+ break;
+ case RID_SW_TP_HTML_OPTTABLE_PAGE:
+ case RID_SW_TP_OPTTABLE_PAGE:
+ pRet = SwTableOptionsTabPage::Create;
+ break;
+ case RID_SW_TP_DOC_STAT :
+ pRet = SwDocStatPage::Create;
+ break;
+ case RID_SW_TP_MAILCONFIG:
+ pRet = SwMailConfigPage::Create;
+ break;
+ case RID_SW_TP_COMPARISON_OPT :
+ pRet = SwCompareOptionsTabPage::Create;
+ break;
+ }
+
+ return pRet;
+}
+
+void SwAbstractDialogFactory_Impl::ExecuteMMResultSaveDialog(weld::Window* pParent)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ SwMMResultSaveDialog aDialog(pParent);
+ aDialog.run();
+#else
+ (void) pParent;
+#endif
+}
+
+void SwAbstractDialogFactory_Impl::ExecuteMMResultPrintDialog(weld::Window* pParent)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ SwMMResultPrintDialog aDialog(pParent);
+ aDialog.run();
+#else
+ (void) pParent;
+#endif
+}
+
+void SwAbstractDialogFactory_Impl::ExecuteMMResultEmailDialog(weld::Window* pParent)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ SwMMResultEmailDialog aDialog(pParent);
+ aDialog.run();
+#else
+ (void) pParent;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx
new file mode 100644
index 0000000000..d5c1c43806
--- /dev/null
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -0,0 +1,881 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_DIALOG_SWDLGFACT_HXX
+#define INCLUDED_SW_SOURCE_UI_DIALOG_SWDLGFACT_HXX
+
+#include <swabstdlg.hxx>
+
+#include <abstract.hxx>
+#include <ascfldlg.hxx>
+#include <cnttab.hxx>
+#include <colwd.hxx>
+#include <contentcontrollistitemdlg.hxx>
+#include <convert.hxx>
+#include <DateFormFieldDialog.hxx>
+#include <dbinsdlg.hxx>
+#include <DropDownFieldDialog.hxx>
+#include <DropDownFormFieldDialog.hxx>
+#include <fldtdlg.hxx>
+#include <glossary.hxx>
+#include <inpdlg.hxx>
+#include <insfnote.hxx>
+#include <javaedit.hxx>
+#include <label.hxx>
+#include <mailmergewizard.hxx>
+#include <mailmrge.hxx>
+#include <mergetbl.hxx>
+#include <multmrk.hxx>
+#include <regionsw.hxx>
+#include <rowht.hxx>
+#include <selglos.hxx>
+#include <splittbl.hxx>
+#include <srtdlg.hxx>
+#include <swmodalredlineacceptdlg.hxx>
+#include <swrenamexnameddlg.hxx>
+#include <swuicnttab.hxx>
+#include <swuiidxmrk.hxx>
+#include <tautofmt.hxx>
+#include <utility>
+#include <wordcountdialog.hxx>
+#include <itabenum.hxx>
+#include <optional>
+#include <o3tl/deleter.hxx>
+#include <pagenumberdlg.hxx>
+
+
+class SwInsertAbstractDlg;
+class SwAsciiFilterDlg;
+class SwBreakDlg;
+class SwMultiTOXMarkDlg;
+class SwSortDlg;
+class SwTableHeightDlg;
+class SwTableWidthDlg;
+class SwMergeTableDlg;
+class SfxTabDialog;
+class SwConvertTableDlg;
+class SwInsertDBColAutoPilot;
+class SwLabDlg;
+class SwSelGlossaryDlg;
+class SwAutoFormatDlg;
+class SwFieldDlg;
+class SwRenameXNamedDlg;
+class SwModalRedlineAcceptDlg;
+class SwTOXMark;
+class SwSplitTableDlg;
+namespace sw
+{
+class DropDownFieldDialog;
+class DropDownFormFieldDialog;
+class DateFormFieldDialog;
+}
+class SwWordCountFloatDlg;
+
+
+class AbstractSwWordCountFloatDlg_Impl : public AbstractSwWordCountFloatDlg
+{
+ std::shared_ptr<SwWordCountFloatDlg> m_xDlg;
+public:
+ explicit AbstractSwWordCountFloatDlg_Impl(std::shared_ptr<SwWordCountFloatDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void UpdateCounts() override;
+ virtual void SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+};
+
+class AbstractSwInsertAbstractDlg_Impl : public AbstractSwInsertAbstractDlg
+{
+ std::unique_ptr<SwInsertAbstractDlg> m_xDlg;
+public:
+ explicit AbstractSwInsertAbstractDlg_Impl(std::unique_ptr<SwInsertAbstractDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual sal_uInt8 GetLevel() const override ;
+ virtual sal_uInt8 GetPara() const override ;
+};
+
+class SwAbstractSfxController_Impl : public SfxAbstractDialog
+{
+ std::unique_ptr<SfxSingleTabDialogController> m_xDlg;
+public:
+ explicit SwAbstractSfxController_Impl(std::unique_ptr<SfxSingleTabDialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual void SetText(const OUString& rStr) override;
+};
+
+class AbstractNumFormatDlg_Impl : public SfxAbstractDialog
+{
+ std::shared_ptr<SfxSingleTabDialogController> m_xDlg;
+public:
+ explicit AbstractNumFormatDlg_Impl(std::shared_ptr<SfxSingleTabDialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual void SetText(const OUString& rStr) override;
+};
+
+class AbstractSwAsciiFilterDlg_Impl : public AbstractSwAsciiFilterDlg
+{
+ std::unique_ptr<SwAsciiFilterDlg> m_xDlg;
+public:
+ explicit AbstractSwAsciiFilterDlg_Impl(std::unique_ptr<SwAsciiFilterDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void FillOptions( SwAsciiOptions& rOptions ) override;
+};
+
+/// Interface implementation for the insert -> fields -> page number wizard dialog
+class AbstractSwPageNumberDlg_Impl : public AbstractSwPageNumberDlg
+{
+ std::shared_ptr<SwPageNumberDlg> m_xDlg;
+public:
+ explicit AbstractSwPageNumberDlg_Impl(std::shared_ptr<SwPageNumberDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual int GetPageNumberPosition() const override;
+ virtual int GetPageNumberAlignment() const override;
+ bool GetMirrorOnEvenPages() const override;
+ bool GetIncludePageTotal() const override;
+ SvxNumType GetPageNumberType() const override;
+ void SetPageNumberType(SvxNumType nSet) override;
+};
+
+class AbstractGenericDialog_Impl : public VclAbstractDialog
+{
+ std::shared_ptr<weld::GenericDialogController> m_xDlg;
+public:
+ explicit AbstractGenericDialog_Impl(std::shared_ptr<weld::GenericDialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+};
+
+class AbstractSwSortDlg_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<SwSortDlg> m_xDlg;
+public:
+ explicit AbstractSwSortDlg_Impl(std::unique_ptr<SwSortDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractMultiTOXMarkDlg_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<SwMultiTOXMarkDlg> m_xDlg;
+public:
+ explicit AbstractMultiTOXMarkDlg_Impl(std::unique_ptr<SwMultiTOXMarkDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractNumBulletDialog_Impl : public AbstractNumBulletDialog
+{
+protected:
+ std::shared_ptr<SfxTabDialogController> m_xDlg;
+public:
+ explicit AbstractNumBulletDialog_Impl(std::shared_ptr<SfxTabDialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetCurPageId( const OUString &rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual const SfxItemSet* GetInputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ //From class Window.
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+class AbstractSwBreakDlg_Impl : public AbstractSwBreakDlg
+{
+ std::shared_ptr<weld::DialogController> m_xDlg;
+public:
+ explicit AbstractSwBreakDlg_Impl(std::shared_ptr<weld::DialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual OUString GetTemplateName() override;
+ virtual sal_uInt16 GetKind() override;
+ virtual ::std::optional<sal_uInt16> GetPageNumber() override;
+ std::optional<SwLineBreakClear> GetClear() override;
+
+ virtual std::shared_ptr<weld::DialogController> getDialogController() override { return m_xDlg; }
+};
+
+class AbstractSwTranslateLangSelectDlg_Impl : public AbstractSwTranslateLangSelectDlg
+{
+ std::shared_ptr<weld::DialogController> m_xDlg;
+public:
+ explicit AbstractSwTranslateLangSelectDlg_Impl(std::shared_ptr<weld::DialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+
+ virtual std::shared_ptr<weld::DialogController> getDialogController() override { return m_xDlg; }
+ virtual std::optional<SwLanguageListItem> GetSelectedLanguage() override;
+};
+
+class AbstractSwTableWidthDlg_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<SwTableWidthDlg> m_xDlg;
+public:
+ explicit AbstractSwTableWidthDlg_Impl(std::unique_ptr<SwTableWidthDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractSwTableHeightDlg_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<SwTableHeightDlg> m_xDlg;
+public:
+ explicit AbstractSwTableHeightDlg_Impl(std::unique_ptr<SwTableHeightDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractSwMergeTableDlg_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<SwMergeTableDlg> m_xDlg;
+public:
+ explicit AbstractSwMergeTableDlg_Impl(std::unique_ptr<SwMergeTableDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractSplitTableDialog_Impl : public AbstractSplitTableDialog // add for
+{
+ std::shared_ptr<SwSplitTableDlg> m_xDlg;
+public:
+ explicit AbstractSplitTableDialog_Impl(std::shared_ptr<SwSplitTableDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual SplitTable_HeadlineOption GetSplitMode() override;
+};
+
+class AbstractTabController_Impl : virtual public SfxAbstractTabDialog
+{
+protected:
+ std::shared_ptr<SfxTabDialogController> m_xDlg;
+public:
+ explicit AbstractTabController_Impl(std::shared_ptr<SfxTabDialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetCurPageId( const OUString &rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ //From class Window.
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+class AbstractApplyTabController_Impl : public AbstractTabController_Impl, virtual public SfxAbstractApplyTabDialog
+{
+public:
+ explicit AbstractApplyTabController_Impl(std::shared_ptr<SfxTabDialogController> p)
+ : AbstractTabController_Impl(std::move(p))
+ {
+ }
+ DECL_LINK(ApplyHdl, weld::Button&, void);
+private:
+ Link<LinkParamNone*,void> m_aHandler;
+ virtual void SetApplyHdl( const Link<LinkParamNone*,void>& rLink ) override;
+};
+
+class AbstractSwConvertTableDlg_Impl : public AbstractSwConvertTableDlg
+{
+ std::unique_ptr<SwConvertTableDlg> m_xDlg;
+public:
+ explicit AbstractSwConvertTableDlg_Impl(std::unique_ptr<SwConvertTableDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void GetValues( sal_Unicode& rDelim,SwInsertTableOptions& rInsTableFlags,
+ SwTableAutoFormat const*& prTAFormat) override;
+};
+
+class AbstractSwInsertDBColAutoPilot_Impl : public AbstractSwInsertDBColAutoPilot
+{
+ std::unique_ptr<SwInsertDBColAutoPilot> m_xDlg;
+public:
+ explicit AbstractSwInsertDBColAutoPilot_Impl(std::unique_ptr<SwInsertDBColAutoPilot> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void DataToDoc( const css::uno::Sequence< css::uno::Any >& rSelection,
+ css::uno::Reference< css::sdbc::XDataSource> rxSource,
+ css::uno::Reference< css::sdbc::XConnection> xConnection,
+ css::uno::Reference< css::sdbc::XResultSet > xResultSet) override;
+};
+
+class AbstractDropDownFieldDialog_Impl : public AbstractDropDownFieldDialog
+{
+ std::unique_ptr<sw::DropDownFieldDialog> m_xDlg;
+public:
+ explicit AbstractDropDownFieldDialog_Impl(std::unique_ptr<sw::DropDownFieldDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool PrevButtonPressed() const override;
+ virtual bool NextButtonPressed() const override;
+};
+
+class AbstractDropDownFormFieldDialog_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<sw::DropDownFormFieldDialog> m_xDlg;
+public:
+ explicit AbstractDropDownFormFieldDialog_Impl(std::unique_ptr<sw::DropDownFormFieldDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractDateFormFieldDialog_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<sw::DateFormFieldDialog> m_xDlg;
+public:
+ explicit AbstractDateFormFieldDialog_Impl(std::unique_ptr<sw::DateFormFieldDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AbstractSwLabDlg_Impl : public AbstractSwLabDlg
+{
+ std::unique_ptr<SwLabDlg> m_xDlg;
+public:
+ explicit AbstractSwLabDlg_Impl(std::unique_ptr<SwLabDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetCurPageId( const OUString &rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ //From class Window.
+ virtual void SetText( const OUString& rStr ) override;
+ virtual const OUString& GetBusinessCardStr() const override;
+ virtual Printer *GetPrt() override;
+};
+
+class AbstractSwSelGlossaryDlg_Impl : public AbstractSwSelGlossaryDlg
+{
+ std::unique_ptr<SwSelGlossaryDlg> m_xDlg;
+public:
+ explicit AbstractSwSelGlossaryDlg_Impl(std::unique_ptr<SwSelGlossaryDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void InsertGlos(const OUString &rRegion, const OUString &rGlosName) override; // inline
+ virtual sal_Int32 GetSelectedIdx() const override; // inline
+ virtual void SelectEntryPos(sal_Int32 nIdx) override; // inline
+};
+
+class AbstractSwAutoFormatDlg_Impl : public AbstractSwAutoFormatDlg
+{
+ std::unique_ptr<SwAutoFormatDlg, o3tl::default_delete<SwAutoFormatDlg>> m_xDlg;
+public:
+ explicit AbstractSwAutoFormatDlg_Impl(std::unique_ptr<SwAutoFormatDlg, o3tl::default_delete<SwAutoFormatDlg>> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual std::unique_ptr<SwTableAutoFormat> FillAutoFormatOfIndex() const override;
+};
+
+class AbstractSwFieldDlg_Impl : public AbstractSwFieldDlg
+{
+ std::shared_ptr<SwFieldDlg> m_xDlg;
+public:
+ explicit AbstractSwFieldDlg_Impl(std::shared_ptr<SwFieldDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetCurPageId( const OUString &rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ //From class Window.
+ virtual void SetText( const OUString& rStr ) override;
+ virtual void ShowReferencePage() override;
+ virtual void Initialize(SfxChildWinInfo *pInfo) override;
+ virtual void ReInitDlg() override;
+ virtual void ActivateDatabasePage() override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+};
+
+class AbstractSwRenameXNamedDlg_Impl : public AbstractSwRenameXNamedDlg
+{
+ std::unique_ptr<SwRenameXNamedDlg> m_xDlg;
+public:
+ explicit AbstractSwRenameXNamedDlg_Impl(std::unique_ptr<SwRenameXNamedDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetForbiddenChars( const OUString& rSet ) override;
+ virtual void SetAlternativeAccess(
+ css::uno::Reference< css::container::XNameAccess > & xSecond,
+ css::uno::Reference< css::container::XNameAccess > & xThird ) override;
+};
+
+/**
+ * Implementation of AbstractSwContentControlListItemDlg, that is only visible to
+ * SwAbstractDialogFactory_Impl::CreateSwContentControlListItemDlg().
+ */
+class AbstractSwContentControlListItemDlg_Impl : public AbstractSwContentControlListItemDlg
+{
+ std::shared_ptr<SwContentControlListItemDlg> m_xDlg;
+
+public:
+ explicit AbstractSwContentControlListItemDlg_Impl(
+ std::shared_ptr<SwContentControlListItemDlg> xDlg)
+ : m_xDlg(std::move(xDlg))
+ {
+ }
+
+ short Execute() override;
+ bool StartExecuteAsync(VclAbstractDialog::AsyncContext &) override;
+};
+
+class AbstractSwModalRedlineAcceptDlg_Impl : public AbstractSwModalRedlineAcceptDlg
+{
+ std::unique_ptr<SwModalRedlineAcceptDlg> m_xDlg;
+public:
+ explicit AbstractSwModalRedlineAcceptDlg_Impl(std::unique_ptr<SwModalRedlineAcceptDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class SwGlossaryDlg;
+class AbstractGlossaryDlg_Impl : public AbstractGlossaryDlg
+{
+ std::unique_ptr<SwGlossaryDlg> m_xDlg;
+public:
+ explicit AbstractGlossaryDlg_Impl(std::unique_ptr<SwGlossaryDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetCurrGrpName() const override;
+ virtual OUString GetCurrShortName() const override;
+};
+
+class SwFieldInputDlg;
+class AbstractFieldInputDlg_Impl : public AbstractFieldInputDlg
+{
+ std::unique_ptr<SwFieldInputDlg> m_xDlg;
+public:
+ explicit AbstractFieldInputDlg_Impl(std::unique_ptr<SwFieldInputDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void EndDialog(sal_Int32) override;
+ virtual bool PrevButtonPressed() const override;
+ virtual bool NextButtonPressed() const override;
+};
+
+class SwInsFootNoteDlg;
+class AbstractInsFootNoteDlg_Impl : public AbstractInsFootNoteDlg
+{
+ std::unique_ptr<SwInsFootNoteDlg> m_xDlg;
+public:
+ explicit AbstractInsFootNoteDlg_Impl(std::unique_ptr<SwInsFootNoteDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetFontName() override;
+ virtual bool IsEndNote() override;
+ virtual OUString GetStr() override;
+ //from class Window
+ virtual void SetHelpId( const OUString& sHelpId ) override;
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+class SwInsTableDlg;
+class AbstractInsTableDlg_Impl : public AbstractInsTableDlg
+{
+ std::shared_ptr<weld::DialogController> m_xDlg;
+public:
+ explicit AbstractInsTableDlg_Impl(std::shared_ptr<weld::DialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual void GetValues( OUString& rName, sal_uInt16& rRow, sal_uInt16& rCol,
+ SwInsertTableOptions& rInsTableFlags, OUString& rTableAutoFormatName,
+ std::unique_ptr<SwTableAutoFormat>& prTAFormat ) override;
+ virtual std::shared_ptr<weld::DialogController> getDialogController() override { return m_xDlg; }
+};
+
+class SwJavaEditDialog;
+class AbstractJavaEditDialog_Impl : public AbstractJavaEditDialog
+{
+ std::unique_ptr<SwJavaEditDialog> m_xDlg;
+public:
+ explicit AbstractJavaEditDialog_Impl(std::unique_ptr<SwJavaEditDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetScriptText() const override;
+ virtual OUString GetScriptType() const override;
+ virtual bool IsUrl() const override;
+ virtual bool IsNew() const override;
+ virtual bool IsUpdate() const override;
+};
+
+class SwMailMergeDlg;
+class AbstractMailMergeDlg_Impl : public AbstractMailMergeDlg
+{
+ std::unique_ptr<SwMailMergeDlg> m_xDlg;
+public:
+ explicit AbstractMailMergeDlg_Impl(std::unique_ptr<SwMailMergeDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual DBManagerOptions GetMergeType() override ;
+ virtual const OUString& GetSaveFilter() const override;
+ virtual css::uno::Sequence< css::uno::Any > GetSelection() const override ;
+ virtual css::uno::Reference< css::sdbc::XResultSet> GetResultSet() const override;
+ virtual bool IsSaveSingleDoc() const override;
+ virtual bool IsGenerateFromDataBase() const override;
+ virtual bool IsFileEncryptedFromDataBase() const override;
+ virtual OUString GetColumnName() const override;
+ virtual OUString GetPasswordColumnName() const override;
+ virtual OUString GetTargetURL() const override;
+};
+
+class SwMailMergeCreateFromDlg;
+class AbstractMailMergeCreateFromDlg_Impl : public AbstractMailMergeCreateFromDlg
+{
+ std::unique_ptr<SwMailMergeCreateFromDlg> m_xDlg;
+public:
+ explicit AbstractMailMergeCreateFromDlg_Impl(std::unique_ptr<SwMailMergeCreateFromDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool IsThisDocument() const override ;
+};
+
+class SwMailMergeFieldConnectionsDlg;
+class AbstractMailMergeFieldConnectionsDlg_Impl : public AbstractMailMergeFieldConnectionsDlg
+{
+ std::unique_ptr<SwMailMergeFieldConnectionsDlg> m_xDlg;
+public:
+ explicit AbstractMailMergeFieldConnectionsDlg_Impl(std::unique_ptr<SwMailMergeFieldConnectionsDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool IsUseExistingConnections() const override ;
+};
+
+class SwMultiTOXTabDialog;
+class AbstractMultiTOXTabDialog_Impl : public AbstractMultiTOXTabDialog
+{
+ std::shared_ptr<SwMultiTOXTabDialog> m_xDlg;
+public:
+ explicit AbstractMultiTOXTabDialog_Impl(std::shared_ptr<SwMultiTOXTabDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) override;
+ virtual CurTOXType GetCurrentTOXType() const override ;
+ virtual SwTOXDescription& GetTOXDescription(CurTOXType eTOXTypes) override;
+ //from SfxTabDialog
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+};
+
+class SwEditRegionDlg;
+class AbstractEditRegionDlg_Impl : public AbstractEditRegionDlg
+{
+ std::shared_ptr<SwEditRegionDlg> m_xDlg;
+public:
+ explicit AbstractEditRegionDlg_Impl(std::shared_ptr<SwEditRegionDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SelectSection(const OUString& rSectionName) override;
+};
+
+class SwInsertSectionTabDialog;
+class AbstractInsertSectionTabDialog_Impl : public AbstractInsertSectionTabDialog
+{
+ std::shared_ptr<SwInsertSectionTabDialog> m_xDlg;
+public:
+ explicit AbstractInsertSectionTabDialog_Impl(std::shared_ptr<SwInsertSectionTabDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetSectionData(SwSectionData const& rSect) override;
+};
+
+class SwIndexMarkFloatDlg;
+class AbstractIndexMarkFloatDlg_Impl : public AbstractMarkFloatDlg
+{
+ std::shared_ptr<SwIndexMarkFloatDlg> m_xDlg;
+public:
+ explicit AbstractIndexMarkFloatDlg_Impl(std::shared_ptr<SwIndexMarkFloatDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void ReInitDlg(SwWrtShell& rWrtShell) override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+};
+
+class SwAuthMarkFloatDlg;
+class AbstractAuthMarkFloatDlg_Impl : public AbstractMarkFloatDlg
+{
+ std::shared_ptr<SwAuthMarkFloatDlg> m_xDlg;
+public:
+ explicit AbstractAuthMarkFloatDlg_Impl(std::shared_ptr<SwAuthMarkFloatDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void ReInitDlg(SwWrtShell& rWrtShell) override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+};
+
+class SwMailMergeWizard;
+class AbstractMailMergeWizard_Impl : public AbstractMailMergeWizard
+{
+ std::shared_ptr<SwMailMergeWizard> m_xDlg;
+
+public:
+ explicit AbstractMailMergeWizard_Impl(std::shared_ptr<SwMailMergeWizard> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual ~AbstractMailMergeWizard_Impl() override;
+ virtual bool StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) override;
+ virtual short Execute() override;
+
+ virtual OUString GetReloadDocument() const override;
+ virtual void ShowPage( sal_uInt16 nLevel ) override;
+ virtual sal_uInt16 GetRestartPage() const override;
+};
+
+//AbstractDialogFactory_Impl implementations
+class SwAbstractDialogFactory_Impl : public SwAbstractDialogFactory
+{
+
+public:
+ virtual ~SwAbstractDialogFactory_Impl() {}
+
+ virtual VclPtr<SfxAbstractDialog> CreateNumFormatDialog(weld::Widget* pParent, const SfxItemSet& rAttr) override;
+ virtual VclPtr<SfxAbstractDialog> CreateSwDropCapsDialog(weld::Window* pParent, const SfxItemSet& rSet) override;
+ virtual VclPtr<SfxAbstractDialog> CreateSwBackgroundDialog(weld::Window* pParent, const SfxItemSet& rSet) override;
+ virtual VclPtr<AbstractSwWordCountFloatDlg> CreateSwWordCountDialog(SfxBindings* pBindings,
+ SfxChildWindow* pChild, weld::Window *pParent, SfxChildWinInfo* pInfo) override;
+ virtual VclPtr<AbstractSwInsertAbstractDlg> CreateSwInsertAbstractDlg(weld::Window* pParent) override;
+ virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(weld::Window* pParent, const SfxItemSet& rSet) override;
+ virtual VclPtr<AbstractSwAsciiFilterDlg> CreateSwAsciiFilterDlg(weld::Window* pParent, SwDocShell& rDocSh,
+ SvStream* pStream) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwInsertBookmarkDlg(weld::Window *pParent, SwWrtShell &rSh, OUString const* pSelected) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwContentControlDlg(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<AbstractSwPageNumberDlg> CreateSwPageNumberDlg(weld::Window *pParent) override;
+
+ VclPtr<AbstractSwContentControlListItemDlg>
+ CreateSwContentControlListItemDlg(weld::Window* pParent,
+ SwContentControlListItem& rItem) override;
+
+ virtual std::shared_ptr<AbstractSwBreakDlg> CreateSwBreakDlg(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual std::shared_ptr<AbstractSwTranslateLangSelectDlg> CreateSwTranslateLangSelectDlg(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwChangeDBDlg(SwView& rVw) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSwCharDlg(weld::Window* pParent, SwView& pVw, const SfxItemSet& rCoreSet,
+ SwCharDlgMode nDialogMode, const OUString* pFormatStr = nullptr) override;
+ virtual VclPtr<AbstractSwConvertTableDlg> CreateSwConvertTableDlg(SwView& rView, bool bToTable) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwCaptionDialog(weld::Window *pParent, SwView &rV) override;
+ virtual VclPtr<AbstractSwInsertDBColAutoPilot> CreateSwInsertDBColAutoPilot(SwView& rView,
+ css::uno::Reference< css::sdbc::XDataSource> rxSource,
+ css::uno::Reference<css::sdbcx::XColumnsSupplier> xColSupp,
+ const SwDBData& rData) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSwFootNoteOptionDlg(weld::Window *pParent, SwWrtShell &rSh) override;
+
+ virtual VclPtr<AbstractDropDownFieldDialog> CreateDropDownFieldDialog(weld::Widget* pParent, SwWrtShell &rSh,
+ SwField* pField, bool bPrevButton, bool bNextButton) override;
+ virtual VclPtr<VclAbstractDialog> CreateDropDownFormFieldDialog(weld::Widget* pParent, sw::mark::IFieldmark* pDropDownField) override;
+ virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(weld::Widget* pParent, sw::mark::IDateFieldmark* pDateField, SwDoc& rDoc) override;
+
+ virtual VclPtr<SfxAbstractTabDialog> CreateSwEnvDlg(weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell* pWrtSh, Printer* pPrt, bool bInsert) override;
+ virtual VclPtr<AbstractSwLabDlg> CreateSwLabDlg(weld::Window* pParent, const SfxItemSet& rSet,
+ SwDBManager* pDBManager, bool bLabel) override;
+
+ virtual SwLabDlgMethod GetSwLabDlgStaticMethod () override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSwParaDlg(weld::Window *pParent,
+ SwView& rVw,
+ const SfxItemSet& rCoreSet,
+ bool bDraw,
+ const OUString& sDefPage = {}) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateSwAutoMarkDialog(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<AbstractSwSelGlossaryDlg> CreateSwSelGlossaryDlg(weld::Window *pParent, const OUString &rShortName) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwSortingDialog(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwTableHeightDialog(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwColumnDialog(weld::Window *pParent, SwWrtShell &rSh) override;
+ virtual VclPtr<AbstractSplitTableDialog> CreateSplitTableDialog(weld::Window* pParent, SwWrtShell &rSh) override;
+
+ virtual VclPtr<AbstractSwAutoFormatDlg> CreateSwAutoFormatDlg(weld::Window* pParent, SwWrtShell* pShell,
+ bool bSetAutoFormat = true,
+ const SwTableAutoFormat* pSelFormat = nullptr) override;
+ virtual VclPtr<SfxAbstractDialog> CreateSwBorderDlg(weld::Window* pParent, SfxItemSet& rSet, SwBorderModes nType) override;
+
+ virtual VclPtr<SfxAbstractDialog> CreateSwWrapDlg(weld::Window* pParent, SfxItemSet& rSet, SwWrtShell* pSh) override;
+ virtual VclPtr<VclAbstractDialog> CreateSwTableWidthDlg(weld::Window *pParent, SwTableFUNC &rFnc) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSwTableTabDlg(weld::Window* pParent,
+ const SfxItemSet* pItemSet, SwWrtShell* pSh) override;
+ virtual VclPtr<AbstractSwFieldDlg> CreateSwFieldDlg(SfxBindings* pB, SwChildWinWrapper* pCW, weld::Window *pParent) override;
+ virtual VclPtr<SfxAbstractDialog> CreateSwFieldEditDlg ( SwView& rVw ) override;
+ virtual VclPtr<AbstractSwRenameXNamedDlg> CreateSwRenameXNamedDlg(weld::Widget* pParent,
+ css::uno::Reference< css::container::XNamed > & xNamed,
+ css::uno::Reference< css::container::XNameAccess > & xNameAccess) override;
+ virtual VclPtr<AbstractSwModalRedlineAcceptDlg> CreateSwModalRedlineAcceptDlg(weld::Window *pParent) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateTableMergeDialog(weld::Window* pParent, bool& rWithPrev) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateFrameTabDialog( const OUString &rDialogType,
+ SfxViewFrame& rFrame, weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bNewFrame = true,
+ const OUString& sDefPage = {}) override;
+ virtual VclPtr<SfxAbstractApplyTabDialog> CreateTemplateDialog(
+ weld::Window *pParent,
+ SfxStyleSheetBase& rBase,
+ SfxStyleFamily nRegion,
+ const OUString& sPage,
+ SwWrtShell* pActShell,
+ bool bNew) override;
+ virtual VclPtr<AbstractGlossaryDlg> CreateGlossaryDlg(SfxViewFrame& rViewFrame,
+ SwGlossaryHdl* pGlosHdl,
+ SwWrtShell *pWrtShell) override;
+ virtual VclPtr<AbstractFieldInputDlg> CreateFieldInputDlg(weld::Widget *pParent,
+ SwWrtShell &rSh, SwField* pField, bool bPrevButton, bool bNextButton) override;
+ virtual VclPtr<AbstractInsFootNoteDlg> CreateInsFootNoteDlg(
+ weld::Window * pParent, SwWrtShell &rSh, bool bEd = false) override;
+ virtual VclPtr<VclAbstractDialog> CreateTitlePageDlg(weld::Window* pParent) override;
+ virtual VclPtr<VclAbstractDialog> CreateVclSwViewDialog(SwView& rView) override;
+ virtual std::shared_ptr<AbstractInsTableDlg> CreateInsTableDlg(SwView& rView) override;
+ virtual VclPtr<AbstractJavaEditDialog> CreateJavaEditDialog(weld::Window* pParent,
+ SwWrtShell* pWrtSh) override;
+ virtual VclPtr<AbstractMailMergeDlg> CreateMailMergeDlg(
+ weld::Window* pParent, SwWrtShell& rSh,
+ const OUString& rSourceName,
+ const OUString& rTableName,
+ sal_Int32 nCommandType,
+ const css::uno::Reference< css::sdbc::XConnection>& xConnection ) override;
+ virtual VclPtr<AbstractMailMergeCreateFromDlg> CreateMailMergeCreateFromDlg(weld::Window* pParent) override;
+ virtual VclPtr<AbstractMailMergeFieldConnectionsDlg> CreateMailMergeFieldConnectionsDlg(weld::Window* pParent) override;
+ virtual VclPtr<VclAbstractDialog> CreateMultiTOXMarkDlg(weld::Window* pParent, SwTOXMgr &rTOXMgr) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateOutlineTabDialog(weld::Window* pParent, const SfxItemSet* pSwItemSet,
+ SwWrtShell &) override;
+ virtual VclPtr<AbstractNumBulletDialog> CreateSvxNumBulletTabDialog(weld::Window* pParent,
+ const SfxItemSet& rSwItemSet,
+ SwWrtShell &) override;
+ virtual VclPtr<AbstractMultiTOXTabDialog> CreateMultiTOXTabDialog(
+ weld::Widget* pParent, const SfxItemSet& rSet,
+ SwWrtShell &rShell,
+ SwTOXBase* pCurTOX,
+ bool bGlobal) override;
+ virtual VclPtr<AbstractEditRegionDlg> CreateEditRegionDlg(weld::Window* pParent, SwWrtShell& rWrtSh) override;
+ virtual VclPtr<AbstractInsertSectionTabDialog> CreateInsertSectionTabDialog(
+ weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell& rSh) override;
+ virtual VclPtr<AbstractMarkFloatDlg> CreateIndexMarkFloatDlg(
+ SfxBindings* pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo* pInfo) override;
+ virtual VclPtr<AbstractMarkFloatDlg> CreateAuthMarkFloatDlg(
+ SfxBindings* pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo* pInfo) override;
+ virtual VclPtr<VclAbstractDialog> CreateIndexMarkModalDlg(
+ weld::Window *pParent, SwWrtShell& rSh, SwTOXMark* pCurTOXMark ) override;
+
+ virtual VclPtr<AbstractMailMergeWizard> CreateMailMergeWizard(SwView& rView, std::shared_ptr<SwMailMergeConfigItem>& rConfigItem) override;
+
+ virtual GlossaryGetCurrGroup GetGlossaryCurrGroupFunc() override;
+ virtual GlossarySetActGroup SetGlossaryActGroupFunc() override;
+
+ // For TabPage
+ virtual CreateTabPage GetTabPageCreatorFunc( sal_uInt16 nId ) override;
+
+ virtual void ExecuteMMResultSaveDialog(weld::Window* pParent) override;
+ virtual void ExecuteMMResultPrintDialog(weld::Window* pParent) override;
+ virtual void ExecuteMMResultEmailDialog(weld::Window* pParent) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/swmessdialog.cxx b/sw/source/ui/dialog/swmessdialog.cxx
new file mode 100644
index 0000000000..abdf16bf4d
--- /dev/null
+++ b/sw/source/ui/dialog/swmessdialog.cxx
@@ -0,0 +1,20 @@
+/* -*- 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 <swmessdialog.hxx>
+
+SwMessageAndEditDialog::SwMessageAndEditDialog(weld::Window* pParent, const OUString& rID,
+ const OUString& rUIXMLDescription)
+ : MessageDialogController(pParent, rUIXMLDescription, rID, "grid")
+ , m_xEdit(m_xBuilder->weld_entry("edit"))
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/swuiexp.cxx b/sw/source/ui/dialog/swuiexp.cxx
new file mode 100644
index 0000000000..e141dab80d
--- /dev/null
+++ b/sw/source/ui/dialog/swuiexp.cxx
@@ -0,0 +1,40 @@
+/* -*- 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 "swdlgfact.hxx"
+
+#include <swuiexp.hxx>
+
+namespace swui
+{
+SwAbstractDialogFactory& GetFactory()
+{
+ static SwAbstractDialogFactory_Impl aFactory;
+ return aFactory;
+}
+}
+
+extern "C" {
+SAL_DLLPUBLIC_EXPORT SwAbstractDialogFactory* SwCreateDialogFactory()
+{
+ return &::swui::GetFactory();
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/uiregionsw.cxx b/sw/source/ui/dialog/uiregionsw.cxx
new file mode 100644
index 0000000000..f0318a4caf
--- /dev/null
+++ b/sw/source/ui/dialog/uiregionsw.cxx
@@ -0,0 +1,2145 @@
+/* -*- 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 <hintids.hxx>
+#include <regionsw.hxx>
+#include <svl/urihelper.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <sfx2/passwd.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/docinsert.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <osl/diagnose.h>
+#include <o3tl/string_view.hxx>
+#include <comphelper/lok.hxx>
+
+#include <uitool.hxx>
+#include <IMark.hxx>
+#include <section.hxx>
+#include <docary.hxx>
+#include <doc.hxx>
+#include <wdocsh.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <column.hxx>
+#include <fmtclbl.hxx>
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+#include <shellio.hxx>
+
+#include <cmdid.h>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <sfx2/bindings.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/flagsdef.hxx>
+#include <memory>
+#include <string_view>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+OUString BuildBitmap(bool bProtect, bool bHidden)
+{
+ if (bProtect)
+ return bHidden ? RID_BMP_PROT_HIDE : RID_BMP_PROT_NO_HIDE;
+ return bHidden ? RID_BMP_HIDE : RID_BMP_NO_HIDE;
+}
+
+OUString CollapseWhiteSpaces(std::u16string_view sName)
+{
+ const sal_Int32 nLen = sName.size();
+ const sal_Unicode cRef = ' ';
+ OUStringBuffer aBuf(nLen);
+ for (sal_Int32 i = 0; i<nLen; )
+ {
+ const sal_Unicode cCur = sName[i++];
+ aBuf.append(cCur);
+ if (cCur!=cRef)
+ continue;
+ while (i<nLen && sName[i]==cRef)
+ ++i;
+ }
+ return aBuf.makeStringAndClear();
+}
+
+}
+
+static void lcl_ReadSections( SfxMedium& rMedium, weld::ComboBox& rBox );
+
+static void lcl_FillList( SwWrtShell& rSh, weld::ComboBox& rSubRegions, weld::ComboBox* pAvailNames, const SwSectionFormat* pNewFormat )
+{
+ if( !pNewFormat )
+ {
+ const size_t nCount = rSh.GetSectionFormatCount();
+ for (size_t i = 0; i<nCount; i++)
+ {
+ SectionType eTmpType;
+ const SwSectionFormat* pFormat = &rSh.GetSectionFormat(i);
+ if( !pFormat->GetParent() &&
+ pFormat->IsInNodesArr() &&
+ (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
+ && SectionType::ToxHeader != eTmpType )
+ {
+ const OUString sString(pFormat->GetSection()->GetSectionName());
+ if (pAvailNames)
+ pAvailNames->append_text(sString);
+ rSubRegions.append_text(sString);
+ lcl_FillList( rSh, rSubRegions, pAvailNames, pFormat );
+ }
+ }
+ }
+ else
+ {
+ SwSections aTmpArr;
+ pNewFormat->GetChildSections(aTmpArr, SectionSort::Pos);
+ if( !aTmpArr.empty() )
+ {
+ SectionType eTmpType;
+ for( const auto pSect : aTmpArr )
+ {
+ const SwSectionFormat* pFormat = pSect->GetFormat();
+ if( pFormat->IsInNodesArr()&&
+ (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
+ && SectionType::ToxHeader != eTmpType )
+ {
+ const OUString sString(pFormat->GetSection()->GetSectionName());
+ if (pAvailNames)
+ pAvailNames->append_text(sString);
+ rSubRegions.append_text(sString);
+ lcl_FillList( rSh, rSubRegions, pAvailNames, pFormat );
+ }
+ }
+ }
+ }
+}
+
+static void lcl_FillSubRegionList( SwWrtShell& rSh, weld::ComboBox& rSubRegions, weld::ComboBox* pAvailNames )
+{
+ rSubRegions.clear();
+ lcl_FillList( rSh, rSubRegions, pAvailNames, nullptr );
+ IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
+ for( IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd();
+ ++ppMark)
+ {
+ const ::sw::mark::IMark* pBkmk = *ppMark;
+ if( pBkmk->IsExpanded() )
+ rSubRegions.append_text( pBkmk->GetName() );
+ }
+}
+
+// user data class for region information
+class SectRepr
+{
+private:
+ SwSectionData m_SectionData;
+ SwFormatCol m_Col;
+ std::unique_ptr<SvxBrushItem> m_Brush;
+ SwFormatFootnoteAtTextEnd m_FootnoteNtAtEnd;
+ SwFormatEndAtTextEnd m_EndNtAtEnd;
+ SwFormatNoBalancedColumns m_Balance;
+ std::shared_ptr<SvxFrameDirectionItem> m_FrameDirItem;
+ std::shared_ptr<SvxLRSpaceItem> m_LRSpaceItem;
+ const size_t m_nArrPos;
+ // shows, if maybe textcontent is in the region
+ bool m_bContent : 1;
+ // for multiselection, mark at first, then work with TreeListBox!
+ bool m_bSelected : 1;
+ uno::Sequence<sal_Int8> m_TempPasswd;
+
+public:
+ SectRepr(size_t nPos, SwSection& rSect);
+
+ SwSectionData & GetSectionData() { return m_SectionData; }
+ SwFormatCol& GetCol() { return m_Col; }
+ std::unique_ptr<SvxBrushItem>& GetBackground() { return m_Brush; }
+ SwFormatFootnoteAtTextEnd& GetFootnoteNtAtEnd() { return m_FootnoteNtAtEnd; }
+ SwFormatEndAtTextEnd& GetEndNtAtEnd() { return m_EndNtAtEnd; }
+ SwFormatNoBalancedColumns& GetBalance() { return m_Balance; }
+ std::shared_ptr<SvxFrameDirectionItem>& GetFrameDir() { return m_FrameDirItem; }
+ std::shared_ptr<SvxLRSpaceItem>& GetLRSpace() { return m_LRSpaceItem; }
+
+ size_t GetArrPos() const { return m_nArrPos; }
+ OUString GetFile() const;
+ OUString GetSubRegion() const;
+ void SetFile(std::u16string_view rFile);
+ void SetFilter(std::u16string_view rFilter);
+ void SetSubRegion(std::u16string_view rSubRegion);
+
+ bool IsContent() const { return m_bContent; }
+ void SetContent(bool const bValue) { m_bContent = bValue; }
+
+ void SetSelected() { m_bSelected = true; }
+ bool IsSelected() const { return m_bSelected; }
+
+ uno::Sequence<sal_Int8> & GetTempPasswd() { return m_TempPasswd; }
+ void SetTempPasswd(const uno::Sequence<sal_Int8> & rPasswd)
+ { m_TempPasswd = rPasswd; }
+};
+
+SectRepr::SectRepr( size_t nPos, SwSection& rSect )
+ : m_SectionData( rSect )
+ , m_Brush(std::make_unique<SvxBrushItem>(RES_BACKGROUND))
+ , m_FrameDirItem(std::make_shared<SvxFrameDirectionItem>(SvxFrameDirection::Environment, RES_FRAMEDIR))
+ , m_LRSpaceItem(std::make_shared<SvxLRSpaceItem>(RES_LR_SPACE))
+ , m_nArrPos(nPos)
+ , m_bContent(m_SectionData.GetLinkFileName().isEmpty())
+ , m_bSelected(false)
+{
+ SwSectionFormat *pFormat = rSect.GetFormat();
+ if( pFormat )
+ {
+ m_Col = pFormat->GetCol();
+ m_Brush = pFormat->makeBackgroundBrushItem();
+ m_FootnoteNtAtEnd = pFormat->GetFootnoteAtTextEnd();
+ m_EndNtAtEnd = pFormat->GetEndAtTextEnd();
+ m_Balance.SetValue(pFormat->GetBalancedColumns().GetValue());
+ m_FrameDirItem.reset(pFormat->GetFrameDir().Clone());
+ m_LRSpaceItem.reset(pFormat->GetLRSpace().Clone());
+ }
+}
+
+void SectRepr::SetFile( std::u16string_view rFile )
+{
+ OUString sNewFile( INetURLObject::decode( rFile,
+ INetURLObject::DecodeMechanism::Unambiguous ));
+ const OUString sOldFileName( m_SectionData.GetLinkFileName() );
+ const std::u16string_view sSub( o3tl::getToken(sOldFileName, 2, sfx2::cTokenSeparator ) );
+
+ if( !rFile.empty() || !sSub.empty() )
+ {
+ sNewFile += OUStringChar(sfx2::cTokenSeparator);
+ if( !rFile.empty() ) // Filter only with FileName
+ sNewFile += o3tl::getToken(sOldFileName, 1, sfx2::cTokenSeparator );
+
+ sNewFile += OUStringChar(sfx2::cTokenSeparator) + sSub;
+ }
+
+ m_SectionData.SetLinkFileName( sNewFile );
+
+ if( !rFile.empty() || !sSub.empty() )
+ {
+ m_SectionData.SetType( SectionType::FileLink );
+ }
+ else
+ {
+ m_SectionData.SetType( SectionType::Content );
+ }
+}
+
+void SectRepr::SetFilter( std::u16string_view rFilter )
+{
+ OUString sNewFile;
+ const OUString sOldFileName( m_SectionData.GetLinkFileName() );
+ sal_Int32 nIdx{ 0 };
+ const std::u16string_view sFile( o3tl::getToken(sOldFileName, 0, sfx2::cTokenSeparator, nIdx ) ); // token 0
+ const std::u16string_view sSub( o3tl::getToken(sOldFileName, 1, sfx2::cTokenSeparator, nIdx ) ); // token 2
+
+ if( !sFile.empty() )
+ sNewFile = sFile + OUStringChar(sfx2::cTokenSeparator) +
+ rFilter + OUStringChar(sfx2::cTokenSeparator) + sSub;
+ else if( !sSub.empty() )
+ sNewFile = OUStringChar(sfx2::cTokenSeparator) + OUStringChar(sfx2::cTokenSeparator) + sSub;
+
+ m_SectionData.SetLinkFileName( sNewFile );
+
+ if( !sNewFile.isEmpty() )
+ {
+ m_SectionData.SetType( SectionType::FileLink );
+ }
+}
+
+void SectRepr::SetSubRegion(std::u16string_view rSubRegion)
+{
+ OUString sNewFile;
+ sal_Int32 n(0);
+ const OUString sLinkFileName(m_SectionData.GetLinkFileName());
+ const std::u16string_view sOldFileName( o3tl::getToken(sLinkFileName, 0, sfx2::cTokenSeparator, n ) );
+ const std::u16string_view sFilter( o3tl::getToken(sLinkFileName, 0, sfx2::cTokenSeparator, n ) );
+
+ if( !rSubRegion.empty() || !sOldFileName.empty() )
+ sNewFile = sOldFileName + OUStringChar(sfx2::cTokenSeparator) +
+ sFilter + OUStringChar(sfx2::cTokenSeparator) + rSubRegion;
+
+ m_SectionData.SetLinkFileName( sNewFile );
+
+ if( !rSubRegion.empty() || !sOldFileName.empty() )
+ {
+ m_SectionData.SetType( SectionType::FileLink );
+ }
+ else
+ {
+ m_SectionData.SetType( SectionType::Content );
+ }
+}
+
+OUString SectRepr::GetFile() const
+{
+ const OUString sLinkFile( m_SectionData.GetLinkFileName() );
+
+ if( sLinkFile.isEmpty() )
+ {
+ return sLinkFile;
+ }
+ if (SectionType::DdeLink == m_SectionData.GetType())
+ {
+ sal_Int32 n = 0;
+ return sLinkFile.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &n )
+ .replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &n );
+ }
+ return INetURLObject::decode( o3tl::getToken(sLinkFile, 0, sfx2::cTokenSeparator ),
+ INetURLObject::DecodeMechanism::Unambiguous );
+}
+
+OUString SectRepr::GetSubRegion() const
+{
+ const OUString sLinkFile( m_SectionData.GetLinkFileName() );
+ if( !sLinkFile.isEmpty() )
+ return sLinkFile.getToken( 2, sfx2::cTokenSeparator );
+ return sLinkFile;
+}
+
+// dialog edit regions
+SwEditRegionDlg::SwEditRegionDlg(weld::Window* pParent, SwWrtShell& rWrtSh)
+ : SfxDialogController(pParent, "modules/swriter/ui/editsectiondialog.ui",
+ "EditSectionDialog")
+ , m_bSubRegionsFilled(false)
+ , m_rSh(rWrtSh)
+ , m_bDontCheckPasswd(true)
+ , m_xCurName(m_xBuilder->weld_entry("curname"))
+ , m_xTree(m_xBuilder->weld_tree_view("tree"))
+ , m_xFileCB(m_xBuilder->weld_check_button("link"))
+ , m_xDDECB(m_xBuilder->weld_check_button("dde"))
+ , m_xDDEFrame(m_xBuilder->weld_widget("ddedepend"))
+ , m_xFileNameFT(m_xBuilder->weld_label("filenameft"))
+ , m_xDDECommandFT(m_xBuilder->weld_label("ddeft"))
+ , m_xFileNameED(m_xBuilder->weld_entry("filename"))
+ , m_xFilePB(m_xBuilder->weld_button("file"))
+ , m_xSubRegionFT(m_xBuilder->weld_label("sectionft"))
+ , m_xSubRegionED(m_xBuilder->weld_combo_box("section"))
+ , m_xProtectCB(m_xBuilder->weld_check_button("protect"))
+ , m_xPasswdCB(m_xBuilder->weld_check_button("withpassword"))
+ , m_xPasswdPB(m_xBuilder->weld_button("password"))
+ , m_xHideCB(m_xBuilder->weld_check_button("hide"))
+ , m_xConditionFT(m_xBuilder->weld_label("conditionft"))
+ , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry("condition")))
+ , m_xEditInReadonlyCB(m_xBuilder->weld_check_button("editinro"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xOptionsPB(m_xBuilder->weld_button("options"))
+ , m_xDismiss(m_xBuilder->weld_button("remove"))
+ , m_xHideFrame(m_xBuilder->weld_widget("hideframe"))
+{
+ m_xTree->set_size_request(-1, m_xTree->get_height_rows(16));
+ m_xFileCB->set_state(TRISTATE_FALSE);
+ m_xSubRegionED->make_sorted();
+ m_xProtectCB->set_state(TRISTATE_FALSE);
+ m_xHideCB->set_state(TRISTATE_FALSE);
+ // edit in readonly sections
+ m_xEditInReadonlyCB->set_state(TRISTATE_FALSE);
+
+ bool bWeb = dynamic_cast<SwWebDocShell*>( m_rSh.GetView().GetDocShell() ) != nullptr;
+
+ m_xTree->connect_changed(LINK(this, SwEditRegionDlg, GetFirstEntryHdl));
+ m_xCurName->connect_changed(LINK(this, SwEditRegionDlg, NameEditHdl));
+ m_xConditionED->connect_changed( LINK( this, SwEditRegionDlg, ConditionEditHdl));
+ m_xOK->connect_clicked( LINK( this, SwEditRegionDlg, OkHdl));
+ m_xPasswdCB->connect_toggled(LINK(this, SwEditRegionDlg, TogglePasswdHdl));
+ m_xPasswdPB->connect_clicked(LINK(this, SwEditRegionDlg, ChangePasswdHdl));
+ m_xHideCB->connect_toggled(LINK(this, SwEditRegionDlg, ChangeHideHdl));
+ // edit in readonly sections
+ m_xEditInReadonlyCB->connect_toggled(LINK(this, SwEditRegionDlg, ChangeEditInReadonlyHdl));
+
+ m_xOptionsPB->connect_clicked(LINK(this, SwEditRegionDlg, OptionsHdl));
+ m_xProtectCB->connect_toggled(LINK(this, SwEditRegionDlg, ChangeProtectHdl));
+ m_xDismiss->connect_clicked( LINK( this, SwEditRegionDlg, ChangeDismissHdl));
+ m_xFileCB->connect_toggled(LINK(this, SwEditRegionDlg, UseFileHdl));
+ m_xFilePB->connect_clicked(LINK(this, SwEditRegionDlg, FileSearchHdl));
+ m_xFileNameED->connect_changed(LINK(this, SwEditRegionDlg, FileNameEntryHdl));
+ m_xSubRegionED->connect_changed(LINK(this, SwEditRegionDlg, FileNameComboBoxHdl));
+ m_xSubRegionED->connect_popup_toggled(LINK(this, SwEditRegionDlg, SubRegionEventHdl));
+ m_xSubRegionED->set_entry_completion(true, true);
+
+ m_xTree->set_selection_mode(SelectionMode::Multiple);
+
+ if (bWeb)
+ {
+ m_xDDECB->hide();
+ m_xHideFrame->hide();
+ m_xPasswdCB->hide();
+ }
+
+ m_xDDECB->connect_toggled(LINK(this, SwEditRegionDlg, DDEHdl));
+
+ m_pCurrSect = m_rSh.GetCurrSection();
+ RecurseList( nullptr, nullptr );
+
+ // if the cursor is not in a region the first one will always be selected
+ if (!m_xTree->get_selected(nullptr))
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
+ if (m_xTree->get_iter_first(*xIter))
+ {
+ m_xTree->select(*xIter);
+ GetFirstEntryHdl(*m_xTree);
+ }
+ }
+
+ m_xTree->show();
+ m_bDontCheckPasswd = false;
+
+ if(comphelper::LibreOfficeKit::isActive())
+ {
+ m_xDDECB->hide();
+ m_xDDECommandFT->hide();
+ m_xFileNameFT->hide();
+ m_xFileNameED->hide();
+ m_xFilePB->hide();
+ }
+}
+
+bool SwEditRegionDlg::CheckPasswd(weld::Toggleable* pBox)
+{
+ if (m_bDontCheckPasswd)
+ return true;
+ bool bRet = true;
+
+ m_xTree->selected_foreach([this, &bRet](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ if (!pRepr->GetTempPasswd().hasElements()
+ && pRepr->GetSectionData().GetPassword().hasElements())
+ {
+ SfxPasswordDialog aPasswdDlg(m_xDialog.get());
+ bRet = false;
+ if (aPasswdDlg.run())
+ {
+ const OUString sNewPasswd(aPasswdDlg.GetPassword());
+ css::uno::Sequence <sal_Int8 > aNewPasswd;
+ SvPasswordHelper::GetHashPassword( aNewPasswd, sNewPasswd );
+ if (SvPasswordHelper::CompareHashPassword(
+ pRepr->GetSectionData().GetPassword(), sNewPasswd))
+ {
+ pRepr->SetTempPasswd(aNewPasswd);
+ bRet = true;
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_WRONG_PASSWORD)));
+ xInfoBox->run();
+ }
+ }
+ }
+ return false;
+ });
+ if (!bRet && pBox)
+ {
+ //reset old button state
+ if (pBox->get_state() != TRISTATE_INDET)
+ pBox->set_active(!pBox->get_active());
+ }
+
+ return bRet;
+}
+
+// recursively look for child-sections
+void SwEditRegionDlg::RecurseList(const SwSectionFormat* pFormat, const weld::TreeIter* pEntry)
+{
+ std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
+ if (!pFormat)
+ {
+ const size_t nCount=m_rSh.GetSectionFormatCount();
+ for ( size_t n = 0; n < nCount; n++ )
+ {
+ SectionType eTmpType;
+ if( !( pFormat = &m_rSh.GetSectionFormat(n))->GetParent() &&
+ pFormat->IsInNodesArr() &&
+ (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
+ && SectionType::ToxHeader != eTmpType )
+ {
+ SwSection *pSect = pFormat->GetSection();
+ SectRepr* pSectRepr = new SectRepr( n, *pSect );
+
+ OUString sText(pSect->GetSectionName());
+ OUString sImage(BuildBitmap(pSect->IsProtect(),pSect->IsHidden()));
+ OUString sId(weld::toId(pSectRepr));
+ m_xTree->insert(nullptr, -1, &sText, &sId, nullptr, nullptr, false, xIter.get());
+ m_xTree->set_image(*xIter, sImage);
+
+ RecurseList(pFormat, xIter.get());
+ if (m_xTree->iter_has_child(*xIter))
+ m_xTree->expand_row(*xIter);
+ if (m_pCurrSect==pSect)
+ {
+ m_xTree->select(*xIter);
+ m_xTree->scroll_to_row(*xIter);
+ GetFirstEntryHdl(*m_xTree);
+ }
+ }
+ }
+ }
+ else
+ {
+ SwSections aTmpArr;
+ pFormat->GetChildSections(aTmpArr, SectionSort::Pos);
+ for( const auto pSect : aTmpArr )
+ {
+ SectionType eTmpType;
+ pFormat = pSect->GetFormat();
+ if( pFormat->IsInNodesArr() &&
+ (eTmpType = pFormat->GetSection()->GetType()) != SectionType::ToxContent
+ && SectionType::ToxHeader != eTmpType )
+ {
+ SectRepr* pSectRepr=new SectRepr(
+ FindArrPos( pSect->GetFormat() ), *pSect );
+
+ OUString sText(pSect->GetSectionName());
+ OUString sImage = BuildBitmap(pSect->IsProtect(), pSect->IsHidden());
+ OUString sId(weld::toId(pSectRepr));
+ m_xTree->insert(pEntry, -1, &sText, &sId, nullptr, nullptr, false, xIter.get());
+ m_xTree->set_image(*xIter, sImage);
+
+ RecurseList(pSect->GetFormat(), xIter.get());
+ if (m_xTree->iter_has_child(*xIter))
+ m_xTree->expand_row(*xIter);
+ if (m_pCurrSect==pSect)
+ {
+ m_xTree->select(*xIter);
+ m_xTree->scroll_to_row(*xIter);
+ GetFirstEntryHdl(*m_xTree);
+ }
+ }
+ }
+ }
+}
+
+size_t SwEditRegionDlg::FindArrPos(const SwSectionFormat* pFormat )
+{
+ const size_t nCount=m_rSh.GetSectionFormatCount();
+ for ( size_t i = 0; i < nCount; i++ )
+ if ( pFormat == &m_rSh.GetSectionFormat(i) )
+ return i;
+
+ OSL_FAIL("SectionFormat not on the list" );
+ return SIZE_MAX;
+}
+
+SwEditRegionDlg::~SwEditRegionDlg( )
+{
+ std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
+ if (m_xTree->get_iter_first(*xIter))
+ {
+ do
+ {
+ delete weld::fromId<SectRepr*>(m_xTree->get_id(*xIter));
+ } while (m_xTree->iter_next(*xIter));
+ }
+}
+
+void SwEditRegionDlg::SelectSection(std::u16string_view rSectionName)
+{
+ std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
+ if (!m_xTree->get_iter_first(*xIter))
+ return;
+
+ do
+ {
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(*xIter));
+ if (pRepr->GetSectionData().GetSectionName() == rSectionName)
+ {
+ m_xTree->unselect_all();
+ m_xTree->select(*xIter);
+ m_xTree->scroll_to_row(*xIter);
+ GetFirstEntryHdl(*m_xTree);
+ break;
+ }
+ } while (m_xTree->iter_next(*xIter));
+}
+
+// selected entry in TreeListBox is showed in Edit window in case of
+// multiselection some controls are disabled
+IMPL_LINK(SwEditRegionDlg, GetFirstEntryHdl, weld::TreeView&, rBox, void)
+{
+ m_bDontCheckPasswd = true;
+ std::unique_ptr<weld::TreeIter> xIter(rBox.make_iterator());
+ bool bEntry = rBox.get_selected(xIter.get());
+ m_xHideCB->set_sensitive(true);
+ // edit in readonly sections
+ m_xEditInReadonlyCB->set_sensitive(true);
+
+ m_xProtectCB->set_sensitive(true);
+ m_xFileCB->set_sensitive(true);
+ css::uno::Sequence <sal_Int8> aCurPasswd;
+ if (1 < rBox.count_selected_rows())
+ {
+ m_xHideCB->set_state(TRISTATE_INDET);
+ m_xProtectCB->set_state(TRISTATE_INDET);
+ // edit in readonly sections
+ m_xEditInReadonlyCB->set_state(TRISTATE_INDET);
+ m_xFileCB->set_state(TRISTATE_INDET);
+
+ bool bHiddenValid = true;
+ bool bProtectValid = true;
+ bool bConditionValid = true;
+ // edit in readonly sections
+ bool bEditInReadonlyValid = true;
+ bool bEditInReadonly = true;
+
+ bool bHidden = true;
+ bool bProtect = true;
+ OUString sCondition;
+ bool bFirst = true;
+ bool bFileValid = true;
+ bool bFile = true;
+ bool bPasswdValid = true;
+
+ m_xTree->selected_foreach([&](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ SwSectionData const& rData( pRepr->GetSectionData() );
+ if(bFirst)
+ {
+ sCondition = rData.GetCondition();
+ bHidden = rData.IsHidden();
+ bProtect = rData.IsProtectFlag();
+ // edit in readonly sections
+ bEditInReadonly = rData.IsEditInReadonlyFlag();
+
+ bFile = (rData.GetType() != SectionType::Content);
+ aCurPasswd = rData.GetPassword();
+ }
+ else
+ {
+ if(sCondition != rData.GetCondition())
+ bConditionValid = false;
+ bHiddenValid = (bHidden == rData.IsHidden());
+ bProtectValid = (bProtect == rData.IsProtectFlag());
+ // edit in readonly sections
+ bEditInReadonlyValid =
+ (bEditInReadonly == rData.IsEditInReadonlyFlag());
+
+ bFileValid = (bFile ==
+ (rData.GetType() != SectionType::Content));
+ bPasswdValid = (aCurPasswd == rData.GetPassword());
+ }
+ bFirst = false;
+ return false;
+ });
+
+ m_xHideCB->set_state(!bHiddenValid ? TRISTATE_INDET :
+ bHidden ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xProtectCB->set_state(!bProtectValid ? TRISTATE_INDET :
+ bProtect ? TRISTATE_TRUE : TRISTATE_FALSE);
+ // edit in readonly sections
+ m_xEditInReadonlyCB->set_state(!bEditInReadonlyValid ? TRISTATE_INDET :
+ bEditInReadonly ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ m_xFileCB->set_state(!bFileValid ? TRISTATE_INDET :
+ bFile ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ if (bConditionValid)
+ m_xConditionED->set_text(sCondition);
+ else
+ {
+ m_xConditionFT->set_sensitive(false);
+ m_xConditionED->set_sensitive(false);
+ }
+
+ m_xCurName->set_sensitive(false);
+ m_xDDECB->set_sensitive(false);
+ m_xDDEFrame->set_sensitive(false);
+ m_xOptionsPB->set_sensitive(false);
+ bool bPasswdEnabled = m_xProtectCB->get_state() == TRISTATE_TRUE;
+ m_xPasswdCB->set_sensitive(bPasswdEnabled);
+ m_xPasswdPB->set_sensitive(bPasswdEnabled);
+ if(!bPasswdValid)
+ {
+ rBox.get_selected(xIter.get());
+ rBox.unselect_all();
+ rBox.select(*xIter);
+ GetFirstEntryHdl(rBox);
+ return;
+ }
+ else
+ m_xPasswdCB->set_active(aCurPasswd.hasElements());
+ }
+ else if (bEntry )
+ {
+ m_xCurName->set_sensitive(true);
+ m_xOptionsPB->set_sensitive(true);
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(*xIter));
+ SwSectionData const& rData( pRepr->GetSectionData() );
+ m_xConditionED->set_text(rData.GetCondition());
+ m_xHideCB->set_sensitive(true);
+ m_xHideCB->set_state((rData.IsHidden()) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ bool bHide = TRISTATE_TRUE == m_xHideCB->get_state();
+ m_xConditionED->set_sensitive(bHide);
+ m_xConditionFT->set_sensitive(bHide);
+ m_xPasswdCB->set_active(rData.GetPassword().hasElements());
+
+ m_xOK->set_sensitive(true);
+ m_xPasswdCB->set_sensitive(true);
+ m_xCurName->set_text(rBox.get_text(*xIter));
+ m_xCurName->set_sensitive(true);
+ m_xDismiss->set_sensitive(true);
+ const OUString aFile = pRepr->GetFile();
+ const OUString sSub = pRepr->GetSubRegion();
+ m_xSubRegionED->clear();
+ m_xSubRegionED->append_text(""); // put in a dummy entry, which is replaced when m_bSubRegionsFilled is set
+ m_bSubRegionsFilled = false;
+ if( !aFile.isEmpty() || !sSub.isEmpty() )
+ {
+ m_xFileCB->set_active(true);
+ m_xFileNameED->set_text(aFile);
+ m_xSubRegionED->set_entry_text(sSub);
+ m_xDDECB->set_active(rData.GetType() == SectionType::DdeLink);
+ }
+ else
+ {
+ m_xFileCB->set_active(false);
+ m_xFileNameED->set_text(aFile);
+ m_xDDECB->set_sensitive(false);
+ m_xDDECB->set_active(false);
+ }
+ UseFileHdl(*m_xFileCB);
+ DDEHdl(*m_xDDECB);
+ m_xProtectCB->set_state((rData.IsProtectFlag())
+ ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xProtectCB->set_sensitive(true);
+
+ // edit in readonly sections
+ m_xEditInReadonlyCB->set_state((rData.IsEditInReadonlyFlag())
+ ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xEditInReadonlyCB->set_sensitive(true);
+
+ bool bPasswdEnabled = m_xProtectCB->get_active();
+ m_xPasswdCB->set_sensitive(bPasswdEnabled);
+ m_xPasswdPB->set_sensitive(bPasswdEnabled);
+ }
+ m_bDontCheckPasswd = false;
+}
+
+// in OkHdl the modified settings are being applied and reversed regions are deleted
+IMPL_LINK_NOARG(SwEditRegionDlg, OkHdl, weld::Button&, void)
+{
+ // temp. Array because during changing of a region the position
+ // inside of the "Core-Arrays" can be shifted:
+ // - at linked regions, when they have more SubRegions or get
+ // new ones.
+ // StartUndo must certainly also happen not before the formats
+ // are copied (ClearRedo!)
+
+ const SwSectionFormats& rDocFormats = m_rSh.GetDoc()->GetSections();
+ SwSectionFormats aOrigArray(rDocFormats);
+
+ m_rSh.StartAllAction();
+ m_rSh.StartUndo();
+ m_rSh.ResetSelect( nullptr,false );
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
+ if (m_xTree->get_iter_first(*xIter))
+ {
+ do
+ {
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(*xIter));
+ SwSectionFormat* pFormat = aOrigArray[ pRepr->GetArrPos() ];
+ if (!pRepr->GetSectionData().IsProtectFlag())
+ {
+ pRepr->GetSectionData().SetPassword(uno::Sequence<sal_Int8 >());
+ }
+ size_t nNewPos = rDocFormats.GetPos(pFormat);
+ if ( SIZE_MAX != nNewPos )
+ {
+ SwAttrSet aSet(pFormat->GetAttrSet().CloneAsValue( false ));
+ if( pFormat->GetCol() != pRepr->GetCol() )
+ aSet.Put( pRepr->GetCol() );
+
+ std::unique_ptr<SvxBrushItem> aBrush(pFormat->makeBackgroundBrushItem(false));
+ if( pRepr->GetBackground() && *aBrush != *pRepr->GetBackground() )
+ aSet.Put( *pRepr->GetBackground() );
+
+ if( pFormat->GetFootnoteAtTextEnd(false) != pRepr->GetFootnoteNtAtEnd() )
+ aSet.Put( pRepr->GetFootnoteNtAtEnd() );
+
+ if( pFormat->GetEndAtTextEnd(false) != pRepr->GetEndNtAtEnd() )
+ aSet.Put( pRepr->GetEndNtAtEnd() );
+
+ if( pFormat->GetBalancedColumns() != pRepr->GetBalance() )
+ aSet.Put( pRepr->GetBalance() );
+
+ if( pFormat->GetFrameDir() != *pRepr->GetFrameDir() )
+ aSet.Put( *pRepr->GetFrameDir() );
+
+ if( pFormat->GetLRSpace() != *pRepr->GetLRSpace())
+ aSet.Put( *pRepr->GetLRSpace());
+
+ m_rSh.UpdateSection( nNewPos, pRepr->GetSectionData(),
+ aSet.Count() ? &aSet : nullptr );
+ }
+ } while (m_xTree->iter_next(*xIter));
+ }
+
+ for (SectReprs_t::reverse_iterator it = m_SectReprs.rbegin(), aEnd = m_SectReprs.rend(); it != aEnd; ++it)
+ {
+ assert(it->first == it->second->GetArrPos());
+ SwSectionFormat* pFormat = aOrigArray[ it->second->GetArrPos() ];
+ const size_t nNewPos = rDocFormats.GetPos( pFormat );
+ if( SIZE_MAX != nNewPos )
+ m_rSh.DelSectionFormat( nNewPos );
+ }
+
+ aOrigArray.clear();
+
+ // response must be called ahead of EndAction's end,
+ // otherwise ScrollError can occur.
+ m_xDialog->response(RET_OK);
+
+ m_rSh.EndUndo();
+ m_rSh.EndAllAction();
+}
+
+// Toggle protect
+IMPL_LINK(SwEditRegionDlg, ChangeProtectHdl, weld::Toggleable&, rButton, void)
+{
+ if (!CheckPasswd(&rButton))
+ return;
+ bool bCheck = TRISTATE_TRUE == rButton.get_state();
+ m_xTree->selected_foreach([this, bCheck](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ pRepr->GetSectionData().SetProtectFlag(bCheck);
+ OUString aImage = BuildBitmap(bCheck, TRISTATE_TRUE == m_xHideCB->get_state());
+ m_xTree->set_image(rEntry, aImage);
+ return false;
+ });
+ m_xPasswdCB->set_sensitive(bCheck);
+ m_xPasswdPB->set_sensitive(bCheck);
+}
+
+// Toggle hide
+IMPL_LINK( SwEditRegionDlg, ChangeHideHdl, weld::Toggleable&, rButton, void)
+{
+ if (!CheckPasswd(&rButton))
+ return;
+ m_xTree->selected_foreach([this, &rButton](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ pRepr->GetSectionData().SetHidden(TRISTATE_TRUE == rButton.get_state());
+ OUString aImage = BuildBitmap(TRISTATE_TRUE == m_xProtectCB->get_state(),
+ TRISTATE_TRUE == rButton.get_state());
+ m_xTree->set_image(rEntry, aImage);
+ return false;
+ });
+ bool bHide = TRISTATE_TRUE == rButton.get_state();
+ m_xConditionED->set_sensitive(bHide);
+ m_xConditionFT->set_sensitive(bHide);
+}
+
+// Toggle edit in readonly
+IMPL_LINK(SwEditRegionDlg, ChangeEditInReadonlyHdl, weld::Toggleable&, rButton, void)
+{
+ if (!CheckPasswd(&rButton))
+ return;
+ m_xTree->selected_foreach([this, &rButton](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ pRepr->GetSectionData().SetEditInReadonlyFlag(
+ TRISTATE_TRUE == rButton.get_state());
+ return false;
+ });
+}
+
+// clear selected region
+IMPL_LINK_NOARG(SwEditRegionDlg, ChangeDismissHdl, weld::Button&, void)
+{
+ if(!CheckPasswd())
+ return;
+ // at first mark all selected
+ m_xTree->selected_foreach([this](weld::TreeIter& rEntry){
+ SectRepr* const pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ pSectRepr->SetSelected();
+ return false;
+ });
+
+ std::unique_ptr<weld::TreeIter> xEntry(m_xTree->make_iterator());
+ bool bEntry(m_xTree->get_selected(xEntry.get()));
+ // then delete
+ while (bEntry)
+ {
+ SectRepr* const pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_id(*xEntry));
+ std::unique_ptr<weld::TreeIter> xRemove;
+ bool bRestart = false;
+ if (pSectRepr->IsSelected())
+ {
+ m_SectReprs.insert(std::make_pair(pSectRepr->GetArrPos(),
+ std::unique_ptr<SectRepr>(pSectRepr)));
+ if (m_xTree->iter_has_child(*xEntry))
+ {
+ std::unique_ptr<weld::TreeIter> xChild(m_xTree->make_iterator(xEntry.get()));
+ (void)m_xTree->iter_children(*xChild);
+ std::unique_ptr<weld::TreeIter> xParent(m_xTree->make_iterator(xEntry.get()));
+ if (!m_xTree->iter_parent(*xParent))
+ xParent.reset();
+ bool bChild = true;
+ do
+ {
+ // because of the repositioning we have to start at the beginning again
+ bRestart = true;
+ std::unique_ptr<weld::TreeIter> xMove(m_xTree->make_iterator(xChild.get()));
+ bChild = m_xTree->iter_next_sibling(*xChild);
+ m_xTree->move_subtree(*xMove, xParent.get(), m_xTree->get_iter_index_in_parent(*xEntry));
+ } while (bChild);
+ }
+ xRemove = m_xTree->make_iterator(xEntry.get());
+ }
+ if (bRestart)
+ bEntry = m_xTree->get_iter_first(*xEntry);
+ else
+ bEntry = m_xTree->iter_next(*xEntry);
+ if (xRemove)
+ m_xTree->remove(*xRemove);
+ }
+
+ if (m_xTree->get_selected(nullptr))
+ return;
+
+ m_xConditionFT->set_sensitive(false);
+ m_xConditionED->set_sensitive(false);
+ m_xDismiss->set_sensitive(false);
+ m_xCurName->set_sensitive(false);
+ m_xProtectCB->set_sensitive(false);
+ m_xPasswdCB->set_sensitive(false);
+ m_xHideCB->set_sensitive(false);
+ // edit in readonly sections
+ m_xEditInReadonlyCB->set_sensitive(false);
+ m_xEditInReadonlyCB->set_state(TRISTATE_FALSE);
+ m_xProtectCB->set_state(TRISTATE_FALSE);
+ m_xPasswdCB->set_active(false);
+ m_xHideCB->set_state(TRISTATE_FALSE);
+ m_xFileCB->set_active(false);
+ // otherwise the focus would be on HelpButton
+ m_xOK->grab_focus();
+ UseFileHdl(*m_xFileCB);
+}
+
+// link CheckBox to file?
+IMPL_LINK(SwEditRegionDlg, UseFileHdl, weld::Toggleable&, rButton, void)
+{
+ if (!CheckPasswd(&rButton))
+ return;
+ bool bMulti = 1 < m_xTree->count_selected_rows();
+ bool bFile = rButton.get_active();
+ if (m_xTree->get_selected(nullptr))
+ {
+ m_xTree->selected_foreach([&](weld::TreeIter& rEntry){
+ SectRepr* const pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ bool bContent = pSectRepr->IsContent();
+ if( rButton.get_active() && bContent && m_rSh.HasSelection() )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ SwResId(STR_QUERY_CONNECT)));
+ if (RET_NO == xQueryBox->run())
+ rButton.set_active( false );
+ }
+ if( bFile )
+ pSectRepr->SetContent(false);
+ else
+ {
+ pSectRepr->SetFile(u"");
+ pSectRepr->SetSubRegion(std::u16string_view());
+ pSectRepr->GetSectionData().SetLinkFilePassword(OUString());
+ }
+ return false;
+ });
+ m_xDDECB->set_sensitive(bFile && !bMulti);
+ m_xDDEFrame->set_sensitive(bFile && !bMulti);
+ if( bFile )
+ {
+ m_xProtectCB->set_state(TRISTATE_TRUE);
+ m_xFileNameED->grab_focus();
+
+ }
+ else
+ {
+ m_xDDECB->set_active(false);
+ m_xSubRegionED->set_entry_text(OUString());
+ }
+ DDEHdl(*m_xDDECB);
+ }
+ else
+ {
+ rButton.set_active(false);
+ rButton.set_sensitive(false);
+ m_xDDECB->set_active(false);
+ m_xDDECB->set_sensitive(false);
+ m_xDDEFrame->set_sensitive(false);
+ }
+}
+
+// call dialog paste file
+IMPL_LINK_NOARG(SwEditRegionDlg, FileSearchHdl, weld::Button&, void)
+{
+ if(!CheckPasswd())
+ return;
+ m_pDocInserter.reset(new ::sfx2::DocumentInserter(m_xDialog.get(), "swriter"));
+ m_pDocInserter->StartExecuteModal( LINK( this, SwEditRegionDlg, DlgClosedHdl ) );
+}
+
+IMPL_LINK_NOARG(SwEditRegionDlg, OptionsHdl, weld::Button&, void)
+{
+ if(!CheckPasswd())
+ return;
+ SectRepr* pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_selected_id());
+ if (!pSectRepr)
+ return;
+
+ SfxItemSetFixed<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_LR_SPACE, RES_LR_SPACE,
+ RES_BACKGROUND, RES_BACKGROUND,
+ RES_COL, RES_COL,
+ RES_FTN_AT_TXTEND, RES_FRAMEDIR,
+ XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE> aSet( m_rSh.GetView().GetPool() );
+
+ aSet.Put( pSectRepr->GetCol() );
+ aSet.Put( *pSectRepr->GetBackground() );
+ aSet.Put( pSectRepr->GetFootnoteNtAtEnd() );
+ aSet.Put( pSectRepr->GetEndNtAtEnd() );
+ aSet.Put( pSectRepr->GetBalance() );
+ aSet.Put( *pSectRepr->GetFrameDir() );
+ aSet.Put( *pSectRepr->GetLRSpace() );
+
+ const SwSectionFormats& rDocFormats = m_rSh.GetDoc()->GetSections();
+ SwSectionFormats aOrigArray(rDocFormats);
+
+ SwSectionFormat* pFormat = aOrigArray[pSectRepr->GetArrPos()];
+ tools::Long nWidth = m_rSh.GetSectionWidth(*pFormat);
+ aOrigArray.clear();
+ if (!nWidth)
+ nWidth = USHRT_MAX;
+
+ aSet.Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth));
+ aSet.Put(SvxSizeItem(SID_ATTR_PAGE_SIZE, Size(nWidth, nWidth)));
+
+ auto pDlg = std::make_shared<SwSectionPropertyTabDialog>(m_xDialog.get(), aSet, m_rSh);
+ SfxTabDialogController::runAsync(pDlg, [pDlg, this](sal_Int32 nResult){
+ if (nResult == RET_OK) {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ if( !(pOutSet && pOutSet->Count()) )
+ return;
+
+ const SwFormatCol* pColItem = pOutSet->GetItemIfSet(
+ RES_COL, false );
+ const SvxBrushItem* pBrushItem = pOutSet->GetItemIfSet(
+ RES_BACKGROUND, false );
+ const SwFormatFootnoteAtTextEnd* pFootnoteItem = pOutSet->GetItemIfSet(
+ RES_FTN_AT_TXTEND, false );
+ const SwFormatEndAtTextEnd* pEndItem = pOutSet->GetItemIfSet(
+ RES_END_AT_TXTEND, false );
+ const SwFormatNoBalancedColumns* pBalanceItem = pOutSet->GetItemIfSet(
+ RES_COLUMNBALANCE, false );
+ const SvxFrameDirectionItem* pFrameDirItem = pOutSet->GetItemIfSet(
+ RES_FRAMEDIR, false );
+ const SvxLRSpaceItem* pLRSpaceItem = pOutSet->GetItemIfSet(
+ RES_LR_SPACE, false );
+
+ if( !(pColItem ||
+ pBrushItem ||
+ pFootnoteItem ||
+ pEndItem ||
+ pBalanceItem ||
+ pFrameDirItem ||
+ pLRSpaceItem) )
+ return;
+
+ m_xTree->selected_foreach([&](weld::TreeIter& rEntry)
+ {
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ if (pColItem)
+ pRepr->GetCol() = *pColItem;
+ if (pBrushItem)
+ pRepr->GetBackground().reset(pBrushItem->Clone());
+ if (pFootnoteItem)
+ pRepr->GetFootnoteNtAtEnd() = *pFootnoteItem;
+ if (pEndItem)
+ pRepr->GetEndNtAtEnd() = *pEndItem;
+ if (pBalanceItem)
+ pRepr->GetBalance().SetValue(pBalanceItem->GetValue());
+ if (pFrameDirItem)
+ pRepr->GetFrameDir()->SetValue(pFrameDirItem->GetValue());
+ if (pLRSpaceItem)
+ pRepr->GetLRSpace().reset(pLRSpaceItem->Clone());
+ return false;
+ });
+ }
+ });
+
+}
+
+IMPL_LINK(SwEditRegionDlg, FileNameComboBoxHdl, weld::ComboBox&, rEdit, void)
+{
+ int nStartPos, nEndPos;
+ rEdit.get_entry_selection_bounds(nStartPos, nEndPos);
+ if (!CheckPasswd())
+ return;
+ rEdit.select_entry_region(nStartPos, nEndPos);
+ SectRepr* pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_selected_id());
+ pSectRepr->SetSubRegion( rEdit.get_active_text() );
+}
+
+// Applying of the filename or the linked region
+IMPL_LINK(SwEditRegionDlg, FileNameEntryHdl, weld::Entry&, rEdit, void)
+{
+ int nStartPos, nEndPos;
+ rEdit.get_selection_bounds(nStartPos, nEndPos);
+ if (!CheckPasswd())
+ return;
+ rEdit.select_region(nStartPos, nEndPos);
+ SectRepr* pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_selected_id());
+ m_xSubRegionED->clear();
+ m_xSubRegionED->append_text(""); // put in a dummy entry, which is replaced when m_bSubRegionsFilled is set
+ m_bSubRegionsFilled = false;
+ if (m_xDDECB->get_active())
+ {
+ OUString sLink( CollapseWhiteSpaces(rEdit.get_text()) );
+ sal_Int32 nPos = 0;
+ sLink = sLink.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nPos );
+ if (nPos>=0)
+ {
+ sLink = sLink.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nPos );
+ }
+
+ pSectRepr->GetSectionData().SetLinkFileName( sLink );
+ pSectRepr->GetSectionData().SetType( SectionType::DdeLink );
+ }
+ else
+ {
+ OUString sTmp(rEdit.get_text());
+ if(!sTmp.isEmpty())
+ {
+ SfxMedium* pMedium = m_rSh.GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+ sTmp = URIHelper::SmartRel2Abs(
+ aAbs, sTmp, URIHelper::GetMaybeFileHdl() );
+ }
+ pSectRepr->SetFile( sTmp );
+ pSectRepr->GetSectionData().SetLinkFilePassword(OUString());
+ }
+}
+
+IMPL_LINK(SwEditRegionDlg, DDEHdl, weld::Toggleable&, rButton, void)
+{
+ if (!CheckPasswd(&rButton))
+ return;
+ SectRepr* pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_selected_id());
+ if (!pSectRepr)
+ return;
+
+ bool bFile = m_xFileCB->get_active();
+ SwSectionData & rData( pSectRepr->GetSectionData() );
+ bool bDDE = rButton.get_active();
+ if(bDDE)
+ {
+ m_xFileNameFT->hide();
+ m_xDDECommandFT->set_sensitive(true);
+ m_xDDECommandFT->show();
+ m_xSubRegionFT->hide();
+ m_xSubRegionED->hide();
+ if (SectionType::FileLink == rData.GetType())
+ {
+ pSectRepr->SetFile(u"");
+ m_xFileNameED->set_text(OUString());
+ rData.SetLinkFilePassword(OUString());
+ }
+ rData.SetType(SectionType::DdeLink);
+ }
+ else
+ {
+ m_xDDECommandFT->hide();
+ m_xFileNameFT->set_sensitive(bFile);
+ if(!comphelper::LibreOfficeKit::isActive())
+ m_xFileNameFT->show();
+ m_xSubRegionED->show();
+ m_xSubRegionFT->show();
+ m_xSubRegionED->set_sensitive(bFile);
+ m_xSubRegionFT->set_sensitive(bFile);
+ m_xSubRegionED->set_sensitive(bFile);
+ if (SectionType::DdeLink == rData.GetType())
+ {
+ rData.SetType(SectionType::FileLink);
+ pSectRepr->SetFile(u"");
+ rData.SetLinkFilePassword(OUString());
+ m_xFileNameED->set_text(OUString());
+ }
+ }
+ m_xFilePB->set_sensitive(bFile && !bDDE);
+}
+
+void SwEditRegionDlg::ChangePasswd(bool bChange)
+{
+ if (!CheckPasswd())
+ {
+ if (!bChange)
+ m_xPasswdCB->set_active(!m_xPasswdCB->get_active());
+ return;
+ }
+
+ bool bSet = bChange ? bChange : m_xPasswdCB->get_active();
+
+ m_xTree->selected_foreach([this, bChange, bSet](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ if(bSet)
+ {
+ if(!pRepr->GetTempPasswd().hasElements() || bChange)
+ {
+ SfxPasswordDialog aPasswdDlg(m_xDialog.get());
+ aPasswdDlg.ShowExtras(SfxShowExtras::CONFIRM);
+ if (RET_OK == aPasswdDlg.run())
+ {
+ const OUString sNewPasswd(aPasswdDlg.GetPassword());
+ if (aPasswdDlg.GetConfirm() == sNewPasswd)
+ {
+ SvPasswordHelper::GetHashPassword( pRepr->GetTempPasswd(), sNewPasswd );
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_WRONG_PASSWD_REPEAT)));
+ xInfoBox->run();
+ ChangePasswd(bChange);
+ return true;
+ }
+ }
+ else
+ {
+ if(!bChange)
+ m_xPasswdCB->set_active(false);
+ return true;
+ }
+ }
+ pRepr->GetSectionData().SetPassword(pRepr->GetTempPasswd());
+ }
+ else
+ {
+ pRepr->GetSectionData().SetPassword(uno::Sequence<sal_Int8 >());
+ }
+ return false;
+ });
+}
+
+IMPL_LINK_NOARG(SwEditRegionDlg, TogglePasswdHdl, weld::Toggleable&, void)
+{
+ ChangePasswd(false);
+}
+
+IMPL_LINK_NOARG(SwEditRegionDlg, ChangePasswdHdl, weld::Button&, void)
+{
+ ChangePasswd(true);
+}
+
+// the current region name is being added to the TreeListBox immediately during
+// editing, with empty string no Ok()
+IMPL_LINK_NOARG(SwEditRegionDlg, NameEditHdl, weld::Entry&, void)
+{
+ if(!CheckPasswd())
+ return;
+ std::unique_ptr<weld::TreeIter> xIter(m_xTree->make_iterator());
+ if (m_xTree->get_selected(xIter.get()))
+ {
+ const OUString aName = m_xCurName->get_text();
+ m_xTree->set_text(*xIter, aName);
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(*xIter));
+ pRepr->GetSectionData().SetSectionName(aName);
+
+ m_xOK->set_sensitive(!aName.isEmpty());
+ }
+}
+
+IMPL_LINK( SwEditRegionDlg, ConditionEditHdl, weld::Entry&, rEdit, void )
+{
+ int nStartPos, nEndPos;
+ rEdit.get_selection_bounds(nStartPos, nEndPos);
+ if(!CheckPasswd())
+ return;
+ rEdit.select_region(nStartPos, nEndPos);
+
+ m_xTree->selected_foreach([this, &rEdit](weld::TreeIter& rEntry){
+ SectRepr* pRepr = weld::fromId<SectRepr*>(m_xTree->get_id(rEntry));
+ pRepr->GetSectionData().SetCondition(rEdit.get_text());
+ return false;
+ });
+}
+
+IMPL_LINK( SwEditRegionDlg, DlgClosedHdl, sfx2::FileDialogHelper *, _pFileDlg, void )
+{
+ OUString sFileName, sFilterName, sPassword;
+ if ( _pFileDlg->GetError() == ERRCODE_NONE )
+ {
+ std::unique_ptr<SfxMedium> pMedium(m_pDocInserter->CreateMedium("sglobal"));
+ if ( pMedium )
+ {
+ sFileName = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ sFilterName = pMedium->GetFilter()->GetFilterName();
+ if ( const SfxStringItem* pItem = pMedium->GetItemSet().GetItemIfSet( SID_PASSWORD, false ) )
+ sPassword = pItem->GetValue();
+ ::lcl_ReadSections(*pMedium, *m_xSubRegionED);
+ }
+ }
+
+ SectRepr* pSectRepr = weld::fromId<SectRepr*>(m_xTree->get_selected_id());
+ if (pSectRepr)
+ {
+ pSectRepr->SetFile( sFileName );
+ pSectRepr->SetFilter( sFilterName );
+ pSectRepr->GetSectionData().SetLinkFilePassword(sPassword);
+ m_xFileNameED->set_text(pSectRepr->GetFile());
+ }
+}
+
+IMPL_LINK_NOARG(SwEditRegionDlg, SubRegionEventHdl, weld::ComboBox&, void)
+{
+ if (m_bSubRegionsFilled)
+ return;
+
+ //if necessary fill the names bookmarks/sections/tables now
+
+ OUString sFileName = m_xFileNameED->get_text();
+ if(!sFileName.isEmpty())
+ {
+ SfxMedium* pMedium = m_rSh.GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+ sFileName = URIHelper::SmartRel2Abs(
+ aAbs, sFileName, URIHelper::GetMaybeFileHdl() );
+
+ //load file and set the shell
+ SfxMedium aMedium( sFileName, StreamMode::STD_READ );
+ sFileName = aMedium.GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ ::lcl_ReadSections(aMedium, *m_xSubRegionED);
+ }
+ else
+ lcl_FillSubRegionList(m_rSh, *m_xSubRegionED, nullptr);
+ m_bSubRegionsFilled = true;
+}
+
+// helper function - read section names from medium
+static void lcl_ReadSections( SfxMedium& rMedium, weld::ComboBox& rBox )
+{
+ rBox.clear();
+ uno::Reference < embed::XStorage > xStg;
+ if( !(rMedium.IsStorage() && (xStg = rMedium.GetStorage()).is()) )
+ return;
+
+ std::vector<OUString> aArr;
+ SotClipboardFormatId nFormat = SotStorage::GetFormatID( xStg );
+ if ( nFormat == SotClipboardFormatId::STARWRITER_60 || nFormat == SotClipboardFormatId::STARWRITERGLOB_60 ||
+ nFormat == SotClipboardFormatId::STARWRITER_8 || nFormat == SotClipboardFormatId::STARWRITERGLOB_8)
+ SwGetReaderXML()->GetSectionList( rMedium, aArr );
+
+ for (auto const& it : aArr)
+ {
+ rBox.append_text(it);
+ }
+}
+
+SwInsertSectionTabDialog::SwInsertSectionTabDialog(
+ weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell& rSh)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/insertsectiondialog.ui",
+ "InsertSectionDialog",&rSet)
+ , m_rWrtSh(rSh)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ AddTabPage("section", SwInsertSectionTabPage::Create, nullptr);
+ AddTabPage("columns", SwColumnPage::Create, nullptr);
+ AddTabPage("background", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG), nullptr);
+ AddTabPage("notes", SwSectionFootnoteEndTabPage::Create, nullptr);
+ AddTabPage("indents", SwSectionIndentTabPage::Create, nullptr);
+
+ tools::Long nHtmlMode = SvxHtmlOptions::GetExportMode();
+
+ bool bWeb = dynamic_cast<SwWebDocShell*>( rSh.GetView().GetDocShell() ) != nullptr ;
+ if(bWeb)
+ {
+ RemoveTabPage("notes");
+ RemoveTabPage("indents");
+ if( HTML_CFG_NS40 != nHtmlMode && HTML_CFG_WRITER != nHtmlMode)
+ RemoveTabPage("columns");
+ }
+ SetCurPageId("section");
+}
+
+SwInsertSectionTabDialog::~SwInsertSectionTabDialog()
+{
+}
+
+void SwInsertSectionTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "section")
+ static_cast<SwInsertSectionTabPage&>(rPage).SetWrtShell(m_rWrtSh);
+ else if (rId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "columns")
+ {
+ const SwFormatFrameSize& rSize = GetInputSetImpl()->Get(RES_FRM_SIZE);
+ static_cast<SwColumnPage&>(rPage).SetPageWidth(rSize.GetWidth());
+ static_cast<SwColumnPage&>(rPage).ShowBalance(true);
+ static_cast<SwColumnPage&>(rPage).SetInSection(true);
+ }
+ else if (rId == "indents")
+ static_cast<SwSectionIndentTabPage&>(rPage).SetWrtShell(m_rWrtSh);
+}
+
+void SwInsertSectionTabDialog::SetSectionData(SwSectionData const& rSect)
+{
+ m_pSectionData.reset( new SwSectionData(rSect) );
+}
+
+short SwInsertSectionTabDialog::Ok()
+{
+ short nRet = SfxTabDialogController::Ok();
+ OSL_ENSURE(m_pSectionData, "SwInsertSectionTabDialog: no SectionData?");
+ const SfxItemSet* pOutputItemSet = GetOutputItemSet();
+ m_rWrtSh.InsertSection(*m_pSectionData, pOutputItemSet);
+ SfxViewFrame& rViewFrame = m_rWrtSh.GetView().GetViewFrame();
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ rViewFrame.GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ SfxRequest aRequest(rViewFrame, FN_INSERT_REGION);
+ if(const SwFormatCol* pCol = pOutputItemSet->GetItemIfSet(RES_COL, false))
+ {
+ aRequest.AppendItem(SfxUInt16Item(SID_ATTR_COLUMNS,
+ pCol->GetColumns().size()));
+ }
+ aRequest.AppendItem(SfxStringItem( FN_PARAM_REGION_NAME,
+ m_pSectionData->GetSectionName()));
+ aRequest.AppendItem(SfxStringItem( FN_PARAM_REGION_CONDITION,
+ m_pSectionData->GetCondition()));
+ aRequest.AppendItem(SfxBoolItem( FN_PARAM_REGION_HIDDEN,
+ m_pSectionData->IsHidden()));
+ aRequest.AppendItem(SfxBoolItem( FN_PARAM_REGION_PROTECT,
+ m_pSectionData->IsProtectFlag()));
+ // edit in readonly sections
+ aRequest.AppendItem(SfxBoolItem( FN_PARAM_REGION_EDIT_IN_READONLY,
+ m_pSectionData->IsEditInReadonlyFlag()));
+
+ const OUString sLinkFileName( m_pSectionData->GetLinkFileName() );
+ sal_Int32 n = 0;
+ aRequest.AppendItem(SfxStringItem( FN_PARAM_1, sLinkFileName.getToken( 0, sfx2::cTokenSeparator, n )));
+ aRequest.AppendItem(SfxStringItem( FN_PARAM_2, sLinkFileName.getToken( 0, sfx2::cTokenSeparator, n )));
+ aRequest.AppendItem(SfxStringItem( FN_PARAM_3, sLinkFileName.getToken( 0, sfx2::cTokenSeparator, n )));
+ aRequest.Done();
+ }
+ return nRet;
+}
+
+SwInsertSectionTabPage::SwInsertSectionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/sectionpage.ui", "SectionPage", &rAttrSet)
+ , m_pWrtSh(nullptr)
+ , m_xCurName(m_xBuilder->weld_entry_tree_view("sectionnames", "sectionnames-entry",
+ "sectionnames-list"))
+ , m_xFileCB(m_xBuilder->weld_check_button("link"))
+ , m_xDDECB(m_xBuilder->weld_check_button("dde"))
+ , m_xDDECommandFT(m_xBuilder->weld_label("ddelabel"))
+ , m_xFileNameFT(m_xBuilder->weld_label("filelabel"))
+ , m_xFileNameED(m_xBuilder->weld_entry("filename"))
+ , m_xFilePB(m_xBuilder->weld_button("selectfile"))
+ , m_xSubRegionFT(m_xBuilder->weld_label("sectionlabel"))
+ , m_xSubRegionED(m_xBuilder->weld_combo_box("sectionname"))
+ , m_xProtectCB(m_xBuilder->weld_check_button("protect"))
+ , m_xPasswdCB(m_xBuilder->weld_check_button("withpassword"))
+ , m_xPasswdPB(m_xBuilder->weld_button("selectpassword"))
+ , m_xHideCB(m_xBuilder->weld_check_button("hide"))
+ , m_xConditionFT(m_xBuilder->weld_label("condlabel"))
+ , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry("withcond")))
+ // edit in readonly sections
+ , m_xEditInReadonlyCB(m_xBuilder->weld_check_button("editable"))
+{
+ m_xCurName->make_sorted();
+ m_xCurName->set_height_request_by_rows(12);
+ m_xSubRegionED->make_sorted();
+
+ m_xProtectCB->connect_toggled( LINK( this, SwInsertSectionTabPage, ChangeProtectHdl));
+ m_xPasswdCB->connect_toggled( LINK( this, SwInsertSectionTabPage, TogglePasswdHdl));
+ m_xPasswdPB->connect_clicked( LINK( this, SwInsertSectionTabPage, ChangePasswdHdl));
+ m_xHideCB->connect_toggled( LINK( this, SwInsertSectionTabPage, ChangeHideHdl));
+ m_xFileCB->connect_toggled( LINK( this, SwInsertSectionTabPage, UseFileHdl ));
+ m_xFilePB->connect_clicked( LINK( this, SwInsertSectionTabPage, FileSearchHdl ));
+ m_xCurName->connect_changed( LINK( this, SwInsertSectionTabPage, NameEditHdl));
+ m_xDDECB->connect_toggled( LINK( this, SwInsertSectionTabPage, DDEHdl ));
+ ChangeProtectHdl(*m_xProtectCB);
+ m_xSubRegionED->set_entry_completion(true, true);
+
+ // Hide Link section. In general it makes no sense to insert a file from the jail,
+ // because it does not contain any usable files (documents).
+ if(comphelper::LibreOfficeKit::isActive())
+ {
+ m_xBuilder->weld_label("label1")->hide(); // Link
+ m_xFileCB->hide();
+ m_xDDECB->hide();
+ m_xDDECommandFT->hide();
+ m_xFileNameFT->hide();
+ m_xFileNameED->hide();
+ m_xFilePB->hide();
+ m_xSubRegionFT->hide();
+ m_xSubRegionED->hide();
+ }
+}
+
+SwInsertSectionTabPage::~SwInsertSectionTabPage()
+{
+}
+
+void SwInsertSectionTabPage::SetWrtShell(SwWrtShell& rSh)
+{
+ m_pWrtSh = &rSh;
+
+ bool bWeb = dynamic_cast<SwWebDocShell*>( m_pWrtSh->GetView().GetDocShell() )!= nullptr;
+ if(bWeb)
+ {
+ m_xHideCB->hide();
+ m_xConditionED->hide();
+ m_xConditionFT->hide();
+ m_xDDECB->hide();
+ m_xDDECommandFT->hide();
+ }
+
+ lcl_FillSubRegionList(*m_pWrtSh, *m_xSubRegionED, m_xCurName.get());
+
+ SwSectionData *const pSectionData =
+ static_cast<SwInsertSectionTabDialog*>(GetDialogController())
+ ->GetSectionData();
+ if (pSectionData) // something set?
+ {
+ const OUString sSectionName(pSectionData->GetSectionName());
+ m_xCurName->set_entry_text(rSh.GetUniqueSectionName(&sSectionName));
+ m_xProtectCB->set_active( pSectionData->IsProtectFlag() );
+ ChangeProtectHdl(*m_xProtectCB);
+ m_sFileName = pSectionData->GetLinkFileName();
+ m_sFilePasswd = pSectionData->GetLinkFilePassword();
+ m_xFileCB->set_active( !m_sFileName.isEmpty() );
+ m_xFileNameED->set_text( m_sFileName );
+ UseFileHdl(*m_xFileCB);
+ }
+ else
+ {
+ m_xCurName->set_entry_text(rSh.GetUniqueSectionName());
+ }
+}
+
+bool SwInsertSectionTabPage::FillItemSet( SfxItemSet* )
+{
+ SwSectionData aSection(SectionType::Content, m_xCurName->get_active_text());
+ aSection.SetCondition(m_xConditionED->get_text());
+ bool bProtected = m_xProtectCB->get_active();
+ aSection.SetProtectFlag(bProtected);
+ aSection.SetHidden(m_xHideCB->get_active());
+ // edit in readonly sections
+ aSection.SetEditInReadonlyFlag(m_xEditInReadonlyCB->get_active());
+
+ if(bProtected)
+ {
+ aSection.SetPassword(m_aNewPasswd);
+ }
+ const OUString sFileName = m_xFileNameED->get_text();
+ const OUString sSubRegion = m_xSubRegionED->get_active_text();
+ bool bDDe = m_xDDECB->get_active();
+ if (m_xFileCB->get_active() && (!sFileName.isEmpty() || !sSubRegion.isEmpty() || bDDe))
+ {
+ OUString aLinkFile;
+ if( bDDe )
+ {
+ aLinkFile = CollapseWhiteSpaces(sFileName);
+ sal_Int32 nPos = 0;
+ aLinkFile = aLinkFile.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nPos );
+ if (nPos>=0)
+ {
+ aLinkFile = aLinkFile.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nPos );
+ }
+ }
+ else
+ {
+ if(!sFileName.isEmpty())
+ {
+ SfxMedium* pMedium = m_pWrtSh->GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+ aLinkFile = URIHelper::SmartRel2Abs(
+ aAbs, sFileName, URIHelper::GetMaybeFileHdl() );
+ aSection.SetLinkFilePassword( m_sFilePasswd );
+ }
+
+ aLinkFile += OUStringChar(sfx2::cTokenSeparator) + m_sFilterName
+ + OUStringChar(sfx2::cTokenSeparator) + sSubRegion;
+ }
+
+ aSection.SetLinkFileName(aLinkFile);
+ if (!aLinkFile.isEmpty())
+ {
+ aSection.SetType( m_xDDECB->get_active() ?
+ SectionType::DdeLink :
+ SectionType::FileLink);
+ }
+ }
+ static_cast<SwInsertSectionTabDialog*>(GetDialogController())->SetSectionData(aSection);
+ return true;
+}
+
+void SwInsertSectionTabPage::Reset( const SfxItemSet* )
+{
+}
+
+std::unique_ptr<SfxTabPage> SwInsertSectionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwInsertSectionTabPage>(pPage, pController, *rAttrSet);
+}
+
+IMPL_LINK(SwInsertSectionTabPage, ChangeHideHdl, weld::Toggleable&, rBox, void)
+{
+ bool bHide = rBox.get_active();
+ m_xConditionED->set_sensitive(bHide);
+ m_xConditionFT->set_sensitive(bHide);
+}
+
+IMPL_LINK(SwInsertSectionTabPage, ChangeProtectHdl, weld::Toggleable&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ m_xPasswdCB->set_sensitive(bCheck);
+ m_xPasswdPB->set_sensitive(bCheck);
+}
+
+void SwInsertSectionTabPage::ChangePasswd(bool bChange)
+{
+ bool bSet = bChange ? bChange : m_xPasswdCB->get_active();
+ if (bSet)
+ {
+ if(!m_aNewPasswd.hasElements() || bChange)
+ {
+ SfxPasswordDialog aPasswdDlg(GetFrameWeld());
+ aPasswdDlg.ShowExtras(SfxShowExtras::CONFIRM);
+ if (RET_OK == aPasswdDlg.run())
+ {
+ const OUString sNewPasswd(aPasswdDlg.GetPassword());
+ if (aPasswdDlg.GetConfirm() == sNewPasswd)
+ {
+ SvPasswordHelper::GetHashPassword( m_aNewPasswd, sNewPasswd );
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_WRONG_PASSWD_REPEAT)));
+ xInfoBox->run();
+ }
+ }
+ else if(!bChange)
+ m_xPasswdCB->set_active(false);
+ }
+ }
+ else
+ m_aNewPasswd.realloc(0);
+}
+
+IMPL_LINK_NOARG(SwInsertSectionTabPage, TogglePasswdHdl, weld::Toggleable&, void)
+{
+ ChangePasswd(false);
+}
+
+IMPL_LINK_NOARG(SwInsertSectionTabPage, ChangePasswdHdl, weld::Button&, void)
+{
+ ChangePasswd(true);
+}
+
+
+IMPL_LINK_NOARG(SwInsertSectionTabPage, NameEditHdl, weld::ComboBox&, void)
+{
+ const OUString aName = m_xCurName->get_active_text();
+ GetDialogController()->GetOKButton().set_sensitive(!aName.isEmpty() &&
+ m_xCurName->find_text(aName) == -1);
+}
+
+IMPL_LINK(SwInsertSectionTabPage, UseFileHdl, weld::Toggleable&, rButton, void)
+{
+ if (rButton.get_active())
+ {
+ if (m_pWrtSh->HasSelection())
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ SwResId(STR_QUERY_CONNECT)));
+ if (RET_NO == xQueryBox->run())
+ rButton.set_active(false);
+ }
+ }
+
+ bool bFile = rButton.get_active();
+ m_xFileNameFT->set_sensitive(bFile);
+ m_xFileNameED->set_sensitive(bFile);
+ m_xFilePB->set_sensitive(bFile);
+ m_xSubRegionFT->set_sensitive(bFile);
+ m_xSubRegionED->set_sensitive(bFile);
+ m_xDDECommandFT->set_sensitive(bFile);
+ m_xDDECB->set_sensitive(bFile);
+ if (bFile)
+ {
+ m_xFileNameED->grab_focus();
+ m_xProtectCB->set_active(true);
+ ChangeProtectHdl(*m_xProtectCB);
+ }
+ else
+ {
+ m_xDDECB->set_active(false);
+ DDEHdl(*m_xDDECB);
+ }
+}
+
+IMPL_LINK_NOARG(SwInsertSectionTabPage, FileSearchHdl, weld::Button&, void)
+{
+ m_pDocInserter.reset(new ::sfx2::DocumentInserter(GetFrameWeld(), "swriter"));
+ m_pDocInserter->StartExecuteModal( LINK( this, SwInsertSectionTabPage, DlgClosedHdl ) );
+}
+
+IMPL_LINK( SwInsertSectionTabPage, DDEHdl, weld::Toggleable&, rButton, void )
+{
+ bool bDDE = rButton.get_active();
+ bool bFile = m_xFileCB->get_active();
+ m_xFilePB->set_sensitive(!bDDE && bFile);
+ if (bDDE)
+ {
+ m_xFileNameFT->hide();
+ m_xDDECommandFT->set_sensitive(bDDE);
+ m_xDDECommandFT->show();
+ m_xSubRegionFT->hide();
+ m_xSubRegionED->hide();
+ m_xFileNameED->set_accessible_name(m_xDDECommandFT->get_label());
+ }
+ else
+ {
+ m_xDDECommandFT->hide();
+ m_xFileNameFT->set_sensitive(bFile);
+ if(!comphelper::LibreOfficeKit::isActive())
+ m_xFileNameFT->show();
+ m_xSubRegionFT->show();
+ m_xSubRegionED->show();
+ m_xSubRegionED->set_sensitive(bFile);
+ m_xFileNameED->set_accessible_name(m_xFileNameFT->get_label());
+ }
+}
+
+IMPL_LINK( SwInsertSectionTabPage, DlgClosedHdl, sfx2::FileDialogHelper *, _pFileDlg, void )
+{
+ if ( _pFileDlg->GetError() == ERRCODE_NONE )
+ {
+ std::unique_ptr<SfxMedium> pMedium(m_pDocInserter->CreateMedium("sglobal"));
+ if ( pMedium )
+ {
+ m_sFileName = pMedium->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ m_sFilterName = pMedium->GetFilter()->GetFilterName();
+ if ( const SfxStringItem* pItem = pMedium->GetItemSet().GetItemIfSet( SID_PASSWORD, false ) )
+ m_sFilePasswd = pItem->GetValue();
+ m_xFileNameED->set_text( INetURLObject::decode(
+ m_sFileName, INetURLObject::DecodeMechanism::Unambiguous ) );
+ ::lcl_ReadSections(*pMedium, *m_xSubRegionED);
+ }
+ }
+ else
+ {
+ m_sFilterName.clear();
+ m_sFilePasswd.clear();
+ }
+}
+
+SwSectionFootnoteEndTabPage::SwSectionFootnoteEndTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/footnotesendnotestabpage.ui", "FootnotesEndnotesTabPage", &rAttrSet)
+ , m_xFootnoteNtAtTextEndCB(m_xBuilder->weld_check_button("ftnntattextend"))
+ , m_xFootnoteNtNumCB(m_xBuilder->weld_check_button("ftnntnum"))
+ , m_xFootnoteOffsetLbl(m_xBuilder->weld_label("ftnoffset_label"))
+ , m_xFootnoteOffsetField(m_xBuilder->weld_spin_button("ftnoffset"))
+ , m_xFootnoteNtNumFormatCB(m_xBuilder->weld_check_button("ftnntnumfmt"))
+ , m_xFootnotePrefixFT(m_xBuilder->weld_label("ftnprefix_label"))
+ , m_xFootnotePrefixED(m_xBuilder->weld_entry("ftnprefix"))
+ , m_xFootnoteNumViewBox(new SwNumberingTypeListBox(m_xBuilder->weld_combo_box("ftnnumviewbox")))
+ , m_xFootnoteSuffixFT(m_xBuilder->weld_label("ftnsuffix_label"))
+ , m_xFootnoteSuffixED(m_xBuilder->weld_entry("ftnsuffix"))
+ , m_xEndNtAtTextEndCB(m_xBuilder->weld_check_button("endntattextend"))
+ , m_xEndNtNumCB(m_xBuilder->weld_check_button("endntnum"))
+ , m_xEndOffsetLbl(m_xBuilder->weld_label("endoffset_label"))
+ , m_xEndOffsetField(m_xBuilder->weld_spin_button("endoffset"))
+ , m_xEndNtNumFormatCB(m_xBuilder->weld_check_button("endntnumfmt"))
+ , m_xEndPrefixFT(m_xBuilder->weld_label("endprefix_label"))
+ , m_xEndPrefixED(m_xBuilder->weld_entry("endprefix"))
+ , m_xEndNumViewBox(new SwNumberingTypeListBox(m_xBuilder->weld_combo_box("endnumviewbox")))
+ , m_xEndSuffixFT(m_xBuilder->weld_label("endsuffix_label"))
+ , m_xEndSuffixED(m_xBuilder->weld_entry("endsuffix"))
+{
+ m_xFootnoteNumViewBox->Reload(SwInsertNumTypes::Extended);
+ m_xEndNumViewBox->Reload(SwInsertNumTypes::Extended);
+
+ Link<weld::Toggleable&,void> aLk( LINK( this, SwSectionFootnoteEndTabPage, FootEndHdl));
+ m_xFootnoteNtAtTextEndCB->connect_toggled( aLk );
+ m_xFootnoteNtNumCB->connect_toggled( aLk );
+ m_xEndNtAtTextEndCB->connect_toggled( aLk );
+ m_xEndNtNumCB->connect_toggled( aLk );
+ m_xFootnoteNtNumFormatCB->connect_toggled( aLk );
+ m_xEndNtNumFormatCB->connect_toggled( aLk );
+}
+
+SwSectionFootnoteEndTabPage::~SwSectionFootnoteEndTabPage()
+{
+}
+
+bool SwSectionFootnoteEndTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ SwFormatFootnoteAtTextEnd aFootnote( m_xFootnoteNtAtTextEndCB->get_active()
+ ? ( m_xFootnoteNtNumCB->get_active()
+ ? ( m_xFootnoteNtNumFormatCB->get_active()
+ ? FTNEND_ATTXTEND_OWNNUMANDFMT
+ : FTNEND_ATTXTEND_OWNNUMSEQ )
+ : FTNEND_ATTXTEND )
+ : FTNEND_ATPGORDOCEND );
+
+ switch( aFootnote.GetValue() )
+ {
+ case FTNEND_ATTXTEND_OWNNUMANDFMT:
+ aFootnote.SetNumType( m_xFootnoteNumViewBox->GetSelectedNumberingType() );
+ aFootnote.SetPrefix( m_xFootnotePrefixED->get_text().replaceAll("\\t", "\t") ); // fdo#65666
+ aFootnote.SetSuffix( m_xFootnoteSuffixED->get_text().replaceAll("\\t", "\t") );
+ [[fallthrough]];
+
+ case FTNEND_ATTXTEND_OWNNUMSEQ:
+ aFootnote.SetOffset( static_cast< sal_uInt16 >( m_xFootnoteOffsetField->get_value()-1 ) );
+ break;
+ default: break;
+ }
+
+ SwFormatEndAtTextEnd aEnd( m_xEndNtAtTextEndCB->get_active()
+ ? ( m_xEndNtNumCB->get_active()
+ ? ( m_xEndNtNumFormatCB->get_active()
+ ? FTNEND_ATTXTEND_OWNNUMANDFMT
+ : FTNEND_ATTXTEND_OWNNUMSEQ )
+ : FTNEND_ATTXTEND )
+ : FTNEND_ATPGORDOCEND );
+
+ switch( aEnd.GetValue() )
+ {
+ case FTNEND_ATTXTEND_OWNNUMANDFMT:
+ aEnd.SetNumType( m_xEndNumViewBox->GetSelectedNumberingType() );
+ aEnd.SetPrefix( m_xEndPrefixED->get_text().replaceAll("\\t", "\t") );
+ aEnd.SetSuffix( m_xEndSuffixED->get_text().replaceAll("\\t", "\t") );
+ [[fallthrough]];
+
+ case FTNEND_ATTXTEND_OWNNUMSEQ:
+ aEnd.SetOffset( static_cast< sal_uInt16 >( m_xEndOffsetField->get_value()-1 ) );
+ break;
+ default: break;
+ }
+
+ rSet->Put( aFootnote );
+ rSet->Put( aEnd );
+
+ return true;
+}
+
+void SwSectionFootnoteEndTabPage::ResetState( bool bFootnote,
+ const SwFormatFootnoteEndAtTextEnd& rAttr )
+{
+ weld::CheckButton *pNtAtTextEndCB, *pNtNumCB, *pNtNumFormatCB;
+ weld::Label *pPrefixFT, *pSuffixFT;
+ weld::Entry *pPrefixED, *pSuffixED;
+ SwNumberingTypeListBox *pNumViewBox;
+ weld::Label *pOffsetText;
+ weld::SpinButton *pOffsetField;
+
+ if( bFootnote )
+ {
+ pNtAtTextEndCB = m_xFootnoteNtAtTextEndCB.get();
+ pNtNumCB = m_xFootnoteNtNumCB.get();
+ pNtNumFormatCB = m_xFootnoteNtNumFormatCB.get();
+ pPrefixFT = m_xFootnotePrefixFT.get();
+ pPrefixED = m_xFootnotePrefixED.get();
+ pSuffixFT = m_xFootnoteSuffixFT.get();
+ pSuffixED = m_xFootnoteSuffixED.get();
+ pNumViewBox = m_xFootnoteNumViewBox.get();
+ pOffsetText = m_xFootnoteOffsetLbl.get();
+ pOffsetField = m_xFootnoteOffsetField.get();
+ }
+ else
+ {
+ pNtAtTextEndCB = m_xEndNtAtTextEndCB.get();
+ pNtNumCB = m_xEndNtNumCB.get();
+ pNtNumFormatCB = m_xEndNtNumFormatCB.get();
+ pPrefixFT = m_xEndPrefixFT.get();
+ pPrefixED = m_xEndPrefixED.get();
+ pSuffixFT = m_xEndSuffixFT.get();
+ pSuffixED = m_xEndSuffixED.get();
+ pNumViewBox = m_xEndNumViewBox.get();
+ pOffsetText = m_xEndOffsetLbl.get();
+ pOffsetField = m_xEndOffsetField.get();
+ }
+
+ const sal_uInt16 eState = rAttr.GetValue();
+ switch( eState )
+ {
+ case FTNEND_ATTXTEND_OWNNUMANDFMT:
+ pNtNumFormatCB->set_state( TRISTATE_TRUE );
+ [[fallthrough]];
+
+ case FTNEND_ATTXTEND_OWNNUMSEQ:
+ pNtNumCB->set_state( TRISTATE_TRUE );
+ [[fallthrough]];
+
+ case FTNEND_ATTXTEND:
+ pNtAtTextEndCB->set_state( TRISTATE_TRUE );
+ // no break;
+ }
+
+ pNumViewBox->SelectNumberingType( rAttr.GetNumType() );
+ pOffsetField->set_value( rAttr.GetOffset() + 1 );
+ pPrefixED->set_text( rAttr.GetPrefix().replaceAll("\t", "\\t") );
+ pSuffixED->set_text( rAttr.GetSuffix().replaceAll("\t", "\\t") );
+
+ switch( eState )
+ {
+ case FTNEND_ATPGORDOCEND:
+ pNtNumCB->set_sensitive( false );
+ [[fallthrough]];
+
+ case FTNEND_ATTXTEND:
+ pNtNumFormatCB->set_sensitive( false );
+ pOffsetField->set_sensitive( false );
+ pOffsetText->set_sensitive( false );
+ [[fallthrough]];
+
+ case FTNEND_ATTXTEND_OWNNUMSEQ:
+ pNumViewBox->set_sensitive( false );
+ pPrefixFT->set_sensitive( false );
+ pPrefixED->set_sensitive( false );
+ pSuffixFT->set_sensitive( false );
+ pSuffixED->set_sensitive( false );
+ // no break;
+ }
+}
+
+void SwSectionFootnoteEndTabPage::Reset( const SfxItemSet* rSet )
+{
+ ResetState( true, rSet->Get( RES_FTN_AT_TXTEND, false ));
+ ResetState( false, rSet->Get( RES_END_AT_TXTEND, false ));
+}
+
+std::unique_ptr<SfxTabPage> SwSectionFootnoteEndTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwSectionFootnoteEndTabPage>(pPage, pController, *rAttrSet);
+}
+
+IMPL_LINK( SwSectionFootnoteEndTabPage, FootEndHdl, weld::Toggleable&, rBox, void )
+{
+ bool bFoot = m_xFootnoteNtAtTextEndCB.get() == &rBox || m_xFootnoteNtNumCB.get() == &rBox ||
+ m_xFootnoteNtNumFormatCB.get() == &rBox ;
+
+ weld::CheckButton *pNumBox, *pNumFormatBox, *pEndBox;
+ SwNumberingTypeListBox* pNumViewBox;
+ weld::Label *pOffsetText;
+ weld::SpinButton *pOffsetField;
+ weld::Label *pPrefixFT, *pSuffixFT;
+ weld::Entry *pPrefixED, *pSuffixED;
+
+ if( bFoot )
+ {
+ pEndBox = m_xFootnoteNtAtTextEndCB.get();
+ pNumBox = m_xFootnoteNtNumCB.get();
+ pNumFormatBox = m_xFootnoteNtNumFormatCB.get();
+ pNumViewBox = m_xFootnoteNumViewBox.get();
+ pOffsetText = m_xFootnoteOffsetLbl.get();
+ pOffsetField = m_xFootnoteOffsetField.get();
+ pPrefixFT = m_xFootnotePrefixFT.get();
+ pSuffixFT = m_xFootnoteSuffixFT.get();
+ pPrefixED = m_xFootnotePrefixED.get();
+ pSuffixED = m_xFootnoteSuffixED.get();
+ }
+ else
+ {
+ pEndBox = m_xEndNtAtTextEndCB.get();
+ pNumBox = m_xEndNtNumCB.get();
+ pNumFormatBox = m_xEndNtNumFormatCB.get();
+ pNumViewBox = m_xEndNumViewBox.get();
+ pOffsetText = m_xEndOffsetLbl.get();
+ pOffsetField = m_xEndOffsetField.get();
+ pPrefixFT = m_xEndPrefixFT.get();
+ pSuffixFT = m_xEndSuffixFT.get();
+ pPrefixED = m_xEndPrefixED.get();
+ pSuffixED = m_xEndSuffixED.get();
+ }
+
+ bool bEnableAtEnd = TRISTATE_TRUE == pEndBox->get_state();
+ bool bEnableNum = bEnableAtEnd && TRISTATE_TRUE == pNumBox->get_state();
+ bool bEnableNumFormat = bEnableNum && TRISTATE_TRUE == pNumFormatBox->get_state();
+
+ pNumBox->set_sensitive( bEnableAtEnd );
+ pOffsetText->set_sensitive( bEnableNum );
+ pOffsetField->set_sensitive( bEnableNum );
+ pNumFormatBox->set_sensitive( bEnableNum );
+ pNumViewBox->set_sensitive( bEnableNumFormat );
+ pPrefixED->set_sensitive( bEnableNumFormat );
+ pSuffixED->set_sensitive( bEnableNumFormat );
+ pPrefixFT->set_sensitive( bEnableNumFormat );
+ pSuffixFT->set_sensitive( bEnableNumFormat );
+}
+
+SwSectionPropertyTabDialog::SwSectionPropertyTabDialog(
+ weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell& rSh)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/formatsectiondialog.ui",
+ "FormatSectionDialog", &rSet)
+ , m_rWrtSh(rSh)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ AddTabPage("columns", SwColumnPage::Create, nullptr);
+ AddTabPage("background", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG), nullptr);
+ AddTabPage("notes", SwSectionFootnoteEndTabPage::Create, nullptr);
+ AddTabPage("indents", SwSectionIndentTabPage::Create, nullptr);
+
+ tools::Long nHtmlMode = SvxHtmlOptions::GetExportMode();
+ bool bWeb = dynamic_cast<SwWebDocShell*>( rSh.GetView().GetDocShell() ) != nullptr ;
+ if(bWeb)
+ {
+ RemoveTabPage("notes");
+ RemoveTabPage("indents");
+ if( HTML_CFG_NS40 != nHtmlMode && HTML_CFG_WRITER != nHtmlMode)
+ RemoveTabPage("columns");
+ }
+}
+
+SwSectionPropertyTabDialog::~SwSectionPropertyTabDialog()
+{
+}
+
+void SwSectionPropertyTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "columns")
+ {
+ static_cast<SwColumnPage&>(rPage).ShowBalance(true);
+ static_cast<SwColumnPage&>(rPage).SetInSection(true);
+ }
+ else if (rId == "indents")
+ static_cast<SwSectionIndentTabPage&>(rPage).SetWrtShell(m_rWrtSh);
+}
+
+SwSectionIndentTabPage::SwSectionIndentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/indentpage.ui", "IndentPage", &rAttrSet)
+ , m_xBeforeMF(m_xBuilder->weld_metric_spin_button("before", FieldUnit::CM))
+ , m_xAfterMF(m_xBuilder->weld_metric_spin_button("after", FieldUnit::CM))
+ , m_xPreviewWin(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin))
+{
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwSectionIndentTabPage, IndentModifyHdl);
+ m_xBeforeMF->connect_value_changed(aLk);
+ m_xAfterMF->connect_value_changed(aLk);
+}
+
+SwSectionIndentTabPage::~SwSectionIndentTabPage()
+{
+}
+
+bool SwSectionIndentTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ if (m_xBeforeMF->get_value_changed_from_saved() || m_xAfterMF->get_value_changed_from_saved())
+ {
+ SvxLRSpaceItem aLRSpace(
+ m_xBeforeMF->denormalize(m_xBeforeMF->get_value(FieldUnit::TWIP)) ,
+ m_xAfterMF->denormalize(m_xAfterMF->get_value(FieldUnit::TWIP)), 0, RES_LR_SPACE);
+ rSet->Put(aLRSpace);
+ }
+ return true;
+}
+
+void SwSectionIndentTabPage::Reset( const SfxItemSet* rSet)
+{
+ //this page doesn't show up in HTML mode
+ FieldUnit aMetric = ::GetDfltMetric(false);
+ SetFieldUnit(*m_xBeforeMF, aMetric);
+ SetFieldUnit(*m_xAfterMF , aMetric);
+
+ SfxItemState eItemState = rSet->GetItemState( RES_LR_SPACE );
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxLRSpaceItem& rSpace =
+ rSet->Get( RES_LR_SPACE );
+
+ m_xBeforeMF->set_value(m_xBeforeMF->normalize(rSpace.GetLeft()), FieldUnit::TWIP);
+ m_xAfterMF->set_value(m_xAfterMF->normalize(rSpace.GetRight()), FieldUnit::TWIP);
+ }
+ else
+ {
+ m_xBeforeMF->set_text("");
+ m_xAfterMF->set_text("");
+ }
+ m_xBeforeMF->save_value();
+ m_xAfterMF->save_value();
+ IndentModifyHdl(*m_xBeforeMF);
+}
+
+std::unique_ptr<SfxTabPage> SwSectionIndentTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwSectionIndentTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SwSectionIndentTabPage::SetWrtShell(SwWrtShell const & rSh)
+{
+ //set sensible values at the preview
+ m_aPreviewWin.SetAdjust(SvxAdjust::Block);
+ m_aPreviewWin.SetLastLine(SvxAdjust::Block);
+ const SwRect& rPageRect = rSh.GetAnyCurRect( CurRectType::Page );
+ Size aPageSize(rPageRect.Width(), rPageRect.Height());
+ m_aPreviewWin.SetSize(aPageSize);
+}
+
+IMPL_LINK_NOARG(SwSectionIndentTabPage, IndentModifyHdl, weld::MetricSpinButton&, void)
+{
+ m_aPreviewWin.SetLeftMargin(m_xBeforeMF->denormalize(m_xBeforeMF->get_value(FieldUnit::TWIP)));
+ m_aPreviewWin.SetRightMargin(m_xAfterMF->denormalize(m_xAfterMF->get_value(FieldUnit::TWIP)));
+ m_aPreviewWin.Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dialog/wordcountdialog.cxx b/sw/source/ui/dialog/wordcountdialog.cxx
new file mode 100644
index 0000000000..1277545c6e
--- /dev/null
+++ b/sw/source/ui/dialog/wordcountdialog.cxx
@@ -0,0 +1,161 @@
+/* -*- 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 <officecfg/Office/Writer.hxx>
+#include <wordcountdialog.hxx>
+#include <docsh.hxx>
+#include <docstat.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <swwait.hxx>
+#include <wrtsh.hxx>
+#include <rtl/math.hxx>
+#include <svl/cjkoptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/lok.hxx>
+#include <PostItMgr.hxx>
+
+#define IS_MOBILE_PHONE (comphelper::LibreOfficeKit::isActive() && SfxViewShell::Current() && SfxViewShell::Current()->isLOKMobilePhone())
+
+SwWordCountFloatDlg::~SwWordCountFloatDlg()
+{
+ SwViewShell::SetCareDialog(nullptr);
+}
+
+namespace
+{
+ void setValue(weld::Label& rWidget, sal_uLong nValue, const LocaleDataWrapper& rLocaleData)
+ {
+ rWidget.set_label(rLocaleData.getNum(nValue, 0));
+ }
+
+ void setDoubleValue(weld::Label& rWidget, double fValue)
+ {
+ OUString sValue(OUString::number(::rtl::math::round(fValue, 1)));
+ rWidget.set_label(sValue);
+ }
+}
+
+void SwWordCountFloatDlg::SetValues(const SwDocStat& rCurrent, const SwDocStat& rDoc)
+{
+ const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper();
+ setValue(*m_xCurrentWordFT, rCurrent.nWord, rLocaleData);
+ setValue(*m_xCurrentCharacterFT, rCurrent.nChar, rLocaleData);
+ setValue(*m_xCurrentCharacterExcludingSpacesFT, rCurrent.nCharExcludingSpaces, rLocaleData);
+ setValue(*m_xCurrentCjkcharsFT, rCurrent.nAsianWord, rLocaleData);
+ setValue(*m_xDocWordFT, rDoc.nWord, rLocaleData);
+ setValue(*m_xDocCharacterFT, rDoc.nChar, rLocaleData);
+ setValue(*m_xDocCharacterExcludingSpacesFT, rDoc.nCharExcludingSpaces, rLocaleData);
+ setValue(*m_xDocCjkcharsFT, rDoc.nAsianWord, rLocaleData);
+ setValue(*m_xDocComments, rCurrent.nComments, rLocaleData);
+
+ const sal_Int64 nCharsPerStandardizedPage = m_xStandardizedPagesLabelFT->get_visible() ?
+ officecfg::Office::Writer::WordCount::StandardizedPageSize::get() : 0;
+ if (nCharsPerStandardizedPage)
+ {
+ setDoubleValue(*m_xCurrentStandardizedPagesFT,
+ static_cast<double>(rCurrent.nChar) / nCharsPerStandardizedPage);
+ setDoubleValue(*m_xDocStandardizedPagesFT,
+ static_cast<double>(rDoc.nChar) / nCharsPerStandardizedPage);
+ }
+
+ bool bShowCJK = (SvtCJKOptions::IsAnyEnabled() || rDoc.nAsianWord);
+ bool bToggleCJK = m_xCurrentCjkcharsFT->get_visible() != bShowCJK;
+ if (bToggleCJK)
+ {
+ showCJK(bShowCJK);
+ m_xDialog->resize_to_request(); //force resize of dialog
+ }
+}
+
+void SwWordCountFloatDlg::showCJK(bool bShowCJK)
+{
+ m_xCurrentCjkcharsFT->set_visible(bShowCJK);
+ m_xDocCjkcharsFT->set_visible(bShowCJK);
+ if (IS_MOBILE_PHONE && m_xCjkcharsLabelFT2)
+ m_xCjkcharsLabelFT2->set_visible(bShowCJK);
+ m_xCjkcharsLabelFT->set_visible(bShowCJK);
+}
+
+void SwWordCountFloatDlg::showStandardizedPages(bool bShowStandardizedPages)
+{
+ m_xCurrentStandardizedPagesFT->set_visible(bShowStandardizedPages);
+ m_xDocStandardizedPagesFT->set_visible(bShowStandardizedPages);
+ if (IS_MOBILE_PHONE && m_xStandardizedPagesLabelFT2)
+ m_xStandardizedPagesLabelFT2->set_visible(bShowStandardizedPages);
+ m_xStandardizedPagesLabelFT->set_visible(bShowStandardizedPages);
+}
+
+SwWordCountFloatDlg::SwWordCountFloatDlg(SfxBindings* _pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo const * pInfo)
+ : SfxModelessDialogController(_pBindings, pChild, pParent, IS_MOBILE_PHONE ? OUString("modules/swriter/ui/wordcount-mobile.ui") : OUString("modules/swriter/ui/wordcount.ui"), "WordCountDialog")
+ , m_xCurrentWordFT(m_xBuilder->weld_label("selectwords"))
+ , m_xCurrentCharacterFT(m_xBuilder->weld_label("selectchars"))
+ , m_xCurrentCharacterExcludingSpacesFT(m_xBuilder->weld_label("selectcharsnospaces"))
+ , m_xCurrentCjkcharsFT(m_xBuilder->weld_label("selectcjkchars"))
+ , m_xCurrentStandardizedPagesFT(m_xBuilder->weld_label("selectstandardizedpages"))
+ , m_xDocWordFT(m_xBuilder->weld_label("docwords"))
+ , m_xDocCharacterFT(m_xBuilder->weld_label("docchars"))
+ , m_xDocCharacterExcludingSpacesFT(m_xBuilder->weld_label("doccharsnospaces"))
+ , m_xDocCjkcharsFT(m_xBuilder->weld_label("doccjkchars"))
+ , m_xDocStandardizedPagesFT(m_xBuilder->weld_label("docstandardizedpages"))
+ , m_xCjkcharsLabelFT(m_xBuilder->weld_label("cjkcharsft"))
+ , m_xCjkcharsLabelFT2(m_xBuilder->weld_label("cjkcharsft2"))
+ , m_xStandardizedPagesLabelFT(m_xBuilder->weld_label("standardizedpages"))
+ , m_xStandardizedPagesLabelFT2(m_xBuilder->weld_label("standardizedpages2"))
+ , m_xDocComments(m_xBuilder->weld_label("docComments"))
+{
+ showCJK(SvtCJKOptions::IsAnyEnabled());
+ showStandardizedPages(officecfg::Office::Writer::WordCount::ShowStandardizedPageCount::get());
+
+ Initialize(pInfo);
+}
+
+void SwWordCountFloatDlg::UpdateCounts()
+{
+ if (SwView* pView = GetActiveView())
+ {
+ SwWrtShell &rSh = pView->GetWrtShell();
+ SwDocStat aCurrCnt;
+ SwDocStat aDocStat;
+ {
+ auto& rDocShell(*pView->GetDocShell());
+ SwWait aWait(rDocShell, true);
+ auto aLock = rDocShell.LockAllViews();
+ rSh.StartAction();
+ rSh.CountWords( aCurrCnt );
+ aDocStat = rSh.GetUpdatedDocStat();
+ rSh.EndAction();
+ }
+ SwPostItMgr* pPostItMgr = rSh.GetPostItMgr();
+ aCurrCnt.nComments = pPostItMgr->end() - pPostItMgr->begin();
+ SetValues(aCurrCnt, aDocStat);
+ }
+}
+
+void SwWordCountFloatDlg::SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat)
+{
+ SetValues(rCurrCnt, rDocStat);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/dochdl/selglos.cxx b/sw/source/ui/dochdl/selglos.cxx
new file mode 100644
index 0000000000..1d2b93f239
--- /dev/null
+++ b/sw/source/ui/dochdl/selglos.cxx
@@ -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 .
+ */
+
+#include <selglos.hxx>
+
+SwSelGlossaryDlg::SwSelGlossaryDlg(weld::Window * pParent, std::u16string_view rShortName)
+ : GenericDialogController(pParent, "modules/swriter/ui/insertautotextdialog.ui", "InsertAutoTextDialog")
+ , m_xFrame(m_xBuilder->weld_frame("frame"))
+ , m_xGlosBox(m_xBuilder->weld_tree_view("treeview"))
+{
+ m_xFrame->set_label(m_xFrame->get_label() + rShortName);
+ m_xGlosBox->set_size_request(-1, m_xGlosBox->get_height_rows(10));
+ m_xGlosBox->connect_row_activated(LINK(this, SwSelGlossaryDlg, DoubleClickHdl));
+}
+
+SwSelGlossaryDlg::~SwSelGlossaryDlg()
+{
+}
+
+IMPL_LINK_NOARG(SwSelGlossaryDlg, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/envfmt.cxx b/sw/source/ui/envelp/envfmt.cxx
new file mode 100644
index 0000000000..ebf99363cd
--- /dev/null
+++ b/sw/source/ui/envelp/envfmt.cxx
@@ -0,0 +1,425 @@
+/* -*- 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 <hintids.hxx>
+
+#include <editeng/paperinf.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svtools/unitconv.hxx>
+#include <svx/drawitem.hxx>
+#include <o3tl/string_view.hxx>
+#include <osl/diagnose.h>
+
+#include <cmdid.h>
+#include <IDocumentDrawModelAccess.hxx>
+#include <drawdoc.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include "envfmt.hxx"
+#include <fmtcol.hxx>
+#include <swuipardlg.hxx>
+#include <chrdlgmodes.hxx>
+#include <pardlg.hxx>
+#include <poolfmt.hxx>
+#include <uitool.hxx>
+
+#include <vector>
+#include <algorithm>
+
+#include <memory>
+
+#include <swabstdlg.hxx>
+#include <swuiexp.hxx>
+
+static tools::Long lUserW = 5669; // 10 cm
+static tools::Long lUserH = 5669; // 10 cm
+
+SwEnvFormatPage::SwEnvFormatPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/envformatpage.ui", "EnvFormatPage", &rSet)
+ , m_pDialog(nullptr)
+ , m_xAddrLeftField(m_xBuilder->weld_metric_spin_button("leftaddr", FieldUnit::CM))
+ , m_xAddrTopField(m_xBuilder->weld_metric_spin_button("topaddr", FieldUnit::CM))
+ , m_xAddrEditButton(m_xBuilder->weld_menu_button("addredit"))
+ , m_xSendLeftField(m_xBuilder->weld_metric_spin_button("leftsender", FieldUnit::CM))
+ , m_xSendTopField(m_xBuilder->weld_metric_spin_button("topsender", FieldUnit::CM))
+ , m_xSendEditButton(m_xBuilder->weld_menu_button("senderedit"))
+ , m_xSizeFormatBox(m_xBuilder->weld_combo_box("format"))
+ , m_xSizeWidthField(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xSizeHeightField(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreview))
+{
+ SetExchangeSupport();
+
+ // Metrics
+ FieldUnit aMetric = ::GetDfltMetric(false);
+ ::SetFieldUnit(*m_xAddrLeftField, aMetric);
+ ::SetFieldUnit(*m_xAddrTopField, aMetric);
+ ::SetFieldUnit(*m_xSendLeftField, aMetric);
+ ::SetFieldUnit(*m_xSendTopField, aMetric);
+ ::SetFieldUnit(*m_xSizeWidthField, aMetric);
+ ::SetFieldUnit(*m_xSizeHeightField, aMetric);
+
+ // Install handlers
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwEnvFormatPage, ModifyHdl);
+ m_xAddrLeftField->connect_value_changed( aLk );
+ m_xAddrTopField->connect_value_changed( aLk );
+ m_xSendLeftField->connect_value_changed( aLk );
+ m_xSendTopField->connect_value_changed( aLk );
+ m_xSizeWidthField->connect_value_changed( aLk );
+ m_xSizeHeightField->connect_value_changed( aLk );
+
+ m_xAddrEditButton->connect_selected(LINK(this, SwEnvFormatPage, AddrEditHdl));
+ m_xSendEditButton->connect_selected(LINK(this, SwEnvFormatPage, SendEditHdl));
+
+ m_xSizeFormatBox->connect_changed(LINK(this, SwEnvFormatPage, FormatHdl));
+
+ // m_xSizeFormatBox
+ for (sal_uInt16 i = PAPER_A3; i <= PAPER_KAI32BIG; i++)
+ {
+ if (i != PAPER_USER)
+ {
+ const OUString aPaperName = SvxPaperInfo::GetName(static_cast<Paper>(i));
+
+ if (aPaperName.isEmpty())
+ continue;
+
+ sal_Int32 nPos = 0;
+ while (nPos < m_xSizeFormatBox->get_count() &&
+ m_xSizeFormatBox->get_text(nPos) < aPaperName)
+ {
+ ++nPos;
+ }
+ m_xSizeFormatBox->insert_text(nPos, aPaperName);
+ m_aIDs.insert( m_aIDs.begin() + nPos, i);
+ }
+ }
+ m_xSizeFormatBox->append_text(SvxPaperInfo::GetName(PAPER_USER));
+ m_aIDs.push_back( sal_uInt16(PAPER_USER) );
+}
+
+void SwEnvFormatPage::Init(SwEnvDlg* pDialog)
+{
+ m_pDialog = pDialog;
+ m_aPreview.SetDialog(m_pDialog);
+}
+
+SwEnvFormatPage::~SwEnvFormatPage()
+{
+}
+
+IMPL_LINK( SwEnvFormatPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
+{
+ int lWVal = getfieldval(*m_xSizeWidthField);
+ int lHVal = getfieldval(*m_xSizeHeightField);
+
+ int lWidth = std::max(lWVal, lHVal);
+ int lHeight = std::min(lWVal, lHVal);
+
+ if (&rEdit == m_xSizeWidthField.get() || &rEdit == m_xSizeHeightField.get())
+ {
+ int nRotatedWidth = lHeight;
+ int nRotatedHeight = lWidth;
+ Paper ePaper = SvxPaperInfo::GetSvxPaper(
+ Size(nRotatedWidth, nRotatedHeight), MapUnit::MapTwip);
+ for (size_t i = 0; i < m_aIDs.size(); ++i)
+ if (m_aIDs[i] == o3tl::narrowing<sal_uInt16>(ePaper))
+ m_xSizeFormatBox->set_active(i);
+
+ // remember user size
+ if (m_aIDs[m_xSizeFormatBox->get_active()] == sal_uInt16(PAPER_USER))
+ {
+ lUserW = lWidth ;
+ lUserH = lHeight;
+ }
+
+ FormatHdl(*m_xSizeFormatBox);
+ }
+ else
+ {
+ FillItem(GetParentSwEnvDlg()->m_aEnvItem);
+ SetMinMax();
+ m_xPreview->queue_draw();
+ }
+}
+
+IMPL_LINK(SwEnvFormatPage, AddrEditHdl, const OUString&, rIdent, void)
+{
+ Edit(rIdent, false);
+}
+
+IMPL_LINK(SwEnvFormatPage, SendEditHdl, const OUString&, rIdent, void)
+{
+ Edit(rIdent, true);
+}
+
+void SwEnvFormatPage::Edit(std::u16string_view rIdent, bool bSender)
+{
+ SwWrtShell* pSh = GetParentSwEnvDlg()->m_pSh;
+ OSL_ENSURE(pSh, "Shell missing");
+
+ SwTextFormatColl* pColl = pSh->GetTextCollFromPool( static_cast< sal_uInt16 >(
+ bSender ? RES_POOLCOLL_SEND_ADDRESS : RES_POOLCOLL_ENVELOPE_ADDRESS));
+ OSL_ENSURE(pColl, "Text collection missing");
+
+ if (o3tl::starts_with(rIdent, u"character"))
+ {
+ SfxItemSet *pCollSet = GetCollItemSet(pColl, bSender);
+
+ // In order for the background color not to get ironed over:
+ SfxAllItemSet aTmpSet(*pCollSet);
+ ::ConvertAttrCharToGen(aTmpSet);
+
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+
+ const OUString sFormatStr = pColl->GetName();
+ ScopedVclPtr<SfxAbstractTabDialog> pDlg(rFact.CreateSwCharDlg(GetFrameWeld(), pSh->GetView(), aTmpSet, SwCharDlgMode::Env, &sFormatStr));
+ if (pDlg->Execute() == RET_OK)
+ {
+ SfxItemSet aOutputSet( *pDlg->GetOutputItemSet() );
+ ::ConvertAttrGenToChar(aOutputSet, aTmpSet);
+ pCollSet->Put(aOutputSet);
+ }
+ }
+ else if (o3tl::starts_with(rIdent, u"paragraph"))
+ {
+ SfxItemSet *pCollSet = GetCollItemSet(pColl, bSender);
+
+ // In order for the tabulators not to get ironed over:
+ SfxAllItemSet aTmpSet(*pCollSet);
+
+ // Insert tabs, default tabs into ItemSet
+ const SvxTabStopItem& rDefTabs =
+ pSh->GetView().GetCurShell()->GetPool().GetDefaultItem(RES_PARATR_TABSTOP);
+
+ const sal_uInt16 nDefDist = o3tl::narrowing<sal_uInt16>(::GetTabDist( rDefTabs ));
+ SfxUInt16Item aDefDistItem( SID_ATTR_TABSTOP_DEFAULTS, nDefDist );
+ aTmpSet.Put( aDefDistItem );
+
+ // Current tab
+ SfxUInt16Item aTabPos( SID_ATTR_TABSTOP_POS, 0 );
+ aTmpSet.Put( aTabPos );
+
+ // left border as offset
+ const tools::Long nOff = aTmpSet.Get(RES_MARGIN_TEXTLEFT).GetTextLeft();
+ SfxInt32Item aOff( SID_ATTR_TABSTOP_OFFSET, nOff );
+ aTmpSet.Put( aOff );
+
+ // set BoxInfo
+ ::PrepareBoxInfo( aTmpSet, *pSh );
+
+ SwDrawModel* pDrawModel = pSh->GetView().GetDocShell()->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel();
+ aTmpSet.Put(SvxColorListItem(pDrawModel->GetColorList(), SID_COLOR_TABLE));
+ aTmpSet.Put(SvxGradientListItem(pDrawModel->GetGradientList(), SID_GRADIENT_LIST));
+ aTmpSet.Put(SvxHatchListItem(pDrawModel->GetHatchList(), SID_HATCH_LIST));
+ aTmpSet.Put(SvxBitmapListItem(pDrawModel->GetBitmapList(), SID_BITMAP_LIST));
+ aTmpSet.Put(SvxPatternListItem(pDrawModel->GetPatternList(), SID_PATTERN_LIST));
+
+ const OUString sFormatStr = pColl->GetName();
+ SwParaDlg aDlg(GetFrameWeld(), pSh->GetView(), aTmpSet, DLG_ENVELOP, &sFormatStr);
+
+ if (aDlg.run() == RET_OK)
+ {
+ // maybe relocate defaults
+ const SfxUInt16Item* pDefaultsItem = nullptr;
+ SfxItemSet* pOutputSet = const_cast<SfxItemSet*>(aDlg.GetOutputItemSet());
+ sal_uInt16 nNewDist;
+
+ if( (pDefaultsItem = pOutputSet->GetItemIfSet( SID_ATTR_TABSTOP_DEFAULTS, false )) &&
+ nDefDist != (nNewDist = pDefaultsItem->GetValue()) )
+ {
+ SvxTabStopItem aDefTabs( 0, 0, SvxTabAdjust::Default, RES_PARATR_TABSTOP );
+ MakeDefTabs( nNewDist, aDefTabs );
+ pSh->SetDefault( aDefTabs );
+ pOutputSet->ClearItem( SID_ATTR_TABSTOP_DEFAULTS );
+ }
+ if( pOutputSet->Count() )
+ {
+ pCollSet->Put(*pOutputSet);
+ }
+ }
+ }
+}
+
+// A temporary Itemset that gets discarded at abort
+SfxItemSet *SwEnvFormatPage::GetCollItemSet(SwTextFormatColl const * pColl, bool bSender)
+{
+ std::unique_ptr<SfxItemSet>& pAddrSet = bSender ? GetParentSwEnvDlg()->m_pSenderSet : GetParentSwEnvDlg()->m_pAddresseeSet;
+ if (!pAddrSet)
+ {
+ // determine range (merge both Itemsets' ranges)
+ const WhichRangesContainer& pRanges = pColl->GetAttrSet().GetRanges();
+
+ static WhichRangesContainer const aRanges(svl::Items<
+ RES_PARATR_BEGIN, RES_PARATR_ADJUST,
+ RES_PARATR_TABSTOP, RES_PARATR_END-1,
+ RES_MARGIN_FIRSTLINE, RES_MARGIN_RIGHT,
+ RES_UL_SPACE, RES_UL_SPACE,
+ RES_BACKGROUND, RES_SHADOW,
+ SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_DEFAULTS,
+ SID_ATTR_TABSTOP_POS, SID_ATTR_TABSTOP_POS,
+ SID_ATTR_TABSTOP_OFFSET, SID_ATTR_TABSTOP_OFFSET,
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER
+ >);
+
+ pAddrSet.reset(new SfxItemSet(GetParentSwEnvDlg()->m_pSh->GetView().GetCurShell()->GetPool(),
+ pRanges));
+ for (const auto& rPair : aRanges)
+ pAddrSet->MergeRange(rPair.first, rPair.second);
+ pAddrSet->Put(pColl->GetAttrSet());
+ }
+
+ return pAddrSet.get();
+}
+
+IMPL_LINK_NOARG(SwEnvFormatPage, FormatHdl, weld::ComboBox&, void)
+{
+ tools::Long lWidth;
+ tools::Long lHeight;
+ tools::Long lSendFromLeft;
+ tools::Long lSendFromTop;
+ tools::Long lAddrFromLeft;
+ tools::Long lAddrFromTop;
+
+ const sal_uInt16 nPaper = m_aIDs[m_xSizeFormatBox->get_active()];
+ if (nPaper != sal_uInt16(PAPER_USER))
+ {
+ Size aSz = SvxPaperInfo::GetPaperSize(static_cast<Paper>(nPaper));
+ lWidth = std::max(aSz.Width(), aSz.Height());
+ lHeight = std::min(aSz.Width(), aSz.Height());
+ }
+ else
+ {
+ lWidth = lUserW;
+ lHeight = lUserH;
+ }
+
+ lSendFromLeft = 566; // 1cm
+ lSendFromTop = 566; // 1cm
+ lAddrFromLeft = lWidth / 2;
+ lAddrFromTop = lHeight / 2;
+
+ setfieldval(*m_xAddrLeftField, lAddrFromLeft);
+ setfieldval(*m_xAddrTopField , lAddrFromTop );
+ setfieldval(*m_xSendLeftField, lSendFromLeft);
+ setfieldval(*m_xSendTopField , lSendFromTop );
+
+ setfieldval(*m_xSizeWidthField , lWidth );
+ setfieldval(*m_xSizeHeightField, lHeight);
+
+ SetMinMax();
+
+ FillItem(GetParentSwEnvDlg()->m_aEnvItem);
+ m_xPreview->queue_draw();
+}
+
+void SwEnvFormatPage::SetMinMax()
+{
+ tools::Long lWVal = static_cast< tools::Long >(getfieldval(*m_xSizeWidthField ));
+ tools::Long lHVal = static_cast< tools::Long >(getfieldval(*m_xSizeHeightField));
+
+ tools::Long lWidth = std::max(lWVal, lHVal),
+ lHeight = std::min(lWVal, lHVal);
+
+ // Min and Max
+ m_xAddrLeftField->set_range(100 * (getfieldval(*m_xSendLeftField) + 566),
+ 100 * (lWidth - 2 * 566), FieldUnit::TWIP);
+ m_xAddrTopField->set_range(100 * (getfieldval(*m_xSendTopField ) + 2 * 566),
+ 100 * (lHeight - 2 * 566), FieldUnit::TWIP);
+ m_xSendLeftField->set_range(100 * 566,
+ 100 * (getfieldval(*m_xAddrLeftField) - 566), FieldUnit::TWIP);
+ m_xSendTopField->set_range(100 * 566,
+ 100 * (getfieldval(*m_xAddrTopField ) - 2 * 566), FieldUnit::TWIP);
+}
+
+std::unique_ptr<SfxTabPage> SwEnvFormatPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwEnvFormatPage>(pPage, pController, *rSet);
+}
+
+void SwEnvFormatPage::ActivatePage(const SfxItemSet& rSet)
+{
+ SfxItemSet aSet(rSet);
+ aSet.Put(GetParentSwEnvDlg()->m_aEnvItem);
+ Reset(&aSet);
+}
+
+DeactivateRC SwEnvFormatPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SwEnvFormatPage::FillItem(SwEnvItem& rItem)
+{
+ rItem.m_nAddrFromLeft = static_cast< sal_Int32 >(getfieldval(*m_xAddrLeftField));
+ rItem.m_nAddrFromTop = static_cast< sal_Int32 >(getfieldval(*m_xAddrTopField ));
+ rItem.m_nSendFromLeft = static_cast< sal_Int32 >(getfieldval(*m_xSendLeftField));
+ rItem.m_nSendFromTop = static_cast< sal_Int32 >(getfieldval(*m_xSendTopField ));
+
+ const sal_uInt16 nPaper = m_aIDs[m_xSizeFormatBox->get_active()];
+ if (nPaper == sal_uInt16(PAPER_USER))
+ {
+ tools::Long lWVal = static_cast< tools::Long >(getfieldval(*m_xSizeWidthField ));
+ tools::Long lHVal = static_cast< tools::Long >(getfieldval(*m_xSizeHeightField));
+ rItem.m_nWidth = std::max(lWVal, lHVal);
+ rItem.m_nHeight = std::min(lWVal, lHVal);
+ }
+ else
+ {
+ tools::Long lWVal = SvxPaperInfo::GetPaperSize(static_cast<Paper>(nPaper)).Width ();
+ tools::Long lHVal = SvxPaperInfo::GetPaperSize(static_cast<Paper>(nPaper)).Height();
+ rItem.m_nWidth = std::max(lWVal, lHVal);
+ rItem.m_nHeight = std::min(lWVal, lHVal);
+ }
+}
+
+bool SwEnvFormatPage::FillItemSet(SfxItemSet* rSet)
+{
+ FillItem(GetParentSwEnvDlg()->m_aEnvItem);
+ rSet->Put(GetParentSwEnvDlg()->m_aEnvItem);
+ return true;
+}
+
+void SwEnvFormatPage::Reset(const SfxItemSet* rSet)
+{
+ const SwEnvItem& rItem = static_cast<const SwEnvItem&>( rSet->Get(FN_ENVELOP));
+
+ Paper ePaper = SvxPaperInfo::GetSvxPaper(
+ Size( std::min(rItem.m_nWidth, rItem.m_nHeight),
+ std::max(rItem.m_nWidth, rItem.m_nHeight)), MapUnit::MapTwip);
+ for (size_t i = 0; i < m_aIDs.size(); ++i)
+ if (m_aIDs[i] == o3tl::narrowing<sal_uInt16>(ePaper))
+ m_xSizeFormatBox->set_active(i);
+
+ // Metric fields
+ setfieldval(*m_xAddrLeftField, rItem.m_nAddrFromLeft);
+ setfieldval(*m_xAddrTopField, rItem.m_nAddrFromTop );
+ setfieldval(*m_xSendLeftField, rItem.m_nSendFromLeft);
+ setfieldval(*m_xSendTopField, rItem.m_nSendFromTop );
+ setfieldval(*m_xSizeWidthField , std::max(rItem.m_nWidth, rItem.m_nHeight));
+ setfieldval(*m_xSizeHeightField , std::min(rItem.m_nWidth, rItem.m_nHeight));
+ SetMinMax();
+
+ GetParentSwEnvDlg()->m_pSenderSet.reset();
+ GetParentSwEnvDlg()->m_pAddresseeSet.reset();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/envfmt.hxx b/sw/source/ui/envelp/envfmt.hxx
new file mode 100644
index 0000000000..8b1405492c
--- /dev/null
+++ b/sw/source/ui/envelp/envfmt.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 <sal/config.h>
+
+#include <string_view>
+
+#include <vcl/weld.hxx>
+#include <envlop.hxx>
+
+class SwTextFormatColl;
+
+class SwEnvFormatPage : public SfxTabPage
+{
+ SwEnvDlg* m_pDialog;
+ std::vector<sal_uInt16> m_aIDs;
+
+ SwEnvPreview m_aPreview;
+ std::unique_ptr<weld::MetricSpinButton> m_xAddrLeftField;
+ std::unique_ptr<weld::MetricSpinButton> m_xAddrTopField;
+ std::unique_ptr<weld::MenuButton> m_xAddrEditButton;
+ std::unique_ptr<weld::MetricSpinButton> m_xSendLeftField;
+ std::unique_ptr<weld::MetricSpinButton> m_xSendTopField;
+ std::unique_ptr<weld::MenuButton> m_xSendEditButton;
+ std::unique_ptr<weld::ComboBox> m_xSizeFormatBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xSizeWidthField;
+ std::unique_ptr<weld::MetricSpinButton> m_xSizeHeightField;
+ std::unique_ptr<weld::CustomWeld> m_xPreview;
+
+ DECL_LINK(ModifyHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(AddrEditHdl, const OUString&, void);
+ DECL_LINK(SendEditHdl, const OUString&, void);
+ DECL_LINK(FormatHdl, weld::ComboBox&, void);
+
+ void SetMinMax();
+
+ SfxItemSet* GetCollItemSet(SwTextFormatColl const* pColl, bool bSender);
+
+ void Edit(std::u16string_view rIdent, bool bSender);
+
+ SwEnvDlg* GetParentSwEnvDlg() { return m_pDialog; }
+
+public:
+ SwEnvFormatPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ void Init(SwEnvDlg* pDialog);
+ virtual ~SwEnvFormatPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+ void FillItem(SwEnvItem& rItem);
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/envlop1.cxx b/sw/source/ui/envelp/envlop1.cxx
new file mode 100644
index 0000000000..ddffac09a6
--- /dev/null
+++ b/sw/source/ui/envelp/envlop1.cxx
@@ -0,0 +1,340 @@
+/* -*- 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 <dbmgr.hxx>
+#include <tools/lineend.hxx>
+#include <vcl/print.hxx>
+#include <vcl/settings.hxx>
+
+#include <swwait.hxx>
+#include <viewopt.hxx>
+
+#include <wrtsh.hxx>
+#include <cmdid.h>
+#include "envfmt.hxx"
+#include <envlop.hxx>
+#include "envprt.hxx"
+#include <fmtcol.hxx>
+#include <poolfmt.hxx>
+#include <view.hxx>
+
+#include <comphelper/string.hxx>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+SwEnvPreview::SwEnvPreview()
+ : m_pDialog(nullptr)
+{
+}
+
+void SwEnvPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 20,
+ pDrawingArea->get_text_height() * 8);
+}
+
+void SwEnvPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
+ rRenderContext.SetBackground(rRenderContext.GetSettings().GetStyleSettings().GetDialogColor());
+ rRenderContext.Erase();
+
+ const SwEnvItem& rItem = m_pDialog->m_aEnvItem;
+
+ const tools::Long nPageW = std::max(rItem.m_nWidth, rItem.m_nHeight);
+ const tools::Long nPageH = std::min(rItem.m_nWidth, rItem.m_nHeight);
+
+ Size aSize(GetOutputSizePixel());
+
+ const double f = 0.8 * std::min(
+ double(aSize.Width()) / double(nPageW),
+ double(aSize.Height()) / double(nPageH));
+
+ Color aBack = rSettings.GetWindowColor();
+ const Color& rFront = SwViewOption::GetCurrentViewOptions().GetFontColor();
+ Color aMedium((aBack.GetRed() + rFront.GetRed()) / 2,
+ (aBack.GetGreen() + rFront.GetGreen()) / 2,
+ (aBack.GetBlue() + rFront.GetBlue()) / 2);
+
+ rRenderContext.SetLineColor(rFront);
+
+ // Envelope
+ const tools::Long nW = static_cast<tools::Long>(f * nPageW);
+ const tools::Long nH = static_cast<tools::Long>(f * nPageH);
+ const tools::Long nX = (aSize.Width () - nW) / 2;
+ const tools::Long nY = (aSize.Height() - nH) / 2;
+ rRenderContext.SetFillColor(aBack);
+ rRenderContext.DrawRect(tools::Rectangle(Point(nX, nY), Size(nW, nH)));
+
+ // Sender
+ if (rItem.m_bSend)
+ {
+ const tools::Long nSendX = nX + static_cast<tools::Long>(f * rItem.m_nSendFromLeft);
+ const tools::Long nSendY = nY + static_cast<tools::Long>(f * rItem.m_nSendFromTop );
+ const tools::Long nSendW = static_cast<tools::Long>(f * (rItem.m_nAddrFromLeft - rItem.m_nSendFromLeft));
+ const tools::Long nSendH = static_cast<tools::Long>(f * (rItem.m_nAddrFromTop - rItem.m_nSendFromTop - 566));
+ rRenderContext.SetFillColor(aMedium);
+
+ rRenderContext.DrawRect(tools::Rectangle(Point(nSendX, nSendY), Size(nSendW, nSendH)));
+ }
+
+ // Addressee
+ const tools::Long nAddrX = nX + static_cast<tools::Long>(f * rItem.m_nAddrFromLeft);
+ const tools::Long nAddrY = nY + static_cast<tools::Long>(f * rItem.m_nAddrFromTop );
+ const tools::Long nAddrW = static_cast<tools::Long>(f * (nPageW - rItem.m_nAddrFromLeft - 566));
+ const tools::Long nAddrH = static_cast<tools::Long>(f * (nPageH - rItem.m_nAddrFromTop - 566));
+ rRenderContext.SetFillColor(aMedium);
+ rRenderContext.DrawRect(tools::Rectangle(Point(nAddrX, nAddrY), Size(nAddrW, nAddrH)));
+
+ // Stamp
+ const tools::Long nStmpW = static_cast<tools::Long>(f * 1417 /* 2,5 cm */);
+ const tools::Long nStmpH = static_cast<tools::Long>(f * 1701 /* 3,0 cm */);
+ const tools::Long nStmpX = nX + nW - static_cast<tools::Long>(f * 566) - nStmpW;
+ const tools::Long nStmpY = nY + static_cast<tools::Long>(f * 566);
+
+ rRenderContext.SetFillColor(aBack);
+ rRenderContext.DrawRect(tools::Rectangle(Point(nStmpX, nStmpY), Size(nStmpW, nStmpH)));
+}
+
+SwEnvDlg::SwEnvDlg(weld::Window* pParent, const SfxItemSet& rSet,
+ SwWrtShell* pWrtSh, Printer* pPrt, bool bInsert)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/envdialog.ui", "EnvDialog", &rSet)
+ , m_aEnvItem(static_cast<const SwEnvItem&>( rSet.Get(FN_ENVELOP)))
+ , m_pSh(pWrtSh)
+ , m_pPrinter(pPrt)
+ , m_xModify(m_xBuilder->weld_button("modify"))
+{
+ if (!bInsert)
+ {
+ GetUserButton()->set_label(m_xModify->get_label());
+ }
+
+ AddTabPage("envelope", SwEnvPage::Create, nullptr);
+ AddTabPage("format", SwEnvFormatPage::Create, nullptr);
+ AddTabPage("printer", SwEnvPrtPage::Create, nullptr);
+}
+
+SwEnvDlg::~SwEnvDlg()
+{
+ m_pAddresseeSet.reset();
+ m_pSenderSet.reset();
+}
+
+void SwEnvDlg::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "printer")
+ {
+ static_cast<SwEnvPrtPage*>(&rPage)->SetPrt(m_pPrinter);
+ }
+ else if (rId == "envelope")
+ {
+ static_cast<SwEnvPage*>(&rPage)->Init(this);
+ }
+ else if (rId == "format")
+ {
+ static_cast<SwEnvFormatPage*>(&rPage)->Init(this);
+ }
+}
+
+short SwEnvDlg::Ok()
+{
+ short nRet = SfxTabDialogController::Ok();
+
+ if (nRet == RET_OK || nRet == RET_USER)
+ {
+ if (m_pAddresseeSet)
+ {
+ SwTextFormatColl* pColl = m_pSh->GetTextCollFromPool(RES_POOLCOLL_ENVELOPE_ADDRESS);
+ pColl->SetFormatAttr(*m_pAddresseeSet);
+ }
+ if (m_pSenderSet)
+ {
+ SwTextFormatColl* pColl = m_pSh->GetTextCollFromPool(RES_POOLCOLL_SEND_ADDRESS);
+ pColl->SetFormatAttr(*m_pSenderSet);
+ }
+ }
+
+ return nRet;
+}
+
+SwEnvPage::SwEnvPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/envaddresspage.ui", "EnvAddressPage", &rSet)
+ , m_pDialog(nullptr)
+ , m_pSh(nullptr)
+ , m_xAddrEdit(m_xBuilder->weld_text_view("addredit"))
+ , m_xDatabaseLB(m_xBuilder->weld_combo_box("database"))
+ , m_xTableLB(m_xBuilder->weld_combo_box("table"))
+ , m_xDBFieldLB(m_xBuilder->weld_combo_box("field"))
+ , m_xInsertBT(m_xBuilder->weld_button("insert"))
+ , m_xSenderBox(m_xBuilder->weld_check_button("sender"))
+ , m_xSenderEdit(m_xBuilder->weld_text_view("senderedit"))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreview))
+{
+ auto nTextBoxHeight(m_xAddrEdit->get_height_rows(10));
+ auto nTextBoxWidth(m_xAddrEdit->get_approximate_digit_width() * 25);
+
+ m_xAddrEdit->set_size_request(nTextBoxWidth, nTextBoxHeight);
+ m_xSenderEdit->set_size_request(nTextBoxWidth, nTextBoxHeight);
+
+ auto nListBoxWidth = m_xTableLB->get_approximate_digit_width() * 25;
+ m_xTableLB->set_size_request(nListBoxWidth, -1);
+ m_xDatabaseLB->set_size_request(nListBoxWidth, -1);
+ m_xDBFieldLB->set_size_request(nListBoxWidth, -1);
+
+ SetExchangeSupport();
+}
+
+void SwEnvPage::Init(SwEnvDlg* pDialog)
+{
+ m_pDialog = pDialog;
+ m_pSh = m_pDialog->m_pSh;
+ m_aPreview.SetDialog(pDialog);
+
+ // Install handlers
+ m_xDatabaseLB->connect_changed(LINK(this, SwEnvPage, DatabaseHdl));
+ m_xTableLB->connect_changed(LINK(this, SwEnvPage, DatabaseHdl));
+ m_xInsertBT->connect_clicked(LINK(this, SwEnvPage, FieldHdl));
+ m_xSenderBox->connect_toggled(LINK(this, SwEnvPage, SenderHdl));
+
+ SwDBData aData = m_pSh->GetDBData();
+ m_sActDBName = aData.sDataSource + OUStringChar(DB_DELIM) + aData.sCommand;
+ InitDatabaseBox();
+}
+
+SwEnvPage::~SwEnvPage()
+{
+}
+
+IMPL_LINK( SwEnvPage, DatabaseHdl, weld::ComboBox&, rListBox, void )
+{
+ SwWait aWait( *m_pSh->GetView().GetDocShell(), true );
+
+ if (&rListBox == m_xDatabaseLB.get())
+ {
+ m_sActDBName = rListBox.get_active_text();
+ m_pSh->GetDBManager()->GetTableNames(*m_xTableLB, m_sActDBName);
+ m_sActDBName += OUStringChar(DB_DELIM);
+ }
+ else
+ {
+ m_sActDBName = comphelper::string::setToken(m_sActDBName, 1, DB_DELIM, m_xTableLB->get_active_text());
+ }
+ m_pSh->GetDBManager()->GetColumnNames(*m_xDBFieldLB, m_xDatabaseLB->get_active_text(),
+ m_xTableLB->get_active_text());
+}
+
+IMPL_LINK_NOARG(SwEnvPage, FieldHdl, weld::Button&, void)
+{
+ OUString aStr("<" + m_xDatabaseLB->get_active_text() + "." +
+ m_xTableLB->get_active_text() + "." +
+ m_xTableLB->get_active_id() + "." +
+ m_xDBFieldLB->get_active_text() + ">");
+ m_xAddrEdit->replace_selection(aStr);
+ int nStartPos, nEndPos;
+ m_xAddrEdit->get_selection_bounds(nStartPos, nEndPos);
+ m_xAddrEdit->grab_focus();
+ m_xAddrEdit->select_region(nStartPos, nEndPos);
+}
+
+IMPL_LINK_NOARG(SwEnvPage, SenderHdl, weld::Toggleable&, void)
+{
+ const bool bEnable = m_xSenderBox->get_active();
+ GetParentSwEnvDlg()->m_aEnvItem.m_bSend = bEnable;
+ m_xSenderEdit->set_sensitive(bEnable);
+ if (bEnable)
+ {
+ m_xSenderEdit->grab_focus();
+ if (m_xSenderEdit->get_text().isEmpty())
+ m_xSenderEdit->set_text(MakeSender());
+ }
+ m_xPreview->queue_draw();
+}
+
+void SwEnvPage::InitDatabaseBox()
+{
+ if (!m_pSh->GetDBManager())
+ return;
+
+ m_xDatabaseLB->clear();
+ const Sequence<OUString> aDataNames = SwDBManager::GetExistingDatabaseNames();
+
+ for (const OUString& rDataName : aDataNames)
+ m_xDatabaseLB->append_text(rDataName);
+
+ sal_Int32 nIdx{ 0 };
+ OUString sDBName = m_sActDBName.getToken( 0, DB_DELIM, nIdx );
+ OUString sTableName = m_sActDBName.getToken( 0, DB_DELIM, nIdx );
+ m_xDatabaseLB->set_active_text(sDBName);
+ if (m_pSh->GetDBManager()->GetTableNames(*m_xTableLB, sDBName))
+ {
+ m_xTableLB->append_text(sTableName);
+ m_pSh->GetDBManager()->GetColumnNames(*m_xDBFieldLB, sDBName, sTableName);
+ }
+ else
+ m_xDBFieldLB->clear();
+}
+
+std::unique_ptr<SfxTabPage> SwEnvPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwEnvPage>(pPage, pController, *rSet);
+}
+
+void SwEnvPage::ActivatePage(const SfxItemSet& rSet)
+{
+ SfxItemSet aSet(rSet);
+ aSet.Put(GetParentSwEnvDlg()->m_aEnvItem);
+ Reset(&aSet);
+}
+
+DeactivateRC SwEnvPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ FillItem(GetParentSwEnvDlg()->m_aEnvItem);
+ if( _pSet )
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SwEnvPage::FillItem(SwEnvItem& rItem)
+{
+ rItem.m_aAddrText = m_xAddrEdit->get_text();
+ rItem.m_bSend = m_xSenderBox->get_active();
+ rItem.m_aSendText = m_xSenderEdit->get_text();
+}
+
+bool SwEnvPage::FillItemSet(SfxItemSet* rSet)
+{
+ FillItem(GetParentSwEnvDlg()->m_aEnvItem);
+ rSet->Put(GetParentSwEnvDlg()->m_aEnvItem);
+ return true;
+}
+
+void SwEnvPage::Reset(const SfxItemSet* rSet)
+{
+ SwEnvItem aItem = static_cast<const SwEnvItem&>( rSet->Get(FN_ENVELOP));
+ m_xAddrEdit->set_text(convertLineEnd(aItem.m_aAddrText, GetSystemLineEnd()));
+ m_xSenderEdit->set_text(convertLineEnd(aItem.m_aSendText, GetSystemLineEnd()));
+ m_xSenderBox->set_active(aItem.m_bSend);
+ SenderHdl(*m_xSenderBox);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/envprt.cxx b/sw/source/ui/envelp/envprt.cxx
new file mode 100644
index 0000000000..d08f718e1f
--- /dev/null
+++ b/sw/source/ui/envelp/envprt.cxx
@@ -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 .
+ */
+
+#include <vcl/print.hxx>
+#include <svtools/prnsetup.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <cmdid.h>
+#include "envprt.hxx"
+#include <envlop.hxx>
+#include <uitool.hxx>
+
+SwEnvPrtPage::SwEnvPrtPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/envprinterpage.ui", "EnvPrinterPage", &rSet)
+ , m_xUpper(m_xBuilder->weld_widget("upper"))
+ , m_xLower(m_xBuilder->weld_widget("lower"))
+ , m_xTopButton(m_xBuilder->weld_radio_button("top"))
+ , m_xBottomButton(m_xBuilder->weld_radio_button("bottom"))
+ , m_xRightField(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
+ , m_xDownField(m_xBuilder->weld_metric_spin_button("down", FieldUnit::CM))
+ , m_xPrinterInfo(m_xBuilder->weld_label("printername"))
+ , m_xPrtSetup(m_xBuilder->weld_button("setup"))
+ , m_aIdsL { m_xBuilder->weld_radio_button("horileftl"),
+ m_xBuilder->weld_radio_button("horicenterl"),
+ m_xBuilder->weld_radio_button("horirightl"),
+ m_xBuilder->weld_radio_button("vertleftl"),
+ m_xBuilder->weld_radio_button("vertcenterl"),
+ m_xBuilder->weld_radio_button("vertrightl") }
+ , m_aIdsU { m_xBuilder->weld_radio_button("horileftu"),
+ m_xBuilder->weld_radio_button("horicenteru"),
+ m_xBuilder->weld_radio_button("horirightu"),
+ m_xBuilder->weld_radio_button("vertleftu"),
+ m_xBuilder->weld_radio_button("vertcenteru"),
+ m_xBuilder->weld_radio_button("vertrightu") }
+{
+ SetExchangeSupport();
+
+ // Metrics
+ FieldUnit eUnit = ::GetDfltMetric(false);
+ ::SetFieldUnit(*m_xRightField, eUnit);
+ ::SetFieldUnit(*m_xDownField, eUnit);
+
+ // Install handlers
+ m_xTopButton->connect_toggled(LINK(this, SwEnvPrtPage, ClickHdl));
+ m_xBottomButton->connect_toggled(LINK(this, SwEnvPrtPage, ClickHdl));
+
+ m_xPrtSetup->connect_clicked(LINK(this, SwEnvPrtPage, ButtonHdl));
+
+ for (auto& a : m_aIdsL)
+ a->connect_toggled(LINK(this, SwEnvPrtPage, LowerHdl));
+ for (auto& a : m_aIdsU)
+ a->connect_toggled(LINK(this, SwEnvPrtPage, UpperHdl));
+
+ // Bitmaps
+ ClickHdl(*m_xBottomButton);
+}
+
+SwEnvPrtPage::~SwEnvPrtPage()
+{
+ m_xPrt.clear();
+}
+
+IMPL_LINK_NOARG(SwEnvPrtPage, ClickHdl, weld::Toggleable&, void)
+{
+ // Envelope from bottom, otherwise Envelope from top
+ const bool bLowerActive = m_xBottomButton->get_active();
+ m_xUpper->set_visible(!bLowerActive);
+ m_xLower->set_visible(bLowerActive);
+}
+
+IMPL_LINK(SwEnvPrtPage, LowerHdl, weld::Toggleable&, rButton, void)
+{
+ for (int i = ENV_HOR_LEFT; i <= ENV_VER_RGHT; ++i)
+ {
+ if (&rButton == m_aIdsL[i].get())
+ {
+ m_aIdsU[i]->set_active(m_aIdsL[i]->get_active());
+ break;
+ }
+ }
+}
+
+IMPL_LINK(SwEnvPrtPage, UpperHdl, weld::Toggleable&, rButton, void)
+{
+ for (int i = ENV_HOR_LEFT; i <= ENV_VER_RGHT; ++i)
+ {
+ if (&rButton == m_aIdsU[i].get())
+ {
+ m_aIdsL[i]->set_active(m_aIdsU[i]->get_active());
+ break;
+ }
+ }
+}
+
+IMPL_LINK(SwEnvPrtPage, ButtonHdl, weld::Button&, rBtn, void)
+{
+ if (&rBtn == m_xPrtSetup.get())
+ {
+ // Call printer setup
+ if (m_xPrt)
+ {
+ PrinterSetupDialog aDlg(GetFrameWeld());
+ aDlg.SetPrinter(m_xPrt);
+ aDlg.run();
+ rBtn.grab_focus();
+ m_xPrinterInfo->set_label(m_xPrt->GetName());
+ }
+ }
+}
+
+std::unique_ptr<SfxTabPage> SwEnvPrtPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwEnvPrtPage>(pPage, pController, *rSet);
+}
+
+void SwEnvPrtPage::ActivatePage(const SfxItemSet&)
+{
+ if (m_xPrt)
+ m_xPrinterInfo->set_label(m_xPrt->GetName());
+}
+
+DeactivateRC SwEnvPrtPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SwEnvPrtPage::FillItem(SwEnvItem& rItem)
+{
+ int nOrient = 0;
+ for (int i = ENV_HOR_LEFT; i <= ENV_VER_RGHT; ++i)
+ {
+ assert(m_aIdsL[i]->get_active() == m_aIdsU[i]->get_active());
+ if (m_aIdsL[i]->get_active())
+ {
+ nOrient = i;
+ break;
+ }
+ }
+
+ rItem.m_eAlign = static_cast<SwEnvAlign>(nOrient);
+ rItem.m_bPrintFromAbove = m_xTopButton->get_active();
+ rItem.m_nShiftRight = getfieldval(*m_xRightField);
+ rItem.m_nShiftDown = getfieldval(*m_xDownField);
+}
+
+bool SwEnvPrtPage::FillItemSet(SfxItemSet* rSet)
+{
+ FillItem(GetParentSwEnvDlg()->m_aEnvItem);
+ rSet->Put(GetParentSwEnvDlg()->m_aEnvItem);
+ return true;
+}
+
+void SwEnvPrtPage::Reset(const SfxItemSet* rSet)
+{
+ // Read item
+ const SwEnvItem& rItem = static_cast<const SwEnvItem&>( rSet->Get(FN_ENVELOP) );
+ m_aIdsL[rItem.m_eAlign]->set_active(true);
+ m_aIdsU[rItem.m_eAlign]->set_active(true);
+
+ if (rItem.m_bPrintFromAbove)
+ m_xTopButton->set_active(true);
+ else
+ m_xBottomButton->set_active(true);
+
+ setfieldval(*m_xRightField, rItem.m_nShiftRight);
+ setfieldval(*m_xDownField , rItem.m_nShiftDown );
+
+ ActivatePage(*rSet);
+ ClickHdl(*m_xTopButton);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/envprt.hxx b/sw/source/ui/envelp/envprt.hxx
new file mode 100644
index 0000000000..4cc3bf4f78
--- /dev/null
+++ b/sw/source/ui/envelp/envprt.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 <vcl/print.hxx>
+#include <vcl/weld.hxx>
+
+#include <envimg.hxx>
+#include <envlop.hxx>
+
+class SwEnvDlg;
+
+class SwEnvPrtPage : public SfxTabPage
+{
+ std::unique_ptr<weld::Widget> m_xUpper;
+ std::unique_ptr<weld::Widget> m_xLower;
+ std::unique_ptr<weld::RadioButton> m_xTopButton;
+ std::unique_ptr<weld::RadioButton> m_xBottomButton;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightField;
+ std::unique_ptr<weld::MetricSpinButton> m_xDownField;
+ std::unique_ptr<weld::Label> m_xPrinterInfo;
+ std::unique_ptr<weld::Button> m_xPrtSetup;
+
+ std::unique_ptr<weld::RadioButton> m_aIdsL[ENV_VER_RGHT - ENV_HOR_LEFT + 1];
+ std::unique_ptr<weld::RadioButton> m_aIdsU[ENV_VER_RGHT - ENV_HOR_LEFT + 1];
+
+ VclPtr<Printer> m_xPrt;
+
+ DECL_LINK(LowerHdl, weld::Toggleable&, void);
+ DECL_LINK(UpperHdl, weld::Toggleable&, void);
+ DECL_LINK(ClickHdl, weld::Toggleable&, void);
+ DECL_LINK(ButtonHdl, weld::Button&, void);
+
+ SwEnvDlg* GetParentSwEnvDlg() { return static_cast<SwEnvDlg*>(GetDialogController()); }
+
+public:
+ SwEnvPrtPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SwEnvPrtPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+ void FillItem(SwEnvItem& rItem);
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+ void SetPrt(Printer* pPrinter) { m_xPrt = pPrinter; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/label1.cxx b/sw/source/ui/envelp/label1.cxx
new file mode 100644
index 0000000000..8e9a3c3eff
--- /dev/null
+++ b/sw/source/ui/envelp/label1.cxx
@@ -0,0 +1,717 @@
+/* -*- 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 <vcl/svapp.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/lineend.hxx>
+#include <svtools/unitconv.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <swtypes.hxx>
+#include <labimp.hxx>
+#include "swuilabimp.hxx"
+#include "labfmt.hxx"
+#include "labprt.hxx"
+#include <dbmgr.hxx>
+#include <uitool.hxx>
+#include <cmdid.h>
+#include <helpids.h>
+#include <strings.hrc>
+#include <envimg.hxx>
+
+void SwLabRec::SetFromItem( const SwLabItem& rItem )
+{
+ m_nHDist = rItem.m_lHDist;
+ m_nVDist = rItem.m_lVDist;
+ m_nWidth = rItem.m_lWidth;
+ m_nHeight = rItem.m_lHeight;
+ m_nLeft = rItem.m_lLeft;
+ m_nUpper = rItem.m_lUpper;
+ m_nCols = rItem.m_nCols;
+ m_nRows = rItem.m_nRows;
+ m_nPWidth = rItem.m_lPWidth;
+ m_nPHeight = rItem.m_lPHeight;
+ m_bCont = rItem.m_bCont;
+}
+
+void SwLabRec::FillItem( SwLabItem& rItem ) const
+{
+ rItem.m_lHDist = m_nHDist;
+ rItem.m_lVDist = m_nVDist;
+ rItem.m_lWidth = m_nWidth;
+ rItem.m_lHeight = m_nHeight;
+ rItem.m_lLeft = m_nLeft;
+ rItem.m_lUpper = m_nUpper;
+ rItem.m_nCols = m_nCols;
+ rItem.m_lPWidth = m_nPWidth;
+ rItem.m_lPHeight = m_nPHeight;
+ rItem.m_nRows = m_nRows;
+}
+
+void SwLabDlg::ReplaceGroup_( const OUString &rMake )
+{
+ // Remove old entries
+ m_pRecs->erase(m_pRecs->begin() + 1, m_pRecs->end());
+ m_aLabelsCfg.FillLabels(rMake, *m_pRecs);
+ m_aLstGroup = rMake;
+}
+
+void SwLabDlg::PageCreated(const OUString &rId, SfxTabPage &rPage)
+{
+ if (rId == "labels")
+ {
+ static_cast<SwLabPage*>(&rPage)->SetDBManager(m_pDBManager);
+ static_cast<SwLabPage*>(&rPage)->InitDatabaseBox();
+ if (!m_bLabel)
+ static_cast<SwLabPage*>(&rPage)->SetToBusinessCard();
+ }
+ else if (rId == "options")
+ m_pPrtPage = static_cast<SwLabPrtPage*>(&rPage);
+}
+
+SwLabDlg::SwLabDlg(weld::Window* pParent, const SfxItemSet& rSet,
+ SwDBManager* pDBManager_, bool bLabel)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/labeldialog.ui", "LabelDialog", &rSet)
+ , m_pDBManager(pDBManager_)
+ , m_pPrtPage(nullptr)
+ , m_aTypeIds(50, 10)
+ , m_pRecs(new SwLabRecs)
+ , m_bLabel(bLabel)
+{
+ weld::WaitObject aWait(pParent);
+
+ // Read user label from writer.cfg
+ SwLabItem aItem(static_cast<const SwLabItem&>(rSet.Get( FN_LABEL )));
+ std::unique_ptr<SwLabRec> pRec(new SwLabRec);
+ pRec->m_aMake = pRec->m_aType = SwResId(STR_CUSTOM_LABEL);
+ pRec->SetFromItem( aItem );
+
+ bool bDouble = false;
+
+ for (const std::unique_ptr<SwLabRec> & i : *m_pRecs)
+ {
+ if (pRec->m_aMake == i->m_aMake &&
+ pRec->m_aType == i->m_aType)
+ {
+ bDouble = true;
+ break;
+ }
+ }
+
+ if (!bDouble)
+ m_pRecs->insert( m_pRecs->begin(), std::move(pRec));
+
+ size_t nLstGroup = 0;
+ const std::vector<OUString>& rMan = m_aLabelsCfg.GetManufacturers();
+ for(size_t nMan = 0; nMan < rMan.size(); ++nMan)
+ {
+ m_aMakes.push_back(rMan[nMan]);
+ if ( rMan[nMan] == aItem.m_aLstMake )
+ nLstGroup = nMan;
+ }
+
+ if ( !m_aMakes.empty() )
+ ReplaceGroup_( m_aMakes[nLstGroup] );
+
+ if (m_xExampleSet)
+ m_xExampleSet->Put(aItem);
+
+ AddTabPage("format", SwLabFormatPage::Create, nullptr);
+ AddTabPage("options", SwLabPrtPage::Create, nullptr);
+ AddTabPage("labels", SwLabPage::Create, nullptr);
+ m_sBusinessCardDlg = SwResId(STR_BUSINESS_CARDS);
+
+ if (m_bLabel)
+ {
+ RemoveTabPage("business");
+ RemoveTabPage("private");
+ }
+ else
+ {
+ AddTabPage("business", SwBusinessDataPage::Create, nullptr );
+ AddTabPage("private", SwPrivateDataPage::Create, nullptr);
+ m_xDialog->set_title(m_sBusinessCardDlg);
+ }
+}
+
+SwLabDlg::~SwLabDlg()
+{
+ m_pRecs.reset();
+}
+
+void SwLabDlg::GetLabItem(SwLabItem &rItem)
+{
+ const SwLabItem& rActItem = static_cast<const SwLabItem&>(GetExampleSet()->Get(FN_LABEL));
+ const SwLabItem& rOldItem = static_cast<const SwLabItem&>(GetInputSetImpl()->Get(FN_LABEL));
+
+ if (rActItem != rOldItem)
+ {
+ // Was already "put" with (hopefully) correct content
+ rItem = rActItem;
+ }
+ else
+ {
+ rItem = rOldItem;
+
+ // In rItem there are only settings defined by users.
+ // Therefore get the real settings directly from Record
+ SwLabRec* pRec = GetRecord(rItem.m_aType, rItem.m_bCont);
+ pRec->FillItem( rItem );
+ }
+}
+
+SwLabRec* SwLabDlg::GetRecord(std::u16string_view rRecName, bool bCont)
+{
+ SwLabRec* pRec = nullptr;
+ bool bFound = false;
+ const OUString sCustom(SwResId(STR_CUSTOM_LABEL));
+
+ const size_t nCount = Recs().size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ pRec = Recs()[i].get();
+ if (pRec->m_aType != sCustom &&
+ rRecName == pRec->m_aType && bCont == pRec->m_bCont)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound) // User defined
+ pRec = Recs()[0].get();
+
+ return pRec;
+}
+
+Printer *SwLabDlg::GetPrt()
+{
+ if (m_pPrtPage)
+ return m_pPrtPage->GetPrt();
+ else
+ return nullptr;
+}
+
+SwLabPage::SwLabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/cardmediumpage.ui", "CardMediumPage", &rSet)
+ , m_pDBManager(nullptr)
+ , m_aItem(static_cast<const SwLabItem&>(rSet.Get(FN_LABEL)))
+ , m_xAddressFrame(m_xBuilder->weld_widget("addressframe"))
+ , m_xAddrBox(m_xBuilder->weld_check_button("address"))
+ , m_xWritingEdit(m_xBuilder->weld_text_view("textview"))
+ , m_xDatabaseLB(m_xBuilder->weld_combo_box("database"))
+ , m_xTableLB(m_xBuilder->weld_combo_box("table"))
+ , m_xInsertBT(m_xBuilder->weld_button("insert"))
+ , m_xDBFieldLB(m_xBuilder->weld_combo_box("field"))
+ , m_xContButton(m_xBuilder->weld_radio_button("continuous"))
+ , m_xSheetButton(m_xBuilder->weld_radio_button("sheet"))
+ , m_xMakeBox(m_xBuilder->weld_combo_box("brand"))
+ , m_xTypeBox(m_xBuilder->weld_combo_box("type"))
+ , m_xHiddenSortTypeBox(m_xBuilder->weld_combo_box("hiddentype"))
+ , m_xFormatInfo(m_xBuilder->weld_label("formatinfo"))
+{
+ weld::WaitObject aWait(GetFrameWeld());
+
+ m_xWritingEdit->set_size_request(m_xWritingEdit->get_approximate_digit_width() * 30,
+ m_xWritingEdit->get_height_rows(10));
+ m_xHiddenSortTypeBox->make_sorted();
+
+ tools::Long nListBoxWidth = m_xWritingEdit->get_approximate_digit_width() * 25;
+ m_xTableLB->set_size_request(nListBoxWidth, -1);
+ m_xDatabaseLB->set_size_request(nListBoxWidth, -1);
+ m_xDBFieldLB->set_size_request(nListBoxWidth, -1);
+
+ SetExchangeSupport();
+
+ // Install handlers
+ m_xAddrBox->connect_toggled(LINK(this, SwLabPage, AddrHdl));
+ m_xDatabaseLB->connect_changed(LINK(this, SwLabPage, DatabaseHdl));
+ m_xTableLB->connect_changed(LINK(this, SwLabPage, DatabaseHdl));
+ m_xDBFieldLB->connect_changed(LINK(this, SwLabPage, DatabaseHdl));
+ m_xInsertBT->connect_clicked(LINK(this, SwLabPage, FieldHdl));
+ // Disable insert button first,
+ // it'll be enabled if m_xDatabaseLB, m_pTableLB and m_pInsertBT are filled
+ m_xInsertBT->set_sensitive(false);
+ m_xContButton->connect_toggled(LINK(this, SwLabPage, PageHdl));
+ m_xSheetButton->connect_toggled(LINK(this, SwLabPage, PageHdl));
+ auto nMaxWidth = m_xMakeBox->get_approximate_digit_width() * 32;
+ m_xMakeBox->set_size_request(nMaxWidth, -1);
+ m_xTypeBox->set_size_request(nMaxWidth, -1);
+ m_xMakeBox->connect_changed(LINK(this, SwLabPage, MakeHdl));
+ m_xTypeBox->connect_changed(LINK(this, SwLabPage, TypeHdl));
+
+ InitDatabaseBox();
+}
+
+SwLabPage::~SwLabPage()
+{
+}
+
+void SwLabPage::SetToBusinessCard()
+{
+ m_xContainer->set_help_id(HID_BUSINESS_FMT_PAGE);
+ m_xContButton->set_help_id(HID_BUSINESS_FMT_PAGE_CONT);
+ m_xSheetButton->set_help_id(HID_BUSINESS_FMT_PAGE_SHEET);
+ m_xMakeBox->set_help_id(HID_BUSINESS_FMT_PAGE_BRAND);
+ m_xTypeBox->set_help_id(HID_BUSINESS_FMT_PAGE_TYPE);
+};
+
+IMPL_LINK_NOARG(SwLabPage, AddrHdl, weld::Toggleable&, void)
+{
+ OUString aWriting;
+
+ if (m_xAddrBox->get_active())
+ aWriting = convertLineEnd(MakeSender(), GetSystemLineEnd());
+
+ m_xWritingEdit->set_text(aWriting);
+ m_xWritingEdit->grab_focus();
+}
+
+IMPL_LINK( SwLabPage, DatabaseHdl, weld::ComboBox&, rListBox, void )
+{
+ m_sActDBName = m_xDatabaseLB->get_active_text();
+
+ weld::WaitObject aObj(GetParentSwLabDlg()->getDialog());
+
+ if (&rListBox == m_xDatabaseLB.get())
+ GetDBManager()->GetTableNames(*m_xTableLB, m_sActDBName);
+
+ if (&rListBox == m_xDatabaseLB.get() || &rListBox == m_xTableLB.get())
+ GetDBManager()->GetColumnNames(*m_xDBFieldLB, m_sActDBName, m_xTableLB->get_active_text());
+
+ if (!m_xDatabaseLB->get_active_text().isEmpty() && !m_xTableLB->get_active_text().isEmpty()
+ && !m_xDBFieldLB->get_active_text().isEmpty())
+ m_xInsertBT->set_sensitive(true);
+ else
+ m_xInsertBT->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SwLabPage, FieldHdl, weld::Button&, void)
+{
+ OUString aStr("<" + m_xDatabaseLB->get_active_text() + "." +
+ m_xTableLB->get_active_text() + "." +
+ m_xTableLB->get_active_id() + "." +
+ m_xDBFieldLB->get_active_text() + ">");
+ m_xWritingEdit->replace_selection(aStr);
+ int nStartPos, nEndPos;
+ m_xWritingEdit->get_selection_bounds(nStartPos, nEndPos);
+ m_xWritingEdit->grab_focus();
+ m_xWritingEdit->select_region(nStartPos, nEndPos);
+}
+
+IMPL_LINK_NOARG(SwLabPage, PageHdl, weld::Toggleable&, void)
+{
+ MakeHdl(*m_xMakeBox);
+}
+
+IMPL_LINK_NOARG(SwLabPage, MakeHdl, weld::ComboBox&, void)
+{
+ weld::WaitObject aWait(GetParentSwLabDlg()->getDialog());
+
+ m_xTypeBox->clear();
+ m_xHiddenSortTypeBox->clear();
+ GetParentSwLabDlg()->TypeIds().clear();
+
+ const OUString aMake = m_xMakeBox->get_active_text();
+ GetParentSwLabDlg()->ReplaceGroup( aMake );
+ m_aItem.m_aLstMake = aMake;
+
+ const bool bCont = m_xContButton->get_active();
+ const size_t nCount = GetParentSwLabDlg()->Recs().size();
+ size_t nLstType = 0;
+
+ const OUString sCustom(SwResId(STR_CUSTOM_LABEL));
+ //insert the entries into the sorted list box
+ for ( size_t i = 0; i < nCount; ++i )
+ {
+ const OUString aType(GetParentSwLabDlg()->Recs()[i]->m_aType);
+ bool bInsert = false;
+ if (GetParentSwLabDlg()->Recs()[i]->m_aType == sCustom)
+ {
+ bInsert = true;
+ m_xTypeBox->append_text(aType );
+ }
+ else if (GetParentSwLabDlg()->Recs()[i]->m_bCont == bCont)
+ {
+ if (m_xHiddenSortTypeBox->find_text(aType) == -1)
+ {
+ bInsert = true;
+ m_xHiddenSortTypeBox->append_text( aType );
+ }
+ }
+ if(bInsert)
+ {
+ GetParentSwLabDlg()->TypeIds().push_back(i);
+ if ( !nLstType && aType == m_aItem.m_aLstType )
+ nLstType = GetParentSwLabDlg()->TypeIds().size();
+ }
+ }
+ for (int nEntry = 0; nEntry < m_xHiddenSortTypeBox->get_count(); ++nEntry)
+ {
+ m_xTypeBox->append_text(m_xHiddenSortTypeBox->get_text(nEntry));
+ }
+ if (nLstType)
+ m_xTypeBox->set_active_text(m_aItem.m_aLstType);
+ else
+ m_xTypeBox->set_active(0);
+ TypeHdl(*m_xTypeBox);
+}
+
+IMPL_LINK_NOARG(SwLabPage, TypeHdl, weld::ComboBox&, void)
+{
+ DisplayFormat();
+ m_aItem.m_aType = m_xTypeBox->get_active_text();
+}
+
+void SwLabPage::DisplayFormat()
+{
+ 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> xField(xBuilder->weld_metric_spin_button("spin", FieldUnit::CM));
+ SetFieldUnit(*xField, ::GetDfltMetric(false));
+ xField->set_digits(2);
+ xField->set_range(0, INT_MAX - 1, FieldUnit::NONE);
+
+ SwLabRec* pRec = GetSelectedEntryPos();
+ m_aItem.m_aLstType = pRec->m_aType;
+ setfldval(*xField, pRec->m_nWidth);
+ xField->reformat();
+ const OUString aWString = xField->get_text();
+
+ setfldval(*xField, pRec->m_nHeight);
+ xField->reformat();
+
+ OUString aText = pRec->m_aType + ": " + aWString +
+ " x " + xField->get_text() +
+ " (" + OUString::number( pRec->m_nCols ) +
+ " x " + OUString::number( pRec->m_nRows ) + ")";
+ m_xFormatInfo->set_label(aText);
+}
+
+SwLabRec* SwLabPage::GetSelectedEntryPos()
+{
+ OUString sSelEntry(m_xTypeBox->get_active_text());
+
+ return GetParentSwLabDlg()->GetRecord(sSelEntry, m_xContButton->get_active());
+}
+
+void SwLabPage::InitDatabaseBox()
+{
+ if( !GetDBManager() )
+ return;
+
+ m_xDatabaseLB->clear();
+ const css::uno::Sequence<OUString> aDataNames = SwDBManager::GetExistingDatabaseNames();
+ for (const OUString& rDataName : aDataNames)
+ m_xDatabaseLB->append_text(rDataName);
+ sal_Int32 nIdx{ 0 };
+ OUString sDBName = m_sActDBName.getToken( 0, DB_DELIM, nIdx );
+ OUString sTableName = m_sActDBName.getToken( 0, DB_DELIM, nIdx );
+ m_xDatabaseLB->set_active_text(sDBName);
+ if( !sDBName.isEmpty() && GetDBManager()->GetTableNames(*m_xTableLB, sDBName))
+ {
+ m_xTableLB->set_active_text(sTableName);
+ GetDBManager()->GetColumnNames(*m_xDBFieldLB, m_sActDBName, sTableName);
+ }
+ else
+ m_xDBFieldLB->clear();
+}
+
+std::unique_ptr<SfxTabPage> SwLabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwLabPage>(pPage, pController, *rSet);
+}
+
+void SwLabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ Reset( &rSet );
+}
+
+DeactivateRC SwLabPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if (_pSet)
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+void SwLabPage::FillItem(SwLabItem& rItem)
+{
+ rItem.m_bAddr = m_xAddrBox->get_active();
+ rItem.m_aWriting = m_xWritingEdit->get_text();
+ rItem.m_bCont = m_xContButton->get_active();
+ rItem.m_aMake = m_xMakeBox->get_active_text();
+ rItem.m_aType = m_xTypeBox->get_active_text();
+ rItem.m_sDBName = m_sActDBName;
+
+ SwLabRec* pRec = GetSelectedEntryPos();
+ pRec->FillItem( rItem );
+
+ rItem.m_aLstMake = m_xMakeBox->get_active_text();
+ rItem.m_aLstType = m_xTypeBox->get_active_text();
+}
+
+bool SwLabPage::FillItemSet(SfxItemSet* rSet)
+{
+ FillItem( m_aItem );
+ rSet->Put( m_aItem );
+
+ return true;
+}
+
+void SwLabPage::Reset(const SfxItemSet* rSet)
+{
+ m_xMakeBox->clear();
+
+ size_t nLstGroup = 0;
+
+ const size_t nCount = GetParentSwLabDlg()->Makes().size();
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ OUString& rStr = GetParentSwLabDlg()->Makes()[i];
+ m_xMakeBox->append_text(rStr);
+
+ if ( rStr == m_aItem.m_aLstMake)
+ nLstGroup = i;
+ }
+
+ m_xMakeBox->set_active( nLstGroup );
+ MakeHdl(*m_xMakeBox);
+
+ m_aItem = static_cast<const SwLabItem&>( rSet->Get(FN_LABEL));
+ OUString sDBName = m_aItem.m_sDBName;
+
+ OUString aWriting(convertLineEnd(m_aItem.m_aWriting, GetSystemLineEnd()));
+
+ m_xAddrBox->set_active( m_aItem.m_bAddr );
+ m_xWritingEdit->set_text( aWriting );
+
+ for(const auto& rMake : GetParentSwLabDlg()->Makes())
+ {
+ if (m_xMakeBox->find_text(rMake) == -1)
+ m_xMakeBox->append_text(rMake);
+ }
+
+ m_xMakeBox->set_active_text(m_aItem.m_aMake);
+ //save the current type
+ OUString sType(m_aItem.m_aType);
+ MakeHdl(*m_xMakeBox);
+ m_aItem.m_aType = sType;
+ //#102806# a newly added make may not be in the type ListBox already
+ if (m_xTypeBox->find_text(m_aItem.m_aType) == -1 && !m_aItem.m_aMake.isEmpty())
+ GetParentSwLabDlg()->UpdateGroup( m_aItem.m_aMake );
+ if (m_xTypeBox->find_text(m_aItem.m_aType) != -1)
+ {
+ m_xTypeBox->set_active_text(m_aItem.m_aType);
+ TypeHdl(*m_xTypeBox);
+ }
+ if (m_xDatabaseLB->find_text(sDBName) != -1)
+ {
+ m_xDatabaseLB->set_active_text(sDBName);
+ DatabaseHdl(*m_xDatabaseLB);
+ }
+
+ if (m_aItem.m_bCont)
+ m_xContButton->set_active(true);
+ else
+ m_xSheetButton->set_active(true);
+}
+
+SwPrivateDataPage::SwPrivateDataPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/privateuserpage.ui", "PrivateUserPage", &rSet)
+ , m_xFirstNameED(m_xBuilder->weld_entry("firstname"))
+ , m_xNameED(m_xBuilder->weld_entry("lastname"))
+ , m_xShortCutED(m_xBuilder->weld_entry("shortname"))
+ , m_xFirstName2ED(m_xBuilder->weld_entry("firstname2"))
+ , m_xName2ED(m_xBuilder->weld_entry("lastname2"))
+ , m_xShortCut2ED(m_xBuilder->weld_entry("shortname2"))
+ , m_xStreetED(m_xBuilder->weld_entry("street"))
+ , m_xZipED(m_xBuilder->weld_entry("izip"))
+ , m_xCityED(m_xBuilder->weld_entry("icity"))
+ , m_xCountryED(m_xBuilder->weld_entry("country"))
+ , m_xStateED(m_xBuilder->weld_entry("state"))
+ , m_xTitleED(m_xBuilder->weld_entry("title"))
+ , m_xProfessionED(m_xBuilder->weld_entry("job"))
+ , m_xPhoneED(m_xBuilder->weld_entry("phone"))
+ , m_xMobilePhoneED(m_xBuilder->weld_entry("mobile"))
+ , m_xFaxED(m_xBuilder->weld_entry("fax"))
+ , m_xHomePageED(m_xBuilder->weld_entry("url"))
+ , m_xMailED(m_xBuilder->weld_entry("email"))
+{
+ SetExchangeSupport();
+}
+
+SwPrivateDataPage::~SwPrivateDataPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwPrivateDataPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwPrivateDataPage>(pPage, pController, *rSet);
+}
+
+void SwPrivateDataPage::ActivatePage(const SfxItemSet& rSet)
+{
+ Reset(&rSet);
+}
+
+DeactivateRC SwPrivateDataPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if (_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SwPrivateDataPage::FillItemSet(SfxItemSet* rSet)
+{
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ assert(pExampleSet);
+ SwLabItem aItem = static_cast<const SwLabItem&>(pExampleSet->Get(FN_LABEL));
+
+ aItem.m_aPrivFirstName = m_xFirstNameED->get_text();
+ aItem.m_aPrivName = m_xNameED->get_text();
+ aItem.m_aPrivShortCut = m_xShortCutED->get_text();
+ aItem.m_aPrivFirstName2 = m_xFirstName2ED->get_text();
+ aItem.m_aPrivName2 = m_xName2ED->get_text();
+ aItem.m_aPrivShortCut2 = m_xShortCut2ED->get_text();
+ aItem.m_aPrivStreet = m_xStreetED->get_text();
+ aItem.m_aPrivZip = m_xZipED->get_text();
+ aItem.m_aPrivCity = m_xCityED->get_text();
+ aItem.m_aPrivCountry = m_xCountryED->get_text();
+ aItem.m_aPrivState = m_xStateED->get_text();
+ aItem.m_aPrivTitle = m_xTitleED->get_text();
+ aItem.m_aPrivProfession= m_xProfessionED->get_text();
+ aItem.m_aPrivPhone = m_xPhoneED->get_text();
+ aItem.m_aPrivMobile = m_xMobilePhoneED->get_text();
+ aItem.m_aPrivFax = m_xFaxED->get_text();
+ aItem.m_aPrivWWW = m_xHomePageED->get_text();
+ aItem.m_aPrivMail = m_xMailED->get_text();
+
+ rSet->Put(aItem);
+ return true;
+}
+
+void SwPrivateDataPage::Reset(const SfxItemSet* rSet)
+{
+ const SwLabItem& aItem = static_cast<const SwLabItem&>( rSet->Get(FN_LABEL) );
+ m_xFirstNameED->set_text(aItem.m_aPrivFirstName);
+ m_xNameED->set_text(aItem.m_aPrivName);
+ m_xShortCutED->set_text(aItem.m_aPrivShortCut);
+ m_xFirstName2ED->set_text(aItem.m_aPrivFirstName2);
+ m_xName2ED->set_text(aItem.m_aPrivName2);
+ m_xShortCut2ED->set_text(aItem.m_aPrivShortCut2);
+ m_xStreetED->set_text(aItem.m_aPrivStreet);
+ m_xZipED->set_text(aItem.m_aPrivZip);
+ m_xCityED->set_text(aItem.m_aPrivCity);
+ m_xCountryED->set_text(aItem.m_aPrivCountry);
+ m_xStateED->set_text(aItem.m_aPrivState);
+ m_xTitleED->set_text(aItem.m_aPrivTitle);
+ m_xProfessionED->set_text(aItem.m_aPrivProfession);
+ m_xPhoneED->set_text(aItem.m_aPrivPhone);
+ m_xMobilePhoneED->set_text(aItem.m_aPrivMobile);
+ m_xFaxED->set_text(aItem.m_aPrivFax);
+ m_xHomePageED->set_text(aItem.m_aPrivWWW);
+ m_xMailED->set_text(aItem.m_aPrivMail);
+}
+
+SwBusinessDataPage::SwBusinessDataPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/businessdatapage.ui", "BusinessDataPage", &rSet)
+ , m_xCompanyED(m_xBuilder->weld_entry("company"))
+ , m_xCompanyExtED(m_xBuilder->weld_entry("company2"))
+ , m_xSloganED(m_xBuilder->weld_entry("slogan"))
+ , m_xStreetED(m_xBuilder->weld_entry("street"))
+ , m_xZipED(m_xBuilder->weld_entry("izip"))
+ , m_xCityED(m_xBuilder->weld_entry("icity"))
+ , m_xCountryED(m_xBuilder->weld_entry("country"))
+ , m_xStateED(m_xBuilder->weld_entry("state"))
+ , m_xPositionED(m_xBuilder->weld_entry("position"))
+ , m_xPhoneED(m_xBuilder->weld_entry("phone"))
+ , m_xMobilePhoneED(m_xBuilder->weld_entry("mobile"))
+ , m_xFaxED(m_xBuilder->weld_entry("fax"))
+ , m_xHomePageED(m_xBuilder->weld_entry("url"))
+ , m_xMailED(m_xBuilder->weld_entry("email"))
+{
+ SetExchangeSupport();
+}
+
+SwBusinessDataPage::~SwBusinessDataPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwBusinessDataPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwBusinessDataPage>(pPage, pController, *rSet);
+}
+
+void SwBusinessDataPage::ActivatePage(const SfxItemSet& rSet)
+{
+ Reset(&rSet);
+}
+
+DeactivateRC SwBusinessDataPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if (_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SwBusinessDataPage::FillItemSet(SfxItemSet* rSet)
+{
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ assert(pExampleSet);
+ SwLabItem aItem = static_cast<const SwLabItem&>(pExampleSet->Get(FN_LABEL));
+
+ aItem.m_aCompCompany = m_xCompanyED->get_text();
+ aItem.m_aCompCompanyExt= m_xCompanyExtED->get_text();
+ aItem.m_aCompSlogan = m_xSloganED->get_text();
+ aItem.m_aCompStreet = m_xStreetED->get_text();
+ aItem.m_aCompZip = m_xZipED->get_text();
+ aItem.m_aCompCity = m_xCityED->get_text();
+ aItem.m_aCompCountry = m_xCountryED->get_text();
+ aItem.m_aCompState = m_xStateED->get_text();
+ aItem.m_aCompPosition = m_xPositionED->get_text();
+ aItem.m_aCompPhone = m_xPhoneED->get_text();
+ aItem.m_aCompMobile = m_xMobilePhoneED->get_text();
+ aItem.m_aCompFax = m_xFaxED->get_text();
+ aItem.m_aCompWWW = m_xHomePageED->get_text();
+ aItem.m_aCompMail = m_xMailED->get_text();
+
+ rSet->Put(aItem);
+ return true;
+}
+
+void SwBusinessDataPage::Reset(const SfxItemSet* rSet)
+{
+ const SwLabItem& aItem = static_cast<const SwLabItem&>( rSet->Get(FN_LABEL) );
+ m_xCompanyED->set_text(aItem.m_aCompCompany);
+ m_xCompanyExtED->set_text(aItem.m_aCompCompanyExt);
+ m_xSloganED->set_text(aItem.m_aCompSlogan);
+ m_xStreetED->set_text(aItem.m_aCompStreet);
+ m_xZipED->set_text(aItem.m_aCompZip);
+ m_xCityED->set_text(aItem.m_aCompCity);
+ m_xCountryED->set_text(aItem.m_aCompCountry);
+ m_xStateED->set_text(aItem.m_aCompState);
+ m_xPositionED->set_text(aItem.m_aCompPosition);
+ m_xPhoneED->set_text(aItem.m_aCompPhone);
+ m_xMobilePhoneED->set_text(aItem.m_aCompMobile);
+ m_xFaxED->set_text(aItem.m_aCompFax);
+ m_xHomePageED->set_text(aItem.m_aCompWWW);
+ m_xMailED->set_text(aItem.m_aCompMail);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/labelexp.cxx b/sw/source/ui/envelp/labelexp.cxx
new file mode 100644
index 0000000000..ba4f37b1e0
--- /dev/null
+++ b/sw/source/ui/envelp/labelexp.cxx
@@ -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 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <label.hxx>
+#include <labimg.hxx>
+#include <unoprnms.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::uno;
+
+void SwLabDlg::UpdateFieldInformation(uno::Reference< frame::XModel > const & xModel, const SwLabItem& rItem)
+{
+ uno::Reference< text::XTextFieldsSupplier > xFields(xModel, uno::UNO_QUERY);
+ uno::Reference< container::XNameAccess > xFieldMasters = xFields->getTextFieldMasters();
+
+ static const struct SwLabItemMap {
+ const char* pName;
+ OUString SwLabItem::*pValue;
+ } aArr[] = {
+ { "BC_PRIV_FIRSTNAME" , &SwLabItem::m_aPrivFirstName },
+ { "BC_PRIV_NAME" , &SwLabItem::m_aPrivName },
+ { "BC_PRIV_INITIALS" , &SwLabItem::m_aPrivShortCut },
+ { "BC_PRIV_FIRSTNAME_2", &SwLabItem::m_aPrivFirstName2 },
+ { "BC_PRIV_NAME_2" , &SwLabItem::m_aPrivName2 },
+ { "BC_PRIV_INITIALS_2" , &SwLabItem::m_aPrivShortCut2 },
+ { "BC_PRIV_STREET" , &SwLabItem::m_aPrivStreet },
+ { "BC_PRIV_ZIP" , &SwLabItem::m_aPrivZip },
+ { "BC_PRIV_CITY" , &SwLabItem::m_aPrivCity },
+ { "BC_PRIV_COUNTRY" , &SwLabItem::m_aPrivCountry },
+ { "BC_PRIV_STATE" , &SwLabItem::m_aPrivState },
+ { "BC_PRIV_TITLE" , &SwLabItem::m_aPrivTitle },
+ { "BC_PRIV_PROFESSION" , &SwLabItem::m_aPrivProfession },
+ { "BC_PRIV_PHONE" , &SwLabItem::m_aPrivPhone },
+ { "BC_PRIV_MOBILE" , &SwLabItem::m_aPrivMobile },
+ { "BC_PRIV_FAX" , &SwLabItem::m_aPrivFax },
+ { "BC_PRIV_WWW" , &SwLabItem::m_aPrivWWW },
+ { "BC_PRIV_MAIL" , &SwLabItem::m_aPrivMail },
+ { "BC_COMP_COMPANY" , &SwLabItem::m_aCompCompany },
+ { "BC_COMP_COMPANYEXT" , &SwLabItem::m_aCompCompanyExt },
+ { "BC_COMP_SLOGAN" , &SwLabItem::m_aCompSlogan },
+ { "BC_COMP_STREET" , &SwLabItem::m_aCompStreet },
+ { "BC_COMP_ZIP" , &SwLabItem::m_aCompZip },
+ { "BC_COMP_CITY" , &SwLabItem::m_aCompCity },
+ { "BC_COMP_COUNTRY" , &SwLabItem::m_aCompCountry },
+ { "BC_COMP_STATE" , &SwLabItem::m_aCompState },
+ { "BC_COMP_POSITION" , &SwLabItem::m_aCompPosition },
+ { "BC_COMP_PHONE" , &SwLabItem::m_aCompPhone },
+ { "BC_COMP_MOBILE" , &SwLabItem::m_aCompMobile },
+ { "BC_COMP_FAX" , &SwLabItem::m_aCompFax },
+ { "BC_COMP_WWW" , &SwLabItem::m_aCompWWW },
+ { "BC_COMP_MAIL" , &SwLabItem::m_aCompMail },
+ { nullptr, nullptr }
+ };
+
+ try
+ {
+ for( const SwLabItemMap* p = aArr; p->pName; ++p )
+ {
+ OUString uFieldName(
+ "com.sun.star.text.FieldMaster.User."
+ + OUString::createFromAscii(p->pName));
+ if( xFieldMasters->hasByName( uFieldName ))
+ {
+ uno::Any aFirstName = xFieldMasters->getByName( uFieldName );
+ uno::Reference< beans::XPropertySet > xField;
+ aFirstName >>= xField;
+ uno::Any aContent;
+ aContent <<= rItem.*p->pValue;
+ xField->setPropertyValue( UNO_NAME_CONTENT, aContent );
+ }
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+
+ }
+
+ uno::Reference< container::XEnumerationAccess > xFieldAcc = xFields->getTextFields();
+ uno::Reference< util::XRefreshable > xRefresh(xFieldAcc, uno::UNO_QUERY);
+ xRefresh->refresh();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/labfmt.cxx b/sw/source/ui/envelp/labfmt.cxx
new file mode 100644
index 0000000000..b90397ab28
--- /dev/null
+++ b/sw/source/ui/envelp/labfmt.cxx
@@ -0,0 +1,609 @@
+/* -*- 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/unitconv.hxx>
+#include <tools/poly.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <sal/log.hxx>
+
+#include <viewopt.hxx>
+
+#include <swtypes.hxx>
+#include <cmdid.h>
+#include <label.hxx>
+#include <labimp.hxx>
+#include <labimg.hxx>
+#include "labfmt.hxx"
+#include <uitool.hxx>
+
+#include <strings.hrc>
+
+using namespace utl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+#define ROUND(x) static_cast<tools::Long>((x) + .5)
+
+namespace {
+
+// Arrow or interval character
+void DrawArrow(vcl::RenderContext& rRenderContext, const Point &rP1, const Point &rP2, bool bArrow)
+{
+ rRenderContext.DrawLine(rP1, rP2);
+ if (bArrow)
+ {
+ Point aArr[3];
+
+ // Arrow character
+ if (rP1.Y() == rP2.Y())
+ {
+ // Horizontal
+ aArr[0].setX( rP2.X() - 5 );
+ aArr[0].setY( rP2.Y() - 2 );
+ aArr[1].setX( rP2.X() );
+ aArr[1].setY( rP2.Y() );
+ aArr[2].setX( rP2.X() - 5 );
+ aArr[2].setY( rP2.Y() + 2 );
+ }
+ else
+ {
+ // Vertical
+ aArr[0].setX( rP2.X() - 2 );
+ aArr[0].setY( rP2.Y() - 5 );
+ aArr[1].setX( rP2.X() + 2 );
+ aArr[1].setY( rP2.Y() - 5 );
+ aArr[2].setX( rP2.X() );
+ aArr[2].setY( rP2.Y() );
+ }
+
+ const Color& rFieldTextColor = SwViewOption::GetCurrentViewOptions().GetFontColor();
+ rRenderContext.SetFillColor(rFieldTextColor);
+ rRenderContext.DrawPolygon( tools::Polygon(3, aArr));
+ }
+ else
+ {
+ // Interval symbol
+ if (rP1.Y() == rP2.Y())
+ {
+ // Horizontal
+ rRenderContext.DrawLine(Point(rP1.X(), rP1.Y() - 2), Point(rP1.X(), rP1.Y() + 2));
+ rRenderContext.DrawLine(Point(rP2.X(), rP2.Y() - 2), Point(rP2.X(), rP2.Y() + 2));
+ }
+ else
+ {
+ // Vertical
+ rRenderContext.DrawLine(Point(rP1.X() - 2, rP1.Y()), Point(rP1.X() + 2, rP1.Y()));
+ rRenderContext.DrawLine(Point(rP2.X() - 2, rP2.Y()), Point(rP2.X() + 2, rP2.Y()));
+ }
+ }
+}
+
+}
+
+SwLabPreview::SwLabPreview()
+ : m_aGrayColor(COL_LIGHTGRAY)
+ , m_aHDistStr(SwResId(STR_HDIST))
+ , m_aVDistStr(SwResId(STR_VDIST))
+ , m_aWidthStr(SwResId(STR_WIDTH))
+ , m_aHeightStr(SwResId(STR_HEIGHT))
+ , m_aLeftStr(SwResId(STR_LEFT))
+ , m_aUpperStr(SwResId(STR_UPPER))
+ , m_aColsStr(SwResId(STR_COLS))
+ , m_aRowsStr(SwResId(STR_ROWS))
+ , m_lHDistWidth(0)
+ , m_lVDistWidth(0)
+ , m_lHeightWidth(0)
+ , m_lLeftWidth(0)
+ , m_lUpperWidth(0)
+ , m_lColsWidth(0)
+ , m_lXWidth(0)
+ , m_lXHeight(0)
+{
+}
+
+void SwLabPreview::SetDrawingArea(weld::DrawingArea* pWidget)
+{
+ CustomWidgetController::SetDrawingArea(pWidget);
+
+ pWidget->set_size_request(pWidget->get_approximate_digit_width() * 54,
+ pWidget->get_text_height() * 15);
+
+ m_lHDistWidth = pWidget->get_pixel_size(m_aHDistStr).Width();
+ m_lVDistWidth = pWidget->get_pixel_size(m_aVDistStr).Width();
+ m_lHeightWidth = pWidget->get_pixel_size(m_aHeightStr).Width();
+ m_lLeftWidth = pWidget->get_pixel_size(m_aLeftStr).Width();
+ m_lUpperWidth = pWidget->get_pixel_size(m_aUpperStr).Width();
+ m_lColsWidth = pWidget->get_pixel_size(m_aColsStr).Width();
+ m_lXWidth = pWidget->get_pixel_size(OUString('X')).Width();
+ m_lXHeight = pWidget->get_text_height();
+}
+
+void SwLabPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ const Size aSize(GetOutputSizePixel());
+ const tools::Long lOutWPix = aSize.Width();
+ const tools::Long lOutHPix = aSize.Height();
+
+ // Scale factor
+ const double fxpix = double(lOutWPix - (2 * (m_lLeftWidth + 15))) / double(lOutWPix);
+
+ const tools::Long lOutWPix23 = tools::Long(double(lOutWPix) * fxpix);
+ const tools::Long lOutHPix23 = tools::Long(double(lOutHPix) * fxpix);
+
+ const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
+ const Color& rWinColor = rStyleSettings.GetWindowColor();
+ const Color& rFieldTextColor = SwViewOption::GetCurrentViewOptions().GetFontColor();
+
+ vcl::Font aFont = rRenderContext.GetFont();
+ aFont.SetFillColor(rWinColor);
+ aFont.SetColor(rFieldTextColor);
+ rRenderContext.SetFont(aFont);
+
+ rRenderContext.SetBackground(Wallpaper(rWinColor));
+ rRenderContext.Erase();
+
+ rRenderContext.SetLineColor(rWinColor);
+ rRenderContext.SetFillColor(m_aGrayColor);
+ vcl::Font aPaintFont(rRenderContext.GetFont());
+ aPaintFont.SetTransparent(false);
+ rRenderContext.SetFont(aPaintFont);
+
+ // size of region to be displayed
+ const tools::Long lDispW = m_aItem.m_lLeft + m_aItem.m_lHDist + ((m_aItem.m_nCols == 1)
+ ? m_aItem.m_lLeft
+ : ROUND(m_aItem.m_lHDist / 10.0));
+
+ const tools::Long lDispH = m_aItem.m_lUpper + m_aItem.m_lVDist + ((m_aItem.m_nRows == 1)
+ ? m_aItem.m_lUpper
+ : ROUND(m_aItem.m_lVDist / 10.0));
+
+ // Scale factor
+ const float fx = float(lOutWPix23) / std::max(tools::Long(1), lDispW);
+ const float fy = float(lOutHPix23) / std::max(tools::Long(1), lDispH);
+ const float f = std::min(fx, fy);
+
+ // zero point
+ const tools::Long lOutlineW = ROUND(f * lDispW);
+ const tools::Long lOutlineH = ROUND(f * lDispH);
+
+ const tools::Long lX0 = (lOutWPix - lOutlineW) / 2;
+ const tools::Long lY0 = (lOutHPix - lOutlineH) / 2;
+ const tools::Long lX1 = lX0 + ROUND(f * m_aItem.m_lLeft );
+ const tools::Long lY1 = lY0 + ROUND(f * m_aItem.m_lUpper);
+ const tools::Long lX2 = lX0 + ROUND(f * (m_aItem.m_lLeft + m_aItem.m_lWidth ));
+ const tools::Long lY2 = lY0 + ROUND(f * (m_aItem.m_lUpper + m_aItem.m_lHeight));
+ const tools::Long lX3 = lX0 + ROUND(f * (m_aItem.m_lLeft + m_aItem.m_lHDist ));
+ const tools::Long lY3 = lY0 + ROUND(f * (m_aItem.m_lUpper + m_aItem.m_lVDist ));
+
+ // draw outline (area)
+ rRenderContext.DrawRect(tools::Rectangle(Point(lX0, lY0), Size(lOutlineW, lOutlineH)));
+
+ // draw outline (border)
+ rRenderContext.SetLineColor(rFieldTextColor);
+ rRenderContext.DrawLine(Point(lX0, lY0), Point(lX0 + lOutlineW - 1, lY0)); // Up
+ rRenderContext.DrawLine(Point(lX0, lY0), Point(lX0, lY0 + lOutlineH - 1)); // Left
+ if (m_aItem.m_nCols == 1)
+ rRenderContext.DrawLine(Point(lX0 + lOutlineW - 1, lY0), Point(lX0 + lOutlineW - 1, lY0 + lOutlineH - 1)); // Right
+ if (m_aItem.m_nRows == 1)
+ rRenderContext.DrawLine(Point(lX0, lY0 + lOutlineH - 1), Point(lX0 + lOutlineW - 1, lY0 + lOutlineH - 1)); // Down
+
+ // Labels
+ rRenderContext.SetClipRegion(vcl::Region(tools::Rectangle(Point(lX0, lY0), Size(lOutlineW, lOutlineH))));
+ rRenderContext.SetFillColor(COL_LIGHTGRAYBLUE);
+ const sal_Int32 nRows = std::min<sal_Int32>(2, m_aItem.m_nRows);
+ const sal_Int32 nCols = std::min<sal_Int32>(2, m_aItem.m_nCols);
+ for (sal_Int32 nRow = 0; nRow < nRows; ++nRow)
+ for (sal_Int32 nCol = 0; nCol < nCols; ++nCol)
+ rRenderContext.DrawRect(tools::Rectangle(Point(lX0 + ROUND(f * (m_aItem.m_lLeft + nCol * m_aItem.m_lHDist)),
+ lY0 + ROUND(f * (m_aItem.m_lUpper + nRow * m_aItem.m_lVDist))),
+ Size(ROUND(f * m_aItem.m_lWidth),
+ ROUND(f * m_aItem.m_lHeight))));
+ rRenderContext.SetClipRegion();
+
+ // annotation: left border
+ if (m_aItem.m_lLeft)
+ {
+ tools::Long lX = (lX0 + lX1) / 2;
+ DrawArrow(rRenderContext, Point(lX0, lY0 - 5), Point(lX1, lY0 - 5), false);
+ DrawArrow(rRenderContext, Point(lX, lY0 - 10), Point(lX, lY0 - 5), true);
+ rRenderContext.DrawText(Point(lX1 - m_lLeftWidth, lY0 - 10 - m_lXHeight), m_aLeftStr);
+ }
+
+ // annotation: upper border
+ if (m_aItem.m_lUpper)
+ {
+ DrawArrow(rRenderContext, Point(lX0 - 5, lY0), Point(lX0 - 5, lY1), false);
+ rRenderContext.DrawText(Point(lX0 - 10 - m_lUpperWidth, lY0 + ROUND(f*m_aItem.m_lUpper/2.0 - m_lXHeight/2.0)), m_aUpperStr);
+ }
+
+ // annotation: width and height
+ {
+ tools::Long lX = lX2 - m_lXWidth / 2 - m_lHeightWidth / 2;
+ tools::Long lY = lY1 + m_lXHeight;
+
+ rRenderContext.DrawLine(Point(lX1, lY), Point(lX2 - 1, lY));
+ rRenderContext.DrawLine(Point(lX, lY1), Point(lX, lY2 - 1));
+
+ rRenderContext.DrawText(Point(lX1 + m_lXWidth / 2, lY - m_lXHeight / 2), m_aWidthStr);
+ rRenderContext.DrawText(Point(lX - m_lHeightWidth / 2, lY2 - m_lXHeight - m_lXHeight / 2), m_aHeightStr);
+ }
+
+ // annotation: horizontal gap
+ if (m_aItem.m_nCols > 1)
+ {
+ tools::Long lX = (lX1 + lX3) / 2;
+ DrawArrow(rRenderContext, Point(lX1, lY0 - 5), Point(lX3, lY0 - 5), false);
+ DrawArrow(rRenderContext, Point(lX, lY0 - 10), Point(lX, lY0 - 5), true);
+ rRenderContext.DrawText(Point(lX - m_lHDistWidth / 2, lY0 - 10 - m_lXHeight), m_aHDistStr);
+ }
+
+ // annotation: vertical gap
+ if (m_aItem.m_nRows > 1)
+ {
+ DrawArrow(rRenderContext, Point(lX0 - 5, lY1), Point(lX0 - 5, lY3), false);
+ rRenderContext.DrawText(Point(lX0 - 10 - m_lVDistWidth, lY1 + ROUND(f*m_aItem.m_lVDist/2.0 - m_lXHeight/2.0)), m_aVDistStr);
+ }
+
+ // annotation: columns
+ {
+ tools::Long lY = lY0 + lOutlineH + 4;
+ DrawArrow(rRenderContext, Point(lX0, lY), Point(lX0 + lOutlineW - 1, lY), true);
+ rRenderContext.DrawText(Point((lX0 + lX0 + lOutlineW - 1) / 2 - m_lColsWidth / 2, lY + 5), m_aColsStr);
+ }
+
+ // annotation: lines
+ {
+ tools::Long lX = lX0 + lOutlineW + 4;
+ DrawArrow(rRenderContext, Point(lX, lY0), Point(lX, lY0 + lOutlineH - 1), true);
+ rRenderContext.DrawText(Point(lX + 5, (lY0 + lY0 + lOutlineH - 1 - m_lXHeight / 2) / 2), m_aRowsStr);
+ }
+}
+
+void SwLabPreview::UpdateItem(const SwLabItem& rItem)
+{
+ m_aItem = rItem;
+ Invalidate();
+}
+
+SwLabFormatPage::SwLabFormatPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/labelformatpage.ui", "LabelFormatPage", &rSet)
+ , m_aPreviewIdle("SwLabFormatPage Preview")
+ , m_aItem(static_cast<const SwLabItem&>( rSet.Get(FN_LABEL) ))
+ , m_bModified(false)
+ , m_xMakeFI(m_xBuilder->weld_label("make"))
+ , m_xTypeFI(m_xBuilder->weld_label("type"))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreview))
+ , m_xHDistField(m_xBuilder->weld_metric_spin_button("hori", FieldUnit::CM))
+ , m_xVDistField(m_xBuilder->weld_metric_spin_button("vert", FieldUnit::CM))
+ , m_xWidthField(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightField(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xLeftField(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
+ , m_xUpperField(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
+ , m_xColsField(m_xBuilder->weld_spin_button("cols"))
+ , m_xRowsField(m_xBuilder->weld_spin_button("rows"))
+ , m_xPWidthField(m_xBuilder->weld_metric_spin_button("pagewidth", FieldUnit::CM))
+ , m_xPHeightField(m_xBuilder->weld_metric_spin_button("pageheight", FieldUnit::CM))
+ , m_xSavePB(m_xBuilder->weld_button("save"))
+{
+ SetExchangeSupport();
+
+ // Metrics
+ FieldUnit aMetric = ::GetDfltMetric(false);
+ ::SetFieldUnit(*m_xHDistField, aMetric);
+ ::SetFieldUnit(*m_xVDistField , aMetric);
+ ::SetFieldUnit(*m_xWidthField , aMetric);
+ ::SetFieldUnit(*m_xHeightField, aMetric);
+ ::SetFieldUnit(*m_xLeftField , aMetric);
+ ::SetFieldUnit(*m_xUpperField , aMetric);
+ ::SetFieldUnit(*m_xPWidthField , aMetric);
+ ::SetFieldUnit(*m_xPHeightField, aMetric);
+
+ // Install handlers
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwLabFormatPage, MetricModifyHdl);
+ m_xHDistField->connect_value_changed( aLk );
+ m_xVDistField->connect_value_changed( aLk );
+ m_xWidthField->connect_value_changed( aLk );
+ m_xHeightField->connect_value_changed( aLk );
+ m_xLeftField->connect_value_changed( aLk );
+ m_xUpperField->connect_value_changed( aLk );
+ m_xPWidthField->connect_value_changed( aLk );
+ m_xPHeightField->connect_value_changed( aLk );
+
+ m_xColsField->connect_value_changed(LINK(this, SwLabFormatPage, ModifyHdl));
+ m_xRowsField->connect_value_changed(LINK(this, SwLabFormatPage, ModifyHdl));
+
+ m_xSavePB->connect_clicked( LINK (this, SwLabFormatPage, SaveHdl));
+ // Set timer
+ m_aPreviewIdle.SetPriority(TaskPriority::LOWEST);
+ m_aPreviewIdle.SetInvokeHandler(LINK(this, SwLabFormatPage, PreviewHdl));
+}
+
+SwLabFormatPage::~SwLabFormatPage()
+{
+}
+
+// Modify-handler of MetricFields. start preview timer
+IMPL_LINK_NOARG(SwLabFormatPage, MetricModifyHdl, weld::MetricSpinButton&, void)
+{
+ m_bModified = true;
+ m_aPreviewIdle.Start();
+}
+
+IMPL_LINK_NOARG(SwLabFormatPage, ModifyHdl, weld::SpinButton&, void)
+{
+ m_bModified = true;
+ m_aPreviewIdle.Start();
+}
+
+// Invalidate preview
+IMPL_LINK_NOARG(SwLabFormatPage, PreviewHdl, Timer *, void)
+{
+ m_aPreviewIdle.Stop();
+ ChangeMinMax();
+ FillItem( m_aItem );
+ m_aPreview.UpdateItem(m_aItem);
+}
+
+void SwLabFormatPage::ChangeMinMax()
+{
+ tools::Long lMax = 31748; // 56 cm
+ tools::Long nMinSize = 10; // 0,1cm
+
+ // Min and Max
+
+ int nCols = m_xColsField->get_value(),
+ nRows = m_xRowsField->get_value();
+ tools::Long lLeft = static_cast< tools::Long >(getfldval(*m_xLeftField )),
+ lUpper = static_cast< tools::Long >(getfldval(*m_xUpperField)),
+ lHDist = static_cast< tools::Long >(getfldval(*m_xHDistField)),
+ lVDist = static_cast< tools::Long >(getfldval(*m_xVDistField)),
+ lWidth = static_cast< tools::Long >(getfldval(*m_xWidthField)),
+ lHeight = static_cast< tools::Long >(getfldval(*m_xHeightField)),
+ lMinPWidth = lLeft + (nCols - 1) * lHDist + lWidth,
+ lMinPHeight = lUpper + (nRows - 1) * lVDist + lHeight;
+
+ m_xHDistField->set_min(nMinSize, FieldUnit::CM);
+ m_xVDistField->set_min(nMinSize, FieldUnit::CM);
+
+ m_xHDistField->set_max(100 * ((lMax - lLeft ) / std::max(1, nCols)), FieldUnit::TWIP);
+ m_xVDistField->set_max(100 * ((lMax - lUpper) / std::max(1, nRows)), FieldUnit::TWIP);
+
+ m_xWidthField->set_min(nMinSize, FieldUnit::CM);
+ m_xHeightField->set_min(nMinSize, FieldUnit::CM);
+
+ m_xWidthField->set_max(tools::Long(100) * lHDist, FieldUnit::TWIP);
+ m_xHeightField->set_max(tools::Long(100) * lVDist, FieldUnit::TWIP);
+
+ m_xLeftField->set_max(tools::Long(100) * (lMax - nCols * lHDist), FieldUnit::TWIP);
+ m_xUpperField->set_max(tools::Long(100) * (lMax - nRows * lVDist), FieldUnit::TWIP);
+
+ m_xColsField->set_range(1, (lMax - lLeft ) / std::max(tools::Long(1), lHDist));
+ m_xRowsField->set_range(1, (lMax - lUpper) / std::max(tools::Long(1), lVDist));
+
+ m_xPWidthField->set_range(tools::Long(100) * lMinPWidth, tools::Long(100) * lMax, FieldUnit::TWIP);
+ m_xPHeightField->set_range(tools::Long(100) * lMinPHeight, tools::Long(100) * lMax, FieldUnit::TWIP);
+}
+
+std::unique_ptr<SfxTabPage> SwLabFormatPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwLabFormatPage>(pPage, pController, *rSet);
+}
+
+void SwLabFormatPage::ActivatePage(const SfxItemSet& rSet)
+{
+ SfxItemSet aSet(rSet);
+ Reset(&aSet);
+}
+
+DeactivateRC SwLabFormatPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if (_pSet)
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+void SwLabFormatPage::FillItem(SwLabItem& rItem)
+{
+ if (!m_bModified)
+ return;
+
+ rItem.m_aMake = rItem.m_aType = SwResId(STR_CUSTOM_LABEL);
+
+ SwLabRec& rRec = *GetParentSwLabDlg()->Recs()[0];
+ rItem.m_lHDist = rRec.m_nHDist = static_cast< tools::Long >(getfldval(*m_xHDistField ));
+ rItem.m_lVDist = rRec.m_nVDist = static_cast< tools::Long >(getfldval(*m_xVDistField ));
+ rItem.m_lWidth = rRec.m_nWidth = static_cast< tools::Long >(getfldval(*m_xWidthField ));
+ rItem.m_lHeight = rRec.m_nHeight = static_cast< tools::Long >(getfldval(*m_xHeightField));
+ rItem.m_lLeft = rRec.m_nLeft = static_cast< tools::Long >(getfldval(*m_xLeftField ));
+ rItem.m_lUpper = rRec.m_nUpper = static_cast< tools::Long >(getfldval(*m_xUpperField ));
+ rItem.m_nCols = rRec.m_nCols = static_cast< sal_Int32 >(m_xColsField->get_value());
+ rItem.m_nRows = rRec.m_nRows = static_cast< sal_Int32 >(m_xRowsField->get_value());
+ rItem.m_lPWidth = rRec.m_nPWidth = static_cast< tools::Long >(getfldval(*m_xPWidthField ));
+ rItem.m_lPHeight = rRec.m_nPHeight = static_cast< tools::Long >(getfldval(*m_xPHeightField));
+
+}
+
+bool SwLabFormatPage::FillItemSet(SfxItemSet* rSet)
+{
+ FillItem(m_aItem);
+ rSet->Put(m_aItem);
+
+ return true;
+}
+
+void SwLabFormatPage::Reset(const SfxItemSet* )
+{
+ // Initialise fields
+ GetParentSwLabDlg()->GetLabItem(m_aItem);
+
+ m_xHDistField->set_max(100 * m_aItem.m_lHDist , FieldUnit::TWIP);
+ m_xVDistField->set_max(100 * m_aItem.m_lVDist , FieldUnit::TWIP);
+ m_xWidthField->set_max(100 * m_aItem.m_lWidth , FieldUnit::TWIP);
+ m_xHeightField->set_max(100 * m_aItem.m_lHeight, FieldUnit::TWIP);
+ m_xLeftField->set_max(100 * m_aItem.m_lLeft , FieldUnit::TWIP);
+ m_xUpperField->set_max(100 * m_aItem.m_lUpper , FieldUnit::TWIP);
+ m_xPWidthField->set_max(100 * m_aItem.m_lPWidth , FieldUnit::TWIP);
+ m_xPHeightField->set_max(100 * m_aItem.m_lPHeight, FieldUnit::TWIP);
+
+ setfldval(*m_xHDistField, m_aItem.m_lHDist );
+ setfldval(*m_xVDistField , m_aItem.m_lVDist );
+ setfldval(*m_xWidthField , m_aItem.m_lWidth );
+ setfldval(*m_xHeightField, m_aItem.m_lHeight);
+ setfldval(*m_xLeftField , m_aItem.m_lLeft );
+ setfldval(*m_xUpperField , m_aItem.m_lUpper );
+ setfldval(*m_xPWidthField , m_aItem.m_lPWidth );
+ setfldval(*m_xPHeightField, m_aItem.m_lPHeight);
+
+ m_xColsField->set_max(m_aItem.m_nCols);
+ m_xRowsField->set_max(m_aItem.m_nRows);
+
+ m_xColsField->set_value(m_aItem.m_nCols);
+ m_xRowsField->set_value(m_aItem.m_nRows);
+ m_xMakeFI->set_label(m_aItem.m_aMake);
+ m_xTypeFI->set_label(m_aItem.m_aType);
+ PreviewHdl(nullptr);
+}
+
+IMPL_LINK_NOARG(SwLabFormatPage, SaveHdl, weld::Button&, void)
+{
+ SwLabRec aRec;
+ aRec.m_nHDist = static_cast< tools::Long >(getfldval(*m_xHDistField));
+ aRec.m_nVDist = static_cast< tools::Long >(getfldval(*m_xVDistField ));
+ aRec.m_nWidth = static_cast< tools::Long >(getfldval(*m_xWidthField ));
+ aRec.m_nHeight = static_cast< tools::Long >(getfldval(*m_xHeightField));
+ aRec.m_nLeft = static_cast< tools::Long >(getfldval(*m_xLeftField ));
+ aRec.m_nUpper = static_cast< tools::Long >(getfldval(*m_xUpperField ));
+ aRec.m_nCols = static_cast< sal_Int32 >(m_xColsField->get_value());
+ aRec.m_nRows = static_cast< sal_Int32 >(m_xRowsField->get_value());
+ aRec.m_nPWidth = static_cast< tools::Long >(getfldval(*m_xPWidthField ));
+ aRec.m_nPHeight = static_cast< tools::Long >(getfldval(*m_xPHeightField));
+ aRec.m_bCont = m_aItem.m_bCont;
+ SwSaveLabelDlg aSaveDlg(GetParentSwLabDlg(), aRec);
+ aSaveDlg.SetLabel(m_aItem.m_aLstMake, m_aItem.m_aLstType);
+ aSaveDlg.run();
+ if (aSaveDlg.GetLabel(m_aItem))
+ {
+ m_bModified = false;
+ const std::vector<OUString>& rMan = GetParentSwLabDlg()->GetLabelsConfig().GetManufacturers();
+ std::vector<OUString>& rMakes(GetParentSwLabDlg()->Makes());
+ if(rMakes.size() < rMan.size())
+ {
+ rMakes = rMan;
+ }
+ m_xMakeFI->set_label(m_aItem.m_aMake);
+ m_xTypeFI->set_label(m_aItem.m_aType);
+ }
+}
+
+SwSaveLabelDlg::SwSaveLabelDlg(SwLabDlg* pParent, SwLabRec& rRec)
+ : GenericDialogController(pParent->getDialog(), "modules/swriter/ui/savelabeldialog.ui", "SaveLabelDialog")
+ , m_bSuccess(false)
+ , m_pLabDialog(pParent)
+ , m_rLabRec(rRec)
+ , m_xMakeCB(m_xBuilder->weld_combo_box("brand"))
+ , m_xTypeED(m_xBuilder->weld_entry("type"))
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+{
+ m_xOKPB->connect_clicked(LINK(this, SwSaveLabelDlg, OkHdl));
+ m_xMakeCB->connect_changed(LINK(this, SwSaveLabelDlg, ModifyComboHdl));
+ m_xTypeED->connect_changed(LINK(this, SwSaveLabelDlg, ModifyEntryHdl));
+
+ SwLabelConfig& rCfg = m_pLabDialog->GetLabelsConfig();
+ const std::vector<OUString>& rMan = rCfg.GetManufacturers();
+ for (const auto & i : rMan)
+ {
+ m_xMakeCB->append_text(i);
+ }
+}
+
+SwSaveLabelDlg::~SwSaveLabelDlg()
+{
+}
+
+IMPL_LINK_NOARG(SwSaveLabelDlg, OkHdl, weld::Button&, void)
+{
+ SwLabelConfig& rCfg = m_pLabDialog->GetLabelsConfig();
+ OUString sMake(m_xMakeCB->get_active_text());
+ OUString sType(m_xTypeED->get_text());
+ if(rCfg.HasLabel(sMake, sType))
+ {
+ if ( rCfg.IsPredefinedLabel(sMake, sType) )
+ {
+ SAL_WARN( "sw.envelp", "label is predefined and cannot be overwritten" );
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "modules/swriter/ui/cannotsavelabeldialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("CannotSaveLabelDialog"));
+ xBox->run();
+ return;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "modules/swriter/ui/querysavelabeldialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QuerySaveLabelDialog"));
+ xQuery->set_primary_text(xQuery->get_primary_text().
+ replaceAll("%1", sMake).replaceAll("%2", sType));
+ xQuery->set_secondary_text(xQuery->get_secondary_text().
+ replaceAll("%1", sMake).replaceAll("%2", sType));
+
+ if (RET_YES != xQuery->run())
+ return;
+ }
+ m_rLabRec.m_aType = sType;
+ rCfg.SaveLabel(sMake, sType, m_rLabRec);
+ m_bSuccess = true;
+ m_xDialog->response(RET_OK);
+}
+
+void SwSaveLabelDlg::Modify()
+{
+ m_xOKPB->set_sensitive(!m_xMakeCB->get_active_text().isEmpty() && !m_xTypeED->get_text().isEmpty());
+}
+
+IMPL_LINK_NOARG(SwSaveLabelDlg, ModifyComboHdl, weld::ComboBox&, void)
+{
+ Modify();
+}
+
+IMPL_LINK_NOARG(SwSaveLabelDlg, ModifyEntryHdl, weld::Entry&, void)
+{
+ Modify();
+}
+
+bool SwSaveLabelDlg::GetLabel(SwLabItem& rItem)
+{
+ if(m_bSuccess)
+ {
+ rItem.m_aMake = m_xMakeCB->get_active_text();
+ rItem.m_aType = m_xTypeED->get_text();
+ rItem.m_lHDist = m_rLabRec.m_nHDist;
+ rItem.m_lVDist = m_rLabRec.m_nVDist;
+ rItem.m_lWidth = m_rLabRec.m_nWidth;
+ rItem.m_lHeight = m_rLabRec.m_nHeight;
+ rItem.m_lLeft = m_rLabRec.m_nLeft;
+ rItem.m_lUpper = m_rLabRec.m_nUpper;
+ rItem.m_nCols = m_rLabRec.m_nCols;
+ rItem.m_nRows = m_rLabRec.m_nRows;
+ rItem.m_lPWidth = m_rLabRec.m_nPWidth;
+ rItem.m_lPHeight = m_rLabRec.m_nPHeight;
+ }
+ return m_bSuccess;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/labfmt.hxx b/sw/source/ui/envelp/labfmt.hxx
new file mode 100644
index 0000000000..bfb1ef3097
--- /dev/null
+++ b/sw/source/ui/envelp/labfmt.hxx
@@ -0,0 +1,140 @@
+/* -*- 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 <labimg.hxx>
+#include <label.hxx>
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+
+class SwLabFormatPage;
+
+class SwLabPreview : public weld::CustomWidgetController
+{
+ Color m_aGrayColor;
+
+ OUString m_aHDistStr;
+ OUString m_aVDistStr;
+ OUString m_aWidthStr;
+ OUString m_aHeightStr;
+ OUString m_aLeftStr;
+ OUString m_aUpperStr;
+ OUString m_aColsStr;
+ OUString m_aRowsStr;
+
+ tools::Long m_lHDistWidth;
+ tools::Long m_lVDistWidth;
+ tools::Long m_lHeightWidth;
+ tools::Long m_lLeftWidth;
+ tools::Long m_lUpperWidth;
+ tools::Long m_lColsWidth;
+
+ tools::Long m_lXWidth;
+ tools::Long m_lXHeight;
+
+ SwLabItem m_aItem;
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+
+public:
+ SwLabPreview();
+
+ void UpdateItem(const SwLabItem& rItem);
+};
+
+class SwLabFormatPage : public SfxTabPage
+{
+ Idle m_aPreviewIdle;
+ SwLabItem m_aItem;
+ bool m_bModified;
+
+ SwLabPreview m_aPreview;
+
+ std::unique_ptr<weld::Label> m_xMakeFI;
+ std::unique_ptr<weld::Label> m_xTypeFI;
+ std::unique_ptr<weld::CustomWeld> m_xPreview;
+ std::unique_ptr<weld::MetricSpinButton> m_xHDistField;
+ std::unique_ptr<weld::MetricSpinButton> m_xVDistField;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthField;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightField;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftField;
+ std::unique_ptr<weld::MetricSpinButton> m_xUpperField;
+ std::unique_ptr<weld::SpinButton> m_xColsField;
+ std::unique_ptr<weld::SpinButton> m_xRowsField;
+ std::unique_ptr<weld::MetricSpinButton> m_xPWidthField;
+ std::unique_ptr<weld::MetricSpinButton> m_xPHeightField;
+ std::unique_ptr<weld::Button> m_xSavePB;
+
+ DECL_LINK(ModifyHdl, weld::SpinButton&, void);
+ DECL_LINK(MetricModifyHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(PreviewHdl, Timer*, void);
+ DECL_LINK(SaveHdl, weld::Button&, void);
+
+ void ChangeMinMax();
+
+public:
+ SwLabFormatPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SwLabFormatPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+ void FillItem(SwLabItem& rItem);
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+ SwLabDlg* GetParentSwLabDlg() { return static_cast<SwLabDlg*>(GetDialogController()); }
+};
+
+class SwSaveLabelDlg : public weld::GenericDialogController
+{
+ bool m_bSuccess;
+ SwLabDlg* m_pLabDialog;
+ SwLabRec& m_rLabRec;
+
+ std::unique_ptr<weld::ComboBox> m_xMakeCB;
+ std::unique_ptr<weld::Entry> m_xTypeED;
+ std::unique_ptr<weld::Button> m_xOKPB;
+
+ DECL_LINK(OkHdl, weld::Button&, void);
+ DECL_LINK(ModifyEntryHdl, weld::Entry&, void);
+ DECL_LINK(ModifyComboHdl, weld::ComboBox&, void);
+
+ void Modify();
+
+public:
+ SwSaveLabelDlg(SwLabDlg* pParent, SwLabRec& rRec);
+ virtual ~SwSaveLabelDlg() override;
+
+ void SetLabel(const OUString& rMake, const OUString& rType)
+ {
+ m_xMakeCB->set_entry_text(rMake);
+ m_xTypeED->set_text(rType);
+ }
+ bool GetLabel(SwLabItem& rItem);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/labprt.cxx b/sw/source/ui/envelp/labprt.cxx
new file mode 100644
index 0000000000..6b1c78f160
--- /dev/null
+++ b/sw/source/ui/envelp/labprt.cxx
@@ -0,0 +1,155 @@
+/* -*- 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/prnsetup.hxx>
+#include <unotools/cmdoptions.hxx>
+#include <vcl/print.hxx>
+#include <label.hxx>
+#include "labprt.hxx"
+#include <labimg.hxx>
+
+SwLabPrtPage::SwLabPrtPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/labeloptionspage.ui", "LabelOptionsPage", &rSet)
+ , m_pPrinter(nullptr)
+ , m_xPageButton(m_xBuilder->weld_radio_button("entirepage"))
+ , m_xSingleButton(m_xBuilder->weld_radio_button("singlelabel"))
+ , m_xSingleGrid(m_xBuilder->weld_widget("singlegrid"))
+ , m_xPrinterFrame(m_xBuilder->weld_widget("printerframe"))
+ , m_xColField(m_xBuilder->weld_spin_button("cols"))
+ , m_xRowField(m_xBuilder->weld_spin_button("rows"))
+ , m_xSynchronCB(m_xBuilder->weld_check_button("synchronize"))
+ , m_xPrinterInfo(m_xBuilder->weld_label("printername"))
+ , m_xPrtSetup(m_xBuilder->weld_button("setup"))
+{
+ SetExchangeSupport();
+
+ // Install handlers
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwLabPrtPage, CountHdl);
+ m_xPageButton->connect_toggled(aLk);
+ m_xSingleButton->connect_toggled(aLk);
+ m_xPrtSetup->connect_clicked(LINK(this, SwLabPrtPage, PrtSetupHdl));
+
+ SvtCommandOptions aCmdOpts;
+ if (aCmdOpts.LookupDisabled("Print"))
+ {
+ m_xPrinterFrame->hide();
+ }
+}
+
+SwLabPrtPage::~SwLabPrtPage()
+{
+ m_pPrinter.disposeAndClear();
+}
+
+IMPL_LINK( SwLabPrtPage, PrtSetupHdl, weld::Button&, rButton, void )
+{
+ // Call printer setup
+ if (!m_pPrinter)
+ m_pPrinter = VclPtr<Printer>::Create();
+
+ PrinterSetupDialog aDlg(GetFrameWeld());
+ aDlg.SetPrinter(m_pPrinter);
+ aDlg.run();
+ rButton.grab_focus();
+ m_xPrinterInfo->set_label(m_pPrinter->GetName());
+}
+
+IMPL_LINK(SwLabPrtPage, CountHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ const bool bEnable = m_xSingleButton->get_active();
+ m_xSingleGrid->set_sensitive(bEnable);
+ m_xSynchronCB->set_sensitive(!bEnable);
+
+ if (bEnable)
+ m_xColField->grab_focus();
+}
+
+std::unique_ptr<SfxTabPage> SwLabPrtPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SwLabPrtPage>(pPage, pController, *rSet );
+}
+
+void SwLabPrtPage::ActivatePage( const SfxItemSet& rSet )
+{
+ Reset(&rSet);
+}
+
+DeactivateRC SwLabPrtPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if ( _pSet )
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+void SwLabPrtPage::FillItem(SwLabItem& rItem)
+{
+ rItem.m_bPage = m_xPageButton->get_active();
+ rItem.m_nCol = m_xColField->get_value();
+ rItem.m_nRow = m_xRowField->get_value();
+ rItem.m_bSynchron = m_xSynchronCB->get_active() && m_xSynchronCB->get_sensitive();
+}
+
+bool SwLabPrtPage::FillItemSet(SfxItemSet* rSet)
+{
+ SwLabItem aItem;
+ GetParentSwLabDlg()->GetLabItem(aItem);
+ FillItem(aItem);
+ rSet->Put(aItem);
+
+ return true;
+}
+
+void SwLabPrtPage::Reset(const SfxItemSet* )
+{
+ SwLabItem aItem;
+ GetParentSwLabDlg()->GetLabItem(aItem);
+
+ m_xColField->set_value(aItem.m_nCol);
+ m_xRowField->set_value(aItem.m_nRow);
+
+ if (aItem.m_bPage)
+ {
+ m_xPageButton->set_active(true);
+ CountHdl(*m_xPageButton);
+ }
+ else
+ {
+ CountHdl(*m_xSingleButton);
+ m_xSingleButton->set_active(true);
+ }
+
+ if (m_pPrinter)
+ {
+ // show printer
+ m_xPrinterInfo->set_label(m_pPrinter->GetName());
+ }
+ else
+ m_xPrinterInfo->set_label(Printer::GetDefaultPrinterName());
+
+ m_xColField->set_max(aItem.m_nCols);
+ m_xRowField->set_max(aItem.m_nRows);
+
+ m_xSynchronCB->set_active(aItem.m_bSynchron);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/labprt.hxx b/sw/source/ui/envelp/labprt.hxx
new file mode 100644
index 0000000000..66a4c13657
--- /dev/null
+++ b/sw/source/ui/envelp/labprt.hxx
@@ -0,0 +1,63 @@
+/* -*- 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 <label.hxx>
+
+class SwLabDlg;
+class SwLabItem;
+
+class SwLabPrtPage : public SfxTabPage
+{
+ VclPtr<Printer> m_pPrinter; // for the shaft setting - unfortunately
+
+ std::unique_ptr<weld::RadioButton> m_xPageButton;
+ std::unique_ptr<weld::RadioButton> m_xSingleButton;
+ std::unique_ptr<weld::Widget> m_xSingleGrid;
+ std::unique_ptr<weld::Widget> m_xPrinterFrame;
+ std::unique_ptr<weld::SpinButton> m_xColField;
+ std::unique_ptr<weld::SpinButton> m_xRowField;
+ std::unique_ptr<weld::CheckButton> m_xSynchronCB;
+ std::unique_ptr<weld::Label> m_xPrinterInfo;
+ std::unique_ptr<weld::Button> m_xPrtSetup;
+
+ DECL_LINK(CountHdl, weld::Toggleable&, void);
+ DECL_LINK(PrtSetupHdl, weld::Button&, void);
+
+ SwLabDlg* GetParentSwLabDlg() { return static_cast<SwLabDlg*>(GetDialogController()); }
+
+public:
+ SwLabPrtPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SwLabPrtPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+ void FillItem(SwLabItem& rItem);
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+ Printer* GetPrt() { return m_pPrinter; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/mailmrge.cxx b/sw/source/ui/envelp/mailmrge.cxx
new file mode 100644
index 0000000000..8567b11443
--- /dev/null
+++ b/sw/source/ui/envelp/mailmrge.cxx
@@ -0,0 +1,617 @@
+/* -*- 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 <comphelper/propertyvalue.hxx>
+
+#include <tools/urlobj.hxx>
+#include <svl/urihelper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <IDocumentDeviceAccess.hxx>
+#include <printdata.hxx>
+#include <wrtsh.hxx>
+#include <dbmgr.hxx>
+#include <swmodule.hxx>
+#include <modcfg.hxx>
+#include <mailmergehelper.hxx>
+#include <mailmrge.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <comphelper/documentconstants.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/form/runtime/XFormController.hpp>
+#include <com/sun/star/frame/Frame.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdbcx/XRowLocate.hpp>
+#include <com/sun/star/sdb/XResultSetAccess.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <osl/diagnose.h>
+
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::ui::dialogs;
+
+struct SwMailMergeDlg_Impl {
+ uno::Reference<runtime::XFormController> xFController;
+ uno::Reference<XSelectionChangeListener> xChgLstnr;
+ uno::Reference<XSelectionSupplier> xSelSupp;
+};
+
+class SwXSelChgLstnr_Impl : public cppu::WeakImplHelper
+ <
+ view::XSelectionChangeListener
+ >
+{
+ SwMailMergeDlg& m_rParent;
+public:
+ explicit SwXSelChgLstnr_Impl(SwMailMergeDlg& rParentDlg);
+
+ virtual void SAL_CALL selectionChanged( const EventObject& aEvent ) override;
+ virtual void SAL_CALL disposing( const EventObject& Source ) override;
+};
+
+SwXSelChgLstnr_Impl::SwXSelChgLstnr_Impl(SwMailMergeDlg& rParentDlg) :
+ m_rParent(rParentDlg)
+{}
+
+void SwXSelChgLstnr_Impl::selectionChanged( const EventObject& )
+{
+ //call the parent to enable selection mode
+ Sequence <Any> aSelection;
+ if(m_rParent.m_pImpl->xSelSupp.is())
+ m_rParent.m_pImpl->xSelSupp->getSelection() >>= aSelection;
+
+ bool bEnable = aSelection.hasElements();
+ m_rParent.m_xMarkedRB->set_sensitive(bEnable);
+ if(bEnable)
+ m_rParent.m_xMarkedRB->set_active(true);
+ else if(m_rParent.m_xMarkedRB->get_active()) {
+ m_rParent.m_xAllRB->set_active(true);
+ m_rParent.m_aSelection.realloc(0);
+ }
+}
+
+void SwXSelChgLstnr_Impl::disposing( const EventObject& )
+{
+ OSL_FAIL("disposing");
+}
+
+SwMailMergeDlg::SwMailMergeDlg(weld::Window* pParent, SwWrtShell& rShell,
+ const OUString& rSourceName,
+ const OUString& rTableName,
+ sal_Int32 nCommandType,
+ const uno::Reference< XConnection>& _xConnection,
+ Sequence< Any > const * pSelection)
+ : SfxDialogController(pParent, "modules/swriter/ui/mailmerge.ui", "MailmergeDialog")
+ , m_pImpl(new SwMailMergeDlg_Impl)
+ , m_rSh(rShell)
+ , m_nMergeType(DBMGR_MERGE_EMAIL)
+ , m_xBeamerWin(m_xBuilder->weld_container("beamer"))
+ , m_xAllRB(m_xBuilder->weld_radio_button("all"))
+ , m_xMarkedRB(m_xBuilder->weld_radio_button("selected"))
+ , m_xFromRB(m_xBuilder->weld_radio_button("rbfrom"))
+ , m_xFromNF(m_xBuilder->weld_spin_button("from"))
+ , m_xToNF(m_xBuilder->weld_spin_button("to"))
+ , m_xPrinterRB(m_xBuilder->weld_radio_button("printer"))
+ , m_xMailingRB(m_xBuilder->weld_radio_button("electronic"))
+ , m_xFileRB(m_xBuilder->weld_radio_button("file"))
+ , m_xSingleJobsCB(m_xBuilder->weld_check_button("singlejobs"))
+ , m_xPasswordCB(m_xBuilder->weld_check_button("passwd-check"))
+ , m_xSaveMergedDocumentFT(m_xBuilder->weld_label("savemergeddoclabel"))
+ , m_xSaveSingleDocRB(m_xBuilder->weld_radio_button("singledocument"))
+ , m_xSaveIndividualRB(m_xBuilder->weld_radio_button("individualdocuments"))
+ , m_xGenerateFromDataBaseCB(m_xBuilder->weld_check_button("generate"))
+ , m_xColumnFT(m_xBuilder->weld_label("fieldlabel"))
+ , m_xColumnLB(m_xBuilder->weld_combo_box("field"))
+ , m_xPasswordFT(m_xBuilder->weld_label("passwd-label"))
+ , m_xPasswordLB(m_xBuilder->weld_combo_box("passwd-combobox"))
+ , m_xPathFT(m_xBuilder->weld_label("pathlabel"))
+ , m_xPathED(m_xBuilder->weld_entry("path"))
+ , m_xPathPB(m_xBuilder->weld_button("pathpb"))
+ , m_xFilterFT(m_xBuilder->weld_label("fileformatlabel"))
+ , m_xFilterLB(m_xBuilder->weld_combo_box("fileformat"))
+ , m_xAddressFieldLB(m_xBuilder->weld_combo_box("address"))
+ , m_xSubjectFT(m_xBuilder->weld_label("subjectlabel"))
+ , m_xSubjectED(m_xBuilder->weld_entry("subject"))
+ , m_xFormatFT(m_xBuilder->weld_label("mailformatlabel"))
+ , m_xAttachFT(m_xBuilder->weld_label("attachmentslabel"))
+ , m_xAttachED(m_xBuilder->weld_entry("attachments"))
+ , m_xAttachPB(m_xBuilder->weld_button("attach"))
+ , m_xFormatHtmlCB(m_xBuilder->weld_check_button("html"))
+ , m_xFormatRtfCB(m_xBuilder->weld_check_button("rtf"))
+ , m_xFormatSwCB(m_xBuilder->weld_check_button("swriter"))
+ , m_xOkBTN(m_xBuilder->weld_button("ok"))
+{
+ m_xSingleJobsCB->hide(); // not supported in since cws printerpullpages anymore
+ //task #97066# mailing of form letters is currently not supported
+ m_xMailingRB->hide();
+ m_xSubjectFT->hide();
+ m_xSubjectED->hide();
+ m_xFormatFT->hide();
+ m_xFormatSwCB->hide();
+ m_xFormatHtmlCB->hide();
+ m_xFormatRtfCB->hide();
+ m_xAttachFT->hide();
+ m_xAttachED->hide();
+ m_xAttachPB->hide();
+ m_xPasswordCB->hide();
+ m_xPasswordFT->hide();
+ m_xPasswordLB->hide();
+
+ uno::Reference< lang::XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
+ if(pSelection) {
+ m_aSelection = *pSelection;
+ m_xBeamerWin->hide();
+ } else {
+ try {
+ // create a frame wrapper for myself
+ m_xFrame = frame::Frame::create( comphelper::getProcessComponentContext() );
+ m_xFrame->initialize(m_xBeamerWin->CreateChildFrame());
+ } catch (const Exception&) {
+ m_xFrame.clear();
+ }
+ if(m_xFrame.is()) {
+ URL aURL;
+ aURL.Complete = ".component:DB/DataSourceBrowser";
+ uno::Reference<XDispatch> xD = m_xFrame->queryDispatch(aURL,
+ "",
+ 0x0C);
+ if(xD.is()) {
+ Sequence<PropertyValue> aProperties
+ {
+ comphelper::makePropertyValue("DataSourceName", rSourceName),
+ comphelper::makePropertyValue("Command", rTableName),
+ comphelper::makePropertyValue("CommandType", nCommandType),
+ };
+ xD->dispatch(aURL, aProperties);
+ m_xBeamerWin->show();
+ }
+ uno::Reference<XController> xController = m_xFrame->getController();
+ m_pImpl->xFController.set(xController, UNO_QUERY);
+ if(m_pImpl->xFController.is()) {
+ uno::Reference< awt::XControl > xCtrl = m_pImpl->xFController->getCurrentControl( );
+ m_pImpl->xSelSupp.set(xCtrl, UNO_QUERY);
+ if(m_pImpl->xSelSupp.is()) {
+ m_pImpl->xChgLstnr = new SwXSelChgLstnr_Impl(*this);
+ m_pImpl->xSelSupp->addSelectionChangeListener( m_pImpl->xChgLstnr );
+ }
+ }
+ }
+ }
+
+ m_pModOpt = SW_MOD()->GetModuleConfig();
+
+ MailTextFormats nMailingMode(m_pModOpt->GetMailingFormats());
+ m_xFormatSwCB->set_active(bool(nMailingMode & MailTextFormats::OFFICE));
+ m_xFormatHtmlCB->set_active(bool(nMailingMode & MailTextFormats::HTML));
+ m_xFormatRtfCB->set_active(bool(nMailingMode & MailTextFormats::RTF));
+
+ m_xAllRB->set_active(true);
+
+ // Install handlers
+ m_xOkBTN->connect_clicked(LINK(this, SwMailMergeDlg, ButtonHdl));
+
+ m_xPathPB->connect_clicked(LINK(this, SwMailMergeDlg, InsertPathHdl));
+
+ m_xPrinterRB->connect_toggled(LINK(this, SwMailMergeDlg, OutputTypeHdl));
+ m_xFileRB->connect_toggled(LINK(this, SwMailMergeDlg, OutputTypeHdl));
+
+ //#i63267# printing might be disabled
+ bool bIsPrintable = !Application::GetSettings().GetMiscSettings().GetDisablePrinting();
+ m_xPrinterRB->set_sensitive(bIsPrintable);
+ OutputTypeHdl(bIsPrintable ? *m_xPrinterRB : *m_xFileRB);
+
+ m_xGenerateFromDataBaseCB->connect_toggled(LINK(this, SwMailMergeDlg, FilenameHdl));
+ bool bColumn = m_pModOpt->IsNameFromColumn();
+ if(bColumn)
+ m_xGenerateFromDataBaseCB->set_active(true);
+
+ FilenameHdl(*m_xGenerateFromDataBaseCB);
+ m_xSaveSingleDocRB->set_active(true);
+ m_xSaveSingleDocRB->connect_toggled(LINK(this, SwMailMergeDlg, SaveTypeHdl));
+ m_xSaveIndividualRB->connect_toggled(LINK(this, SwMailMergeDlg, SaveTypeHdl));
+ SaveTypeHdl(*m_xSaveSingleDocRB);
+
+ m_xFilterLB->connect_changed(LINK(this, SwMailMergeDlg, FileFormatHdl));
+
+ Link<weld::SpinButton&,void> aLk2 = LINK(this, SwMailMergeDlg, ModifyHdl);
+ m_xFromNF->connect_value_changed(aLk2);
+ m_xToNF->connect_value_changed(aLk2);
+ m_xFromNF->set_max(SAL_MAX_INT32);
+ m_xToNF->set_max(SAL_MAX_INT32);
+
+ SwDBManager* pDBManager = m_rSh.GetDBManager();
+ if(_xConnection.is())
+ SwDBManager::GetColumnNames(*m_xAddressFieldLB, _xConnection, rTableName);
+ else
+ pDBManager->GetColumnNames(*m_xAddressFieldLB, rSourceName, rTableName);
+ for(sal_Int32 nEntry = 0, nEntryCount = m_xAddressFieldLB->get_count(); nEntry < nEntryCount; ++nEntry)
+ {
+ m_xColumnLB->append_text(m_xAddressFieldLB->get_text(nEntry));
+ m_xPasswordLB->append_text(m_xAddressFieldLB->get_text(nEntry));
+ }
+
+ m_xAddressFieldLB->set_active_text("EMAIL");
+
+ OUString sPath(m_pModOpt->GetMailingPath());
+ if(sPath.isEmpty()) {
+ SvtPathOptions aPathOpt;
+ sPath = aPathOpt.GetWorkPath();
+ }
+ INetURLObject aURL(sPath);
+ if(aURL.GetProtocol() == INetProtocol::File)
+ m_xPathED->set_text(aURL.PathToFileName());
+ else
+ m_xPathED->set_text(aURL.GetFull());
+
+ if (!bColumn )
+ {
+ m_xColumnLB->set_active_text("NAME");
+ m_xPasswordLB->set_active_text("PASSWORD");
+ }
+ else
+ {
+ m_xColumnLB->set_active_text(m_pModOpt->GetNameFromColumn());
+ m_xPasswordLB->set_active_text(m_pModOpt->GetPasswordFromColumn());
+ }
+
+ if (m_xAddressFieldLB->get_active() == -1)
+ m_xAddressFieldLB->set_active(0);
+ if (m_xColumnLB->get_active() == -1)
+ m_xColumnLB->set_active(0);
+ if (m_xPasswordLB->get_active() == -1)
+ m_xPasswordLB->set_active(0);
+
+ const bool bEnable = m_aSelection.hasElements();
+ m_xMarkedRB->set_sensitive(bEnable);
+ if (bEnable)
+ m_xMarkedRB->set_active(true);
+ else {
+ m_xAllRB->set_active(true);
+ m_xMarkedRB->set_sensitive(false);
+ }
+ try {
+ uno::Reference< container::XNameContainer> xFilterFactory(
+ xMSF->createInstance("com.sun.star.document.FilterFactory"), UNO_QUERY_THROW);
+ uno::Reference< container::XContainerQuery > xQuery(xFilterFactory, UNO_QUERY_THROW);
+ const OUString sCommand("matchByDocumentService=com.sun.star.text.TextDocument:iflags="
+ + OUString::number(static_cast<sal_Int32>(SfxFilterFlags::EXPORT))
+ + ":eflags="
+ + OUString::number(static_cast<sal_Int32>(SfxFilterFlags::NOTINFILEDLG))
+ + ":default_first");
+ uno::Reference< container::XEnumeration > xList = xQuery->createSubSetEnumerationByQuery(sCommand);
+ static constexpr OUStringLiteral sName(u"Name");
+ sal_Int32 nODT = -1;
+ while(xList->hasMoreElements()) {
+ comphelper::SequenceAsHashMap aFilter(xList->nextElement());
+ const OUString sFilter = aFilter.getUnpackedValueOrDefault(sName, OUString());
+
+ uno::Any aProps = xFilterFactory->getByName(sFilter);
+ uno::Sequence< beans::PropertyValue > aFilterProperties;
+ aProps >>= aFilterProperties;
+ OUString sUIName2;
+ auto pProp = std::find_if(std::cbegin(aFilterProperties), std::cend(aFilterProperties),
+ [](const beans::PropertyValue& rProp) { return rProp.Name == "UIName"; });
+ if (pProp != std::cend(aFilterProperties))
+ pProp->Value >>= sUIName2;
+ if( !sUIName2.isEmpty() ) {
+ if( sFilter == "writer8" )
+ nODT = m_xFilterLB->get_count();
+ m_xFilterLB->append(sFilter, sUIName2);
+ }
+ }
+ m_xFilterLB->set_active( nODT );
+ } catch (const uno::Exception&) {
+ }
+}
+
+SwMailMergeDlg::~SwMailMergeDlg()
+{
+ if(m_xFrame.is()) {
+ m_xFrame->setComponent(nullptr, nullptr);
+ m_xFrame->dispose();
+ }
+}
+
+IMPL_LINK_NOARG(SwMailMergeDlg, ButtonHdl, weld::Button&, void)
+{
+ if (ExecQryShell())
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwMailMergeDlg, OutputTypeHdl, weld::Toggleable&, void)
+{
+ bool bPrint = m_xPrinterRB->get_active();
+ m_xSingleJobsCB->set_sensitive(bPrint);
+
+ m_xSaveMergedDocumentFT->set_sensitive( !bPrint );
+ m_xSaveSingleDocRB->set_sensitive( !bPrint );
+ m_xSaveIndividualRB->set_sensitive( !bPrint );
+
+ if( !bPrint ) {
+ SaveTypeHdl( m_xSaveSingleDocRB->get_active() ? *m_xSaveSingleDocRB : *m_xSaveIndividualRB );
+ } else {
+ m_xPathFT->set_sensitive(false);
+ m_xPathED->set_sensitive(false);
+ m_xPathPB->set_sensitive(false);
+ m_xColumnFT->set_sensitive(false);
+ m_xColumnLB->set_sensitive(false);
+ m_xFilterFT->set_sensitive(false);
+ m_xFilterLB->set_sensitive(false);
+ m_xGenerateFromDataBaseCB->set_sensitive(false);
+ m_xPasswordCB->set_sensitive( false );
+ m_xPasswordFT->set_sensitive( false );
+ m_xPasswordLB->set_sensitive( false );
+ }
+}
+
+IMPL_LINK_NOARG(SwMailMergeDlg, SaveTypeHdl, weld::Toggleable&, void)
+{
+ bool bIndividual = m_xSaveIndividualRB->get_active();
+
+ m_xGenerateFromDataBaseCB->set_sensitive( bIndividual );
+ if( bIndividual )
+ {
+ FilenameHdl(*m_xGenerateFromDataBaseCB);
+ }
+ else
+ {
+ m_xColumnFT->set_sensitive(false);
+ m_xColumnLB->set_sensitive(false);
+ m_xPathFT->set_sensitive( false );
+ m_xPathED->set_sensitive( false );
+ m_xPathPB->set_sensitive( false );
+ m_xFilterFT->set_sensitive( false );
+ m_xFilterLB->set_sensitive( false );
+ m_xPasswordCB->set_sensitive( false );
+ m_xPasswordFT->set_sensitive( false );
+ m_xPasswordLB->set_sensitive( false );
+ }
+}
+
+IMPL_LINK( SwMailMergeDlg, FilenameHdl, weld::Toggleable&, rBox, void )
+{
+ bool bEnable = rBox.get_active();
+ m_xColumnFT->set_sensitive( bEnable );
+ m_xColumnLB->set_sensitive(bEnable);
+ m_xPathFT->set_sensitive( bEnable );
+ m_xPathED->set_sensitive(bEnable);
+ m_xPathPB->set_sensitive( bEnable );
+ m_xFilterFT->set_sensitive( bEnable );
+ m_xFilterLB->set_sensitive( bEnable );
+
+ if(m_xFilterLB->get_active_id() == "writer_pdf_Export")
+ {
+ m_xPasswordCB->show();
+ m_xPasswordFT->show();
+ m_xPasswordLB->show();
+
+ m_xPasswordCB->set_sensitive( bEnable );
+ m_xPasswordFT->set_sensitive( bEnable );
+ m_xPasswordLB->set_sensitive( bEnable );
+ }
+}
+
+IMPL_LINK_NOARG( SwMailMergeDlg, FileFormatHdl, weld::ComboBox&, void )
+{
+ if(m_xFilterLB->get_active_id() == "writer_pdf_Export")
+ {
+ m_xPasswordCB->show();
+ m_xPasswordFT->show();
+ m_xPasswordLB->show();
+
+ m_xPasswordCB->set_sensitive( true );
+ m_xPasswordFT->set_sensitive( true );
+ m_xPasswordLB->set_sensitive( true );
+ }
+ else
+ {
+ m_xPasswordCB->hide();
+ m_xPasswordFT->hide();
+ m_xPasswordLB->hide();
+ }
+}
+
+IMPL_LINK_NOARG(SwMailMergeDlg, ModifyHdl, weld::SpinButton&, void)
+{
+ m_xFromRB->set_active(true);
+}
+
+bool SwMailMergeDlg::AskUserFilename() const
+{
+ return (m_xSaveSingleDocRB->get_active() || !m_xGenerateFromDataBaseCB->get_active());
+}
+
+OUString SwMailMergeDlg::GetURLfromPath() const
+{
+ SfxMedium* pMedium = m_rSh.GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+ if( INetProtocol::NotValid == aAbs.GetProtocol() )
+ {
+ SvtPathOptions aPathOpt;
+ aAbs.SetURL( aPathOpt.GetWorkPath() );
+ }
+ return URIHelper::SmartRel2Abs(
+ aAbs, m_xPathED->get_text(), URIHelper::GetMaybeFileHdl());
+}
+
+bool SwMailMergeDlg::ExecQryShell()
+{
+ if(m_pImpl->xSelSupp.is()) {
+ m_pImpl->xSelSupp->removeSelectionChangeListener( m_pImpl->xChgLstnr );
+ }
+
+ if (m_xPrinterRB->get_active())
+ m_nMergeType = DBMGR_MERGE_PRINTER;
+ else {
+ m_nMergeType = DBMGR_MERGE_FILE;
+ m_pModOpt->SetMailingPath( GetURLfromPath() );
+ m_pModOpt->SetIsNameFromColumn(m_xGenerateFromDataBaseCB->get_active());
+ m_pModOpt->SetIsFileEncryptedFromColumn(m_xPasswordCB->get_active());
+
+ if (!AskUserFilename())
+ {
+ m_pModOpt->SetNameFromColumn(m_xColumnLB->get_active_text());
+ m_pModOpt->SetPasswordFromColumn(m_xPasswordLB->get_active_text());
+ if (m_xFilterLB->get_active() != -1)
+ m_sSaveFilter = m_xFilterLB->get_active_id();
+ m_sFilename = OUString();
+ } else {
+ //#i97667# reset column name - otherwise it's remembered from the last run
+ m_pModOpt->SetNameFromColumn(OUString());
+ m_pModOpt->SetPasswordFromColumn(OUString());
+ //start save as dialog
+ OUString sFilter;
+ m_sFilename = SwMailMergeHelper::CallSaveAsDialog(m_xDialog.get(), sFilter);
+ if (m_sFilename.isEmpty())
+ return false;
+ m_sSaveFilter = sFilter;
+ }
+ }
+
+ if (m_xFromRB->get_active()) { // Insert list
+ // Safe: the maximal value of the fields is limited
+ sal_Int32 nStart = m_xFromNF->get_value();
+ sal_Int32 nEnd = m_xToNF->get_value();
+
+ if (nEnd < nStart)
+ std::swap(nEnd, nStart);
+
+ m_aSelection.realloc(nEnd - nStart + 1);
+ Any* pSelection = m_aSelection.getArray();
+ for (sal_Int32 i = nStart; i <= nEnd; ++i, ++pSelection)
+ *pSelection <<= i;
+ } else if (m_xAllRB->get_active() )
+ m_aSelection.realloc(0); // Empty selection = insert all
+ else {
+ if(m_pImpl->xSelSupp.is()) {
+ //update selection
+ uno::Reference< XRowLocate > xRowLocate(GetResultSet(),UNO_QUERY);
+ uno::Reference< XResultSet > xRes(xRowLocate,UNO_QUERY);
+ m_pImpl->xSelSupp->getSelection() >>= m_aSelection;
+ if ( xRowLocate.is() ) {
+ for (Any& rRow : asNonConstRange(m_aSelection)) {
+ if ( xRowLocate->moveToBookmark(rRow) )
+ rRow <<= xRes->getRow();
+ }
+ }
+ }
+ }
+ IDocumentDeviceAccess& rIDDA = m_rSh.getIDocumentDeviceAccess();
+ SwPrintData aPrtData( rIDDA.getPrintData() );
+ aPrtData.SetPrintSingleJobs(m_xSingleJobsCB->get_active());
+ rIDDA.setPrintData(aPrtData);
+
+ m_pModOpt->SetSinglePrintJob(m_xSingleJobsCB->get_active());
+
+ MailTextFormats nMailingMode = MailTextFormats::NONE;
+
+ if (m_xFormatSwCB->get_active())
+ nMailingMode |= MailTextFormats::OFFICE;
+ if (m_xFormatHtmlCB->get_active())
+ nMailingMode |= MailTextFormats::HTML;
+ if (m_xFormatRtfCB->get_active())
+ nMailingMode |= MailTextFormats::RTF;
+ m_pModOpt->SetMailingFormats(nMailingMode);
+ return true;
+}
+
+OUString SwMailMergeDlg::GetTargetURL() const
+{
+ if( AskUserFilename() )
+ return m_sFilename;
+ OUString sPath( m_pModOpt->GetMailingPath() );
+ if( sPath.isEmpty() ) {
+ SvtPathOptions aPathOpt;
+ sPath = aPathOpt.GetWorkPath();
+ }
+ if( !sPath.endsWith("/") )
+ sPath += "/";
+ return sPath;
+}
+
+IMPL_LINK_NOARG(SwMailMergeDlg, InsertPathHdl, weld::Button&, void)
+{
+ uno::Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference < XFolderPicker2 > xFP = sfx2::createFolderPicker(xContext, m_xDialog.get());
+ xFP->setDisplayDirectory( GetURLfromPath() );
+ if( xFP->execute() == RET_OK ) {
+ INetURLObject aURL(xFP->getDirectory());
+ if(aURL.GetProtocol() == INetProtocol::File)
+ m_xPathED->set_text(aURL.PathToFileName());
+ else
+ m_xPathED->set_text(aURL.GetFull());
+ }
+}
+
+uno::Reference<XResultSet> SwMailMergeDlg::GetResultSet() const
+{
+ uno::Reference< XResultSet > xResSetClone;
+ if ( m_pImpl->xFController.is() ) {
+ // we create a clone to do the task
+ uno::Reference< XResultSetAccess > xResultSetAccess( m_pImpl->xFController->getModel(),UNO_QUERY);
+ if ( xResultSetAccess.is() )
+ xResSetClone = xResultSetAccess->createResultSet();
+ }
+ return xResSetClone;
+}
+
+SwMailMergeCreateFromDlg::SwMailMergeCreateFromDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "modules/swriter/ui/mailmergedialog.ui", "MailMergeDialog")
+ , m_xThisDocRB(m_xBuilder->weld_radio_button("document"))
+{
+}
+
+SwMailMergeCreateFromDlg::~SwMailMergeCreateFromDlg()
+{
+}
+
+SwMailMergeFieldConnectionsDlg::SwMailMergeFieldConnectionsDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "modules/swriter/ui/mergeconnectdialog.ui", "MergeConnectDialog")
+ , m_xUseExistingRB(m_xBuilder->weld_radio_button("existing"))
+{
+}
+
+SwMailMergeFieldConnectionsDlg::~SwMailMergeFieldConnectionsDlg()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/envelp/swuilabimp.hxx b/sw/source/ui/envelp/swuilabimp.hxx
new file mode 100644
index 0000000000..222c9fd911
--- /dev/null
+++ b/sw/source/ui/envelp/swuilabimp.hxx
@@ -0,0 +1,145 @@
+/* -*- 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 <label.hxx>
+#include <labimg.hxx>
+#include <labrec.hxx>
+#include <sfx2/tabdlg.hxx>
+
+class SwLabPage : public SfxTabPage
+{
+ SwDBManager* m_pDBManager;
+ OUString m_sActDBName;
+ SwLabItem m_aItem;
+
+ std::unique_ptr<weld::Widget> m_xAddressFrame;
+ std::unique_ptr<weld::CheckButton> m_xAddrBox;
+ std::unique_ptr<weld::TextView> m_xWritingEdit;
+ std::unique_ptr<weld::ComboBox> m_xDatabaseLB;
+ std::unique_ptr<weld::ComboBox> m_xTableLB;
+ std::unique_ptr<weld::Button> m_xInsertBT;
+ std::unique_ptr<weld::ComboBox> m_xDBFieldLB;
+ std::unique_ptr<weld::RadioButton> m_xContButton;
+ std::unique_ptr<weld::RadioButton> m_xSheetButton;
+ std::unique_ptr<weld::ComboBox> m_xMakeBox;
+ std::unique_ptr<weld::ComboBox> m_xTypeBox;
+ std::unique_ptr<weld::ComboBox> m_xHiddenSortTypeBox;
+ std::unique_ptr<weld::Label> m_xFormatInfo;
+
+ DECL_LINK(AddrHdl, weld::Toggleable&, void);
+ DECL_LINK(DatabaseHdl, weld::ComboBox&, void);
+ DECL_LINK(FieldHdl, weld::Button&, void);
+ DECL_LINK(PageHdl, weld::Toggleable&, void);
+ DECL_LINK(MakeHdl, weld::ComboBox&, void);
+ DECL_LINK(TypeHdl, weld::ComboBox&, void);
+
+ void DisplayFormat();
+ SwLabRec* GetSelectedEntryPos();
+
+public:
+ SwLabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+
+ virtual ~SwLabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+ void FillItem(SwLabItem& rItem);
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+ SwLabDlg* GetParentSwLabDlg() { return static_cast<SwLabDlg*>(GetDialogController()); }
+
+ void SetToBusinessCard();
+
+ void InitDatabaseBox();
+ void SetDBManager(SwDBManager* pDBManager_) { m_pDBManager = pDBManager_; }
+ SwDBManager* GetDBManager() const { return m_pDBManager; }
+};
+
+class SwPrivateDataPage : public SfxTabPage
+{
+ std::unique_ptr<weld::Entry> m_xFirstNameED;
+ std::unique_ptr<weld::Entry> m_xNameED;
+ std::unique_ptr<weld::Entry> m_xShortCutED;
+ std::unique_ptr<weld::Entry> m_xFirstName2ED;
+ std::unique_ptr<weld::Entry> m_xName2ED;
+ std::unique_ptr<weld::Entry> m_xShortCut2ED;
+ std::unique_ptr<weld::Entry> m_xStreetED;
+ std::unique_ptr<weld::Entry> m_xZipED;
+ std::unique_ptr<weld::Entry> m_xCityED;
+ std::unique_ptr<weld::Entry> m_xCountryED;
+ std::unique_ptr<weld::Entry> m_xStateED;
+ std::unique_ptr<weld::Entry> m_xTitleED;
+ std::unique_ptr<weld::Entry> m_xProfessionED;
+ std::unique_ptr<weld::Entry> m_xPhoneED;
+ std::unique_ptr<weld::Entry> m_xMobilePhoneED;
+ std::unique_ptr<weld::Entry> m_xFaxED;
+ std::unique_ptr<weld::Entry> m_xHomePageED;
+ std::unique_ptr<weld::Entry> m_xMailED;
+
+public:
+ SwPrivateDataPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SwPrivateDataPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ 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 SwBusinessDataPage : public SfxTabPage
+{
+ std::unique_ptr<weld::Entry> m_xCompanyED;
+ std::unique_ptr<weld::Entry> m_xCompanyExtED;
+ std::unique_ptr<weld::Entry> m_xSloganED;
+ std::unique_ptr<weld::Entry> m_xStreetED;
+ std::unique_ptr<weld::Entry> m_xZipED;
+ std::unique_ptr<weld::Entry> m_xCityED;
+ std::unique_ptr<weld::Entry> m_xCountryED;
+ std::unique_ptr<weld::Entry> m_xStateED;
+ std::unique_ptr<weld::Entry> m_xPositionED;
+ std::unique_ptr<weld::Entry> m_xPhoneED;
+ std::unique_ptr<weld::Entry> m_xMobilePhoneED;
+ std::unique_ptr<weld::Entry> m_xFaxED;
+ std::unique_ptr<weld::Entry> m_xHomePageED;
+ std::unique_ptr<weld::Entry> m_xMailED;
+
+public:
+ SwBusinessDataPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SwBusinessDataPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ 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;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx
new file mode 100644
index 0000000000..24461c47d6
--- /dev/null
+++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx
@@ -0,0 +1,126 @@
+/* -*- 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 <DateFormFieldDialog.hxx>
+#include <IMark.hxx>
+#include <xmloff/odffields.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <doc.hxx>
+
+namespace sw
+{
+DateFormFieldDialog::DateFormFieldDialog(weld::Widget* pParent,
+ sw::mark::IDateFieldmark* pDateField, SwDoc& rDoc)
+ : GenericDialogController(pParent, "modules/swriter/ui/dateformfielddialog.ui",
+ "DateFormFieldDialog")
+ , m_pDateField(pDateField)
+ , m_pNumberFormatter(rDoc.GetNumberFormatter())
+ , m_xFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("date_formats_treeview")))
+{
+ m_xFormatLB->SetFormatType(SvNumFormatType::DATE);
+ m_xFormatLB->SetAutomaticLanguage(true);
+ m_xFormatLB->SetShowLanguageControl(true);
+ m_xFormatLB->SetOneArea(true);
+
+ // Set a default height
+ weld::TreeView& rTreeView = dynamic_cast<weld::TreeView&>(m_xFormatLB->get_widget());
+ rTreeView.set_size_request(rTreeView.get_preferred_size().Width(),
+ rTreeView.get_height_rows(10));
+ InitControls();
+}
+
+DateFormFieldDialog::~DateFormFieldDialog() {}
+
+void DateFormFieldDialog::Apply()
+{
+ if (m_pDateField == nullptr)
+ return;
+
+ // Try to find out the current date value and replace the content
+ // with the right formatted date string
+ sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters();
+ const SvNumberformat* pFormat = m_pNumberFormatter->GetEntry(m_xFormatLB->GetFormat());
+
+ // Get date value first
+ std::pair<bool, double> aResult = m_pDateField->GetCurrentDate();
+
+ // Then set the date format
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring();
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE]
+ <<= LanguageTag(pFormat->GetLanguage()).getBcp47();
+
+ // Update current date
+ if (aResult.first)
+ {
+ m_pDateField->SetCurrentDate(aResult.second);
+ }
+ else
+ {
+ (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= OUString();
+ }
+}
+
+void DateFormFieldDialog::InitControls()
+{
+ if (m_pDateField == nullptr)
+ return;
+
+ sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters();
+
+ OUString sFormatString;
+ auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sFormatString;
+ }
+
+ OUString sLang;
+ pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sLang;
+ }
+
+ if (sFormatString.isEmpty() || sLang.isEmpty())
+ return;
+
+ LanguageType aLangType = LanguageTag(sLang).getLanguageType();
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ m_pNumberFormatter->PutEntry(sFormatString, nCheckPos, nType, nFormat,
+ LanguageTag(sLang).getLanguageType());
+ }
+
+ if (aLangType == LANGUAGE_DONTKNOW || nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ return;
+
+ if (m_xFormatLB->GetCurLanguage() == aLangType)
+ {
+ m_xFormatLB->SetAutomaticLanguage(true);
+ }
+ else
+ {
+ m_xFormatLB->SetAutomaticLanguage(false);
+ m_xFormatLB->SetLanguage(aLangType);
+
+ // Change format and change back for regenerating the list
+ m_xFormatLB->SetFormatType(SvNumFormatType::ALL);
+ m_xFormatLB->SetFormatType(SvNumFormatType::DATE);
+ }
+ m_xFormatLB->SetDefFormat(nFormat);
+}
+
+} // namespace sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/ui/fldui/DropDownFieldDialog.cxx b/sw/source/ui/fldui/DropDownFieldDialog.cxx
new file mode 100644
index 0000000000..d85bc5365b
--- /dev/null
+++ b/sw/source/ui/fldui/DropDownFieldDialog.cxx
@@ -0,0 +1,142 @@
+/* -*- 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 <wrtsh.hxx>
+#include <fldbas.hxx>
+#include <DropDownFieldDialog.hxx>
+#include <flddropdown.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+
+// edit insert-field
+sw::DropDownFieldDialog::DropDownFieldDialog(weld::Widget *pParent, SwWrtShell &rS,
+ SwField* pField, bool bPrevButton, bool bNextButton)
+ : GenericDialogController(pParent, "modules/swriter/ui/dropdownfielddialog.ui", "DropdownFieldDialog")
+ , m_rSh( rS )
+ , m_pDropField(nullptr)
+ , m_pPressedButton(nullptr)
+ , m_xListItemsLB(m_xBuilder->weld_tree_view("list"))
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+ , m_xPrevPB(m_xBuilder->weld_button("prev"))
+ , m_xNextPB(m_xBuilder->weld_button("next"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+{
+ m_xListItemsLB->set_size_request(m_xListItemsLB->get_approximate_digit_width() * 24,
+ m_xListItemsLB->get_height_rows(12));
+ Link<weld::TreeView&, bool> aDoubleLk = LINK(this, DropDownFieldDialog, DoubleClickHdl);
+ m_xListItemsLB->connect_row_activated( aDoubleLk );
+
+ Link<weld::Button&, void> aEditButtonLk = LINK(this, DropDownFieldDialog, EditHdl);
+ Link<weld::Button&,void> aPrevButtonLk = LINK(this, DropDownFieldDialog, PrevHdl);
+ Link<weld::Button&, void> aNextButtonLk = LINK(this, DropDownFieldDialog, NextHdl);
+ m_xEditPB->connect_clicked(aEditButtonLk);
+ if( bPrevButton || bNextButton )
+ {
+ m_xPrevPB->show();
+ m_xPrevPB->connect_clicked(aPrevButtonLk);
+ m_xPrevPB->set_sensitive(bPrevButton);
+
+ m_xNextPB->show();
+ m_xNextPB->connect_clicked(aNextButtonLk);
+ m_xNextPB->set_sensitive(bNextButton);
+ }
+ if( SwFieldIds::Dropdown == pField->GetTyp()->Which() )
+ {
+
+ m_pDropField = static_cast<SwDropDownField*>(pField);
+ OUString sTitle = m_xDialog->get_title() +
+ m_pDropField->GetPar2();
+ m_xDialog->set_title(sTitle);
+ const uno::Sequence< OUString > aItems = m_pDropField->GetItemSequence();
+ for (const OUString& rItem : aItems)
+ m_xListItemsLB->append_text(rItem);
+ m_xListItemsLB->select_text(m_pDropField->GetSelectedItem());
+ }
+
+ bool bEnable = !m_rSh.IsCursorReadonly();
+ m_xOKPB->set_sensitive(bEnable);
+
+ m_xListItemsLB->grab_focus();
+}
+
+sw::DropDownFieldDialog::~DropDownFieldDialog()
+{
+}
+
+void sw::DropDownFieldDialog::Apply()
+{
+ if (!m_pDropField)
+ return;
+
+ OUString sSelect = m_xListItemsLB->get_selected_text();
+ if (m_pDropField->GetPar1() == sSelect)
+ return;
+
+ m_rSh.StartAllAction();
+
+ std::unique_ptr<SwDropDownField> const pCopy(
+ static_cast<SwDropDownField*>(m_pDropField->CopyField().release()));
+
+ pCopy->SetPar1(sSelect);
+ m_rSh.SwEditShell::UpdateOneField(*pCopy);
+
+ m_rSh.SetUndoNoResetModified();
+ m_rSh.EndAllAction();
+}
+
+bool sw::DropDownFieldDialog::PrevButtonPressed() const
+{
+ return m_pPressedButton == m_xPrevPB.get();
+}
+
+bool sw::DropDownFieldDialog::NextButtonPressed() const
+{
+ return m_pPressedButton == m_xNextPB.get();
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, EditHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xEditPB.get();
+ m_xDialog->response(RET_YES);
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, PrevHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xPrevPB.get();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, NextHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xNextPB.get();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, DoubleClickHdl, weld::TreeView&, bool)
+{
+ // tdf#114144, when next is available make double-click accept and go to next field
+ if (m_xNextPB->get_visible() && m_xNextPB->get_sensitive())
+ m_pPressedButton = m_xNextPB.get();
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/DropDownFormFieldDialog.cxx b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
new file mode 100644
index 0000000000..2115bbda48
--- /dev/null
+++ b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
@@ -0,0 +1,200 @@
+/* -*- 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 <DropDownFormFieldDialog.hxx>
+#include <vcl/event.hxx>
+#include <IMark.hxx>
+#include <xmloff/odffields.hxx>
+#include <vcl/svapp.hxx>
+#include <strings.hrc>
+#include <swtypes.hxx>
+
+namespace sw
+{
+DropDownFormFieldDialog::DropDownFormFieldDialog(weld::Widget* pParent,
+ mark::IFieldmark* pDropDownField)
+ : GenericDialogController(pParent, "modules/swriter/ui/dropdownformfielddialog.ui",
+ "DropDownFormFieldDialog")
+ , m_pDropDownField(pDropDownField)
+ , m_bListHasChanged(false)
+ , m_xListItemEntry(m_xBuilder->weld_entry("item_entry"))
+ , m_xListAddButton(m_xBuilder->weld_button("add_button"))
+ , m_xListItemsTreeView(m_xBuilder->weld_tree_view("items_treeview"))
+ , m_xListRemoveButton(m_xBuilder->weld_button("remove_button"))
+ , m_xListUpButton(m_xBuilder->weld_button("up_button"))
+ , m_xListDownButton(m_xBuilder->weld_button("down_button"))
+{
+ m_xListItemEntry->connect_key_press(LINK(this, DropDownFormFieldDialog, KeyPressedHdl));
+ m_xListItemEntry->connect_changed(LINK(this, DropDownFormFieldDialog, EntryChangedHdl));
+
+ m_xListItemsTreeView->set_size_request(m_xListItemEntry->get_preferred_size().Width(),
+ m_xListItemEntry->get_preferred_size().Height() * 5);
+ m_xListItemsTreeView->connect_changed(LINK(this, DropDownFormFieldDialog, ListChangedHdl));
+
+ Link<weld::Button&, void> aPushButtonLink(LINK(this, DropDownFormFieldDialog, ButtonPushedHdl));
+ m_xListAddButton->connect_clicked(aPushButtonLink);
+ m_xListRemoveButton->connect_clicked(aPushButtonLink);
+ m_xListUpButton->connect_clicked(aPushButtonLink);
+ m_xListDownButton->connect_clicked(aPushButtonLink);
+
+ InitControls();
+}
+
+DropDownFormFieldDialog::~DropDownFormFieldDialog() {}
+
+IMPL_LINK_NOARG(DropDownFormFieldDialog, ListChangedHdl, weld::TreeView&, void) { UpdateButtons(); }
+
+IMPL_LINK(DropDownFormFieldDialog, KeyPressedHdl, const KeyEvent&, rEvent, bool)
+{
+ if (rEvent.GetKeyCode().GetCode() == KEY_RETURN && !m_xListItemEntry->get_text().isEmpty())
+ {
+ AppendItemToList();
+ return true;
+ }
+ return false;
+}
+
+IMPL_LINK_NOARG(DropDownFormFieldDialog, EntryChangedHdl, weld::Entry&, void) { UpdateButtons(); }
+
+IMPL_LINK(DropDownFormFieldDialog, ButtonPushedHdl, weld::Button&, rButton, void)
+{
+ if (&rButton == m_xListAddButton.get())
+ {
+ AppendItemToList();
+ }
+ else if (m_xListItemsTreeView->get_selected_index() != -1)
+ {
+ int nSelPos = m_xListItemsTreeView->get_selected_index();
+ if (&rButton == m_xListRemoveButton.get())
+ {
+ m_xListItemsTreeView->remove(nSelPos);
+ if (m_xListItemsTreeView->n_children() > 0)
+ m_xListItemsTreeView->select(nSelPos ? nSelPos - 1 : 0);
+ }
+ else if (&rButton == m_xListUpButton.get())
+ {
+ const OUString sEntry = m_xListItemsTreeView->get_selected_text();
+ m_xListItemsTreeView->remove(nSelPos);
+ nSelPos--;
+ m_xListItemsTreeView->insert_text(nSelPos, sEntry);
+ m_xListItemsTreeView->select(nSelPos);
+ }
+ else if (&rButton == m_xListDownButton.get())
+ {
+ const OUString sEntry = m_xListItemsTreeView->get_selected_text();
+ m_xListItemsTreeView->remove(nSelPos);
+ nSelPos++;
+ m_xListItemsTreeView->insert_text(nSelPos, sEntry);
+ m_xListItemsTreeView->select(nSelPos);
+ }
+ m_bListHasChanged = true;
+ }
+ UpdateButtons();
+}
+
+void DropDownFormFieldDialog::InitControls()
+{
+ if (m_pDropDownField != nullptr)
+ {
+ const mark::IFieldmark::parameter_map_t* const pParameters
+ = m_pDropDownField->GetParameters();
+
+ auto pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
+ if (pListEntries != pParameters->end())
+ {
+ css::uno::Sequence<OUString> vListEntries;
+ pListEntries->second >>= vListEntries;
+ for (const OUString& rItem : std::as_const(vListEntries))
+ m_xListItemsTreeView->append_text(rItem);
+
+ // Select the current one
+ auto pResult = pParameters->find(ODF_FORMDROPDOWN_RESULT);
+ if (pResult != pParameters->end())
+ {
+ sal_Int32 nSelection = -1;
+ pResult->second >>= nSelection;
+ if (nSelection >= 0 && nSelection < vListEntries.getLength())
+ m_xListItemsTreeView->select_text(vListEntries[nSelection]);
+ }
+ }
+ }
+ UpdateButtons();
+}
+
+void DropDownFormFieldDialog::AppendItemToList()
+{
+ if (!m_xListAddButton->get_sensitive())
+ return;
+
+ if (m_xListItemsTreeView->n_children() >= ODF_FORMDROPDOWN_ENTRY_COUNT_LIMIT)
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
+ m_xDialog.get(), VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_DROP_DOWN_FIELD_ITEM_LIMIT)));
+ xInfoBox->run();
+ return;
+ }
+
+ const OUString sEntry(m_xListItemEntry->get_text());
+ if (!sEntry.isEmpty())
+ {
+ m_xListItemsTreeView->append_text(sEntry);
+ m_xListItemsTreeView->select_text(sEntry);
+ m_bListHasChanged = true;
+
+ // Clear entry
+ m_xListItemEntry->set_text(OUString());
+ m_xListItemEntry->grab_focus();
+ }
+ UpdateButtons();
+}
+
+void DropDownFormFieldDialog::UpdateButtons()
+{
+ m_xListAddButton->set_sensitive(!m_xListItemEntry->get_text().isEmpty()
+ && m_xListItemsTreeView->find_text(m_xListItemEntry->get_text())
+ == -1);
+
+ int nSelPos = m_xListItemsTreeView->get_selected_index();
+ m_xListRemoveButton->set_sensitive(nSelPos != -1);
+ m_xListUpButton->set_sensitive(nSelPos > 0);
+ m_xListDownButton->set_sensitive(nSelPos != -1
+ && nSelPos < m_xListItemsTreeView->n_children() - 1);
+}
+
+void DropDownFormFieldDialog::Apply()
+{
+ if (!(m_pDropDownField != nullptr && m_bListHasChanged))
+ return;
+
+ mark::IFieldmark::parameter_map_t* pParameters = m_pDropDownField->GetParameters();
+
+ css::uno::Sequence<OUString> vListEntries(m_xListItemsTreeView->n_children());
+ auto vListEntriesRange = asNonConstRange(vListEntries);
+ for (int nIndex = 0; nIndex < m_xListItemsTreeView->n_children(); ++nIndex)
+ {
+ vListEntriesRange[nIndex] = m_xListItemsTreeView->get_text(nIndex);
+ }
+
+ if (m_xListItemsTreeView->n_children() != 0)
+ {
+ (*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] <<= vListEntries;
+ }
+ else
+ {
+ pParameters->erase(ODF_FORMDROPDOWN_LISTENTRY);
+ }
+
+ // After editing the drop down field's list we don't specify the selected item
+ pParameters->erase(ODF_FORMDROPDOWN_RESULT);
+}
+
+} // namespace sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/ui/fldui/changedb.cxx b/sw/source/ui/fldui/changedb.cxx
new file mode 100644
index 0000000000..a1e1803d90
--- /dev/null
+++ b/sw/source/ui/fldui/changedb.cxx
@@ -0,0 +1,258 @@
+/* -*- 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 <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <dbmgr.hxx>
+#include <changedb.hxx>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::uno;
+
+// edit insert-field
+SwChangeDBDlg::SwChangeDBDlg(SwView const & rVw)
+ : SfxDialogController(rVw.GetViewFrame().GetFrameWeld(), "modules/swriter/ui/exchangedatabases.ui",
+ "ExchangeDatabasesDialog")
+ , m_pSh(rVw.GetWrtShellPtr())
+ , m_xUsedDBTLB(m_xBuilder->weld_tree_view("inuselb"))
+ , m_xAvailDBTLB(new SwDBTreeList(m_xBuilder->weld_tree_view("availablelb")))
+ , m_xAddDBPB(m_xBuilder->weld_button("browse"))
+ , m_xDocDBNameFT(m_xBuilder->weld_label("dbnameft"))
+ , m_xDefineBT(m_xBuilder->weld_button("ok"))
+{
+ int nWidth = m_xUsedDBTLB->get_approximate_digit_width() * 25;
+ int nHeight = m_xUsedDBTLB->get_height_rows(8);
+ m_xUsedDBTLB->set_size_request(nWidth, nHeight);
+ m_xAvailDBTLB->set_size_request(nWidth, nHeight);
+
+ m_xAvailDBTLB->SetWrtShell(*m_pSh);
+ FillDBPopup();
+
+ ShowDBName(m_pSh->GetDBData());
+ m_xDefineBT->connect_clicked(LINK(this, SwChangeDBDlg, ButtonHdl));
+ m_xAddDBPB->connect_clicked(LINK(this, SwChangeDBDlg, AddDBHdl));
+
+ m_xUsedDBTLB->set_selection_mode(SelectionMode::Multiple);
+ m_xUsedDBTLB->make_sorted();
+
+ Link<weld::TreeView&,void> aLink = LINK(this, SwChangeDBDlg, TreeSelectHdl);
+
+ m_xUsedDBTLB->connect_changed(aLink);
+ m_xAvailDBTLB->connect_changed(aLink);
+ TreeSelect();
+}
+
+// initialise database listboxes
+void SwChangeDBDlg::FillDBPopup()
+{
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference<XDatabaseContext> xDBContext = DatabaseContext::create(xContext);
+ const SwDBData& rDBData = m_pSh->GetDBData();
+ m_xAvailDBTLB->Select(rDBData.sDataSource, rDBData.sCommand, u"");
+ TreeSelect();
+
+ Sequence< OUString > aDBNames = xDBContext->getElementNames();
+ auto aAllDBNames = comphelper::sequenceToContainer<std::vector<OUString>>(aDBNames);
+
+ std::vector<OUString> aDBNameList;
+ m_pSh->GetAllUsedDB( aDBNameList, &aAllDBNames );
+
+ size_t nCount = aDBNameList.size();
+ m_xUsedDBTLB->clear();
+ std::unique_ptr<weld::TreeIter> xFirst;
+
+ for(size_t k = 0; k < nCount; k++)
+ {
+ std::unique_ptr<weld::TreeIter> xLast = Insert(o3tl::getToken(aDBNameList[k], 0, ';'));
+ if (!xFirst)
+ xFirst = std::move(xLast);
+ }
+
+ if (xFirst)
+ {
+ m_xUsedDBTLB->expand_row(*xFirst);
+ m_xUsedDBTLB->scroll_to_row(*xFirst);
+ m_xUsedDBTLB->select(*xFirst);
+ }
+}
+
+std::unique_ptr<weld::TreeIter> SwChangeDBDlg::Insert(std::u16string_view rDBName)
+{
+ sal_Int32 nIdx{ 0 };
+ const OUString sDBName(o3tl::getToken(rDBName, 0, DB_DELIM, nIdx));
+ const OUString sTableName(o3tl::getToken(rDBName, 0, DB_DELIM, nIdx));
+ OUString sUserData( o3tl::getToken(rDBName, 0, DB_DELIM, nIdx) );
+ sal_Int32 nCommandType = sUserData.toInt32();
+
+ const OUString & rToInsert ( nCommandType ? RID_BMP_DBQUERY : RID_BMP_DBTABLE );
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xUsedDBTLB->make_iterator());
+ if (m_xUsedDBTLB->get_iter_first(*xIter))
+ {
+ do
+ {
+ if (sDBName == m_xUsedDBTLB->get_text(*xIter))
+ {
+ if (m_xUsedDBTLB->iter_has_child(*xIter))
+ {
+ std::unique_ptr<weld::TreeIter> xChild(m_xUsedDBTLB->make_iterator(xIter.get()));
+ if (m_xUsedDBTLB->iter_children(*xChild))
+ {
+ do
+ {
+ if (sTableName == m_xUsedDBTLB->get_text(*xChild))
+ return xChild;
+ } while (m_xUsedDBTLB->iter_next_sibling(*xChild));
+ }
+ }
+ m_xUsedDBTLB->insert(xIter.get(), -1, &sTableName, &sUserData, nullptr, nullptr,
+ false, xIter.get());
+ m_xUsedDBTLB->set_image(*xIter, rToInsert);
+ return xIter;
+ }
+ } while (m_xUsedDBTLB->iter_next_sibling(*xIter));
+ }
+
+ m_xUsedDBTLB->insert(nullptr, -1, &sDBName, nullptr, nullptr, nullptr,
+ false, xIter.get());
+ m_xUsedDBTLB->set_image(*xIter, RID_BMP_DB);
+ m_xUsedDBTLB->insert(xIter.get(), -1, &sTableName, &sUserData, nullptr, nullptr,
+ false, xIter.get());
+ m_xUsedDBTLB->set_image(*xIter, rToInsert);
+ return xIter;
+}
+
+// destroy dialog
+SwChangeDBDlg::~SwChangeDBDlg()
+{
+}
+
+short SwChangeDBDlg::run()
+{
+ short nRet = SfxDialogController::run();
+ if (nRet == RET_OK)
+ UpdateFields();
+ return nRet;
+}
+
+void SwChangeDBDlg::UpdateFields()
+{
+ std::vector<OUString> aDBNames;
+
+ m_xUsedDBTLB->selected_foreach([this, &aDBNames](weld::TreeIter& rEntry){
+ if (m_xUsedDBTLB->get_iter_depth(rEntry))
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xUsedDBTLB->make_iterator(&rEntry));
+ m_xUsedDBTLB->iter_parent(*xIter);
+ OUString sTmp(m_xUsedDBTLB->get_text(*xIter) +
+ OUStringChar(DB_DELIM) + m_xUsedDBTLB->get_text(rEntry) + OUStringChar(DB_DELIM) +
+ m_xUsedDBTLB->get_id(rEntry));
+ aDBNames.push_back(sTmp);
+ }
+ return false;
+ });
+
+ m_pSh->StartAllAction();
+ OUString sTableName;
+ OUString sColumnName;
+ sal_Bool bIsTable = false;
+ const OUString DBName(m_xAvailDBTLB->GetDBName(sTableName, sColumnName, &bIsTable));
+ const OUString sTemp = DBName
+ + OUStringChar(DB_DELIM)
+ + sTableName
+ + OUStringChar(DB_DELIM)
+ + OUString::number(bIsTable
+ ? CommandType::TABLE
+ : CommandType::QUERY);
+ m_pSh->ChangeDBFields( aDBNames, sTemp);
+ m_pSh->EndAllAction();
+}
+
+IMPL_LINK_NOARG(SwChangeDBDlg, ButtonHdl, weld::Button&, void)
+{
+ OUString sTableName;
+ OUString sColumnName;
+ SwDBData aData;
+ sal_Bool bIsTable = false;
+ aData.sDataSource = m_xAvailDBTLB->GetDBName(sTableName, sColumnName, &bIsTable);
+ aData.sCommand = sTableName;
+ aData.nCommandType = bIsTable ? 0 : 1;
+ m_pSh->ChgDBData(aData);
+ ShowDBName(m_pSh->GetDBData());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwChangeDBDlg, TreeSelectHdl, weld::TreeView&, void)
+{
+ TreeSelect();
+}
+
+void SwChangeDBDlg::TreeSelect()
+{
+ bool bEnable = false;
+ std::unique_ptr<weld::TreeIter> xIter(m_xAvailDBTLB->make_iterator());
+ if (m_xAvailDBTLB->get_selected(xIter.get()))
+ {
+ if (m_xAvailDBTLB->get_iter_depth(*xIter))
+ bEnable = true;
+ }
+ m_xDefineBT->set_sensitive(bEnable);
+}
+
+
+// convert database name for display
+void SwChangeDBDlg::ShowDBName(const SwDBData& rDBData)
+{
+ if (rDBData.sDataSource.isEmpty() && rDBData.sCommand.isEmpty())
+ {
+ m_xDocDBNameFT->set_label(SwResId(SW_STR_NONE));
+ }
+ else
+ {
+ const OUString sName(rDBData.sDataSource + "." + rDBData.sCommand);
+ m_xDocDBNameFT->set_label(sName.replaceAll("~", "~~"));
+ }
+}
+
+IMPL_LINK_NOARG(SwChangeDBDlg, AddDBHdl, weld::Button&, void)
+{
+ const OUString sNewDB = SwDBManager::LoadAndRegisterDataSource(m_xDialog.get());
+ if (!sNewDB.isEmpty())
+ {
+ m_xAvailDBTLB->AddDataSource(sNewDB);
+ TreeSelect();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddb.cxx b/sw/source/ui/fldui/flddb.cxx
new file mode 100644
index 0000000000..0c0210eeda
--- /dev/null
+++ b/sw/source/ui/fldui/flddb.cxx
@@ -0,0 +1,541 @@
+/* -*- 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 <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <dbfld.hxx>
+#include <doc.hxx>
+
+#include "flddb.hxx"
+#include <dbconfig.hxx>
+#include <dbmgr.hxx>
+#include <o3tl/string_view.hxx>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldDBPage::SwFieldDBPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/flddbpage.ui", "FieldDbPage", pCoreSet)
+ , m_nOldFormat(0)
+ , m_nOldSubType(0)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xDatabaseTLB(new SwDBTreeList(m_xBuilder->weld_tree_view("select")))
+ , m_xAddDBPB(m_xBuilder->weld_button("browse"))
+ , m_xCondition(m_xBuilder->weld_widget("condgroup"))
+ , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry("condition")))
+ , m_xValue(m_xBuilder->weld_widget("recgroup"))
+ , m_xValueED(m_xBuilder->weld_entry("recnumber"))
+ , m_xDBFormatRB(m_xBuilder->weld_radio_button("fromdatabasecb"))
+ , m_xNewFormatRB(m_xBuilder->weld_radio_button("userdefinedcb"))
+ , m_xNumFormatLB(new NumFormatListBox(m_xBuilder->weld_combo_box("numformat")))
+ , m_xFormatLB(m_xBuilder->weld_combo_box("format"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+{
+ SetTypeSel(-1); //TODO
+
+ m_xTypeLB->make_sorted();
+ m_xFormatLB->make_sorted();
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xDatabaseTLB->set_size_request(nWidth*2, nHeight);
+
+ m_xNumFormatLB->connect_changed(LINK(this, SwFieldDBPage, NumSelectHdl));
+ m_xDatabaseTLB->connect_changed(LINK(this, SwFieldDBPage, TreeSelectHdl));
+ m_xDatabaseTLB->connect_row_activated(LINK(this, SwFieldDBPage, TreeViewInsertHdl));
+
+ m_xValueED->connect_changed(LINK(this, SwFieldDBPage, ModifyHdl));
+ m_xAddDBPB->connect_clicked(LINK(this, SwFieldDBPage, AddDBHdl));
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-db");
+ m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-db");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-db");
+}
+
+SwFieldDBPage::~SwFieldDBPage()
+{
+ // If we have no stored SwWrtShell, it means we didn't do anything useful - no need to revoke.
+ if (SwWrtShell* pSh = CheckAndGetWrtShell())
+ {
+ // This would cleanup in the case of cancelled dialog
+ SwDBManager* pDbManager = pSh->GetDoc()->GetDBManager();
+ if (pDbManager)
+ pDbManager->RevokeLastRegistrations();
+ }
+}
+
+// initialise TabPage
+void SwFieldDBPage::Reset(const SfxItemSet*)
+{
+ Init(); // general initialization
+
+ const sal_Int32 nOldPos = m_xTypeLB->get_selected_index();
+ m_xTypeLB->freeze();
+ m_sOldDBName = m_xDatabaseTLB->GetDBName(m_sOldTableName, m_sOldColumnName);
+
+ m_xTypeLB->clear();
+
+ if (!IsFieldEdit())
+ {
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ for(sal_uInt16 i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+ else
+ {
+ const SwFieldTypesEnum nTypeId = GetCurField()->GetTypeId();
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)),
+ SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+ }
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ if (GetTypeSel() != -1)
+ m_xTypeLB->select(GetTypeSel());
+
+ m_xFormatLB->clear();
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(SwFieldTypesEnum::DatabaseSetNumber, IsFieldDlgHtmlMode());
+ for( sal_uInt16 i = 0; i < nSize; ++i )
+ {
+ const sal_uInt16 nFormatId = GetFieldMgr().GetFormatId( SwFieldTypesEnum::DatabaseSetNumber, i );
+ OUString sId(OUString::number(nFormatId));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(SwFieldTypesEnum::DatabaseSetNumber, i));
+ if (SVX_NUM_ARABIC == nFormatId)
+ m_xFormatLB->set_active_id(sId);
+ }
+
+ if (!IsFieldEdit())
+ {
+ if (nOldPos != -1)
+ m_xTypeLB->select(nOldPos);
+
+ if (!m_sOldDBName.isEmpty())
+ {
+ m_xDatabaseTLB->Select(m_sOldDBName, m_sOldTableName, m_sOldColumnName);
+ }
+ else
+ {
+ if (SwWrtShell *pSh = CheckAndGetWrtShell())
+ {
+ SwDBData aTmp(pSh->GetDBData());
+ m_xDatabaseTLB->Select(aTmp.sDataSource, aTmp.sCommand, u"");
+ }
+ }
+ }
+
+ if( !IsRefresh() )
+ {
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if (nVal != USHRT_MAX)
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ TypeHdl(nullptr);
+
+ m_xTypeLB->connect_changed(LINK(this, SwFieldDBPage, TypeListBoxHdl));
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldDBPage, TreeViewInsertHdl));
+
+ if (IsFieldEdit())
+ {
+ m_xConditionED->save_value();
+ m_xValueED->save_value();
+ m_sOldDBName = m_xDatabaseTLB->GetDBName(m_sOldTableName, m_sOldColumnName);
+ m_nOldFormat = GetCurField()->GetFormat();
+ m_nOldSubType = GetCurField()->GetSubType();
+ }
+}
+
+// SwFieldDBPage may ask for password to select current document's data source,
+// so only do that when activating the page, not when dialog is creating all pages
+bool SwFieldDBPage::DeferResetToFirstActivation() { return true; }
+
+bool SwFieldDBPage::FillItemSet(SfxItemSet* )
+{
+ OUString sTableName;
+ OUString sColumnName;
+ SwDBData aData;
+ sal_Bool bIsTable;
+ aData.sDataSource = m_xDatabaseTLB->GetDBName(sTableName, sColumnName, &bIsTable);
+ aData.sCommand = sTableName;
+ aData.nCommandType = bIsTable ? 0 : 1;
+
+ if (SwWrtShell *pSh = CheckAndGetWrtShell())
+ {
+ SwDBManager* pDbManager = pSh->GetDoc()->GetDBManager();
+ if (pDbManager)
+ pDbManager->CommitLastRegistrations();
+
+ if (aData.sDataSource.isEmpty())
+ aData = pSh->GetDBData();
+ }
+
+ if(!aData.sDataSource.isEmpty()) // without database no new field command
+ {
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ sal_uInt32 nFormat = 0;
+ sal_uInt16 nSubType = 0;
+
+ OUString sDBName = aData.sDataSource
+ + OUStringChar(DB_DELIM)
+ + aData.sCommand
+ + OUStringChar(DB_DELIM)
+ + OUString::number(aData.nCommandType)
+ + OUStringChar(DB_DELIM);
+ if (!sColumnName.isEmpty())
+ {
+ sDBName += sColumnName + OUStringChar(DB_DELIM);
+ }
+ OUString aName = sDBName + m_xConditionED->get_text();
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Database:
+ nFormat = m_xNumFormatLB->GetFormat();
+ if (m_xNewFormatRB->get_sensitive() && m_xNewFormatRB->get_active())
+ nSubType = nsSwExtendedSubType::SUB_OWN_FMT;
+ aName = sDBName;
+ break;
+
+ case SwFieldTypesEnum::DatabaseSetNumber:
+ nFormat = m_xFormatLB->get_active_id().toUInt32();
+ break;
+ default: break;
+ }
+
+ const OUString aVal(m_xValueED->get_text());
+ OUString sTempTableName;
+ OUString sTempColumnName;
+ OUString sTempDBName = m_xDatabaseTLB->GetDBName(sTempTableName, sTempColumnName);
+ bool bDBListBoxChanged = m_sOldDBName != sTempDBName ||
+ m_sOldTableName != sTempTableName || m_sOldColumnName != sTempColumnName;
+ if (!IsFieldEdit() ||
+ m_xConditionED->get_value_changed_from_saved() ||
+ m_xValueED->get_saved_value() != aVal ||
+ bDBListBoxChanged ||
+ m_nOldFormat != nFormat || m_nOldSubType != nSubType)
+ {
+ InsertField( nTypeId, nSubType, aName, aVal, nFormat);
+ }
+ }
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldDBPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet )
+{
+ return std::make_unique<SwFieldDBPage>( pPage, pController, pAttrSet );
+}
+
+sal_uInt16 SwFieldDBPage::GetGroup()
+{
+ return GRP_DB;
+}
+
+IMPL_LINK( SwFieldDBPage, TypeListBoxHdl, weld::TreeView&, rBox, void )
+{
+ TypeHdl(&rBox);
+}
+
+void SwFieldDBPage::TypeHdl(const weld::TreeView* pBox)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if (GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ bool bCond = false, bSetNo = false, bFormat = false, bDBFormat = false;
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ m_xDatabaseTLB->ShowColumns(nTypeId == SwFieldTypesEnum::Database);
+
+ if (IsFieldEdit())
+ {
+ SwDBData aData;
+ OUString sColumnName;
+ if (nTypeId == SwFieldTypesEnum::Database)
+ {
+ if (auto const*const pField = dynamic_cast<SwDBField*>(GetCurField()))
+ {
+ aData = pField->GetDBData();
+ sColumnName = static_cast<SwDBFieldType*>(GetCurField()->GetTyp())->GetColumnName();
+ }
+ }
+ else
+ {
+ if (auto *const pField = dynamic_cast<SwDBNameInfField*>(GetCurField()))
+ {
+ if(SwWrtShell *pSh = CheckAndGetWrtShell())
+ aData = pField->GetDBData(pSh->GetDoc());
+ }
+ }
+ m_xDatabaseTLB->Select(aData.sDataSource, aData.sCommand, sColumnName);
+ }
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Database:
+ {
+ bFormat = true;
+ bDBFormat = true;
+ m_xNumFormatLB->show();
+ m_xFormatLB->hide();
+
+ weld::Widget& rWidget = m_xNumFormatLB->get_widget();
+ rWidget.set_accessible_relation_labeled_by(m_xNewFormatRB.get());
+
+ if (pBox) // type was changed by user
+ m_xDBFormatRB->set_active(true);
+
+ if (IsFieldEdit())
+ {
+ if (GetCurField()->GetFormat() != 0 && GetCurField()->GetFormat() != SAL_MAX_UINT32)
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+
+ if (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_OWN_FMT)
+ m_xNewFormatRB->set_active(true);
+ else
+ m_xDBFormatRB->set_active(true);
+ }
+ break;
+ }
+ case SwFieldTypesEnum::DatabaseNumberSet:
+ bSetNo = true;
+ [[fallthrough]];
+ case SwFieldTypesEnum::DatabaseNextSet:
+ bCond = true;
+ if (IsFieldEdit())
+ {
+ m_xConditionED->set_text(GetCurField()->GetPar1());
+ m_xValueED->set_text(GetCurField()->GetPar2());
+ }
+ break;
+
+ case SwFieldTypesEnum::DatabaseName:
+ break;
+
+ case SwFieldTypesEnum::DatabaseSetNumber:
+ {
+ bFormat = true;
+ m_xNewFormatRB->set_active(true);
+ m_xNumFormatLB->hide();
+ m_xFormatLB->show();
+
+ m_xFormatLB->set_accessible_relation_labeled_by(m_xNewFormatRB.get());
+
+ if( IsFieldEdit() )
+ {
+ for (sal_Int32 nI = m_xFormatLB->get_count(); nI;)
+ {
+ if (GetCurField()->GetFormat() == m_xFormatLB->get_id(--nI).toUInt32())
+ {
+ m_xFormatLB->set_active( nI );
+ break;
+ }
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+
+ m_xCondition->set_sensitive(bCond);
+ m_xValue->set_sensitive(bSetNo);
+ if (nTypeId != SwFieldTypesEnum::Database)
+ {
+ m_xDBFormatRB->set_sensitive(bDBFormat);
+ m_xNewFormatRB->set_sensitive(bDBFormat || bFormat);
+ m_xNumFormatLB->set_sensitive(bDBFormat);
+ m_xFormatLB->set_sensitive(bFormat);
+ }
+ m_xFormat->set_sensitive(bDBFormat || bFormat);
+
+ if (!IsFieldEdit())
+ {
+ m_xValueED->set_text(OUString());
+ if (bCond)
+ m_xConditionED->set_text("TRUE");
+ else
+ m_xConditionED->set_text(OUString());
+ }
+
+ CheckInsert();
+}
+
+IMPL_LINK_NOARG(SwFieldDBPage, NumSelectHdl, weld::ComboBox&, void)
+{
+ m_xNewFormatRB->set_active(true);
+ m_xNumFormatLB->CallSelectHdl();
+}
+
+void SwFieldDBPage::CheckInsert()
+{
+ bool bInsert = true;
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xDatabaseTLB->make_iterator());
+ if (m_xDatabaseTLB->get_selected(xIter.get()))
+ {
+ bool bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ if (nTypeId == SwFieldTypesEnum::Database && bEntry)
+ bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ bInsert &= bEntry;
+ }
+ else
+ bInsert = false;
+
+ if (nTypeId == SwFieldTypesEnum::DatabaseNumberSet)
+ {
+ bool bHasValue = !m_xValueED->get_text().isEmpty();
+
+ bInsert &= bHasValue;
+ }
+
+ EnableInsert(bInsert);
+}
+
+IMPL_LINK(SwFieldDBPage, TreeSelectHdl, weld::TreeView&, rBox, void)
+{
+ std::unique_ptr<weld::TreeIter> xIter(rBox.make_iterator());
+ if (!rBox.get_selected(xIter.get()))
+ return;
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ bool bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ if (nTypeId == SwFieldTypesEnum::Database && bEntry)
+ bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ CheckInsert();
+
+ if (nTypeId != SwFieldTypesEnum::Database)
+ return;
+
+ bool bNumFormat = false;
+
+ if (bEntry)
+ {
+ OUString sTableName;
+ OUString sColumnName;
+ sal_Bool bIsTable;
+ OUString sDBName = m_xDatabaseTLB->GetDBName(sTableName, sColumnName, &bIsTable);
+ bNumFormat = GetFieldMgr().IsDBNumeric(sDBName,
+ sTableName,
+ bIsTable,
+ sColumnName);
+ if (!IsFieldEdit())
+ m_xDBFormatRB->set_active(true);
+ }
+
+ m_xDBFormatRB->set_sensitive(bNumFormat);
+ m_xNewFormatRB->set_sensitive(bNumFormat);
+ m_xNumFormatLB->set_sensitive(bNumFormat);
+ m_xFormat->set_sensitive(bNumFormat);
+}
+
+IMPL_LINK_NOARG(SwFieldDBPage, AddDBHdl, weld::Button&, void)
+{
+ if (SwWrtShell* pSh = CheckAndGetWrtShell())
+ {
+ OUString sNewDB
+ = SwDBManager::LoadAndRegisterDataSource(GetFrameWeld(), pSh->GetDoc()->GetDocShell());
+ if (!sNewDB.isEmpty())
+ {
+ m_xDatabaseTLB->AddDataSource(sNewDB);
+ }
+ }
+}
+
+// Modify
+IMPL_LINK_NOARG(SwFieldDBPage, ModifyHdl, weld::Entry&, void)
+{
+ CheckInsert();
+}
+
+void SwFieldDBPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+void SwFieldDBPage::ActivateMailMergeAddress()
+{
+ m_xTypeLB->select_id(OUString::number(static_cast<sal_uInt16>(SwFieldTypesEnum::Database)));
+ TypeListBoxHdl(*m_xTypeLB);
+ const SwDBData& rData = SW_MOD()->GetDBConfig()->GetAddressSource();
+ m_xDatabaseTLB->Select(rData.sDataSource, rData.sCommand, u"");
+}
+
+void SwFieldDBPage::SetWrtShell(SwWrtShell& rSh)
+{
+ // We need to remember the shell to be able to call correct SwDBManager
+ SwFieldPage::SetWrtShell(&rSh);
+ m_xDatabaseTLB->SetWrtShell(rSh);
+}
+
+SwWrtShell* SwFieldDBPage::CheckAndGetWrtShell()
+{
+ SwWrtShell* pSh = GetWrtShell();
+ if (!pSh)
+ {
+ pSh = ::GetActiveWrtShell();
+ if (pSh) // this is not guaranteed: e.g., activating print preview with dialog active
+ SetWrtShell(*pSh);
+ }
+ return pSh;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddb.hxx b/sw/source/ui/fldui/flddb.hxx
new file mode 100644
index 0000000000..9fb967b9a5
--- /dev/null
+++ b/sw/source/ui/fldui/flddb.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDDB_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDDB_HXX
+
+#include <condedit.hxx>
+#include <dbtree.hxx>
+#include <numfmtlb.hxx>
+
+#include "fldpage.hxx"
+
+class SwFieldDBPage : public SwFieldPage
+{
+ OUString m_sOldDBName;
+ OUString m_sOldTableName;
+ OUString m_sOldColumnName;
+ sal_uInt32 m_nOldFormat;
+ sal_uInt16 m_nOldSubType;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<SwDBTreeList> m_xDatabaseTLB;
+ std::unique_ptr<weld::Button> m_xAddDBPB;
+ std::unique_ptr<weld::Widget> m_xCondition;
+ std::unique_ptr<ConditionEdit> m_xConditionED;
+ std::unique_ptr<weld::Widget> m_xValue;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::RadioButton> m_xDBFormatRB;
+ std::unique_ptr<weld::RadioButton> m_xNewFormatRB;
+ std::unique_ptr<NumFormatListBox> m_xNumFormatLB;
+ std::unique_ptr<weld::ComboBox> m_xFormatLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+
+ DECL_LINK( TypeListBoxHdl, weld::TreeView&, void );
+ DECL_LINK( NumSelectHdl, weld::ComboBox&, void );
+ DECL_LINK( TreeSelectHdl, weld::TreeView&, void );
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( AddDBHdl, weld::Button&, void );
+ void TypeHdl(const weld::TreeView*);
+
+ void CheckInsert();
+
+ using SwFieldPage::SetWrtShell;
+ SwWrtShell* CheckAndGetWrtShell();
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldDBPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual ~SwFieldDBPage() 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 bool DeferResetToFirstActivation() override;
+
+ virtual void FillUserData() override;
+ void ActivateMailMergeAddress();
+
+ void SetWrtShell(SwWrtShell& rSh);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddinf.cxx b/sw/source/ui/fldui/flddinf.cxx
new file mode 100644
index 0000000000..7cb69c1d0e
--- /dev/null
+++ b/sw/source/ui/fldui/flddinf.cxx
@@ -0,0 +1,511 @@
+/* -*- 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/frame.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <swtypes.hxx>
+#include <flddinf.hrc>
+#include <strings.hrc>
+#include <fldbas.hxx>
+#include <docufld.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+
+#include "flddinf.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/Date.hpp>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+using namespace nsSwDocInfoSubType;
+using namespace com::sun::star;
+
+void FillFieldSelect(weld::TreeView& rListBox)
+{
+ for (auto const& aID : FLD_SELECT)
+ rListBox.append_text(SwResId(aID));
+}
+
+SwFieldDokInfPage::SwFieldDokInfPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/flddocinfopage.ui", "FieldDocInfoPage", pCoreSet)
+ , m_nOldSel(0)
+ , m_nOldFormat(0)
+ , m_xTypeList(m_xBuilder->weld_tree_view("type-list"))
+ , m_xTypeTree(m_xBuilder->weld_tree_view("type-tree"))
+ // tdf#104278 have two tree views, one with expander and one without, the one with is only used
+ // when there are custom properties which use the expander, so the common case of no custom
+ // properties doesn't have an 'unexplained' expander margin
+ , m_pTypeView(m_xTypeTree.get())
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("format")))
+ , m_xFixedCB(m_xBuilder->weld_check_button("fixed"))
+{
+ m_xTypeList->make_sorted();
+ m_xTypeTree->make_sorted();
+ FillFieldSelect(*m_xSelectionLB);
+
+ auto nWidth = m_pTypeView->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_pTypeView->get_height_rows(10);
+ m_xTypeTree->set_size_request(nWidth, nHeight);
+ m_xTypeList->set_size_request(nWidth, nHeight);
+ m_xFormatLB->get_widget().set_size_request(nWidth * 2, nHeight);
+ m_xSelectionLB->set_size_request(nWidth, nHeight);
+
+ //enable 'active' language selection
+ m_xFormatLB->SetShowLanguageControl(true);
+
+ const SfxUnoAnyItem* pItem = pCoreSet
+ ? pCoreSet->GetItem(FN_FIELD_DIALOG_DOC_PROPS, false)
+ : nullptr;
+ if ( pItem )
+ pItem->GetValue() >>= m_xCustomPropertySet;
+
+ // uitests
+ m_pTypeView->set_buildable_name("type-docinf");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-docinf");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-docinf");
+}
+
+SwFieldDokInfPage::~SwFieldDokInfPage()
+{
+}
+
+void SwFieldDokInfPage::Reset(const SfxItemSet* )
+{
+ Init(); // general initialisation
+
+ uno::Sequence<beans::Property> aCustomProperties;
+ if (m_xCustomPropertySet.is())
+ {
+ uno::Reference<beans::XPropertySetInfo> xSetInfo = m_xCustomPropertySet->getPropertySetInfo();
+ aCustomProperties = xSetInfo->getProperties();
+ }
+
+ if (aCustomProperties.hasElements())
+ {
+ m_xTypeList->hide();
+ m_xTypeList->set_buildable_name("type-list");
+ m_xTypeTree->show();
+ m_pTypeView = m_xTypeTree.get();
+ }
+ else
+ {
+ m_xTypeTree->hide();
+ m_xTypeTree->set_buildable_name("type-tree");
+ m_xTypeList->show();
+ m_pTypeView = m_xTypeList.get();
+ }
+
+ m_pTypeView->set_buildable_name("type-docinf");
+
+ // initialise TypeListBox
+ m_pTypeView->freeze();
+ m_pTypeView->clear();
+ m_xSelEntry.reset();
+
+ // display SubTypes in TypeLB
+ sal_uInt16 nSubType = USHRT_MAX;
+ if (IsFieldEdit())
+ {
+ const SwField* pCurField = GetCurField();
+ nSubType = pCurField->GetSubType() & 0xff;
+ if( nSubType == DI_CUSTOM )
+ {
+ if (auto const pField = dynamic_cast<SwDocInfoField const*>(pCurField))
+ {
+ m_sOldCustomFieldName = pField->GetName();
+ }
+ }
+ m_xFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
+ SwWrtShell *pSh = GetWrtShell();
+ if(pSh)
+ {
+ const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
+ if(pFormat)
+ m_xFormatLB->SetLanguage(pFormat->GetLanguage());
+ }
+ }
+
+ sal_Int32 nSelEntryData = -1;
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ nSelEntryData = o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx));
+ }
+
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(SwFieldTypesEnum::DocumentInfo, aLst);
+ std::unique_ptr<weld::TreeIter> xEntry(m_pTypeView->make_iterator());
+ std::unique_ptr<weld::TreeIter> xExpandEntry;
+ for(size_t i = 0; i < aLst.size(); ++i)
+ {
+ if (!IsFieldEdit() || nSubType == i)
+ {
+ const OUString sId(OUString::number(i));
+ if (DI_CUSTOM == i)
+ {
+ if(m_xCustomPropertySet.is() )
+ {
+ if (aCustomProperties.hasElements())
+ {
+ std::unique_ptr<weld::TreeIter> xInfo(m_pTypeView->make_iterator());
+
+ OUString sText(SwResId(STR_CUSTOM_FIELD));
+ OUString sEntryId(OUString::number(USHRT_MAX));
+ m_pTypeView->insert(nullptr, -1, &sText, &sEntryId, nullptr,
+ nullptr, false, xInfo.get());
+ for (const auto& rProperty : aCustomProperties)
+ {
+ const OUString sEntry = rProperty.Name;
+
+ m_pTypeView->insert(xInfo.get(), -1, &sEntry, &sId,
+ nullptr, nullptr, false, xEntry.get());
+ if (m_sOldCustomFieldName == sEntry)
+ {
+ m_xSelEntry = m_pTypeView->make_iterator(xEntry.get());
+ xExpandEntry = m_pTypeView->make_iterator(xInfo.get());
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!(IsFieldDlgHtmlMode() && (i == DI_EDIT || i == DI_SUBJECT || i == DI_PRINT)))
+ {
+ m_pTypeView->insert(nullptr, -1, &aLst[i], &sId,
+ nullptr, nullptr, false, xEntry.get());
+ }
+ }
+ if (static_cast<size_t>(nSelEntryData) == i)
+ m_xSelEntry = std::move(xEntry);
+ }
+ }
+
+ m_pTypeView->thaw();
+
+ if (xExpandEntry)
+ m_pTypeView->expand_row(*xExpandEntry);
+
+ // select old Pos
+ if (m_xSelEntry)
+ {
+ m_pTypeView->select(*m_xSelEntry);
+ nSubType = m_pTypeView->get_id(*m_xSelEntry).toUInt32();
+ }
+ else
+ {
+ m_xSelEntry = m_pTypeView->make_iterator();
+ if (m_pTypeView->get_iter_first(*m_xSelEntry))
+ nSubType = m_pTypeView->get_id(*m_xSelEntry).toUInt32();
+ else
+ m_xSelEntry.reset();
+ }
+
+ FillSelectionLB(nSubType);
+ if (m_xSelEntry)
+ TypeHdl(*m_pTypeView);
+
+ m_pTypeView->connect_changed(LINK(this, SwFieldDokInfPage, TypeHdl));
+ m_pTypeView->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldDokInfPage, SubTypeHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
+
+ if (IsFieldEdit())
+ {
+ m_nOldSel = m_xSelectionLB->get_selected_index();
+ m_nOldFormat = GetCurField()->GetFormat();
+ m_xFixedCB->save_state();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldDokInfPage, TypeHdl, weld::TreeView&, void)
+{
+ // current ListBoxPos
+ if (!m_pTypeView->get_selected(m_xSelEntry.get()) &&
+ m_pTypeView->get_iter_first(*m_xSelEntry))
+ {
+ m_pTypeView->select(*m_xSelEntry);
+ }
+ FillSelectionLB(m_pTypeView->get_id(*m_xSelEntry).toUInt32());
+ SubTypeHdl(*m_xSelectionLB);
+}
+
+IMPL_LINK_NOARG(SwFieldDokInfPage, SubTypeHdl, weld::TreeView&, void)
+{
+ sal_uInt16 nSubType = m_pTypeView->get_id(*m_xSelEntry).toUInt32();
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ sal_uInt16 nExtSubType;
+ SvNumFormatType nNewType = SvNumFormatType::ALL;
+
+ if (nSubType != DI_EDIT)
+ {
+ if (nPos == -1)
+ {
+ if (!m_xSelectionLB->n_children())
+ {
+ m_xFormatLB->clear();
+ m_xFormat->set_sensitive(false);
+ if( nSubType == DI_CUSTOM )
+ {
+ //find out which type the custom field has - for a start set to DATE format
+ const OUString sName = m_pTypeView->get_text(*m_xSelEntry);
+ try
+ {
+ uno::Any aVal = m_xCustomPropertySet->getPropertyValue( sName );
+ const uno::Type& rValueType = aVal.getValueType();
+ if( rValueType == ::cppu::UnoType<util::DateTime>::get())
+ {
+ nNewType = SvNumFormatType::DATETIME;
+ }
+ else if( rValueType == ::cppu::UnoType<util::Date>::get())
+ {
+ nNewType = SvNumFormatType::DATE;
+ }
+ else if( rValueType == ::cppu::UnoType<util::Time>::get())
+ {
+ nNewType = SvNumFormatType::TIME;
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ }
+ }
+ else
+ return;
+ }
+ nPos = 0;
+ }
+
+ nExtSubType = m_xSelectionLB->get_id(nPos).toUInt32();
+ }
+ else
+ nExtSubType = DI_SUB_TIME;
+
+ SvNumFormatType nOldType = SvNumFormatType::ALL;
+ bool bEnable = false;
+ bool bOneArea = false;
+
+ if (m_xFormatLB->get_active())
+ nOldType = m_xFormatLB->GetFormatType();
+
+ switch (nExtSubType)
+ {
+ case DI_SUB_AUTHOR:
+ break;
+
+ case DI_SUB_DATE:
+ nNewType = SvNumFormatType::DATE;
+ bOneArea = true;
+ break;
+
+ case DI_SUB_TIME:
+ nNewType = SvNumFormatType::TIME;
+ bOneArea = true;
+ break;
+ }
+ if (nNewType == SvNumFormatType::ALL)
+ {
+ m_xFormatLB->clear();
+ }
+ else
+ {
+ if (nOldType != nNewType)
+ {
+ m_xFormatLB->SetFormatType(nNewType);
+ m_xFormatLB->SetOneArea(bOneArea);
+ }
+ bEnable = true;
+ }
+
+ sal_uInt32 nFormat = 0;
+
+ sal_uInt16 nOldSubType = 0;
+
+ if (IsFieldEdit())
+ {
+ if (auto const pField = dynamic_cast<SwDocInfoField const*>(GetCurField()))
+ {
+ nFormat = pField->GetFormat();
+ nOldSubType = pField->GetSubType() & 0xff00;
+ }
+ nPos = m_xSelectionLB->get_selected_index();
+ if (nPos != -1)
+ {
+ nSubType = m_xSelectionLB->get_id(nPos).toUInt32();
+
+ nOldSubType &= ~DI_SUB_FIXED;
+ if (nOldSubType == nSubType)
+ {
+ if (!nFormat && (nNewType == SvNumFormatType::DATE || nNewType == SvNumFormatType::TIME))
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(pSh)
+ {
+ SvNumberFormatter* pFormatter = pSh->GetNumberFormatter();
+ LanguageType eLang = m_xFormatLB->GetCurLanguage();
+ if (nNewType == SvNumFormatType::DATE)
+ nFormat = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLang);
+ else if (nNewType == SvNumFormatType::TIME)
+ nFormat = pFormatter->GetFormatIndex( NF_TIME_HHMM, eLang);
+ }
+ }
+ m_xFormatLB->SetDefFormat(nFormat);
+ }
+ }
+ else if( (nSubType == DI_CUSTOM) && (nNewType != SvNumFormatType::ALL) )
+ {
+ m_xFormatLB->SetDefFormat(nFormat);
+ }
+ }
+
+ // Always allow Fixed Content to be turned off if it is currently on
+ m_xFormat->set_sensitive(bEnable || m_xFixedCB->get_active());
+
+ if (!bEnable)
+ m_xFormatLB->clear();
+ else if (m_xFormatLB->get_selected_index() == -1)
+ m_xFormatLB->select(0);
+}
+
+sal_Int32 SwFieldDokInfPage::FillSelectionLB(sal_uInt16 nSubType)
+{
+ // fill Format-Listbox
+ SwFieldTypesEnum nTypeId = SwFieldTypesEnum::DocumentInfo;
+
+ EnableInsert(nSubType != USHRT_MAX);
+
+ if (nSubType == USHRT_MAX) // Info-Text
+ nSubType = DI_SUBTYPE_BEGIN;
+
+ m_xSelectionLB->clear();
+
+ sal_uInt16 nSize = 0;
+ sal_Int32 nSelPos = -1;
+ sal_uInt16 nExtSubType = 0;
+
+ if (IsFieldEdit())
+ {
+ if (auto const pField = dynamic_cast<SwDocInfoField const*>(GetCurField()))
+ {
+ nExtSubType = pField->GetSubType() & 0xff00;
+ }
+ m_xFixedCB->set_active((nExtSubType & DI_SUB_FIXED) != 0);
+ nExtSubType = ((nExtSubType & ~DI_SUB_FIXED) >> 8) - 1;
+ }
+
+ if (nSubType < DI_CREATE || nSubType == DI_DOCNO || nSubType == DI_EDIT|| nSubType == DI_CUSTOM )
+ {
+ // Format Box is empty for Title and Time
+ }
+ else
+ {
+ nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+ for (sal_uInt16 i = 0; i < nSize; ++i)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nTypeId, i)));
+ m_xSelectionLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ if (IsFieldEdit() && i == nExtSubType)
+ nSelPos = i;
+ }
+ }
+
+ bool bEnable = nSize != 0;
+
+ if (nSize)
+ {
+ if (m_xSelectionLB->get_selected_index() == -1)
+ m_xSelectionLB->select(nSelPos == USHRT_MAX ? 0 : nSelPos);
+ bEnable = true;
+ }
+
+ m_xSelection->set_sensitive(bEnable);
+
+ return nSize;
+}
+
+bool SwFieldDokInfPage::FillItemSet(SfxItemSet* )
+{
+ if (!m_xSelEntry)
+ return false;
+
+ sal_uInt16 nSubType = m_pTypeView->get_id(*m_xSelEntry).toUInt32();
+ if (nSubType == USHRT_MAX)
+ return false;
+
+ sal_uInt32 nFormat = 0;
+
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+
+ OUString aName;
+ if (DI_CUSTOM == nSubType)
+ aName = m_pTypeView->get_text(*m_xSelEntry);
+
+ if (nPos != -1)
+ nSubType |= m_xSelectionLB->get_id(nPos).toUInt32();
+
+ if (m_xFixedCB->get_active())
+ nSubType |= DI_SUB_FIXED;
+
+ nPos = m_xFormatLB->get_selected_index();
+ if(nPos != -1)
+ nFormat = m_xFormatLB->GetFormat();
+
+ if (!IsFieldEdit() || m_nOldSel != m_xSelectionLB->get_selected_index() ||
+ m_nOldFormat != nFormat || m_xFixedCB->get_state_changed_from_saved()
+ || (DI_CUSTOM == nSubType && aName != m_sOldCustomFieldName ))
+ {
+ InsertField(SwFieldTypesEnum::DocumentInfo, nSubType, aName, OUString(), nFormat,
+ ' ', m_xFormatLB->IsAutomaticLanguage());
+ }
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldDokInfPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldDokInfPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldDokInfPage::GetGroup()
+{
+ return GRP_REG;
+}
+
+void SwFieldDokInfPage::FillUserData()
+{
+ int nEntry = m_pTypeView->get_selected_index();
+ sal_uInt16 nTypeSel = nEntry != -1 ? m_pTypeView->get_id(nEntry).toUInt32() : USHRT_MAX;
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddinf.hxx b/sw/source/ui/fldui/flddinf.hxx
new file mode 100644
index 0000000000..c3773af163
--- /dev/null
+++ b/sw/source/ui/fldui/flddinf.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDDINF_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDDINF_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <numfmtlb.hxx>
+#include "fldpage.hxx"
+
+namespace com::sun::star::beans { class XPropertySet; }
+
+class SwFieldDokInfPage : public SwFieldPage
+{
+ std::unique_ptr<weld::TreeIter> m_xSelEntry;
+ css::uno::Reference < css::beans::XPropertySet > m_xCustomPropertySet;
+
+ sal_Int32 m_nOldSel;
+ sal_uInt32 m_nOldFormat;
+ OUString m_sOldCustomFieldName;
+
+ std::unique_ptr<weld::TreeView> m_xTypeList;
+ std::unique_ptr<weld::TreeView> m_xTypeTree;
+ weld::TreeView* m_pTypeView;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<SwNumFormatTreeView> m_xFormatLB;
+ std::unique_ptr<weld::CheckButton> m_xFixedCB;
+
+ DECL_LINK(TypeHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeHdl, weld::TreeView&, void);
+
+ sal_Int32 FillSelectionLB(sal_uInt16 nSubTypeId);
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldDokInfPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ virtual ~SwFieldDokInfPage() 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 FillUserData() override;
+};
+
+void FillFieldSelect(weld::TreeView& rListBox);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddok.cxx b/sw/source/ui/fldui/flddok.cxx
new file mode 100644
index 0000000000..1a2857bedb
--- /dev/null
+++ b/sw/source/ui/fldui/flddok.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 <flddat.hxx>
+#include <docufld.hxx>
+#include <strings.hrc>
+#include <chpfld.hxx>
+#include "flddok.hxx"
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
+#include <o3tl/string_view.hxx>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldDokPage::SwFieldDokPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/flddocumentpage.ui",
+ "FieldDocumentPage", pCoreSet)
+ , m_nOldSel(0)
+ , m_nOldFormat(0)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xValueFT(m_xBuilder->weld_label("valueft"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xLevelFT(m_xBuilder->weld_label("levelft"))
+ , m_xLevelED(m_xBuilder->weld_combo_box("level"))
+ , m_xDateFT(m_xBuilder->weld_label("daysft"))
+ , m_xTimeFT(m_xBuilder->weld_label("minutesft"))
+ , m_xDateOffsetED(m_xBuilder->weld_spin_button("offset"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("numformat")))
+ , m_xFixedCB(m_xBuilder->weld_check_button("fixed"))
+{
+ m_xTypeLB->make_sorted();
+ m_xFormatLB->make_sorted();
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xSelectionLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->set_size_request(nWidth * 2, nHeight);
+
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldDokPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldDokPage, TreeViewInsertHdl));
+ m_xNumFormatLB->connect_row_activated(LINK(this, SwFieldDokPage, NumFormatHdl));
+
+ for (sal_uInt16 i = 1; i <= MAXLEVEL; i++)
+ m_xLevelED->append_text(OUString::number(i));
+
+ m_xLevelED->set_active(0);
+ m_xDateOffsetED->set_range(INT_MIN, INT_MAX);
+ //enable 'active' language selection
+ m_xNumFormatLB->SetShowLanguageControl(true);
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-doc");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-doc");
+ m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-doc");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-doc");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-doc");
+}
+
+SwFieldDokPage::~SwFieldDokPage()
+{
+}
+
+void SwFieldDokPage::Reset(const SfxItemSet* )
+{
+ SavePos(*m_xTypeLB);
+ Init(); // general initialisation
+
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ if (!IsFieldEdit())
+ {
+ bool bPage = false;
+ // fill Type-Listbox
+ for(sal_uInt16 i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::NextPage:
+ case SwFieldTypesEnum::PageNumber:
+ if (!bPage)
+ {
+ m_xTypeLB->append(OUString::number(USHRT_MAX), SwResId(FMT_REF_PAGE));
+ bPage = true;
+ }
+ break;
+
+ default:
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ break;
+ }
+ }
+ }
+ else
+ {
+ const SwField* pCurField = GetCurField();
+ SwFieldTypesEnum nTypeId = pCurField->GetTypeId();
+ if (nTypeId == SwFieldTypesEnum::FixedDate)
+ nTypeId = SwFieldTypesEnum::Date;
+ if (nTypeId == SwFieldTypesEnum::FixedTime)
+ nTypeId = SwFieldTypesEnum::Time;
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+ m_xNumFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
+ if(pFormat)
+ m_xNumFormatLB->SetLanguage(pFormat->GetLanguage());
+ }
+ }
+
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ RestorePos(*m_xTypeLB);
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldDokPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldDokPage, TypeHdl));
+ m_xFormatLB->connect_changed(LINK(this, SwFieldDokPage, FormatHdl));
+
+ if( !IsRefresh() )
+ {
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if(nVal != USHRT_MAX)
+ {
+ for (int i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; i++)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ TypeHdl(*m_xTypeLB);
+
+ if (IsFieldEdit())
+ {
+ m_nOldSel = m_xSelectionLB->get_selected_index();
+ m_nOldFormat = GetCurField()->GetFormat();
+ m_xFixedCB->save_state();
+ m_xValueED->save_value();
+ m_xLevelED->save_value();
+ m_xDateOffsetED->save_value();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldDokPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ size_t nCount;
+
+ m_xDateFT->hide();
+ m_xTimeFT->hide();
+
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ // fill Selection-Listbox
+ m_xSelectionLB->clear();
+
+ if (nTypeId != SwFieldTypesEnum::Unknown)
+ {
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(nTypeId, aLst);
+
+ if (nTypeId != SwFieldTypesEnum::Author)
+ nCount = aLst.size();
+ else
+ nCount = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ if (!IsFieldEdit())
+ {
+ OUString sId(OUString::number(i));
+ if (nTypeId != SwFieldTypesEnum::Author)
+ m_xSelectionLB->append(sId, aLst[i]);
+ else
+ m_xSelectionLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ }
+ else
+ {
+ bool bInsert = false;
+
+ OUString sId(OUString::number(i));
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Date:
+ case SwFieldTypesEnum::Time:
+ m_xSelectionLB->append(sId, aLst[i]);
+ if (static_cast<SwDateTimeField*>(GetCurField())->IsFixed() && !i)
+ m_xSelectionLB->select_id(sId);
+ if (!static_cast<SwDateTimeField*>(GetCurField())->IsFixed() && i)
+ m_xSelectionLB->select_id(sId);
+ break;
+ case SwFieldTypesEnum::ExtendedUser:
+ case SwFieldTypesEnum::DocumentStatistics:
+ m_xSelectionLB->append(sId, aLst[i]);
+ if (GetCurField()->GetSubType() == i)
+ m_xSelectionLB->select_id(sId);
+ break;
+
+ case SwFieldTypesEnum::Author:
+ {
+ const OUString sFormat(GetFieldMgr().GetFormatStr(nTypeId, i));
+ m_xSelectionLB->append(sId, sFormat);
+ m_xSelectionLB->select_text(GetFieldMgr().GetFormatStr(nTypeId, GetCurField()->GetFormat()));
+ break;
+ }
+
+ default:
+ if (aLst[i] == GetCurField()->GetPar1())
+ bInsert = true;
+ break;
+ }
+ if (bInsert)
+ {
+ m_xSelectionLB->append(sId, aLst[i]);
+ break;
+ }
+ }
+ }
+ m_xSelectionLB->connect_changed(Link<weld::TreeView&,void>());
+ }
+ else
+ {
+ AddSubType(SwFieldTypesEnum::PageNumber);
+ AddSubType(SwFieldTypesEnum::PreviousPage);
+ AddSubType(SwFieldTypesEnum::NextPage);
+ nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(0).toUInt32());
+ nCount = 3;
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldDokPage, SubTypeHdl));
+ }
+
+ bool bEnable = nCount != 0;
+
+ if (bEnable && m_xSelectionLB->get_selected_index() == -1)
+ m_xSelectionLB->select(0);
+
+ m_xSelection->set_sensitive( bEnable );
+
+ // fill Format-Listbox
+ sal_Int32 nSize = FillFormatLB(nTypeId);
+
+ bool bValue = false, bLevel = false, bNumFormat = false, bOffset = false;
+ bool bFormat = nSize != 0;
+ bool bOneArea = false;
+ bool bFixed = false;
+ SvNumFormatType nFormatType = SvNumFormatType::ALL;
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Date:
+ bFormat = bNumFormat = bOneArea = bOffset = true;
+
+ nFormatType = SvNumFormatType::DATE;
+
+ m_xDateFT->show();
+
+ m_xDateOffsetED->set_range(INT_MIN, INT_MAX); // no limit
+
+ if (IsFieldEdit())
+ m_xDateOffsetED->set_value( static_cast<SwDateTimeField*>(GetCurField())->GetOffset() / 24 / 60);
+ break;
+
+ case SwFieldTypesEnum::Time:
+ bFormat = bNumFormat = bOneArea = bOffset = true;
+
+ nFormatType = SvNumFormatType::TIME;
+
+ m_xTimeFT->show();
+
+ m_xDateOffsetED->set_range(-1440, 1440); // one day
+
+ if (IsFieldEdit())
+ m_xDateOffsetED->set_value( static_cast<SwDateTimeField*>(GetCurField())->GetOffset() );
+ break;
+
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::NextPage:
+ if (IsFieldEdit())
+ {
+ const sal_uInt16 nTmp = m_xFormatLB->get_selected_id().toUInt32();
+
+ if(SVX_NUM_CHAR_SPECIAL != nTmp)
+ {
+ sal_Int32 nOff = GetCurField()->GetPar2().toInt32();
+ if( SwFieldTypesEnum::NextPage == nTypeId && 1 != nOff )
+ m_xValueED->set_text(
+ OUString::number(nOff - 1) );
+ else if( SwFieldTypesEnum::PreviousPage == nTypeId && -1 != nOff )
+ m_xValueED->set_text(
+ OUString::number(nOff + 1) );
+ else
+ m_xValueED->set_text(OUString());
+ }
+ else
+ m_xValueED->set_text(static_cast<SwPageNumberField*>(GetCurField())->GetUserString());
+ }
+ bValue = true;
+ break;
+
+ case SwFieldTypesEnum::Chapter:
+ m_xValueFT->set_label(SwResId(STR_LEVEL));
+ if (IsFieldEdit())
+ m_xLevelED->set_active(static_cast<SwChapterField*>(GetCurField())->GetLevel(GetWrtShell()->GetLayout()));
+ bLevel = true;
+ break;
+
+ case SwFieldTypesEnum::PageNumber:
+ m_xValueFT->set_label( SwResId( STR_OFFSET ));
+ if (IsFieldEdit())
+ m_xValueED->set_text(GetCurField()->GetPar2());
+ bValue = true;
+ break;
+
+ case SwFieldTypesEnum::ExtendedUser:
+ case SwFieldTypesEnum::Author:
+ case SwFieldTypesEnum::Filename:
+ bFixed = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (bNumFormat)
+ {
+ if (IsFieldEdit())
+ {
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+
+ if (m_xNumFormatLB->GetFormatType() == (SvNumFormatType::DATE|SvNumFormatType::TIME))
+ {
+ // always set Format-Type because otherwise when date/time formats are combined,
+ // both formats would be displayed at the same time
+ m_xNumFormatLB->SetFormatType(SvNumFormatType::ALL);
+ m_xNumFormatLB->SetFormatType(nFormatType);
+ // set correct format once again
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+ }
+ }
+ else
+ m_xNumFormatLB->SetFormatType(nFormatType);
+
+ m_xNumFormatLB->SetOneArea(bOneArea);
+ }
+
+ m_xFormatLB->set_visible(!bNumFormat);
+ m_xNumFormatLB->set_visible(bNumFormat);
+
+ m_xValueFT->set_visible(bValue);
+ m_xValueED->set_visible(bValue);
+ m_xLevelFT->set_visible(bLevel);
+ m_xLevelED->set_visible(bLevel);
+ m_xDateOffsetED->set_visible(bOffset);
+ m_xFixedCB->set_visible(!bValue && !bLevel && !bOffset);
+
+ m_xFormat->set_sensitive(bFormat);
+ m_xFixedCB->set_sensitive(bFixed);
+
+ if (IsFieldEdit())
+ m_xFixedCB->set_active((GetCurField()->GetFormat() & AF_FIXED) != 0 && bFixed);
+
+ if (m_xNumFormatLB->get_selected_index() == -1)
+ m_xNumFormatLB->select(0);
+ m_xValueFT->set_sensitive(bValue || bLevel || bOffset);
+ m_xValueED->set_sensitive(bValue);
+}
+
+void SwFieldDokPage::AddSubType(SwFieldTypesEnum nTypeId)
+{
+ m_xSelectionLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldType::GetTypeStr(nTypeId));
+}
+
+IMPL_LINK_NOARG(SwFieldDokPage, SubTypeHdl, weld::TreeView&, void)
+{
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos == -1)
+ nPos = 0;
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(nPos).toUInt32());
+ FillFormatLB(nTypeId);
+
+ TranslateId pTextRes;
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Chapter:
+ pTextRes = STR_LEVEL;
+ break;
+
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::NextPage:
+ pTextRes = SVX_NUM_CHAR_SPECIAL == m_xFormatLB->get_selected_id().toUInt32()
+ ? STR_VALUE : STR_OFFSET;
+ break;
+
+ case SwFieldTypesEnum::PageNumber:
+ pTextRes = STR_OFFSET;
+ break;
+ default: break;
+ }
+
+ if (pTextRes)
+ m_xValueFT->set_label(SwResId(pTextRes));
+}
+
+sal_Int32 SwFieldDokPage::FillFormatLB(SwFieldTypesEnum nTypeId)
+{
+ // fill Format-Listbox
+ m_xFormatLB->clear();
+
+ if (nTypeId == SwFieldTypesEnum::Author)
+ return m_xFormatLB->n_children();
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ for( sal_uInt16 i = 0; i < nSize; ++i )
+ {
+ const sal_uInt16 nFormatId = GetFieldMgr().GetFormatId( nTypeId, i );
+ OUString sId(OUString::number(nFormatId));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ }
+
+ if (IsFieldEdit())
+ {
+ m_xFormatLB->select_id(OUString::number(GetCurField()->GetFormat() & ~AF_FIXED));
+ }
+ else
+ {
+ // Select default selected value for "Insert" dialog
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::PageNumber:
+ case SwFieldTypesEnum::DocumentStatistics:
+ m_xFormatLB->select_text(SwResId(FMT_NUM_PAGEDESC));
+ break;
+ default:
+ m_xFormatLB->select(0);
+ }
+ }
+
+ FormatHdl(*m_xFormatLB);
+
+ return nSize;
+}
+
+IMPL_LINK_NOARG(SwFieldDokPage, FormatHdl, weld::TreeView&, void)
+{
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if (nTypeId == SwFieldTypesEnum::Unknown)
+ {
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos == -1)
+ nPos = 0;
+
+ nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(nPos).toUInt32());
+ }
+
+ if (nTypeId != SwFieldTypesEnum::NextPage && nTypeId != SwFieldTypesEnum::PreviousPage)
+ return;
+
+ // Prev/Next - PageNumFields special treatment:
+ sal_uInt16 nTmp = m_xFormatLB->get_selected_id().toUInt32();
+ const OUString sOldText( m_xValueFT->get_label() );
+ const OUString sNewText( SwResId( SVX_NUM_CHAR_SPECIAL == nTmp ? STR_VALUE
+ : STR_OFFSET ));
+
+ if (sOldText != sNewText)
+ m_xValueFT->set_label(sNewText);
+
+ if (sOldText != m_xValueFT->get_label())
+ m_xValueED->set_text(OUString());
+}
+
+bool SwFieldDokPage::FillItemSet(SfxItemSet* )
+{
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if (nTypeId == SwFieldTypesEnum::Unknown)
+ {
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos == -1)
+ nPos = 0;
+ nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(nPos).toUInt32());
+ }
+
+ OUString aVal(m_xValueED->get_text());
+ sal_uInt32 nFormat = 0;
+ sal_uInt16 nSubType = 0;
+
+ if (m_xFormatLB->get_sensitive())
+ {
+ sal_Int32 nPos = m_xFormatLB->get_selected_index();
+ if(nPos != -1)
+ nFormat = m_xFormatLB->get_id(nPos).toUInt32();
+ }
+
+ if (m_xSelectionLB->get_sensitive())
+ {
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos != -1)
+ nSubType = m_xSelectionLB->get_id(nPos).toUInt32();
+ }
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Author:
+ nFormat = nSubType;
+ nSubType = 0;
+ [[fallthrough]];
+ case SwFieldTypesEnum::ExtendedUser:
+ nFormat |= m_xFixedCB->get_active() ? AF_FIXED : 0;
+ break;
+
+ case SwFieldTypesEnum::Filename:
+ nFormat |= m_xFixedCB->get_active() ? FF_FIXED : 0;
+ break;
+
+ case SwFieldTypesEnum::Date:
+ case SwFieldTypesEnum::Time:
+ {
+ nFormat = m_xNumFormatLB->GetFormat();
+ tools::Long nVal = static_cast< tools::Long >(m_xDateOffsetED->get_value());
+ if (nTypeId == SwFieldTypesEnum::Date)
+ aVal = OUString::number(nVal * 60 * 24);
+ else
+ aVal = OUString::number(nVal);
+ break;
+ }
+
+ case SwFieldTypesEnum::NextPage:
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::PageNumber:
+ case SwFieldTypesEnum::GetRefPage:
+ {
+ if( SVX_NUM_CHAR_SPECIAL != nFormat &&
+ (SwFieldTypesEnum::PreviousPage == nTypeId || SwFieldTypesEnum::NextPage == nTypeId))
+ {
+ sal_Int32 nVal = m_xValueED->get_text().toInt32();
+ aVal = OUString::number(nVal);
+ }
+ break;
+ }
+
+ case SwFieldTypesEnum::Chapter:
+ aVal = OUString::number(m_xLevelED->get_active());
+ break;
+
+ default:
+ break;
+ }
+
+ if (!IsFieldEdit() ||
+ m_nOldSel != m_xSelectionLB->get_selected_index() ||
+ m_nOldFormat != nFormat ||
+ m_xFixedCB->get_state_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xLevelED->get_value_changed_from_saved() ||
+ m_xDateOffsetED->get_value_changed_from_saved())
+ {
+ InsertField(nTypeId, nSubType, OUString(), aVal, nFormat, ' ', m_xNumFormatLB->IsAutomaticLanguage());
+ }
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldDokPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldDokPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldDokPage::GetGroup()
+{
+ return GRP_DOC;
+}
+
+void SwFieldDokPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddok.hxx b/sw/source/ui/fldui/flddok.hxx
new file mode 100644
index 0000000000..3192ecc0c6
--- /dev/null
+++ b/sw/source/ui/fldui/flddok.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDDOK_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDDOK_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include <numfmtlb.hxx>
+#include "fldpage.hxx"
+
+class SwFieldDokPage : public SwFieldPage
+{
+ sal_Int32 m_nOldSel;
+ sal_uInt32 m_nOldFormat;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Label> m_xValueFT;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::Label> m_xLevelFT;
+ std::unique_ptr<weld::ComboBox> m_xLevelED;
+ std::unique_ptr<weld::Label> m_xDateFT;
+ std::unique_ptr<weld::Label> m_xTimeFT;
+ std::unique_ptr<weld::SpinButton> m_xDateOffsetED;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<SwNumFormatTreeView> m_xNumFormatLB;
+ std::unique_ptr<weld::CheckButton> m_xFixedCB;
+
+ DECL_LINK(TypeHdl, weld::TreeView&, void);
+ DECL_LINK(FormatHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeHdl, weld::TreeView&, void);
+
+ void AddSubType(SwFieldTypesEnum nTypeId);
+ sal_Int32 FillFormatLB(SwFieldTypesEnum nTypeId);
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldDokPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet * pSet);
+
+ virtual ~SwFieldDokPage() 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 FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldedt.cxx b/sw/source/ui/fldui/fldedt.cxx
new file mode 100644
index 0000000000..306d864fab
--- /dev/null
+++ b/sw/source/ui/fldui/fldedt.cxx
@@ -0,0 +1,336 @@
+/* -*- 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 <config_fuzzers.h>
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/optgenrl.hxx>
+#include <docufld.hxx>
+#include <expfld.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include "flddb.hxx"
+#include "flddinf.hxx"
+#include "fldvar.hxx"
+#include "flddok.hxx"
+#include "fldfunc.hxx"
+#include "fldref.hxx"
+#include <fldedt.hxx>
+
+#include <cmdid.h>
+#include <swabstdlg.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <memory>
+#include <swuiexp.hxx>
+
+void SwFieldEditDlg::EnsureSelection(SwField *pCurField, SwFieldMgr &rMgr)
+{
+ if (m_pSh->CursorInsideInputField())
+ {
+ // move cursor to start of Input Field
+ SwInputField* pInputField = dynamic_cast<SwInputField*>(pCurField);
+ if (pInputField && pInputField->GetFormatField())
+ {
+ m_pSh->GotoField( *(pInputField->GetFormatField()) );
+ }
+ else
+ {
+ SwSetExpField *const pSetField(dynamic_cast<SwSetExpField*>(pCurField));
+ if (pSetField)
+ {
+ assert(pSetField->GetFormatField());
+ m_pSh->GotoField( *(pSetField->GetFormatField()) );
+ }
+ else
+ {
+ assert(!"what input field is this");
+ }
+ }
+ }
+
+ /* Only create selection if there is none already.
+ Normalize PaM instead of swapping. */
+ if (!m_pSh->HasSelection())
+ {
+ SwShellCursor* pCursor = m_pSh->getShellCursor(true);
+ SwPosition aOrigPos(*pCursor->GetPoint());
+
+ //After this attempt it is possible that rMgr.GetCurField() != pCurField if
+ //the field was in e.g. a zero height portion and so invisible in which
+ //case it will be skipped over
+ m_pSh->Right(SwCursorSkipMode::Chars, true, 1, false );
+ //So (fdo#50640) if it didn't work then reposition back to the original
+ //location where the field was
+ SwField *pRealCurField = rMgr.GetCurField();
+ bool bSelectionFailed = pCurField != pRealCurField;
+ if (bSelectionFailed)
+ {
+ pCursor->DeleteMark();
+ *pCursor->GetPoint() = aOrigPos;
+ }
+ }
+
+ m_pSh->NormalizePam();
+
+ assert(pCurField == rMgr.GetCurField());
+}
+
+SwFieldEditDlg::SwFieldEditDlg(SwView const & rVw)
+ : SfxSingleTabDialogController(rVw.GetViewFrame().GetFrameWeld(), nullptr,
+ "modules/swriter/ui/editfielddialog.ui", "EditFieldDialog")
+ , m_pSh(rVw.GetWrtShellPtr())
+ , m_xPrevBT(m_xBuilder->weld_button("prev"))
+ , m_xNextBT(m_xBuilder->weld_button("next"))
+ , m_xAddressBT(m_xBuilder->weld_button("edit"))
+{
+ SwFieldMgr aMgr(m_pSh);
+
+ SwField *pCurField = aMgr.GetCurField();
+ if (!pCurField)
+ return;
+
+ SwViewShell::SetCareDialog(m_xDialog);
+
+ EnsureSelection(pCurField, aMgr);
+
+ sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
+
+ CreatePage(nGroup);
+
+ GetOKButton().connect_clicked(LINK(this, SwFieldEditDlg, OKHdl));
+
+ m_xPrevBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
+ m_xNextBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
+
+ m_xAddressBT->connect_clicked(LINK(this, SwFieldEditDlg, AddressHdl));
+
+ Init();
+}
+
+// initialise controls
+void SwFieldEditDlg::Init()
+{
+ SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
+ if (pTabPage)
+ {
+ SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
+
+ SwField *pCurField = rMgr.GetCurField();
+
+ if(!pCurField)
+ return;
+
+ // Traveling only when more than one field
+ m_pSh->StartAction();
+ m_pSh->ClearMark();
+ m_pSh->CreateCursor();
+
+ bool bMove = rMgr.GoNext();
+ if( bMove )
+ rMgr.GoPrev();
+ m_xNextBT->set_sensitive(bMove);
+
+ bMove = rMgr.GoPrev();
+ if( bMove )
+ rMgr.GoNext();
+ m_xPrevBT->set_sensitive( bMove );
+
+ if (pCurField->GetTypeId() == SwFieldTypesEnum::ExtendedUser)
+ m_xAddressBT->set_sensitive(true);
+ else
+ m_xAddressBT->set_sensitive(false);
+
+ m_pSh->DestroyCursor();
+ m_pSh->EndAction();
+ }
+
+ GetOKButton().set_sensitive(!m_pSh->IsReadOnlyAvailable() ||
+ !m_pSh->HasReadonlySel());
+}
+
+SfxTabPage* SwFieldEditDlg::CreatePage(sal_uInt16 nGroup)
+{
+ // create TabPage
+ std::unique_ptr<SfxTabPage> xTabPage;
+
+ switch (nGroup)
+ {
+ case GRP_DOC:
+ xTabPage = SwFieldDokPage::Create(get_content_area(), this, nullptr);
+ break;
+ case GRP_FKT:
+ xTabPage = SwFieldFuncPage::Create(get_content_area(), this, nullptr);
+ break;
+ case GRP_REF:
+ xTabPage = SwFieldRefPage::Create(get_content_area(), this, nullptr);
+ break;
+ case GRP_REG:
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ auto pSet = new SfxItemSetFixed<FN_FIELD_DIALOG_DOC_PROPS, FN_FIELD_DIALOG_DOC_PROPS>( pDocSh->GetPool() );
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocSh->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ uno::Reference< beans::XPropertySet > xUDProps(
+ xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ pSet->Put( SfxUnoAnyItem( FN_FIELD_DIALOG_DOC_PROPS, uno::Any(xUDProps) ) );
+ xTabPage = SwFieldDokInfPage::Create(get_content_area(), this, pSet);
+ }
+ break;
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ case GRP_DB:
+ xTabPage = SwFieldDBPage::Create(get_content_area(), this, nullptr);
+ static_cast<SwFieldDBPage*>(xTabPage.get())->SetWrtShell(*m_pSh);
+ break;
+#endif
+ case GRP_VAR:
+ xTabPage = SwFieldVarPage::Create(get_content_area(), this, nullptr);
+ break;
+
+ }
+
+ assert(xTabPage);
+
+ static_cast<SwFieldPage*>(xTabPage.get())->SetWrtShell(m_pSh);
+ SetTabPage(std::move(xTabPage));
+
+ return GetTabPage();
+}
+
+SwFieldEditDlg::~SwFieldEditDlg()
+{
+ SwViewShell::SetCareDialog(nullptr);
+ m_pSh->EnterStdMode();
+}
+
+void SwFieldEditDlg::EnableInsert(bool bEnable)
+{
+ if( bEnable && m_pSh->IsReadOnlyAvailable() && m_pSh->HasReadonlySel() )
+ bEnable = false;
+ GetOKButton().set_sensitive(bEnable);
+}
+
+void SwFieldEditDlg::InsertHdl()
+{
+ GetOKButton().clicked();
+}
+
+// kick off changing of the field
+IMPL_LINK_NOARG(SwFieldEditDlg, OKHdl, weld::Button&, void)
+{
+ if (GetOKButton().get_sensitive())
+ {
+ SfxTabPage* pTabPage = GetTabPage();
+ if (pTabPage)
+ pTabPage->FillItemSet(nullptr);
+ m_xDialog->response(RET_OK);
+ }
+}
+
+short SwFieldEditDlg::run()
+{
+ // without TabPage no dialog
+ return GetTabPage() ? SfxSingleTabDialogController::run() : static_cast<short>(RET_CANCEL);
+}
+
+// Traveling between fields of the same type
+IMPL_LINK(SwFieldEditDlg, NextPrevHdl, weld::Button&, rButton, void)
+{
+ bool bNext = &rButton == m_xNextBT.get();
+
+ m_pSh->EnterStdMode();
+
+ SwFieldType *pOldTyp = nullptr;
+ SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
+
+ //#112462# FillItemSet may delete the current field
+ //that's why it has to be called before accessing the current field
+ if (GetOKButton().get_sensitive())
+ pTabPage->FillItemSet(nullptr);
+
+ SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
+ SwField *pCurField = rMgr.GetCurField();
+ if (pCurField->GetTypeId() == SwFieldTypesEnum::Database)
+ pOldTyp = pCurField->GetTyp();
+
+ rMgr.GoNextPrev( bNext, pOldTyp );
+ pCurField = rMgr.GetCurField();
+
+ sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
+
+ if (nGroup != pTabPage->GetGroup())
+ pTabPage = static_cast<SwFieldPage*>(CreatePage(nGroup));
+
+ pTabPage->EditNewField();
+
+ Init();
+ EnsureSelection(pCurField, rMgr);
+}
+
+IMPL_LINK_NOARG(SwFieldEditDlg, AddressHdl, weld::Button&, void)
+{
+ SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
+ SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
+ SwField *pCurField = rMgr.GetCurField();
+
+ SfxItemSetFixed<SID_FIELD_GRABFOCUS, SID_FIELD_GRABFOCUS> aSet( m_pSh->GetAttrPool() );
+
+ EditPosition nEditPos = EditPosition::UNKNOWN;
+
+ switch(pCurField->GetSubType())
+ {
+ case EU_FIRSTNAME: nEditPos = EditPosition::FIRSTNAME; break;
+ case EU_NAME: nEditPos = EditPosition::LASTNAME; break;
+ case EU_SHORTCUT: nEditPos = EditPosition::SHORTNAME; break;
+ case EU_COMPANY: nEditPos = EditPosition::COMPANY; break;
+ case EU_STREET: nEditPos = EditPosition::STREET; break;
+ case EU_TITLE: nEditPos = EditPosition::TITLE; break;
+ case EU_POSITION: nEditPos = EditPosition::POSITION; break;
+ case EU_PHONE_PRIVATE:nEditPos = EditPosition::TELPRIV; break;
+ case EU_PHONE_COMPANY:nEditPos = EditPosition::TELCOMPANY; break;
+ case EU_FAX: nEditPos = EditPosition::FAX; break;
+ case EU_EMAIL: nEditPos = EditPosition::EMAIL; break;
+ case EU_COUNTRY: nEditPos = EditPosition::COUNTRY; break;
+ case EU_ZIP: nEditPos = EditPosition::PLZ; break;
+ case EU_CITY: nEditPos = EditPosition::CITY; break;
+ case EU_STATE: nEditPos = EditPosition::STATE; break;
+
+ default: nEditPos = EditPosition::UNKNOWN; break;
+
+ }
+ aSet.Put(SfxUInt16Item(SID_FIELD_GRABFOCUS, static_cast<sal_uInt16>(nEditPos)));
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+
+ ScopedVclPtr<SfxAbstractDialog> pDlg(rFact.CreateSwAddressAbstractDlg(m_xDialog.get(), aSet));
+ if (RET_OK == pDlg->Execute())
+ {
+ m_pSh->UpdateOneField(*pCurField);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldfunc.cxx b/sw/source/ui/fldui/fldfunc.cxx
new file mode 100644
index 0000000000..6447c375e5
--- /dev/null
+++ b/sw/source/ui/fldui/fldfunc.cxx
@@ -0,0 +1,611 @@
+/* -*- 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 <swtypes.hxx>
+#include <strings.hrc>
+#include <fldbas.hxx>
+#include <docufld.hxx>
+#include <wrtsh.hxx>
+#include <swmodule.hxx>
+#include "fldfunc.hxx"
+#include "flddinf.hxx"
+#include <flddropdown.hxx>
+#include <o3tl/string_view.hxx>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+using namespace ::com::sun::star;
+
+SwFieldFuncPage::SwFieldFuncPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/fldfuncpage.ui", "FieldFuncPage", pCoreSet)
+ , m_nOldFormat(0)
+ , m_bDropDownLBChanged(false)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xNameFT(m_xBuilder->weld_label("nameft"))
+ , m_xNameED(new ConditionEdit(m_xBuilder->weld_entry("condFunction")))
+ , m_xValueGroup(m_xBuilder->weld_widget("valuegroup"))
+ , m_xValueFT(m_xBuilder->weld_label("valueft"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xCond1FT(m_xBuilder->weld_label("cond1ft"))
+ , m_xCond1ED(new ConditionEdit(m_xBuilder->weld_entry("cond1")))
+ , m_xCond2FT(m_xBuilder->weld_label("cond2ft"))
+ , m_xCond2ED(new ConditionEdit(m_xBuilder->weld_entry("cond2")))
+ , m_xMacroBT(m_xBuilder->weld_button("macro"))
+ , m_xListGroup(m_xBuilder->weld_widget("listgroup"))
+ , m_xListItemED(m_xBuilder->weld_entry("item"))
+ , m_xListAddPB(m_xBuilder->weld_button("add"))
+ , m_xListItemsLB(m_xBuilder->weld_tree_view("listitems"))
+ , m_xListRemovePB(m_xBuilder->weld_button("remove"))
+ , m_xListUpPB(m_xBuilder->weld_button("up"))
+ , m_xListDownPB(m_xBuilder->weld_button("down"))
+ , m_xListNameED(m_xBuilder->weld_entry("listname"))
+{
+ FillFieldSelect(*m_xSelectionLB);
+ FillFieldSelect(*m_xFormatLB);
+ m_xListItemsLB->set_size_request(m_xListItemED->get_preferred_size().Width(),
+ m_xListItemsLB->get_height_rows(5));
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->set_size_request(nWidth, nHeight);
+
+ m_xNameED->connect_changed(LINK(this, SwFieldFuncPage, ModifyHdl));
+
+ m_sOldValueFT = m_xValueFT->get_label();
+ m_sOldNameFT = m_xNameFT->get_label();
+
+ m_xCond1ED->ShowBrackets(false);
+ m_xCond2ED->ShowBrackets(false);
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-func");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-func");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-func");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-func");
+}
+
+SwFieldFuncPage::~SwFieldFuncPage()
+{
+}
+
+void SwFieldFuncPage::Reset(const SfxItemSet* )
+{
+ SavePos(*m_xTypeLB);
+ Init(); // general initialisation
+
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ if (!IsFieldEdit())
+ {
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ // fill Typ-Listbox
+ for(sal_uInt16 i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+ else
+ {
+ const SwFieldTypesEnum nTypeId = GetCurField()->GetTypeId();
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+
+ if (nTypeId == SwFieldTypesEnum::Macro)
+ {
+ GetFieldMgr().SetMacroPath(GetCurField()->GetPar1());
+ }
+ }
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldFuncPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldFuncPage, TypeHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldFuncPage, SelectHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldFuncPage, InsertMacroHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldFuncPage, TreeViewInsertHdl));
+ m_xMacroBT->connect_clicked(LINK(this, SwFieldFuncPage, MacroHdl));
+ Link<weld::Button&,void> aListModifyLk( LINK(this, SwFieldFuncPage, ListModifyButtonHdl));
+ m_xListAddPB->connect_clicked(aListModifyLk);
+ m_xListRemovePB->connect_clicked(aListModifyLk);
+ m_xListUpPB->connect_clicked(aListModifyLk);
+ m_xListDownPB->connect_clicked(aListModifyLk);
+ m_xListItemED->connect_activate(LINK(this, SwFieldFuncPage, ListModifyReturnActionHdl));
+ Link<weld::Entry&,void> aListEnableLk = LINK(this, SwFieldFuncPage, ListEnableHdl);
+ m_xListItemED->connect_changed(aListEnableLk);
+ m_xListItemsLB->connect_changed(LINK(this, SwFieldFuncPage, ListEnableListBoxHdl));
+
+ int nSelect = -1;
+ if( !IsRefresh() )
+ {
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if(o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if(nVal != USHRT_MAX)
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ nSelect = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ m_xTypeLB->thaw();
+ if (nSelect != -1)
+ m_xTypeLB->select(nSelect);
+ else
+ {
+ // select old Pos
+ RestorePos(*m_xTypeLB);
+ }
+ TypeHdl(*m_xTypeLB);
+
+ if (IsFieldEdit())
+ {
+ m_xNameED->save_value();
+ m_xValueED->save_value();
+ m_xCond1ED->save_value();
+ m_xCond2ED->save_value();
+ m_nOldFormat = GetCurField()->GetFormat();
+ }
+}
+
+const TranslateId FMT_MARK_ARY[] =
+{
+ FMT_MARK_TEXT,
+ FMT_MARK_TABLE,
+ FMT_MARK_FRAME,
+ FMT_MARK_GRAFIC,
+ FMT_MARK_OLE
+};
+
+IMPL_LINK_NOARG(SwFieldFuncPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ // fill Selection-Listbox
+ UpdateSubType();
+
+ // fill Format-Listbox
+ m_xFormatLB->clear();
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ m_xFormatLB->append(OUString::number(GetFieldMgr().GetFormatId(nTypeId, i)),
+ GetFieldMgr().GetFormatStr(nTypeId, i));
+ }
+
+ if (nSize)
+ {
+ if (IsFieldEdit() && nTypeId == SwFieldTypesEnum::JumpEdit)
+ m_xFormatLB->select_text(SwResId(FMT_MARK_ARY[GetCurField()->GetFormat()]));
+
+ if (m_xFormatLB->get_selected_index() == -1)
+ m_xFormatLB->select(0);
+ }
+
+ bool bValue = false, bName = false, bMacro = false, bInsert = true;
+ bool bFormat = nSize != 0;
+
+ // two controls for conditional text
+ bool bDropDown = SwFieldTypesEnum::Dropdown == nTypeId;
+ bool bCondTextField = SwFieldTypesEnum::ConditionalText == nTypeId;
+
+ m_xCond1FT->set_visible(!bDropDown && bCondTextField);
+ m_xCond1ED->set_visible(!bDropDown && bCondTextField);
+ m_xCond2FT->set_visible(!bDropDown && bCondTextField);
+ m_xCond2ED->set_visible(!bDropDown && bCondTextField);
+ m_xValueGroup->set_visible(!bDropDown && !bCondTextField);
+ m_xMacroBT->set_visible(!bDropDown);
+ m_xNameED->set_visible(!bDropDown);
+ m_xNameFT->set_visible(!bDropDown);
+
+ m_xListGroup->set_visible(bDropDown);
+
+ m_xNameED->SetDropEnable(false);
+
+ if (IsFieldEdit())
+ {
+ if(bDropDown)
+ {
+ const SwDropDownField* pDrop = static_cast<const SwDropDownField*>(GetCurField());
+ const uno::Sequence<OUString> aItems = pDrop->GetItemSequence();
+ m_xListItemsLB->clear();
+ for (const OUString& rItem : aItems)
+ m_xListItemsLB->append_text(rItem);
+ m_xListItemsLB->select_text(pDrop->GetSelectedItem());
+ m_xListNameED->set_text(pDrop->GetPar2());
+ m_xListNameED->save_value();
+ m_bDropDownLBChanged = false;
+ }
+ else
+ {
+ m_xNameED->set_text(GetCurField()->GetPar1());
+ m_xValueED->set_text(GetCurField()->GetPar2());
+ }
+ }
+ else
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+ if(bDropDown)
+ ListEnableHdl(*m_xListItemED);
+
+ if (m_xNameFT->get_label() != m_sOldNameFT)
+ m_xNameFT->set_label(m_sOldNameFT);
+ if (m_xValueFT->get_label() != m_sOldValueFT)
+ m_xValueFT->set_label(m_sOldValueFT);
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Macro:
+ bMacro = true;
+ if (!GetFieldMgr().GetMacroPath().isEmpty())
+ bValue = true;
+ else
+ bInsert = false;
+
+ m_xNameFT->set_label(SwResId(STR_MACNAME));
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+ m_xNameED->set_text(GetFieldMgr().GetMacroName());
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::HiddenParagraph:
+ m_xNameFT->set_label(SwResId(STR_COND));
+ m_xNameED->SetDropEnable(true);
+ bName = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::HiddenText:
+ {
+ m_xNameFT->set_label(SwResId(STR_COND));
+ m_xNameED->SetDropEnable(true);
+ m_xValueFT->set_label(SwResId(STR_INSTEXT));
+ SwWrtShell* pSh = GetActiveWrtShell();
+ if (!IsFieldEdit() && pSh)
+ m_xValueED->set_text(pSh->GetSelText());
+ bName = bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ }
+ break;
+
+ case SwFieldTypesEnum::ConditionalText:
+ m_xNameFT->set_label(SwResId(STR_COND));
+ m_xNameED->SetDropEnable(true);
+ if (IsFieldEdit())
+ {
+ sal_Int32 nIdx{ 0 };
+ m_xCond1ED->set_text(GetCurField()->GetPar2().getToken(0, '|', nIdx));
+ m_xCond2ED->set_text(GetCurField()->GetPar2().getToken(0, '|', nIdx));
+ }
+
+ bName = bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::JumpEdit:
+ m_xNameFT->set_label(SwResId(STR_JUMPEDITFLD));
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+ bName = bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::Input:
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+ bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::CombinedChars:
+ {
+ m_xNameFT->set_label(SwResId(STR_COMBCHRS_FT));
+ m_xNameED->SetDropEnable(true);
+ bName = true;
+
+ const sal_Int32 nLen = m_xNameED->get_text().getLength();
+ if( !nLen || nLen > MAX_COMBINED_CHARACTERS )
+ bInsert = false;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ }
+ break;
+ case SwFieldTypesEnum::Dropdown :
+ break;
+ default:
+ break;
+ }
+
+ m_xSelectionLB->hide();
+
+ m_xFormat->set_sensitive(bFormat);
+ m_xNameFT->set_sensitive(bName);
+ m_xNameED->set_sensitive(bName);
+ m_xValueGroup->set_sensitive(bValue);
+ m_xMacroBT->set_sensitive(bMacro);
+
+ EnableInsert( bInsert );
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, SelectHdl, weld::TreeView&, void)
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if( SwFieldTypesEnum::Macro == nTypeId )
+ m_xNameED->set_text( m_xSelectionLB->get_selected_text() );
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, InsertMacroHdl, weld::TreeView&, bool)
+{
+ SelectHdl(*m_xSelectionLB);
+ InsertHdl(nullptr);
+ return true;
+}
+
+IMPL_LINK(SwFieldFuncPage, ListModifyButtonHdl, weld::Button&, rControl, void)
+{
+ ListModifyHdl(&rControl);
+}
+
+IMPL_LINK(SwFieldFuncPage, ListModifyReturnActionHdl, weld::Entry&, rControl, bool)
+{
+ ListModifyHdl(&rControl);
+ return true;
+}
+
+void SwFieldFuncPage::ListModifyHdl(const weld::Widget* pControl)
+{
+ if (pControl == m_xListAddPB.get() ||
+ (pControl == m_xListItemED.get() && m_xListAddPB->get_sensitive()))
+ {
+ const OUString sEntry(m_xListItemED->get_text());
+ m_xListItemsLB->append_text(sEntry);
+ m_xListItemsLB->select_text(sEntry);
+ }
+ else if (m_xListItemsLB->get_selected_index() != -1)
+ {
+ sal_Int32 nSelPos = m_xListItemsLB->get_selected_index();
+ if (pControl == m_xListRemovePB.get())
+ {
+ m_xListItemsLB->remove(nSelPos);
+ m_xListItemsLB->select(nSelPos ? nSelPos - 1 : 0);
+ }
+ else if (pControl == m_xListUpPB.get())
+ {
+ if(nSelPos)
+ {
+ const OUString sEntry = m_xListItemsLB->get_selected_text();
+ m_xListItemsLB->remove(nSelPos);
+ nSelPos--;
+ m_xListItemsLB->insert_text(nSelPos, sEntry);
+ m_xListItemsLB->select(nSelPos);
+ }
+ }
+ else if (pControl == m_xListDownPB.get())
+ {
+ if( nSelPos < m_xListItemsLB->n_children() - 1)
+ {
+ const OUString sEntry = m_xListItemsLB->get_selected_text();
+ m_xListItemsLB->remove(nSelPos);
+ nSelPos++;
+ m_xListItemsLB->insert_text(nSelPos, sEntry);
+ m_xListItemsLB->select(nSelPos);
+ }
+ }
+ }
+ m_bDropDownLBChanged = true;
+ ListEnableHdl(*m_xListItemED);
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, ListEnableListBoxHdl, weld::TreeView&, void)
+{
+ ListEnableHdl(*m_xListItemED);
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, ListEnableHdl, weld::Entry&, void)
+{
+ //enable "Add" button when text is in the Edit that's not already member of the box
+ m_xListAddPB->set_sensitive(!m_xListItemED->get_text().isEmpty() &&
+ -1 == m_xListItemsLB->find_text(m_xListItemED->get_text()));
+ bool bEnableButtons = m_xListItemsLB->get_selected_index() != -1;
+ m_xListRemovePB->set_sensitive(bEnableButtons);
+ m_xListUpPB->set_sensitive(bEnableButtons && (m_xListItemsLB->get_selected_index() > 0));
+ m_xListDownPB->set_sensitive(bEnableButtons &&
+ (m_xListItemsLB->get_selected_index() < (m_xListItemsLB->n_children() - 1)));
+}
+
+// renew types in SelectionBox
+void SwFieldFuncPage::UpdateSubType()
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ // fill Selection-Listbox
+ m_xSelectionLB->freeze();
+ m_xSelectionLB->clear();
+
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(nTypeId, aLst);
+ const size_t nCount = aLst.size();
+
+ for (size_t i = 0; i < nCount; ++i)
+ m_xSelectionLB->append(OUString::number(i), aLst[i]);
+ m_xSelectionLB->thaw();
+
+ bool bEnable = nCount != 0;
+
+ m_xSelectionLB->set_sensitive( bEnable );
+
+ if (bEnable)
+ m_xSelectionLB->select(0);
+
+ if (nTypeId == SwFieldTypesEnum::Macro)
+ {
+ const bool bHasMacro = !GetFieldMgr().GetMacroPath().isEmpty();
+
+ if (bHasMacro)
+ {
+ m_xNameED->set_text(GetFieldMgr().GetMacroName());
+ m_xValueGroup->set_sensitive(true);
+ }
+ EnableInsert(bHasMacro);
+ }
+}
+
+// call MacroBrowser, fill Listbox with Macros
+IMPL_LINK_NOARG( SwFieldFuncPage, MacroHdl, weld::Button&, void)
+{
+ if (GetFieldMgr().ChooseMacro(GetFrameWeld()))
+ UpdateSubType();
+}
+
+bool SwFieldFuncPage::FillItemSet(SfxItemSet* )
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ sal_uInt16 nSubType = 0;
+
+ const sal_Int32 nEntryPos = m_xFormatLB->get_selected_index();
+ const sal_uInt32 nFormat = (nEntryPos == -1)
+ ? 0 : m_xFormatLB->get_id(nEntryPos).toUInt32();
+
+ OUString aVal(m_xValueED->get_text());
+ OUString aName(m_xNameED->get_text());
+
+ switch(nTypeId)
+ {
+ case SwFieldTypesEnum::Input:
+ nSubType = INP_TXT;
+ // to prevent removal of CR/LF restore old content
+ if (!m_xNameED->get_value_changed_from_saved() && IsFieldEdit())
+ aName = GetCurField()->GetPar1();
+
+ break;
+
+ case SwFieldTypesEnum::Macro:
+ // use the full script URL, not the name in the Edit control
+ aName = GetFieldMgr().GetMacroPath();
+ break;
+
+ case SwFieldTypesEnum::ConditionalText:
+ aVal = m_xCond1ED->get_text() + "|" + m_xCond2ED->get_text();
+ break;
+ case SwFieldTypesEnum::Dropdown :
+ {
+ aName = m_xListNameED->get_text();
+ for (sal_Int32 i = 0, nEntryCount = m_xListItemsLB->n_children(); i < nEntryCount; ++i)
+ {
+ if(i)
+ aVal += OUStringChar(DB_DELIM);
+ aVal += m_xListItemsLB->get_text(i);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!IsFieldEdit() ||
+ m_xNameED->get_value_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xCond1ED->get_value_changed_from_saved() ||
+ m_xCond2ED->get_value_changed_from_saved() ||
+ m_xListNameED->get_value_changed_from_saved() ||
+ m_bDropDownLBChanged ||
+ m_nOldFormat != nFormat)
+ {
+ InsertField( nTypeId, nSubType, aName, aVal, nFormat );
+ }
+
+ ModifyHdl(m_xNameED->get_widget()); // enable/disable Insert if applicable
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldFuncPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldFuncPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldFuncPage::GetGroup()
+{
+ return GRP_FKT;
+}
+
+void SwFieldFuncPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX
+ : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, ModifyHdl, weld::Entry&, void)
+{
+ const sal_Int32 nLen = m_xNameED->get_text().getLength();
+
+ bool bEnable = true;
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if( SwFieldTypesEnum::CombinedChars == nTypeId &&
+ (!nLen || nLen > MAX_COMBINED_CHARACTERS ))
+ bEnable = false;
+
+ EnableInsert( bEnable );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldfunc.hxx b/sw/source/ui/fldui/fldfunc.hxx
new file mode 100644
index 0000000000..9fef98d256
--- /dev/null
+++ b/sw/source/ui/fldui/fldfunc.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDFUNC_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDFUNC_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include <condedit.hxx>
+#include "fldpage.hxx"
+
+class SwFieldFuncPage : public SwFieldPage
+{
+ OUString m_sOldValueFT;
+ OUString m_sOldNameFT;
+
+ sal_uInt32 m_nOldFormat;
+ bool m_bDropDownLBChanged;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<weld::Label> m_xNameFT;
+ std::unique_ptr<ConditionEdit> m_xNameED;
+ std::unique_ptr<weld::Widget> m_xValueGroup;
+ std::unique_ptr<weld::Label> m_xValueFT;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::Label> m_xCond1FT;
+ std::unique_ptr<ConditionEdit> m_xCond1ED;
+ std::unique_ptr<weld::Label> m_xCond2FT;
+ std::unique_ptr<ConditionEdit> m_xCond2ED;
+ std::unique_ptr<weld::Button> m_xMacroBT;
+
+ //controls of "Input list"
+ std::unique_ptr<weld::Widget> m_xListGroup;
+ std::unique_ptr<weld::Entry> m_xListItemED;
+ std::unique_ptr<weld::Button> m_xListAddPB;
+ std::unique_ptr<weld::TreeView> m_xListItemsLB;
+ std::unique_ptr<weld::Button> m_xListRemovePB;
+ std::unique_ptr<weld::Button> m_xListUpPB;
+ std::unique_ptr<weld::Button> m_xListDownPB;
+ std::unique_ptr<weld::Entry> m_xListNameED;
+
+ DECL_LINK( TypeHdl, weld::TreeView&, void );
+ DECL_LINK( SelectHdl, weld::TreeView&, void );
+ DECL_LINK( InsertMacroHdl, weld::TreeView&, bool );
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( ListModifyReturnActionHdl, weld::Entry&, bool );
+ DECL_LINK( ListModifyButtonHdl, weld::Button&, void );
+ DECL_LINK( ListEnableHdl, weld::Entry&, void );
+ DECL_LINK( ListEnableListBoxHdl, weld::TreeView&, void );
+ void ListModifyHdl(const weld::Widget*);
+
+ // select Macro
+ DECL_LINK( MacroHdl, weld::Button&, void );
+
+ void UpdateSubType();
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldFuncPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ virtual ~SwFieldFuncPage() 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 FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldpage.cxx b/sw/source/ui/fldui/fldpage.cxx
new file mode 100644
index 0000000000..7e7f5ade3b
--- /dev/null
+++ b/sw/source/ui/fldui/fldpage.cxx
@@ -0,0 +1,350 @@
+/* -*- 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 <svl/stritem.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <dbfld.hxx>
+#include <flddat.hxx>
+#include <fmtfld.hxx>
+#include <viewopt.hxx>
+#include <fldedt.hxx>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <expfld.hxx>
+#include <fldtdlg.hxx>
+#include "fldpage.hxx"
+#include <docufld.hxx>
+#include <cmdid.h>
+#include <sfx2/bindings.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+
+// note: pAttrSet may be null if the dialog is restored on startup
+SwFieldPage::SwFieldPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription,
+ const OUString& rID, const SfxItemSet *pAttrSet)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, pAttrSet)
+ , m_pCurField(nullptr)
+ , m_pWrtShell(nullptr)
+ , m_nTypeSel(-1)
+ , m_nSelectionSel(-1)
+ , m_bFieldEdit(false)
+ , m_bInsert(true)
+ , m_bFieldDlgHtmlMode(false)
+ , m_bRefresh(false)
+ , m_bFirstHTMLInit(true)
+{
+}
+
+SwFieldPage::~SwFieldPage()
+{
+}
+
+// initialise TabPage
+void SwFieldPage::Init()
+{
+ SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
+ bool bNewMode = 0 != (::GetHtmlMode(pDocSh) & HTMLMODE_ON);
+
+ m_bFieldEdit = nullptr == dynamic_cast<SwFieldDlg*>(GetDialogController());
+
+ // newly initialise FieldManager. important for
+ // Dok-Switch (fldtdlg:ReInitTabPage)
+ m_pCurField = m_aMgr.GetCurField();
+
+ if( bNewMode == m_bFieldDlgHtmlMode )
+ return;
+
+ m_bFieldDlgHtmlMode = bNewMode;
+
+ // initialise Rangelistbox
+ if( !(m_bFieldDlgHtmlMode && m_bFirstHTMLInit) )
+ return;
+
+ m_bFirstHTMLInit = false;
+ SwWrtShell *pSh = m_pWrtShell;
+ if(! pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwDoc* pDoc = pSh->GetDoc();
+ pSh->InsertFieldType( SwSetExpFieldType( pDoc,
+ "HTML_ON", 1));
+ pSh->InsertFieldType( SwSetExpFieldType(pDoc,
+ "HTML_OFF", 1));
+ }
+}
+
+// newly initialise page
+void SwFieldPage::Activate()
+{
+ EnableInsert(m_bInsert);
+}
+
+// complete reset; edit new field
+void SwFieldPage::EditNewField( bool bOnlyActivate )
+{
+ if (!bOnlyActivate)
+ m_nTypeSel = -1;
+ m_nSelectionSel = -1;
+ m_bRefresh = true;
+ Reset(nullptr);
+ m_bRefresh = false;
+}
+
+// insert field
+void SwFieldPage::InsertField(SwFieldTypesEnum nTypeId, sal_uInt16 nSubType, const OUString& rPar1,
+ const OUString& rPar2, sal_uInt32 nFormatId,
+ sal_Unicode cSeparator, bool bIsAutomaticLanguage)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+
+ SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : pView->GetWrtShellPtr();
+ if (!pSh)
+ return;
+
+ if (!IsFieldEdit()) // insert new field
+ {
+ SwInsertField_Data aData(nTypeId, nSubType, rPar1, rPar2, nFormatId, nullptr, cSeparator, bIsAutomaticLanguage );
+ //#i26566# provide parent for SwWrtShell::StartInputFieldDlg
+ aData.m_pParent = &GetDialogController()->GetOKButton();
+ m_aMgr.InsertField( aData );
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ pView->GetViewFrame().GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ bool bRecordDB = SwFieldTypesEnum::Database == nTypeId ||
+ SwFieldTypesEnum::DatabaseSetNumber == nTypeId ||
+ SwFieldTypesEnum::DatabaseNumberSet == nTypeId ||
+ SwFieldTypesEnum::DatabaseNextSet == nTypeId ||
+ SwFieldTypesEnum::DatabaseName == nTypeId ;
+
+ SfxRequest aReq(pView->GetViewFrame(),
+ bRecordDB ? FN_INSERT_DBFIELD : FN_INSERT_FIELD);
+ if(bRecordDB)
+ {
+ sal_Int32 nIdx{ 0 };
+ aReq.AppendItem(SfxStringItem
+ (FN_INSERT_DBFIELD,rPar1.getToken(0, DB_DELIM, nIdx)));
+ aReq.AppendItem(SfxStringItem
+ (FN_PARAM_1,rPar1.getToken(0, DB_DELIM, nIdx)));
+ aReq.AppendItem(SfxInt32Item
+ (TypedWhichId<SfxInt32Item>(FN_PARAM_3), o3tl::toInt32(o3tl::getToken(rPar1, 0, DB_DELIM, nIdx))));
+ aReq.AppendItem(SfxStringItem
+ (FN_PARAM_2,rPar1.getToken(0, DB_DELIM, nIdx)));
+ }
+ else
+ {
+ aReq.AppendItem(SfxStringItem(FN_INSERT_FIELD, rPar1));
+ aReq.AppendItem(SfxStringItem
+ (FN_PARAM_3, OUString(cSeparator)));
+ aReq.AppendItem(SfxUInt16Item(FN_PARAM_FIELD_SUBTYPE, nSubType));
+ }
+ aReq.AppendItem(SfxUInt16Item(FN_PARAM_FIELD_TYPE , static_cast<sal_uInt16>(nTypeId)));
+ aReq.AppendItem(SfxStringItem(FN_PARAM_FIELD_CONTENT, rPar2));
+ aReq.AppendItem(SfxUInt32Item(FN_PARAM_FIELD_FORMAT , nFormatId));
+ aReq.Done();
+ }
+
+ }
+ else // change field
+ {
+ std::unique_ptr<SwField> pTmpField = m_pCurField->CopyField();
+
+ OUString sPar1(rPar1);
+ OUString sPar2(rPar2);
+ switch( nTypeId )
+ {
+ case SwFieldTypesEnum::Date:
+ case SwFieldTypesEnum::Time:
+ nSubType = static_cast< sal_uInt16 >(((nTypeId == SwFieldTypesEnum::Date) ? DATEFLD : TIMEFLD) |
+ ((nSubType == DATE_VAR) ? 0 : FIXEDFLD));
+ break;
+
+ case SwFieldTypesEnum::DatabaseName:
+ case SwFieldTypesEnum::DatabaseNextSet:
+ case SwFieldTypesEnum::DatabaseNumberSet:
+ case SwFieldTypesEnum::DatabaseSetNumber:
+ {
+ sal_Int32 nPos = 0;
+ SwDBData aData;
+
+ aData.sDataSource = rPar1.getToken(0, DB_DELIM, nPos);
+ aData.sCommand = rPar1.getToken(0, DB_DELIM, nPos);
+ aData.nCommandType = o3tl::toInt32(o3tl::getToken(rPar1, 0, DB_DELIM, nPos));
+ sPar1 = rPar1.copy(nPos);
+
+ static_cast<SwDBNameInfField*>(pTmpField.get())->SetDBData(aData);
+ }
+ break;
+
+ case SwFieldTypesEnum::Database:
+ {
+ SwDBData aData;
+ sal_Int32 nIdx{ 0 };
+ aData.sDataSource = rPar1.getToken(0, DB_DELIM, nIdx);
+ aData.sCommand = rPar1.getToken(0, DB_DELIM, nIdx);
+ aData.nCommandType = o3tl::toInt32(o3tl::getToken(rPar1, 0, DB_DELIM, nIdx));
+ OUString sColumn = rPar1.getToken(0, DB_DELIM, nIdx);
+
+ auto pOldType = static_cast<SwDBFieldType*>(pTmpField->GetTyp());
+ auto pType = static_cast<SwDBFieldType*>(pSh->InsertFieldType(SwDBFieldType(pSh->GetDoc(), sColumn, aData)));
+ if(auto pFormatField = pOldType->FindFormatForField(m_pCurField))
+ {
+ pFormatField->RegisterToFieldType(*pType);
+ pTmpField->ChgTyp(pType);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::Sequence:
+ {
+ SwSetExpFieldType* pTyp = static_cast<SwSetExpFieldType*>(pTmpField->GetTyp());
+ pTyp->SetOutlineLvl( static_cast< sal_uInt8 >(nSubType & 0xff));
+ pTyp->SetDelimiter(OUString(cSeparator));
+
+ nSubType = nsSwGetSetExpType::GSE_SEQ;
+ }
+ break;
+
+ case SwFieldTypesEnum::Input:
+ {
+ // User- or SetField ?
+ if (m_aMgr.GetFieldType(SwFieldIds::User, sPar1) == nullptr &&
+ !(pTmpField->GetSubType() & INP_TXT)) // SETEXPFLD
+ {
+ SwSetExpField* pField = static_cast<SwSetExpField*>(pTmpField.get());
+ pField->SetPromptText(sPar2);
+ sPar2 = pField->GetPar2();
+ }
+ }
+ break;
+ case SwFieldTypesEnum::DocumentInfo:
+ {
+ if( nSubType == nsSwDocInfoSubType::DI_CUSTOM )
+ {
+ SwDocInfoField* pDocInfo = static_cast<SwDocInfoField*>( pTmpField.get() );
+ pDocInfo->SetName( rPar1 );
+ }
+ }
+ break;
+ default: break;
+ }
+
+ pSh->StartAllAction();
+
+ pTmpField->SetSubType(nSubType);
+ pTmpField->SetAutomaticLanguage(bIsAutomaticLanguage);
+
+ m_aMgr.UpdateCurField( nFormatId, sPar1, sPar2, std::move(pTmpField) );
+
+ m_pCurField = m_aMgr.GetCurField();
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::HiddenText:
+ case SwFieldTypesEnum::HiddenParagraph:
+ m_aMgr.EvalExpFields(pSh);
+ break;
+ default: break;
+ }
+
+ pSh->SetUndoNoResetModified();
+ pSh->EndAllAction();
+ }
+}
+
+void SwFieldPage::SavePos( const weld::TreeView& rLst1 )
+{
+ if (rLst1.n_children())
+ m_aLstStrArr[ 0 ] = rLst1.get_selected_text();
+ else
+ m_aLstStrArr[ 0 ].clear();
+ m_aLstStrArr[ 1 ].clear();
+ m_aLstStrArr[ 2 ].clear();
+}
+
+void SwFieldPage::RestorePos(weld::TreeView& rLst1)
+{
+ sal_Int32 nPos = 0;
+ if (rLst1.n_children() && !m_aLstStrArr[ 0 ].isEmpty() &&
+ -1 != ( nPos = rLst1.find_text(m_aLstStrArr[ 0 ] ) ) )
+ rLst1.select( nPos );
+}
+
+// Insert new fields
+IMPL_LINK( SwFieldPage, TreeViewInsertHdl, weld::TreeView&, rBox, bool )
+{
+ InsertHdl(&rBox);
+ return true;
+}
+
+void SwFieldPage::InsertHdl(weld::Widget* pBtn)
+{
+ if (SwFieldDlg *pDlg = dynamic_cast<SwFieldDlg*>(GetDialogController()))
+ {
+ pDlg->InsertHdl();
+
+ if (pBtn)
+ pBtn->grab_focus(); // because of InputField-Dlg
+ }
+ else
+ {
+ SwFieldEditDlg *pEditDlg = static_cast<SwFieldEditDlg*>(GetDialogController());
+ pEditDlg->InsertHdl();
+ }
+}
+
+// enable/disable "Insert"-Button
+void SwFieldPage::EnableInsert(bool bEnable)
+{
+ if (SwFieldDlg *pDlg = dynamic_cast<SwFieldDlg*>(GetDialogController()))
+ {
+ if (pDlg->GetCurTabPage() == this)
+ pDlg->EnableInsert(bEnable);
+ }
+ else
+ {
+ SwFieldEditDlg *pEditDlg = static_cast<SwFieldEditDlg*>(GetDialogController());
+ pEditDlg->EnableInsert(bEnable);
+ }
+
+ m_bInsert = bEnable;
+}
+
+IMPL_LINK_NOARG(SwFieldPage, NumFormatHdl, weld::TreeView&, bool)
+{
+ InsertHdl(nullptr);
+ return true;
+}
+
+void SwFieldPage::SetWrtShell( SwWrtShell* pShell )
+{
+ m_pWrtShell = pShell;
+ m_aMgr.SetWrtShell( pShell );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldpage.hxx b/sw/source/ui/fldui/fldpage.hxx
new file mode 100644
index 0000000000..fbfa8cf2ba
--- /dev/null
+++ b/sw/source/ui/fldui/fldpage.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDPAGE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <fldmgr.hxx>
+
+#define FIELD_COLUMN_WIDTH 19
+
+const int coLBCount = 3;
+
+class SwFieldPage : public SfxTabPage
+{
+ OUString m_aLstStrArr[ coLBCount ];
+ SwFieldMgr m_aMgr;
+ SwField *m_pCurField;
+ SwWrtShell* m_pWrtShell;
+ sal_Int32 m_nTypeSel;
+ sal_Int32 m_nSelectionSel;
+ bool m_bFieldEdit;
+ bool m_bInsert;
+ bool m_bFieldDlgHtmlMode;
+ bool m_bRefresh;
+ bool m_bFirstHTMLInit;
+
+protected:
+
+ sal_Int32 GetTypeSel() const { return m_nTypeSel;}
+ void SetTypeSel(sal_Int32 nSet) { m_nTypeSel = nSet;}
+ sal_Int32 GetSelectionSel() const { return m_nSelectionSel;}
+ void SetSelectionSel(sal_Int32 nSet){ m_nSelectionSel = nSet;}
+ bool IsFieldDlgHtmlMode() const { return m_bFieldDlgHtmlMode;}
+ bool IsRefresh() const { return m_bRefresh;}
+ SwField* GetCurField() { return m_pCurField;}
+ SwWrtShell* GetWrtShell() { return m_pWrtShell;}
+
+ DECL_LINK( TreeViewInsertHdl, weld::TreeView&, bool );
+ DECL_LINK( NumFormatHdl, weld::TreeView&, bool );
+ void InsertHdl(weld::Widget*);
+
+ void Init();
+ void SavePos( const weld::TreeView& rLst1);
+ void RestorePos( weld::TreeView& rLst1 );
+ void EnableInsert(bool bEnable);
+ bool IsFieldEdit() const { return m_bFieldEdit; }
+
+ // insert field
+ void InsertField(SwFieldTypesEnum nTypeId,
+ sal_uInt16 nSubType,
+ const OUString& rPar1,
+ const OUString& rPar2,
+ sal_uInt32 nFormatId,
+ sal_Unicode cDelim = ' ',
+ bool bIsAutomaticLanguage = true);
+
+public:
+ SwFieldPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription,
+ const OUString& rID, const SfxItemSet *pAttrSet);
+
+ virtual ~SwFieldPage() override;
+
+ virtual void Activate() override;
+
+ SwFieldMgr& GetFieldMgr() { return m_aMgr; }
+ void SetWrtShell( SwWrtShell* m_pWrtShell );
+ void EditNewField( bool bOnlyActivate = false );
+ virtual sal_uInt16 GetGroup() = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
new file mode 100644
index 0000000000..a08715c8ca
--- /dev/null
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -0,0 +1,1239 @@
+/* -*- 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 <swtypes.hxx>
+#include <IMark.hxx>
+#include <expfld.hxx>
+#include <swmodule.hxx>
+#include "fldref.hxx"
+#include <frmatr.hxx>
+#include <reffld.hxx>
+#include <wrtsh.hxx>
+
+#include <fldref.hrc>
+#include <strings.hrc>
+#include <SwNodeNum.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <unotools/charclass.hxx>
+#include <osl/diagnose.h>
+
+#include <comphelper/string.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <vcl/settings.hxx>
+
+
+static sal_uInt16 nFieldDlgFormatSel = 0;
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+namespace {
+
+enum FMT_REF_IDX
+{
+ FMT_REF_PAGE_IDX = 0,
+ FMT_REF_CHAPTER_IDX = 1,
+ FMT_REF_TEXT_IDX = 2,
+ FMT_REF_UPDOWN_IDX = 3,
+ FMT_REF_PAGE_PGDSC_IDX = 4,
+ FMT_REF_ONLYNUMBER_IDX = 5,
+ FMT_REF_ONLYCAPTION_IDX = 6,
+ FMT_REF_ONLYSEQNO_IDX = 7,
+ FMT_REF_NUMBER_IDX = 8,
+ FMT_REF_NUMBER_NO_CONTEXT_IDX = 9,
+ FMT_REF_NUMBER_FULL_CONTEXT_IDX = 10
+};
+
+}
+
+SwFieldRefPage::SwFieldRefPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet )
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/fldrefpage.ui", "FieldRefPage", pCoreSet)
+ , mpSavedSelectedTextNode(nullptr)
+ , mnSavedSelectedPos(0)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xSelectionToolTipLB(m_xBuilder->weld_tree_view("selecttip"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xNameFT(m_xBuilder->weld_label("nameft"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xFilterED(m_xBuilder->weld_entry("filter"))
+ , m_xStylerefFlags(m_xBuilder->weld_widget("stylerefflagsframe"))
+ , m_xStylerefFromBottomCB(m_xBuilder->weld_check_button("stylereffrombottomcheckbox"))
+ , m_xStylerefHideNonNumericalCB(m_xBuilder->weld_check_button("stylerefhidenonnumericalcheckbox"))
+{
+ m_xSelectionLB->make_sorted();
+ // #i83479#
+ for (auto const& aID : FLD_REF_PAGE_TYPES)
+ {
+ m_xTypeLB->append_text(SwResId(aID));
+ m_xFormatLB->append_text(SwResId(aID));
+ }
+
+ m_sBookmarkText = m_xTypeLB->get_text(0);
+ m_sFootnoteText = m_xTypeLB->get_text(1);
+ m_sEndnoteText = m_xTypeLB->get_text(2);
+ // #i83479#
+ m_sHeadingText = m_xTypeLB->get_text(3);
+ m_sNumItemText = m_xTypeLB->get_text(4);
+ m_sStyleText = m_xTypeLB->get_text(5);
+
+ auto nHeight = m_xTypeLB->get_height_rows(8);
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ m_xTypeLB->set_size_request(nWidth * 1.33, nHeight);
+ m_xFormatLB->set_size_request(nWidth * 1.33, nHeight);
+ m_xSelection->set_size_request(nWidth * 2, nHeight);
+ nHeight = m_xTypeLB->get_height_rows(8);
+ m_xSelectionToolTipLB->set_size_request(nHeight, nWidth*2);
+
+ m_xTypeLB->clear();
+
+ m_xNameED->connect_changed(LINK(this, SwFieldRefPage, ModifyHdl));
+ m_xFilterED->connect_changed( LINK( this, SwFieldRefPage, ModifyHdl_Impl ) );
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldRefPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldRefPage, TypeHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldRefPage, SubTypeListBoxHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldRefPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldRefPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_changed(LINK(this, SwFieldRefPage, FormatHdl));
+
+ // #i83479#
+ m_xSelectionToolTipLB->connect_changed( LINK(this, SwFieldRefPage, SubTypeTreeListBoxHdl) );
+ m_xSelectionToolTipLB->connect_row_activated( LINK(this, SwFieldRefPage, TreeViewInsertHdl) );
+ m_xFilterED->grab_focus();
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-ref");
+ m_xNameED->set_buildable_name(m_xNameED->get_buildable_name() + "-ref");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-ref");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-ref");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-ref");
+}
+
+SwFieldRefPage::~SwFieldRefPage()
+{
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, ModifyHdl_Impl, weld::Entry&, void)
+{
+ UpdateSubType(comphelper::string::strip(m_xFilterED->get_text(), ' '));
+ // tdf#135938 - refresh cross-reference name after filter selection has changed
+ SubTypeHdl();
+}
+
+// #i83479#
+void SwFieldRefPage::SaveSelectedTextNode()
+{
+ mpSavedSelectedTextNode = nullptr;
+ mnSavedSelectedPos = 0;
+ if ( !m_xSelectionToolTipLB->get_visible() )
+ return;
+
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ const sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ if ( nTypeId == REFFLDFLAG_HEADING )
+ {
+ mnSavedSelectedPos = m_xSelectionToolTipLB->get_id(nEntry).toUInt32();
+ if ( mnSavedSelectedPos < maOutlineNodes.size() )
+ {
+ mpSavedSelectedTextNode = maOutlineNodes[mnSavedSelectedPos];
+ }
+ }
+ else if ( nTypeId == REFFLDFLAG_NUMITEM )
+ {
+ mnSavedSelectedPos = m_xSelectionToolTipLB->get_id(nEntry).toUInt32();
+ if ( mnSavedSelectedPos < maNumItems.size() )
+ {
+ mpSavedSelectedTextNode = maNumItems[mnSavedSelectedPos]->GetTextNode();
+ }
+ }
+}
+
+void SwFieldRefPage::Reset(const SfxItemSet* )
+{
+ if (!IsFieldEdit())
+ {
+ SavePos(*m_xTypeLB);
+ // #i83479#
+ SaveSelectedTextNode();
+ }
+ SetSelectionSel(-1);
+ SetTypeSel(-1);
+ Init(); // general initialisation
+
+ // initialise TypeListBox
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ // fill Type-Listbox
+
+ // set/insert reference
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ for (short i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+
+ if (!IsFieldEdit() || nTypeId != SwFieldTypesEnum::SetRef)
+ {
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+
+ // #i83479#
+ // entries for headings and numbered items
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_HEADING), m_sHeadingText);
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_NUMITEM), m_sNumItemText);
+
+ // fill up with the sequence types
+ SwWrtShell *pSh = GetWrtShell();
+ if (!pSh)
+ pSh = ::GetActiveWrtShell();
+ if (!pSh)
+ return;
+
+ // tdf#148432 in LTR UI override the navigator treeview direction based on
+ // the first page directionality
+ if (!AllSettings::GetLayoutRTL())
+ {
+ const SwPageDesc& rDesc = pSh->GetPageDesc(0);
+ const SvxFrameDirectionItem& rFrameDir = rDesc.GetMaster().GetFrameDir();
+ m_xSelectionToolTipLB->set_direction(rFrameDir.GetValue() == SvxFrameDirection::Horizontal_RL_TB);
+ }
+
+ const size_t nFieldTypeCnt = pSh->GetFieldTypeCount(SwFieldIds::SetExp);
+
+ OSL_ENSURE( nFieldTypeCnt < o3tl::make_unsigned(REFFLDFLAG), "<SwFieldRefPage::Reset> - Item index will overlap flags!" );
+
+ for (size_t n = 0; n < nFieldTypeCnt; ++n)
+ {
+ SwSetExpFieldType* pType = static_cast<SwSetExpFieldType*>(pSh->GetFieldType(n, SwFieldIds::SetExp));
+
+ if ((nsSwGetSetExpType::GSE_SEQ & pType->GetType()) && pType->HasWriterListeners() && pSh->IsUsed(*pType))
+ {
+ m_xTypeLB->append(OUString::number(REFFLDFLAG | n), pType->GetName());
+ }
+ }
+
+ // text marks - now always (because of globaldocuments)
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_BOOKMARK), m_sBookmarkText);
+
+ // footnotes:
+ if( pSh->HasFootnotes() )
+ {
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_FOOTNOTE), m_sFootnoteText);
+ }
+
+ // endnotes:
+ if ( pSh->HasFootnotes(true) )
+ {
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_ENDNOTE), m_sEndnoteText);
+ }
+
+ // stylerefs
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_STYLE), m_sStyleText);
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ if (!IsFieldEdit())
+ RestorePos(*m_xTypeLB);
+
+ nFieldDlgFormatSel = 0;
+
+ sal_uInt16 nFormatBoxPosition = USHRT_MAX;
+ if( !IsRefresh() )
+ {
+ sal_Int32 nIdx{ 0 };
+ const OUString sUserData = GetUserData();
+ if(!IsRefresh() && o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx),
+ u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if(nVal != USHRT_MAX)
+ {
+ for(sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ if (nIdx>=0 && nIdx<sUserData.getLength())
+ {
+ nFormatBoxPosition = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ }
+ }
+ }
+ }
+ TypeHdl(*m_xTypeLB);
+ if (!IsFieldEdit() && nFormatBoxPosition < m_xFormatLB->n_children())
+ {
+ m_xFormatLB->select(nFormatBoxPosition);
+ }
+ if (IsFieldEdit())
+ {
+ m_xTypeLB->save_value();
+ m_xSelectionLB->save_value();
+ m_xFormatLB->save_value();
+ m_xNameED->save_value();
+ m_xValueED->save_value();
+ m_xFilterED->set_text(OUString());
+ m_xStylerefFromBottomCB->save_state();
+ m_xStylerefHideNonNumericalCB->save_state();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ if (IsFieldEdit())
+ {
+ // select positions
+ OUString sName;
+ sal_uInt16 nFlag = 0;
+
+ switch( GetCurField()->GetSubType() )
+ {
+ case REF_BOOKMARK:
+ {
+ // #i83479#
+ SwGetRefField* pRefField = dynamic_cast<SwGetRefField*>(GetCurField());
+ if ( pRefField &&
+ pRefField->IsRefToHeadingCrossRefBookmark() )
+ {
+ sName = m_sHeadingText;
+ nFlag = REFFLDFLAG_HEADING;
+ }
+ else if ( pRefField &&
+ pRefField->IsRefToNumItemCrossRefBookmark() )
+ {
+ sName = m_sNumItemText;
+ nFlag = REFFLDFLAG_NUMITEM;
+ }
+ else
+ {
+ sName = m_sBookmarkText;
+ nFlag = REFFLDFLAG_BOOKMARK;
+ }
+ }
+ break;
+
+ case REF_FOOTNOTE:
+ sName = m_sFootnoteText;
+ nFlag = REFFLDFLAG_FOOTNOTE;
+ break;
+
+ case REF_ENDNOTE:
+ sName = m_sEndnoteText;
+ nFlag = REFFLDFLAG_ENDNOTE;
+ break;
+
+ case REF_SETREFATTR:
+ sName = SwResId(STR_GETREFFLD);
+ nFlag = REF_SETREFATTR;
+ break;
+
+ case REF_SEQUENCEFLD:
+ {
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+ if (pRefField)
+ {
+ sName = pRefField->GetSetRefName();
+ }
+ nFlag = REFFLDFLAG;
+ break;
+ }
+
+ case REF_STYLE:
+ {
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+ if (pRefField)
+ {
+ sName = pRefField->GetPar1();
+ }
+ nFlag = REFFLDFLAG_STYLE;
+ break;
+ }
+ }
+
+ if (m_xTypeLB->find_text(sName) == -1) // reference to deleted mark
+ {
+ m_xTypeLB->append(OUString::number(nFlag), sName);
+ }
+
+ m_xTypeLB->select_text(sName);
+ SetTypeSel(m_xTypeLB->get_selected_index());
+ }
+ else
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ bool bName = false;
+ nFieldDlgFormatSel = 0;
+
+ if ( ( !IsFieldEdit() || m_xSelectionLB->n_children() ) &&
+ nOld != -1 )
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ m_xFilterED->set_text(OUString());
+ }
+
+ // fill selection-ListBox
+ UpdateSubType(comphelper::string::strip(m_xFilterED->get_text(), ' '));
+
+ switch (nTypeId)
+ {
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ if (nOld != -1 && REFFLDFLAG & m_xTypeLB->get_id(nOld).toUInt32())
+ // the old one stays
+ nFieldDlgFormatSel = m_xFormatLB->get_selected_index();
+ bName = true;
+ break;
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef):
+ bName = true;
+ break;
+
+ case REFFLDFLAG_BOOKMARK:
+ bName = true;
+ [[fallthrough]];
+ default:
+ if( REFFLDFLAG & nTypeId )
+ {
+ const sal_uInt16 nOldId = nOld != -1 ? m_xTypeLB->get_id(nOld).toUInt32() : 0;
+ if( nOldId & REFFLDFLAG || nOldId == static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef) )
+ // then the old one stays
+ nFieldDlgFormatSel = m_xFormatLB->get_selected_index();
+ }
+ break;
+ }
+
+ m_xNameED->set_sensitive(bName);
+ m_xNameFT->set_sensitive(bName);
+
+ // fill Format-Listbox
+ sal_Int32 nSize = FillFormatLB(nTypeId);
+ bool bFormat = nSize != 0;
+ m_xFormat->set_sensitive(bFormat);
+
+ SubTypeHdl();
+ ModifyHdl(*m_xNameED);
+ ModifyHdl(*m_xFilterED);
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, SubTypeTreeListBoxHdl, weld::TreeView&, void)
+{
+ SubTypeHdl();
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, SubTypeListBoxHdl, weld::TreeView&, void)
+{
+ SubTypeHdl();
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, FormatHdl, weld::TreeView&, void)
+{
+ SubTypeHdl();
+}
+
+void SwFieldRefPage::SubTypeHdl()
+{
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ sal_uInt16 nFormat = m_xFormatLB->get_selected_id().toUInt32();
+ m_xStylerefHideNonNumericalCB->set_visible(nFormat == FMT_REF_NUMBER_IDX
+ || nFormat == FMT_REF_NUMBER_NO_CONTEXT_IDX
+ || nFormat == FMT_REF_NUMBER_FULL_CONTEXT_IDX);
+ m_xStylerefFlags->set_visible(nTypeId == REFFLDFLAG_STYLE);
+
+ switch(nTypeId)
+ {
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ if (!IsFieldEdit() || m_xSelectionLB->get_selected_index() != -1)
+ {
+ m_xNameED->set_text(m_xSelectionLB->get_selected_text());
+ ModifyHdl(*m_xNameED);
+ }
+ break;
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef):
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ m_xValueED->set_text(pSh->GetSelText());
+ }
+
+ }
+ break;
+ // #i83479#
+ case REFFLDFLAG_HEADING:
+ case REFFLDFLAG_NUMITEM:
+ {
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ if (nEntry != -1)
+ m_xNameED->set_text(m_xSelectionToolTipLB->get_text(nEntry));
+ }
+ break;
+
+ default:
+ if (!IsFieldEdit() || m_xSelectionLB->get_selected_index() != -1)
+ m_xNameED->set_text(m_xSelectionLB->get_selected_text());
+ break;
+ }
+}
+
+// renew types in SelectionLB after filtering
+void SwFieldRefPage::UpdateSubType(const OUString& filterString)
+{
+ SwWrtShell *pSh = GetWrtShell();
+ if (!pSh)
+ pSh = ::GetActiveWrtShell();
+ if (!pSh)
+ return;
+
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+ const sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ OUString sOldSel;
+ // #i83479#
+ if ( m_xSelectionLB->get_visible() )
+ {
+ const sal_Int32 nSelectionSel = m_xSelectionLB->get_selected_index();
+ if (nSelectionSel != -1)
+ sOldSel = m_xSelectionLB->get_text(nSelectionSel);
+ }
+ if (IsFieldEdit() && pRefField && sOldSel.isEmpty())
+ sOldSel = OUString::number( pRefField->GetSeqNo() + 1 );
+
+ m_xSelectionLB->freeze();
+ m_xSelectionLB->clear();
+
+ if (REFFLDFLAG & nTypeId)
+ {
+ if (nTypeId == REFFLDFLAG_FOOTNOTE || nTypeId == REFFLDFLAG_ENDNOTE)
+ {
+ m_xSelectionLB->thaw();
+ m_xSelectionLB->make_unsorted();
+ m_xSelectionLB->freeze();
+ }
+ // #i83479#
+ else if (nTypeId != REFFLDFLAG_HEADING && nTypeId != REFFLDFLAG_NUMITEM)
+ {
+ m_xSelectionLB->thaw();
+ m_xSelectionLB->make_sorted();
+ m_xSelectionLB->freeze();
+ }
+ }
+
+ // #i83479#
+ m_xSelectionToolTipLB->freeze();
+ m_xSelectionToolTipLB->clear();
+ OUString m_sSelectionToolTipLBId;
+ bool bShowSelectionToolTipLB( false );
+
+ if( REFFLDFLAG & nTypeId )
+ {
+ if (nTypeId == REFFLDFLAG_BOOKMARK) // text marks!
+ {
+ // get all text marks
+ IDocumentMarkAccess* const pMarkAccess = pSh->getIDocumentMarkAccess();
+ for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd();
+ ++ppMark)
+ {
+ const ::sw::mark::IMark* pBkmk = *ppMark;
+ if(IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(*pBkmk))
+ {
+ bool isSubstring = MatchSubstring(pBkmk->GetName(), filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( pBkmk->GetName() );
+ }
+ }
+ }
+ if (IsFieldEdit() && pRefField)
+ sOldSel = pRefField->GetSetRefName();
+ }
+ else if (nTypeId == REFFLDFLAG_FOOTNOTE)
+ {
+ SwSeqFieldList aArr;
+ const size_t nCnt = pSh->GetSeqFootnoteList( aArr );
+
+ for( size_t n = 0; n < nCnt; ++n )
+ {
+ bool isSubstring = MatchSubstring(aArr[ n ].sDlgEntry, filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( aArr[ n ].sDlgEntry );
+ }
+ if (IsFieldEdit() && pRefField && pRefField->GetSeqNo() == aArr[ n ].nSeqNo)
+ sOldSel = aArr[n].sDlgEntry;
+ }
+ }
+ else if (nTypeId == REFFLDFLAG_ENDNOTE)
+ {
+ SwSeqFieldList aArr;
+ const size_t nCnt = pSh->GetSeqFootnoteList( aArr, true );
+
+ for( size_t n = 0; n < nCnt; ++n )
+ {
+ bool isSubstring = MatchSubstring(aArr[ n ].sDlgEntry, filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( aArr[ n ].sDlgEntry );
+ }
+ if (IsFieldEdit() && pRefField && pRefField->GetSeqNo() == aArr[ n ].nSeqNo)
+ sOldSel = aArr[n].sDlgEntry;
+ }
+ }
+ // #i83479#
+ else if ( nTypeId == REFFLDFLAG_HEADING )
+ {
+ bShowSelectionToolTipLB = true;
+
+ const IDocumentOutlineNodes* pIDoc( pSh->getIDocumentOutlineNodesAccess() );
+ pIDoc->getOutlineNodes( maOutlineNodes );
+ bool bCertainTextNodeSelected( false );
+ for ( size_t nOutlIdx = 0; nOutlIdx < maOutlineNodes.size(); ++nOutlIdx )
+ {
+ if (!pIDoc->isOutlineInLayout(nOutlIdx, *pSh->GetLayout()))
+ {
+ continue; // skip it
+ }
+ bool isSubstring = MatchSubstring(pIDoc->getOutlineText(nOutlIdx, pSh->GetLayout(), true, true, false), filterString);
+ if(isSubstring)
+ {
+ OUString sId(OUString::number(nOutlIdx));
+ m_xSelectionToolTipLB->append(sId,
+ pIDoc->getOutlineText(nOutlIdx, pSh->GetLayout(), true, true, false));
+ if ((IsFieldEdit() && pRefField
+ && pRefField->GetReferencedTextNode(nullptr, nullptr) == maOutlineNodes[nOutlIdx])
+ || mpSavedSelectedTextNode == maOutlineNodes[nOutlIdx])
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ bCertainTextNodeSelected = true;
+ }
+ else if ( !bCertainTextNodeSelected && mnSavedSelectedPos == nOutlIdx )
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ }
+ }
+ }
+ }
+ else if ( nTypeId == REFFLDFLAG_NUMITEM )
+ {
+ bShowSelectionToolTipLB = true;
+
+ const IDocumentListItems* pIDoc( pSh->getIDocumentListItemsAccess() );
+ pIDoc->getNumItems( maNumItems );
+ bool bCertainTextNodeSelected( false );
+ for ( size_t nNumItemIdx = 0; nNumItemIdx < maNumItems.size(); ++nNumItemIdx )
+ {
+ if (!pIDoc->isNumberedInLayout(*maNumItems[nNumItemIdx], *pSh->GetLayout()))
+ {
+ continue; // skip it
+ }
+ bool isSubstring = MatchSubstring(pIDoc->getListItemText(*maNumItems[nNumItemIdx], *pSh->GetLayout()), filterString);
+ if(isSubstring)
+ {
+ OUString sId(OUString::number(nNumItemIdx));
+ m_xSelectionToolTipLB->append(sId,
+ pIDoc->getListItemText(*maNumItems[nNumItemIdx], *pSh->GetLayout()));
+ if ((IsFieldEdit() && pRefField
+ && pRefField->GetReferencedTextNode(nullptr, nullptr) == maNumItems[nNumItemIdx]->GetTextNode())
+ || mpSavedSelectedTextNode == maNumItems[nNumItemIdx]->GetTextNode())
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ bCertainTextNodeSelected = true;
+ }
+ else if ( !bCertainTextNodeSelected && mnSavedSelectedPos == nNumItemIdx )
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ }
+ }
+ }
+ }
+ else if (nTypeId == REFFLDFLAG_STYLE)
+ {
+ const IDocumentOutlineNodes* pIDoc(pSh->getIDocumentOutlineNodesAccess());
+ pIDoc->getOutlineNodes(maOutlineNodes);
+
+ SfxStyleSheetBasePool* pStyleSheetPool
+ = pSh->GetDoc()->GetDocShell()->GetStyleSheetPool();
+ auto stylesheetIterator
+ = pStyleSheetPool->CreateIterator(SfxStyleFamily::Para, SfxStyleSearchBits::Used);
+
+ SfxStyleSheetBase* pStyle = stylesheetIterator->First();
+ while (pStyle != nullptr)
+ {
+ bool isSubstring = MatchSubstring(pStyle->GetName(), filterString);
+
+ if (isSubstring)
+ {
+ m_xSelectionLB->append_text(pStyle->GetName());
+ }
+
+ pStyle = stylesheetIterator->Next();
+ }
+
+ if (IsFieldEdit() && pRefField) {
+ sOldSel = pRefField->GetPar1();
+ m_xStylerefFromBottomCB->set_active((pRefField->GetFlags() & REFFLDFLAG_STYLE_FROM_BOTTOM) == REFFLDFLAG_STYLE_FROM_BOTTOM);
+ m_xStylerefHideNonNumericalCB->set_active((pRefField->GetFlags() & REFFLDFLAG_STYLE_HIDE_NON_NUMERICAL) == REFFLDFLAG_STYLE_HIDE_NON_NUMERICAL);
+ }
+ }
+ else
+ {
+ // get the fields to Seq-FieldType:
+
+ SwSetExpFieldType* pType = static_cast<SwSetExpFieldType*>(pSh->GetFieldType(
+ nTypeId & ~REFFLDFLAG, SwFieldIds::SetExp ));
+ if( pType )
+ {
+ SwSeqFieldList aArr;
+ // old selection should be kept in non-edit mode
+ if(IsFieldEdit())
+ sOldSel.clear();
+
+ const size_t nCnt = pType->GetSeqFieldList(aArr, pSh->GetLayout());
+ for( size_t n = 0; n < nCnt; ++n )
+ {
+ bool isSubstring = MatchSubstring(aArr[ n ].sDlgEntry, filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( aArr[ n ].sDlgEntry );
+ }
+ if (IsFieldEdit() && pRefField && sOldSel.isEmpty() &&
+ aArr[ n ].nSeqNo == pRefField->GetSeqNo())
+ sOldSel = aArr[ n ].sDlgEntry;
+ }
+
+ if (IsFieldEdit() && pRefField && sOldSel.isEmpty())
+ sOldSel = OUString::number( pRefField->GetSeqNo() + 1);
+ }
+ }
+ }
+ else
+ {
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(static_cast<SwFieldTypesEnum>(nTypeId), aLst);
+ for(const OUString & i : aLst)
+ {
+ bool isSubstring = MatchSubstring( i , filterString );
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text(i);
+ }
+ }
+
+ if (IsFieldEdit() && pRefField)
+ sOldSel = pRefField->GetSetRefName();
+ }
+
+ // #i83479#
+ m_xSelectionLB->thaw();
+ m_xSelectionToolTipLB->thaw();
+ if (!m_sSelectionToolTipLBId.isEmpty())
+ m_xSelectionToolTipLB->select_id(m_sSelectionToolTipLBId);
+ m_xSelectionToolTipLB->set_visible( bShowSelectionToolTipLB );
+ m_xSelectionLB->set_visible( !bShowSelectionToolTipLB );
+ if ( bShowSelectionToolTipLB )
+ {
+ bool bEnable = m_xSelectionToolTipLB->n_children() != 0;
+ m_xSelection->set_sensitive( bEnable );
+
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ if (nEntry != -1)
+ m_xSelectionToolTipLB->scroll_to_row(nEntry);
+
+ if (IsFieldEdit() && nEntry == -1)
+ {
+ m_xNameED->set_text(sOldSel);
+ }
+ }
+ else
+ {
+ // enable or disable
+ bool bEnable = m_xSelectionLB->n_children() != 0;
+ m_xSelection->set_sensitive( bEnable );
+
+ if ( bEnable )
+ {
+ m_xSelectionLB->select_text(sOldSel);
+ if (m_xSelectionLB->get_selected_index() == -1 && !IsFieldEdit())
+ m_xSelectionLB->select(0);
+ }
+
+ if (IsFieldEdit() && m_xSelectionLB->get_selected_index() == -1) // in case the reference was already deleted...
+ m_xNameED->set_text(sOldSel);
+ }
+}
+
+bool SwFieldRefPage::MatchSubstring( const OUString& rListString, const OUString& rSubstr )
+{
+ if(rSubstr.isEmpty())
+ return true;
+ OUString aListString = GetAppCharClass().lowercase(rListString);
+ OUString aSubstr = GetAppCharClass().lowercase(rSubstr);
+ return aListString.indexOf(aSubstr) >= 0;
+}
+
+const TranslateId FMT_REF_ARY[] =
+{
+ FMT_REF_PAGE,
+ FMT_REF_CHAPTER,
+ FMT_REF_TEXT,
+ FMT_REF_UPDOWN,
+ FMT_REF_PAGE_PGDSC,
+ FMT_REF_ONLYNUMBER,
+ FMT_REF_ONLYCAPTION,
+ FMT_REF_ONLYSEQNO,
+ FMT_REF_NUMBER,
+ FMT_REF_NUMBER_NO_CONTEXT,
+ FMT_REF_NUMBER_FULL_CONTEXT
+};
+
+sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
+{
+ OUString sOldSel;
+
+ sal_Int32 nFormatSel = m_xFormatLB->get_selected_index();
+ if (nFormatSel != -1)
+ sOldSel = m_xFormatLB->get_text(nFormatSel);
+
+ // fill Format-Listbox
+ m_xFormatLB->clear();
+
+ // reference has less that the annotation
+ sal_uInt16 nSize( 0 );
+ sal_uInt16 nOffset( 0 );
+ bool bAddCrossRefFormats( false );
+ switch (nTypeId)
+ {
+ // #i83479#
+ case REFFLDFLAG_HEADING:
+ case REFFLDFLAG_NUMITEM:
+ bAddCrossRefFormats = true;
+ [[fallthrough]];
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ case REFFLDFLAG_BOOKMARK:
+ case REFFLDFLAG_FOOTNOTE:
+ case REFFLDFLAG_ENDNOTE:
+ nSize = FMT_REF_PAGE_PGDSC_IDX + 1;
+ break;
+ case REFFLDFLAG_STYLE:
+ nOffset = FMT_REF_TEXT_IDX;
+ nSize = FMT_REF_UPDOWN_IDX + 1 - nOffset;
+ bAddCrossRefFormats = true;
+ break;
+
+ default:
+ // #i83479#
+
+ if ( REFFLDFLAG & nTypeId )
+ {
+ nSize = FMT_REF_ONLYSEQNO_IDX + 1;
+ }
+ else
+ {
+ nSize = GetFieldMgr().GetFormatCount( static_cast<SwFieldTypesEnum>(nTypeId), IsFieldDlgHtmlMode() );
+ }
+ break;
+ }
+
+ if (REFFLDFLAG & nTypeId)
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+
+ SwFieldTypesEnum nFieldType = static_cast<SwFieldTypesEnum>(nTypeId);
+ for (sal_uInt16 i = nOffset; i < nSize + nOffset; i++)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i )));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nFieldType, i));
+ }
+ // #i83479#
+
+ sal_uInt16 nExtraSize( 0 );
+ if ( bAddCrossRefFormats )
+ {
+ sal_uInt16 nFormat = FMT_REF_NUMBER_IDX;
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat)));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr( nFieldType, nFormat ));
+ nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX;
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr( nFieldType, nFormat ));
+ nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX;
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr( nFieldType, nFormat ));
+ nExtraSize = 3;
+ }
+
+ // extra list items optionally, depending from reference-language
+ SvtSysLocaleOptions aSysLocaleOptions;
+ static const LanguageTag& rLang = aSysLocaleOptions.GetRealLanguageTag();
+
+ if (rLang.getLanguage() == "hu")
+ {
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i + SAL_N_ELEMENTS(FMT_REF_ARY))));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, i ));
+ }
+ nExtraSize += nSize;
+
+ if ( bAddCrossRefFormats )
+ {
+ sal_uInt16 nFormat = FMT_REF_NUMBER_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat)));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nExtraSize += 3;
+ }
+ // uppercase article
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i + 2 * SAL_N_ELEMENTS(FMT_REF_ARY))));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, i ));
+ }
+ nExtraSize += nSize;
+ if ( bAddCrossRefFormats )
+ {
+ sal_uInt16 nFormat = FMT_REF_NUMBER_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat)));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nExtraSize += 3;
+ }
+ }
+
+ nSize += nExtraSize;
+
+ // select a certain entry
+ if (nSize)
+ {
+ if (!IsFieldEdit())
+ m_xFormatLB->select_text(sOldSel);
+ else
+ m_xFormatLB->select_text(SwResId(FMT_REF_ARY[GetCurField()->GetFormat() % SAL_N_ELEMENTS(FMT_REF_ARY)]));
+
+ if (m_xFormatLB->get_selected_index() == -1)
+ {
+ if (nFieldDlgFormatSel < m_xFormatLB->n_children())
+ m_xFormatLB->select(nFieldDlgFormatSel);
+ else
+ m_xFormatLB->select(0);
+ }
+ }
+
+ return nSize;
+}
+
+// Modify
+IMPL_LINK_NOARG(SwFieldRefPage, ModifyHdl, weld::Entry&, void)
+{
+ OUString aName(m_xNameED->get_text());
+ const bool bEmptyName = aName.isEmpty();
+
+ bool bEnable = true;
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ if ((nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef) && !GetFieldMgr().CanInsertRefMark(aName)) ||
+ (bEmptyName && (nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef) || nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef) ||
+ nTypeId == REFFLDFLAG_BOOKMARK)))
+ bEnable = false;
+
+ EnableInsert(bEnable);
+
+ m_xSelectionLB->select_text(aName);
+}
+
+bool SwFieldRefPage::FillItemSet(SfxItemSet* )
+{
+ bool bModified = false;
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ sal_uInt16 nSubType = 0;
+ const sal_Int32 nEntryPos = m_xFormatLB->get_selected_index();
+ const sal_uInt32 nFormat = (nEntryPos == -1)
+ ? 0 : m_xFormatLB->get_id(nEntryPos).toUInt32();
+
+ OUString aVal(m_xValueED->get_text());
+ OUString aName(m_xNameED->get_text());
+
+ switch(nTypeId)
+ {
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ nSubType = REF_SETREFATTR;
+ break;
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef):
+ {
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::SetExp, aName);
+
+ if(!pType) // Only insert when the name doesn't exist yet
+ {
+ m_xSelectionLB->append_text(aName);
+ m_xSelection->set_sensitive(true);
+ }
+ break;
+ }
+ }
+
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+
+ if (pSh && REFFLDFLAG & nTypeId)
+ {
+ if (nTypeId == REFFLDFLAG_BOOKMARK) // text marks!
+ {
+ aName = m_xNameED->get_text();
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_BOOKMARK;
+ }
+ else if (REFFLDFLAG_FOOTNOTE == nTypeId) // footnotes
+ {
+ SwSeqFieldList aArr;
+ SeqFieldLstElem aElem( m_xSelectionLB->get_selected_text(), 0 );
+
+ size_t nPos = 0;
+
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_FOOTNOTE;
+ aName.clear();
+
+ if (pSh->GetSeqFootnoteList(aArr) && aArr.SeekEntry(aElem, &nPos))
+ {
+ aVal = OUString::number( aArr[nPos].nSeqNo );
+
+ if (IsFieldEdit() && pRefField && aArr[nPos].nSeqNo == pRefField->GetSeqNo())
+ bModified = true; // can happen with fields of which the references were deleted
+ }
+ else if (IsFieldEdit() && pRefField)
+ aVal = OUString::number( pRefField->GetSeqNo() );
+ }
+ else if (REFFLDFLAG_ENDNOTE == nTypeId) // endnotes
+ {
+ SwSeqFieldList aArr;
+ SeqFieldLstElem aElem( m_xSelectionLB->get_selected_text(), 0 );
+
+ size_t nPos = 0;
+
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_ENDNOTE;
+ aName.clear();
+
+ if (pSh->GetSeqFootnoteList(aArr, true) && aArr.SeekEntry(aElem, &nPos))
+ {
+ aVal = OUString::number( aArr[nPos].nSeqNo );
+
+ if (IsFieldEdit() && pRefField && aArr[nPos].nSeqNo == pRefField->GetSeqNo())
+ bModified = true; // can happen with fields of which the reference was deleted
+ }
+ else if (IsFieldEdit() && pRefField)
+ aVal = OUString::number( pRefField->GetSeqNo() );
+ }
+ // #i83479#
+ else if ( nTypeId == REFFLDFLAG_HEADING )
+ {
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ OSL_ENSURE( nEntry != -1,
+ "<SwFieldRefPage::FillItemSet(..)> - no entry selected in selection tool tip listbox!" );
+ if (nEntry != -1)
+ {
+ const size_t nOutlIdx(m_xSelectionToolTipLB->get_id(nEntry).toUInt32());
+ pSh->getIDocumentOutlineNodesAccess()->getOutlineNodes( maOutlineNodes );
+ if ( nOutlIdx < maOutlineNodes.size() )
+ {
+ ::sw::mark::IMark const * const pMark = pSh->getIDocumentMarkAccess()->getMarkForTextNode(
+ *(maOutlineNodes[nOutlIdx]),
+ IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK);
+ aName = pMark->GetName();
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_BOOKMARK;
+ }
+ }
+ }
+ else if ( nTypeId == REFFLDFLAG_NUMITEM )
+ {
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ OSL_ENSURE( nEntry != -1,
+ "<SwFieldRefPage::FillItemSet(..)> - no entry selected in selection tool tip listbox!" );
+ if (nEntry != -1)
+ {
+ const size_t nNumItemIdx(m_xSelectionToolTipLB->get_id(nEntry).toUInt32());
+ pSh->getIDocumentListItemsAccess()->getNumItems(maNumItems);
+ if ( nNumItemIdx < maNumItems.size() )
+ {
+ ::sw::mark::IMark const * const pMark = pSh->getIDocumentMarkAccess()->getMarkForTextNode(
+ *(maNumItems[nNumItemIdx]->GetTextNode()),
+ IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK);
+ aName = pMark->GetName();
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_BOOKMARK;
+ }
+ }
+ }
+ else if (nTypeId == REFFLDFLAG_STYLE)
+ {
+ int nEntry = m_xSelectionLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ aName = m_xSelectionLB->get_text(nEntry);
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_STYLE;
+ sal_uInt16 nVal = REFFLDFLAG_STYLE;
+
+ if (m_xStylerefFromBottomCB->get_active()) {
+ nVal |= REFFLDFLAG_STYLE_FROM_BOTTOM;
+ }
+
+ if (m_xStylerefHideNonNumericalCB->get_active()) {
+ nVal |= REFFLDFLAG_STYLE_HIDE_NON_NUMERICAL;
+ }
+
+ aVal = OUString::number(nVal);
+ } else {
+ SAL_WARN("sw.ui", "<SwFieldRefPage::FillItemSet(..)> no entry selected in selection listbox!");
+ }
+ }
+ else // SequenceFields
+ {
+ // get fields for Seq-FieldType:
+ SwSetExpFieldType* pType = static_cast<SwSetExpFieldType*>(pSh->GetFieldType(
+ nTypeId & ~REFFLDFLAG, SwFieldIds::SetExp ));
+ if( pType )
+ {
+ SwSeqFieldList aArr;
+ SeqFieldLstElem aElem( m_xSelectionLB->get_selected_text(), 0 );
+
+ size_t nPos = 0;
+
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_SEQUENCEFLD;
+ aName = pType->GetName();
+
+ if (pType->GetSeqFieldList(aArr, pSh->GetLayout())
+ && aArr.SeekEntry(aElem, &nPos))
+ {
+ aVal = OUString::number( aArr[nPos].nSeqNo );
+
+ if (IsFieldEdit() && pRefField && aArr[nPos].nSeqNo == pRefField->GetSeqNo())
+ bModified = true; // can happen with fields of which the reference was deleted
+ }
+ else if (IsFieldEdit() && pRefField)
+ aVal = OUString::number( pRefField->GetSeqNo() );
+ }
+ }
+ }
+
+ if (IsFieldEdit() && nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef))
+ {
+ aVal = OUString::number(nSubType) + "|" + aVal;
+ }
+
+ if (!IsFieldEdit() || bModified ||
+ m_xNameED->get_value_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xTypeLB->get_value_changed_from_saved() ||
+ m_xSelectionLB->get_value_changed_from_saved() ||
+ m_xFormatLB->get_value_changed_from_saved() ||
+ (nSubType == REF_STYLE
+ && (m_xStylerefFromBottomCB->get_state_changed_from_saved() || m_xStylerefHideNonNumericalCB->get_state_changed_from_saved())))
+ {
+ InsertField( static_cast<SwFieldTypesEnum>(nTypeId), nSubType, aName, aVal, nFormat );
+ }
+
+ ModifyHdl(*m_xNameED); // enable/disable insert if applicable
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldRefPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldRefPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldRefPage::GetGroup()
+{
+ return GRP_REF;
+}
+
+void SwFieldRefPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX
+ : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ const sal_Int32 nFormatEntryPos = m_xFormatLB->get_selected_index();
+ const sal_uInt32 nFormatSel = -1 == nFormatEntryPos ? USHRT_MAX : nFormatEntryPos;
+ SetUserData( USER_DATA_VERSION ";" +
+ OUString::number( nTypeSel ) + ";" +
+ OUString::number( nFormatSel ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldref.hxx b/sw/source/ui/fldui/fldref.hxx
new file mode 100644
index 0000000000..472d26a3c4
--- /dev/null
+++ b/sw/source/ui/fldui/fldref.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDREF_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDREF_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include "fldpage.hxx"
+#include <IDocumentOutlineNodes.hxx>
+#include <IDocumentListItems.hxx>
+class SwTextNode;
+
+class SwFieldRefPage : public SwFieldPage
+{
+ OUString m_sBookmarkText;
+ OUString m_sFootnoteText;
+ OUString m_sEndnoteText;
+ // #i83479#
+ OUString m_sHeadingText;
+ OUString m_sNumItemText;
+ OUString m_sStyleText;
+
+ IDocumentOutlineNodes::tSortedOutlineNodeList maOutlineNodes;
+ IDocumentListItems::tSortedNodeNumList maNumItems;
+
+ // selected text node in the listbox for headings and numbered items
+ // in order to restore selection after update of selection listbox
+ const SwTextNode* mpSavedSelectedTextNode;
+ // fallback, if previously selected text node doesn't exist anymore
+ size_t mnSavedSelectedPos;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ // #i83479#
+ std::unique_ptr<weld::TreeView> m_xSelectionToolTipLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<weld::Label> m_xNameFT;
+ std::unique_ptr<weld::Entry> m_xNameED;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::Entry> m_xFilterED;
+
+ std::unique_ptr<weld::Widget> m_xStylerefFlags;
+ std::unique_ptr<weld::CheckButton> m_xStylerefFromBottomCB;
+ std::unique_ptr<weld::CheckButton> m_xStylerefHideNonNumericalCB;
+
+ DECL_LINK(TypeHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeListBoxHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeTreeListBoxHdl, weld::TreeView&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(FormatHdl, weld::TreeView&, void);
+
+ void SubTypeHdl();
+
+ void UpdateSubType(const OUString& filterString);
+
+ static bool MatchSubstring( const OUString& list_string, const OUString& substr );
+
+ sal_Int32 FillFormatLB(sal_uInt16 nTypeId);
+
+ // #i83479#
+ void SaveSelectedTextNode();
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldRefPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ virtual ~SwFieldRefPage() 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 FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldtdlg.cxx b/sw/source/ui/fldui/fldtdlg.cxx
new file mode 100644
index 0000000000..8c20586167
--- /dev/null
+++ b/sw/source/ui/fldui/fldtdlg.cxx
@@ -0,0 +1,313 @@
+/* -*- 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 <config_fuzzers.h>
+
+#include <cmdid.h>
+#include <unotools/confignode.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <osl/diagnose.h>
+#include <viewopt.hxx>
+#include <chldwrap.hxx>
+#include <docsh.hxx>
+#include "flddb.hxx"
+#include "flddinf.hxx"
+#include "fldvar.hxx"
+#include "flddok.hxx"
+#include "fldfunc.hxx"
+#include "fldref.hxx"
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <fldtdlg.hxx>
+#include <swmodule.hxx>
+#include <comphelper/lok.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+// carrier of the dialog
+SwFieldDlg::SwFieldDlg(SfxBindings* pB, SwChildWinWrapper* pCW, weld::Window *pParent)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/fielddialog.ui", "FieldDialog")
+ , m_pChildWin(pCW)
+ , m_pBindings(pB)
+ , m_bDataBaseMode(false)
+ , m_bClosing(false)
+{
+ m_bHtmlMode = (::GetHtmlMode(static_cast<SwDocShell*>(SfxObjectShell::Current())) & HTMLMODE_ON) != 0;
+
+ GetCancelButton().connect_clicked(LINK(this, SwFieldDlg, CancelHdl));
+ GetOKButton().connect_clicked(LINK(this, SwFieldDlg, OKHdl));
+
+ AddTabPage("document", SwFieldDokPage::Create, nullptr);
+ AddTabPage("variables", SwFieldVarPage::Create, nullptr);
+ AddTabPage("docinfo", SwFieldDokInfPage::Create, nullptr);
+
+ if (!m_bHtmlMode)
+ {
+ AddTabPage("ref", SwFieldRefPage::Create, nullptr);
+ AddTabPage("functions", SwFieldFuncPage::Create, nullptr);
+
+ utl::OConfigurationTreeRoot aCfgRoot
+ = utl::OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(),
+ "/org.openoffice.Office.DataAccess/Policies/Features/Writer",
+ -1,
+ utl::OConfigurationTreeRoot::CM_READONLY);
+
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ bool bDatabaseFields = true;
+ aCfgRoot.getNodeValue(
+ OUString("DatabaseFields")) >>= bDatabaseFields;
+
+ if (bDatabaseFields)
+ AddTabPage("database", SwFieldDBPage::Create, nullptr);
+ else
+#endif
+ RemoveTabPage("database");
+ }
+ else
+ {
+ RemoveTabPage("ref");
+ RemoveTabPage("functions");
+ RemoveTabPage("database");
+ }
+
+ if (comphelper::LibreOfficeKit::isActive())
+ RemoveTabPage("database");
+}
+
+SwFieldDlg::~SwFieldDlg()
+{
+}
+
+void SwFieldDlg::EndDialog(int nResponse)
+{
+ m_bClosing = true;
+ SfxTabDialogController::EndDialog(nResponse);
+ m_bClosing = false;
+}
+
+void SwFieldDlg::Close()
+{
+ if (m_bClosing)
+ return;
+ const SfxPoolItemHolder aResult(m_pBindings->GetDispatcher()->
+ Execute(m_bDataBaseMode ? FN_INSERT_FIELD_DATA_ONLY : FN_INSERT_FIELD,
+ SfxCallMode::SYNCHRON|SfxCallMode::RECORD));
+ if (nullptr == aResult.getItem())
+ {
+ // If Execute action did fail for whatever reason, this means that request
+ // to close did fail or wasn't delivered to SwTextShell::ExecField().
+ // Just explicitly close dialog in this case.
+ SfxTabDialogController::EndDialog(RET_CLOSE);
+ }
+}
+
+void SwFieldDlg::Initialize(SfxChildWinInfo const *pInfo)
+{
+ OUString aWinState = pInfo->aWinState;
+ if (aWinState.isEmpty())
+ return;
+ m_xDialog->set_window_state(aWinState);
+}
+
+SfxItemSet* SwFieldDlg::CreateInputItemSet(const OUString& rID)
+{
+ SwDocShell *const pDocSh(static_cast<SwDocShell*>(SfxObjectShell::Current()));
+ if (rID == "docinfo" && pDocSh) // might not have a shell if the dialog is restored on startup
+ {
+ mxInputItemSet = std::make_unique<SfxItemSetFixed<FN_FIELD_DIALOG_DOC_PROPS, FN_FIELD_DIALOG_DOC_PROPS>>( pDocSh->GetPool() );
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocSh->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ uno::Reference< beans::XPropertySet > xUDProps(
+ xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ mxInputItemSet->Put( SfxUnoAnyItem( FN_FIELD_DIALOG_DOC_PROPS, uno::Any(xUDProps) ) );
+ return mxInputItemSet.get();
+ }
+ else
+ return nullptr;
+}
+
+// kick off inserting of new fields
+IMPL_LINK_NOARG(SwFieldDlg, OKHdl, weld::Button&, void)
+{
+ if (GetOKButton().get_sensitive())
+ {
+ SfxTabPage* pPage = GetTabPage(GetCurPageId());
+ assert(pPage);
+ pPage->FillItemSet(nullptr);
+
+ GetOKButton().grab_focus(); // because of InputField-Dlg
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldDlg, CancelHdl, weld::Button&, void)
+{
+ Close();
+}
+
+// newly initialise dialog after Doc-Switch
+void SwFieldDlg::ReInitDlg()
+{
+ SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
+ bool bNewMode = (::GetHtmlMode(pDocSh) & HTMLMODE_ON) != 0;
+
+ if (bNewMode != m_bHtmlMode)
+ {
+ if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
+ {
+ pViewFrm->GetDispatcher()->
+ Execute(FN_INSERT_FIELD, SfxCallMode::ASYNCHRON|SfxCallMode::RECORD);
+ }
+ Close();
+ }
+
+ SwView* pActiveView = ::GetActiveView();
+ if(!pActiveView)
+ return;
+ const SwWrtShell& rSh = pActiveView->GetWrtShell();
+ GetOKButton().set_sensitive(( !rSh.IsReadOnlyAvailable()
+ || !rSh.HasReadonlySel())
+ && !SwCursorShell::PosInsideInputField(*rSh.GetCursor()->GetPoint()));
+
+ ReInitTabPage(u"document");
+ ReInitTabPage(u"variables");
+ ReInitTabPage(u"docinfo");
+
+ if (!m_bHtmlMode)
+ {
+ ReInitTabPage(u"ref");
+ ReInitTabPage(u"functions");
+ ReInitTabPage(u"database");
+ }
+
+ m_pChildWin->SetOldDocShell(pDocSh);
+}
+
+// newly initialise TabPage after Doc-Switch
+void SwFieldDlg::ReInitTabPage(std::u16string_view rPageId, bool bOnlyActivate)
+{
+ SwFieldPage* pPage = static_cast<SwFieldPage*>(GetTabPage(rPageId));
+ if (pPage)
+ pPage->EditNewField( bOnlyActivate ); // newly initialise TabPage
+}
+
+// newly initialise after activation of a few TabPages
+void SwFieldDlg::Activate()
+{
+ SwView* pView = GetActiveView();
+ if( !pView )
+ return;
+
+ bool bHtmlMode = (::GetHtmlMode(static_cast<SwDocShell*>(SfxObjectShell::Current())) & HTMLMODE_ON) != 0;
+ const SwWrtShell& rSh = pView->GetWrtShell();
+ GetOKButton().set_sensitive(( !rSh.IsReadOnlyAvailable()
+ || !rSh.HasReadonlySel())
+ && !SwCursorShell::PosInsideInputField(*rSh.GetCursor()->GetPoint()));
+
+
+ ReInitTabPage(u"variables", true);
+
+ if( !bHtmlMode )
+ {
+ ReInitTabPage(u"ref", true);
+ ReInitTabPage(u"functions", true);
+ }
+}
+
+void SwFieldDlg::EnableInsert(bool bEnable)
+{
+ if( bEnable )
+ {
+ SwView* pView = ::GetActiveView();
+ if( !pView ||
+ (pView->GetWrtShell().IsReadOnlyAvailable() &&
+ pView->GetWrtShell().HasReadonlySel())
+ || SwCursorShell::PosInsideInputField(*pView->GetWrtShell().GetCursor()->GetPoint()))
+ {
+ bEnable = false;
+ }
+ }
+ GetOKButton().set_sensitive(bEnable);
+}
+
+void SwFieldDlg::InsertHdl()
+{
+ GetOKButton().clicked();
+}
+
+void SwFieldDlg::ActivateDatabasePage()
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ m_bDataBaseMode = true;
+ ShowPage("database");
+ SfxTabPage* pDBPage = GetTabPage(u"database");
+ if( pDBPage )
+ {
+ static_cast<SwFieldDBPage*>(pDBPage)->ActivateMailMergeAddress();
+ }
+ //remove all other pages
+ RemoveTabPage("document");
+ RemoveTabPage("variables");
+ RemoveTabPage("docinfo");
+ RemoveTabPage("ref");
+ RemoveTabPage("functions");
+#endif
+}
+
+void SwFieldDlg::ShowReferencePage()
+{
+ ShowPage("ref");
+}
+
+void SwFieldDlg::PageCreated(const OUString& rId, SfxTabPage& rPage)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ if (rId != "database")
+ return;
+
+ SfxDispatcher* pDispatch = m_pBindings->GetDispatcher();
+ SfxViewFrame* pViewFrame = pDispatch ? pDispatch->GetFrame() : nullptr;
+ if(pViewFrame)
+ {
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst( true, checkSfxViewShell<SwView> );
+ while(pViewShell && &pViewShell->GetViewFrame() != pViewFrame)
+ {
+ pViewShell = SfxViewShell::GetNext( *pViewShell, true, checkSfxViewShell<SwView> );
+ }
+ if(pViewShell)
+ static_cast<SwFieldDBPage&>(rPage).SetWrtShell(static_cast<SwView*>(pViewShell)->GetWrtShell());
+ }
+#else
+ (void) rId;
+ (void) rPage;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldvar.cxx b/sw/source/ui/fldui/fldvar.cxx
new file mode 100644
index 0000000000..13265523ba
--- /dev/null
+++ b/sw/source/ui/fldui/fldvar.cxx
@@ -0,0 +1,1277 @@
+/* -*- 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 <swtypes.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <usrfld.hxx>
+#include <docufld.hxx>
+#include <expfld.hxx>
+#include <ddefld.hxx>
+#include <wrtsh.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <swmodule.hxx>
+#include "fldvar.hxx"
+#include "flddinf.hxx"
+#include <calc.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
+#include <o3tl/string_view.hxx>
+#include <strings.hrc>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldVarPage::SwFieldVarPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet )
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/fldvarpage.ui", "FieldVarPage", pCoreSet)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xNameFT(m_xBuilder->weld_label("nameft"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xValueFT(m_xBuilder->weld_label("valueft"))
+ , m_xValueED(new ConditionEdit(m_xBuilder->weld_entry("value")))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("numformat")))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xChapterFrame(m_xBuilder->weld_widget("chapterframe"))
+ , m_xChapterLevelLB(m_xBuilder->weld_combo_box("level"))
+ , m_xInvisibleCB(m_xBuilder->weld_check_button("invisible"))
+ , m_xSeparatorFT(m_xBuilder->weld_label("separatorft"))
+ , m_xSeparatorED(m_xBuilder->weld_entry("separator"))
+ , m_xNewPB(m_xBuilder->weld_button("apply"))
+ , m_xDelPB(m_xBuilder->weld_button("delete"))
+ , m_nOldFormat(0)
+ , m_bInit(true)
+{
+ FillFieldSelect(*m_xTypeLB);
+ m_xSelectionLB->make_sorted();
+ FillFieldSelect(*m_xFormatLB);
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xSelectionLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->set_size_request(nWidth, nHeight/2);
+
+ m_sOldValueFT = m_xValueFT->get_label();
+ m_sOldNameFT = m_xNameFT->get_label();
+
+ for (sal_uInt16 i = 1; i <= MAXLEVEL; i++)
+ m_xChapterLevelLB->append_text(OUString::number(i));
+
+ m_xChapterLevelLB->set_active(0);
+ //enable 'active' language selection
+ m_xNumFormatLB->SetShowLanguageControl(true);
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-var");
+ m_xNameED->set_buildable_name(m_xNameED->get_buildable_name() + "-var");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-var");
+ m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-var");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-var");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-var");
+}
+
+SwFieldVarPage::~SwFieldVarPage()
+{
+}
+
+void SwFieldVarPage::Reset(const SfxItemSet* )
+{
+ SavePos(*m_xTypeLB);
+
+ Init(); // general initialisation
+
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ SwFieldTypesEnum nTypeId;
+
+ if (!IsFieldEdit())
+ {
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ for (short i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ nTypeId = SwFieldMgr::GetTypeId(i);
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+ else
+ {
+ const SwField* pCurField = GetCurField();
+ assert(pCurField && "<SwFieldVarPage::Reset(..)> - <SwField> instance missing!");
+ nTypeId = pCurField->GetTypeId();
+ if (nTypeId == SwFieldTypesEnum::SetInput)
+ nTypeId = SwFieldTypesEnum::Input;
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+ m_xNumFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
+ if(pFormat)
+ m_xNumFormatLB->SetLanguage(pFormat->GetLanguage());
+ }
+ }
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ RestorePos(*m_xTypeLB);
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldVarPage, TypeHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldVarPage, SubTypeListBoxHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldVarPage, SubTypeInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
+ m_xNumFormatLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
+ m_xNameED->connect_changed(LINK(this, SwFieldVarPage, ModifyHdl));
+ m_xValueED->connect_changed(LINK(this, SwFieldVarPage, ModifyHdl));
+ m_xNewPB->connect_clicked(LINK(this, SwFieldVarPage, TBClickHdl));
+ m_xDelPB->connect_clicked(LINK(this, SwFieldVarPage, TBClickHdl));
+ m_xChapterLevelLB->connect_changed(LINK(this, SwFieldVarPage, ChapterHdl));
+ m_xSeparatorED->connect_changed(LINK(this, SwFieldVarPage, SeparatorHdl));
+
+ if( !IsRefresh() )
+ {
+ OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if(!IsRefresh() && o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ std::u16string_view sVal = o3tl::getToken(sUserData, 0, ';', nIdx);
+ sal_uInt16 nVal = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(sVal));
+ if (USHRT_MAX != nVal)
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; i++)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ TypeHdl(*m_xTypeLB);
+
+ if (IsFieldEdit())
+ {
+ m_xSelectionLB->save_value();
+ m_xFormatLB->save_value();
+ m_nOldFormat = m_xNumFormatLB->GetFormat();
+ m_xNameED->save_value();
+ m_xValueED->save_value();
+ m_xInvisibleCB->save_state();
+ m_xChapterLevelLB->save_value();
+ m_xSeparatorED->save_value();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldVarPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld != GetTypeSel() || nOld == -1)
+ {
+ m_bInit = true;
+ if (nOld != -1)
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+
+ m_xValueED->SetDropEnable(false);
+ UpdateSubType(); // initialise selection-listboxes
+ }
+
+ m_bInit = false;
+}
+
+IMPL_LINK( SwFieldVarPage, SubTypeListBoxHdl, weld::TreeView&, rBox, void )
+{
+ SubTypeHdl(&rBox);
+}
+
+static inline sal_uInt32 lcl_getUsedNumFormat( const SwNumFormatTreeView& rNumFormatLB, bool& rbText )
+{
+ sal_uInt32 nNumberFormat = 0;
+ const sal_Int32 nNumFormatPos = rNumFormatLB.get_selected_index();
+ if (nNumFormatPos != -1)
+ {
+ nNumberFormat = rNumFormatLB.GetFormat();
+ if ((rbText = (nNumFormatPos == 0 && nNumberFormat == SAL_MAX_UINT32)))
+ nNumberFormat = 0;
+ }
+ return nNumberFormat;
+}
+
+void SwFieldVarPage::SubTypeHdl(const weld::TreeView* pBox)
+{
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ sal_Int32 nSelPos = m_xSelectionLB->get_selected_index();
+ size_t nSelData = SIZE_MAX;
+
+ if (nSelPos != -1)
+ nSelData = m_xSelectionLB->get_id(nSelPos).toUInt32();
+
+ if (IsFieldEdit() && (!pBox || m_bInit))
+ {
+ if (nTypeId != SwFieldTypesEnum::Formel)
+ m_xNameED->set_text(GetFieldMgr().GetCurFieldPar1());
+
+ m_xValueED->set_text(GetFieldMgr().GetCurFieldPar2());
+ }
+
+ if (m_xNameFT->get_label() != m_sOldNameFT)
+ m_xNameFT->set_label(m_sOldNameFT);
+ if (m_xValueFT->get_label() != m_sOldValueFT)
+ m_xValueFT->set_label(m_sOldValueFT);
+
+ FillFormatLB(nTypeId);
+
+ sal_Int32 nSize = m_xFormatLB->n_children();
+
+ bool bValue = false, bName = false, bNumFormat = false,
+ bInvisible = false, bShowChapterFrame = false;
+ bool bFormat = nSize != 0;
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User:
+ {
+ // change or create user type
+ SwUserFieldType* pType = static_cast<SwUserFieldType*>(
+ GetFieldMgr().GetFieldType(SwFieldIds::User, nSelData));
+
+ if (pType)
+ {
+ if (!IsFieldEdit())
+ {
+ if (pBox || (m_bInit && !IsRefresh())) // only when interacting via mouse
+ {
+ m_xNameED->set_text(pType->GetName());
+
+ if (pType->GetType() == UF_STRING)
+ {
+ m_xValueED->set_text(pType->GetContent());
+ m_xNumFormatLB->select(0);
+ }
+ else
+ {
+ bool bText = false;
+ const sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
+ m_xValueED->set_text(pType->GetInputOrDateTime(nNumberFormat));
+ }
+ }
+ }
+ else
+ {
+ bool bText = false;
+ const sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
+ m_xValueED->set_text(pType->GetInputOrDateTime(nNumberFormat));
+ }
+ }
+ else
+ {
+ if (pBox) // only when interacting via mouse
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+ }
+ bValue = bName = bNumFormat = bInvisible = true;
+
+ m_xValueED->SetDropEnable(true);
+ break;
+ }
+
+ case SwFieldTypesEnum::Set:
+ bValue = true;
+
+ bNumFormat = bInvisible = true;
+
+ if (!IsFieldDlgHtmlMode())
+ bName = true;
+ else
+ {
+ m_xNumFormatLB->clear();
+ m_xNumFormatLB->append(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND), SwResId(FMT_SETVAR_TEXT));
+ m_xNumFormatLB->select(0);
+ }
+ // is there a corresponding SetField
+ if (IsFieldEdit() || pBox) // only when interacting via mouse
+ {
+ if (nSelPos != -1)
+ {
+ OUString sName(m_xSelectionLB->get_selected_text());
+ m_xNameED->set_text(sName);
+
+ if (!IsFieldDlgHtmlMode())
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
+ pSh->GetFieldType(SwFieldIds::SetExp, sName));
+
+ if (pSetTyp && pSetTyp->GetType() == nsSwGetSetExpType::GSE_STRING)
+ m_xNumFormatLB->select(0); // textual
+ }
+ }
+ }
+ }
+ if (GetCurField() != nullptr && IsFieldEdit())
+ {
+ m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetInputOrDateTime());
+ }
+ m_xValueED->SetDropEnable(true);
+ break;
+
+ case SwFieldTypesEnum::Formel:
+ {
+ bValue = true;
+ bNumFormat = true;
+ m_xValueFT->set_label(SwResId(STR_FORMULA));
+ m_xValueED->SetDropEnable(true);
+ }
+ break;
+
+ case SwFieldTypesEnum::Get:
+ {
+ if (!IsFieldEdit())
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+
+ if (nSelPos != -1)
+ {
+ OUString sName(m_xSelectionLB->get_selected_text());
+ if (!IsFieldEdit())
+ m_xNameED->set_text(sName);
+
+ // is there a corresponding SetField
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
+ pSh->GetFieldType(SwFieldIds::SetExp, sName));
+
+ if(pSetTyp)
+ {
+ if (pSetTyp->GetType() & nsSwGetSetExpType::GSE_STRING) // textual?
+ bFormat = true;
+ else // numeric
+ bNumFormat = true;
+ }
+ }
+ }
+ else
+ bFormat = false;
+
+ EnableInsert(bFormat || bNumFormat);
+ }
+ break;
+
+ case SwFieldTypesEnum::Input:
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+
+ if (nSelPos != -1)
+ {
+ bValue = bNumFormat = true;
+
+ OUString sName = m_xSelectionLB->get_selected_text();
+ m_xNameED->set_text( sName );
+
+ // User- or SetField ?
+ if (!GetFieldMgr().GetFieldType(SwFieldIds::User, sName)) // SetExp
+ {
+ // is there a corresponding SetField
+ SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
+ GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName));
+
+ if(pSetTyp)
+ {
+ if (pSetTyp->GetType() == nsSwGetSetExpType::GSE_STRING) // textual?
+ {
+ m_xNumFormatLB->clear();
+ m_xNumFormatLB->append(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND), SwResId(FMT_USERVAR_TEXT));
+ m_xNumFormatLB->select(0);
+ }
+ }
+ if (GetCurField() && IsFieldEdit() && (!pBox || m_bInit) )
+ m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetPromptText());
+ }
+ else // USERFLD
+ bFormat = bNumFormat = false;
+ }
+ break;
+
+ case SwFieldTypesEnum::DDE:
+ m_xValueFT->set_label(SwResId(STR_DDE_CMD));
+
+ if (IsFieldEdit() || pBox) // only when interacting via mouse
+ {
+ if (nSelPos != -1)
+ {
+ SwDDEFieldType* pType =
+ static_cast<SwDDEFieldType*>( GetFieldMgr().GetFieldType(SwFieldIds::Dde, nSelData) );
+
+ if(pType)
+ {
+ m_xNameED->set_text(pType->GetName());
+
+ //JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
+ // That's not considered here yet
+ OUString sCmd( pType->GetCmd() );
+ sal_Int32 nTmpPos = 0;
+ sCmd = sCmd.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &nTmpPos );
+ sCmd = sCmd.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &nTmpPos );
+
+ m_xValueED->set_text( sCmd );
+ m_xFormatLB->select(static_cast<int>(pType->GetType()));
+ }
+ }
+ }
+ bName = bValue = true;
+ break;
+
+ case SwFieldTypesEnum::Sequence:
+ {
+ bName = bValue = bShowChapterFrame = true;
+
+ SwFieldType* pFieldTyp;
+ if( GetCurField() && IsFieldEdit() )
+ pFieldTyp = GetCurField()->GetTyp();
+ else
+ {
+ OUString sFieldTypeName(m_xSelectionLB->get_text(nSelPos));
+ if( !sFieldTypeName.isEmpty() )
+ pFieldTyp = GetFieldMgr().GetFieldType( SwFieldIds::SetExp,
+ sFieldTypeName );
+ else
+ pFieldTyp = nullptr;
+ }
+
+ if( GetCurField() && IsFieldEdit() )
+ m_xValueED->set_text( static_cast<SwSetExpField*>(GetCurField())->
+ GetFormula() );
+
+ if( IsFieldEdit() || pBox ) // only when interacting via mouse
+ m_xNameED->set_text( m_xSelectionLB->get_selected_text() );
+
+ if( pFieldTyp )
+ {
+ sal_uInt8 nLevel = static_cast<SwSetExpFieldType*>(pFieldTyp)->GetOutlineLvl();
+ if( 0x7f == nLevel )
+ m_xChapterLevelLB->set_active(0);
+ else
+ m_xChapterLevelLB->set_active(nLevel + 1);
+ OUString sDelim = static_cast<SwSetExpFieldType*>(pFieldTyp)->GetDelimiter();
+ m_xSeparatorED->set_text( sDelim );
+ ChapterHdl(*m_xChapterLevelLB);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::SetRefPage:
+ {
+ bValue = false;
+ m_xValueFT->set_label( SwResId( STR_OFFSET ));
+
+ if (IsFieldEdit() || pBox) // only when interacting via mouse
+ m_xNameED->set_text(OUString());
+
+ if (nSelData != 0 && nSelData != SIZE_MAX)
+ {
+ bValue = true; // SubType OFF - knows no Offset
+ if (GetCurField() && IsFieldEdit())
+ m_xValueED->set_text(OUString::number(static_cast<SwRefPageSetField*>(GetCurField())->GetOffset()));
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::GetRefPage:
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ break;
+
+ default: break;
+ }
+
+ m_xNumFormatLB->set_visible(bNumFormat);
+ m_xFormatLB->set_visible(!bNumFormat);
+
+ if (IsFieldEdit())
+ bName = false;
+
+ m_xFormat->set_sensitive(bFormat || bNumFormat);
+ m_xNameFT->set_sensitive(bName);
+ m_xNameED->set_sensitive(bName);
+ m_xValueFT->set_sensitive(bValue);
+ m_xValueED->set_sensitive(bValue);
+
+ m_xInvisibleCB->set_visible(!bShowChapterFrame);
+ m_xChapterFrame->set_visible(bShowChapterFrame);
+ m_xInvisibleCB->set_sensitive(bInvisible);
+
+ ModifyHdl(*m_xNameED); // apply/insert/delete status update
+}
+
+IMPL_LINK(SwFieldVarPage, SubTypeInsertHdl, weld::TreeView&, rBox, bool)
+{
+ if (!m_bInit)
+ {
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ if (nTypeId == SwFieldTypesEnum::Formel)
+ {
+ auto nSelPos = m_xSelectionLB->get_selected_index();
+ if (nSelPos != -1)
+ {
+ m_xValueED->replace_selection(m_xSelectionLB->get_text(nSelPos));
+ ModifyHdl(*m_xNameED);
+ return true;
+ }
+ }
+ }
+ TreeViewInsertHdl(rBox);
+ return true;
+}
+
+// renew types in SelectionBox
+void SwFieldVarPage::UpdateSubType()
+{
+ SetSelectionSel(m_xSelectionLB->get_selected_index());
+
+ OUString sOldSel;
+ if (GetSelectionSel() != -1)
+ sOldSel = m_xSelectionLB->get_text(GetSelectionSel());
+
+ // fill Selection-Listbox
+ m_xSelectionLB->freeze();
+ m_xSelectionLB->clear();
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ std::vector<OUString> aList;
+ GetFieldMgr().GetSubTypes(nTypeId, aList);
+ const size_t nCount = aList.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ if (nTypeId != SwFieldTypesEnum::Input || i)
+ {
+ if (!IsFieldEdit())
+ {
+ m_xSelectionLB->append(OUString::number(i), aList[i]);
+ }
+ else
+ {
+ bool bInsert = false;
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Input:
+ if (GetCurField() && aList[i] == GetCurField()->GetPar1())
+ bInsert = true;
+ break;
+
+ case SwFieldTypesEnum::Formel:
+ bInsert = true;
+ break;
+
+ case SwFieldTypesEnum::Get:
+ if (GetCurField() && aList[i] == static_cast<const SwFormulaField*>(GetCurField())->GetFormula())
+ bInsert = true;
+ break;
+
+ case SwFieldTypesEnum::Set:
+ case SwFieldTypesEnum::User:
+ if (GetCurField() && aList[i] == GetCurField()->GetTyp()->GetName())
+ {
+ bInsert = true;
+ if (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE)
+ m_xInvisibleCB->set_active(true);
+ }
+ break;
+
+ case SwFieldTypesEnum::SetRefPage:
+ {
+ if (GetCurField() != nullptr
+ && ((static_cast<SwRefPageSetField*>(GetCurField())->IsOn()
+ && i) || (!static_cast<SwRefPageSetField*>(GetCurField())
+ ->IsOn() && !i)))
+ {
+ sOldSel = aList[i];
+ }
+
+ // allow all entries for selection:
+ m_xSelectionLB->append(OUString::number(i), aList[i]);
+ break;
+ }
+ default:
+ if (GetCurField() && aList[i] == GetCurField()->GetPar1())
+ bInsert = true;
+ break;
+ }
+
+ if (bInsert)
+ {
+ m_xSelectionLB->append(OUString::number(i), aList[i]);
+ if (nTypeId != SwFieldTypesEnum::Formel)
+ break;
+ }
+ }
+ }
+ }
+
+ m_xSelectionLB->thaw();
+
+ const bool bEnable = m_xSelectionLB->n_children() != 0;
+ weld::TreeView* pLB = nullptr;
+
+ if (bEnable)
+ {
+ int nIndex = m_xSelectionLB->find_text(sOldSel);
+ if (nIndex != -1)
+ m_xSelectionLB->select(nIndex);
+ else
+ {
+ m_xSelectionLB->select(0);
+ pLB = m_xSelectionLB.get(); // newly initialise all controls
+ }
+ }
+
+ m_xSelection->set_sensitive(bEnable);
+
+ SubTypeHdl(pLB);
+}
+
+void SwFieldVarPage::FillFormatLB(SwFieldTypesEnum nTypeId)
+{
+ OUString sOldSel;
+ const sal_Int32 nFormatSel = m_xFormatLB->get_selected_index();
+ if (nFormatSel != -1)
+ sOldSel = m_xFormatLB->get_text(nFormatSel);
+
+ weld::TreeView& rWidget = dynamic_cast<weld::TreeView&>(m_xNumFormatLB->get_widget());
+
+ OUString sOldNumSel;
+ sal_uInt32 nOldNumFormat = 0;
+ sal_Int32 nNumFormatSel = rWidget.get_selected_index();
+ if (nNumFormatSel != -1)
+ {
+ sOldNumSel = rWidget.get_text(nNumFormatSel);
+ nOldNumFormat = m_xNumFormatLB->GetFormat();
+ }
+
+ // fill Format-Listbox
+ m_xFormatLB->freeze();
+ m_xFormatLB->clear();
+ m_xNumFormatLB->clear(); // flags list as dirty and needing refilling with stock entries
+ bool bSpecialFormat = false;
+
+ if( SwFieldTypesEnum::GetRefPage != nTypeId )
+ {
+ if (GetCurField() != nullptr && IsFieldEdit())
+ {
+ bSpecialFormat = GetCurField()->GetFormat() == NUMBERFORMAT_ENTRY_NOT_FOUND;
+
+ if (!bSpecialFormat)
+ {
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+ sOldNumSel.clear();
+ }
+ else if (nTypeId == SwFieldTypesEnum::Get || nTypeId == SwFieldTypesEnum::Formel)
+ {
+ m_xNumFormatLB->SetFormatType(SvNumFormatType::NUMBER);
+ }
+ }
+ else
+ {
+ if (nOldNumFormat && nOldNumFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ m_xNumFormatLB->SetDefFormat(nOldNumFormat);
+ else
+ m_xNumFormatLB->SetFormatType(SvNumFormatType::NUMBER);
+ }
+ }
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User:
+ {
+ if (!IsFieldEdit() || bSpecialFormat)
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_MARK_TEXT), &sId, nullptr, nullptr);
+ rWidget.insert(1, SwResId(FMT_USERVAR_CMD), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 2);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::Set:
+ {
+ if (!IsFieldEdit() || bSpecialFormat)
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_SETVAR_TEXT), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 1);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::Formel:
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_GETVAR_NAME), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 1);
+ }
+ break;
+
+ case SwFieldTypesEnum::Get:
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_GETVAR_NAME), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 1);
+ }
+ break;
+
+ default: break;
+ }
+
+ if (IsFieldEdit() && bSpecialFormat)
+ {
+ if (nTypeId == SwFieldTypesEnum::User && (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_CMD))
+ rWidget.select(1);
+ else
+ rWidget.select(0);
+ }
+ else
+ {
+ if (!nOldNumFormat && (nNumFormatSel = rWidget.find_text(sOldNumSel)) != -1)
+ rWidget.select(nNumFormatSel);
+ else if (nOldNumFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ rWidget.select_text(sOldSel);
+ }
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ OUString sSelectId;
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ const sal_uInt16 nFieldId = GetFieldMgr().GetFormatId( nTypeId, i );
+ OUString sId(OUString::number(nFieldId));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ if (IsFieldEdit() && GetCurField() && nFieldId == GetCurField()->GetFormat())
+ sSelectId = sId;
+ }
+
+ m_xFormatLB->thaw();
+ if (!sSelectId.isEmpty())
+ m_xFormatLB->select_id(sSelectId);
+
+ if (nSize && (!IsFieldEdit() || m_xFormatLB->get_selected_index() == -1))
+ {
+ int nIndex = m_xFormatLB->find_text(sOldSel);
+ if (nIndex == -1)
+ nIndex = m_xFormatLB->find_text(SwResId(FMT_NUM_PAGEDESC));
+ if (nIndex == -1)
+ nIndex = m_xFormatLB->find_text(SwResId(FMT_NUM_ARABIC));
+ if (nIndex == -1)
+ nIndex = 0;
+ m_xFormatLB->select(nIndex);
+ }
+}
+
+// Modify
+IMPL_LINK_NOARG(SwFieldVarPage, ModifyHdl, weld::Entry&, void)
+{
+ OUString sValue(m_xValueED->get_text());
+ bool bHasValue = !sValue.isEmpty();
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ bool bInsert = false, bApply = false, bDelete = false;
+
+ OUString sName( m_xNameED->get_text() );
+ sal_Int32 nLen = sName.getLength();
+
+ switch( nTypeId )
+ {
+ case SwFieldTypesEnum::DDE:
+ case SwFieldTypesEnum::User:
+ case SwFieldTypesEnum::Set:
+ case SwFieldTypesEnum::Sequence:
+ SwCalc::IsValidVarName( sName, &sName );
+ if ( sName.getLength() != nLen )
+ {
+ nLen = sName.getLength();
+ int nStartPos, nEndPos;
+ m_xNameED->get_selection_bounds(nStartPos, nEndPos);
+ m_xNameED->set_text( sName );
+ m_xNameED->select_region(nStartPos, nEndPos); // restore Cursorpos
+ }
+ break;
+ default: break;
+ }
+
+ // check buttons
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::DDE:
+ if( nLen )
+ {
+ // is there already a corresponding type
+ bInsert = bApply = true;
+
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::Dde, sName);
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh && pType)
+ bDelete = !pSh->IsUsed( *pType );
+ }
+ break;
+
+ case SwFieldTypesEnum::User:
+ if( nLen )
+ {
+ // is there already a corresponding type
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::User, sName);
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh && pType)
+ bDelete = !pSh->IsUsed( *pType );
+
+ pType = GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName);
+ if (!pType) // no name conflict with variables
+ {
+ // user fields can also be inserted without content!
+ // Bug #56845
+ bInsert = bApply = true;
+ }
+ }
+ break;
+
+ default:
+ bInsert = true;
+
+ if (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Sequence)
+ {
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(
+ GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName));
+
+ if (pFieldType)
+ {
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ const SwFieldTypes* p = pSh->GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
+ sal_uInt16 i;
+
+ for (i = 0; i < INIT_FLDTYPES; i++)
+ {
+ SwFieldType* pType = (*p)[ i ].get();
+ if (pType == pFieldType)
+ break;
+ }
+
+ if (i >= INIT_FLDTYPES && !pSh->IsUsed(*pFieldType))
+ bDelete = true;
+
+ if (nTypeId == SwFieldTypesEnum::Sequence && !(pFieldType->GetType() & nsSwGetSetExpType::GSE_SEQ))
+ bInsert = false;
+
+ if (nTypeId == SwFieldTypesEnum::Set && (pFieldType->GetType() & nsSwGetSetExpType::GSE_SEQ))
+ bInsert = false;
+ }
+ }
+ if (GetFieldMgr().GetFieldType(SwFieldIds::User, sName))
+ bInsert = false;
+ }
+
+ if (!nLen && (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Input ||
+ (!IsFieldEdit() && nTypeId == SwFieldTypesEnum::Get ) ) )
+ bInsert = false;
+
+ if( (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Formel) &&
+ !bHasValue )
+ bInsert = false;
+ break;
+ }
+
+ m_xNewPB->set_sensitive(bApply);
+ m_xDelPB->set_sensitive(bDelete);
+ EnableInsert(bInsert);
+}
+
+IMPL_LINK(SwFieldVarPage, TBClickHdl, weld::Button&, rBox, void)
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if (&rBox == m_xDelPB.get())
+ {
+ if( nTypeId == SwFieldTypesEnum::User )
+ GetFieldMgr().RemoveFieldType(SwFieldIds::User, m_xSelectionLB->get_selected_text());
+ else
+ {
+ SwFieldIds nWhich;
+
+ switch(nTypeId)
+ {
+ case SwFieldTypesEnum::Set:
+ case SwFieldTypesEnum::Sequence:
+ nWhich = SwFieldIds::SetExp;
+ break;
+ default:
+ nWhich = SwFieldIds::Dde;
+ break;
+ }
+
+ GetFieldMgr().RemoveFieldType(nWhich, m_xSelectionLB->get_selected_text());
+ }
+
+ UpdateSubType();
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ pSh->SetModified();
+ }
+ }
+ else if (&rBox == m_xNewPB.get())
+ {
+ OUString sName(m_xNameED->get_text()), sValue(m_xValueED->get_text());
+ SwFieldType* pType = nullptr;
+ SwFieldIds nId = SwFieldIds::Database;
+ sal_Int32 nNumFormatPos = m_xNumFormatLB->get_selected_index();
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User: nId = SwFieldIds::User; break;
+ case SwFieldTypesEnum::DDE: nId = SwFieldIds::Dde; break;
+ case SwFieldTypesEnum::Set: nId = SwFieldIds::SetExp;break;
+ default: break;
+ }
+ pType = GetFieldMgr().GetFieldType(nId, sName);
+
+ int nFormat = m_xFormatLB->get_selected_index();
+ if (nFormat != -1)
+ nFormat = m_xFormatLB->get_id(nFormat).toUInt32();
+
+ if (pType) // change
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ pSh->StartAllAction();
+
+ if (nTypeId == SwFieldTypesEnum::User)
+ {
+ if (nNumFormatPos != -1)
+ {
+ // The first listbox entry is Text and second is
+ // Formula and both are SAL_MAX_UINT32 :-/ but only if
+ // not another yet unlisted of Additional Formats was
+ // selected that may claim the top position :-/
+ bool bText = false;
+ sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
+ if (nNumberFormat && nNumberFormat != SAL_MAX_UINT32)
+ { // Switch language to office-language because calculator expects
+ // String in office format and it should be fed into dialog like
+ // that
+ nNumberFormat = SwValueField::GetSystemFormat(pSh->GetNumberFormatter(), nNumberFormat);
+ }
+ static_cast<SwUserFieldType*>(pType)->SetContent(m_xValueED->get_text(), nNumberFormat);
+ static_cast<SwUserFieldType*>(pType)->SetType(
+ bText ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR );
+ }
+ }
+ else
+ {
+ if (nFormat != -1)
+ {
+ // DDE-Topics/-Items can have blanks in their names!
+ // That's not being considered here yet.
+ sal_Int32 nTmpPos = 0;
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+ static_cast<SwDDEFieldType*>(pType)->SetCmd(sValue);
+ static_cast<SwDDEFieldType*>(pType)->SetType(static_cast<SfxLinkUpdateMode>(nFormat));
+ }
+ }
+ pType->UpdateFields();
+
+ pSh->EndAllAction();
+ }
+ }
+ else // new
+ {
+ if(nTypeId == SwFieldTypesEnum::User)
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwUserFieldType aType( pSh->GetDoc(), sName );
+
+ if (nNumFormatPos != -1)
+ {
+ // The first listbox entry is Text and second is
+ // Formula and both are SAL_MAX_UINT32 :-/ but only if
+ // not another yet unlisted of Additional Formats was
+ // selected that may claim the top position :-/
+ bool bText = false;
+ sal_uInt32 nNumberFormat = lcl_getUsedNumFormat( *m_xNumFormatLB, bText);
+ aType.SetType(bText ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR);
+ aType.SetContent( sValue, nNumberFormat );
+ m_xSelectionLB->append_text(sName);
+ m_xSelectionLB->select_text(sName);
+ GetFieldMgr().InsertFieldType( aType ); // Userfld new
+ }
+ }
+ }
+ else
+ {
+ if (nFormat != -1)
+ {
+ // DDE-Topics/-Items can have blanks in their names!
+ // That's not being considered here yet.
+ sal_Int32 nTmpPos = 0;
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+
+ SwDDEFieldType aType(sName, sValue, static_cast<SfxLinkUpdateMode>(nFormat));
+ m_xSelectionLB->append_text(sName);
+ m_xSelectionLB->select_text(sName);
+ GetFieldMgr().InsertFieldType(aType); // DDE-Field new
+ }
+ }
+ }
+ if (IsFieldEdit())
+ GetFieldMgr().GetCurField(); // update FieldManager
+
+ UpdateSubType();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldVarPage, ChapterHdl, weld::ComboBox&, void)
+{
+ bool bEnable = m_xChapterLevelLB->get_active() != 0;
+
+ m_xSeparatorED->set_sensitive(bEnable);
+ m_xSeparatorFT->set_sensitive(bEnable);
+ SeparatorHdl(*m_xSeparatorED);
+}
+
+IMPL_LINK_NOARG(SwFieldVarPage, SeparatorHdl, weld::Entry&, void)
+{
+ bool bEnable = !m_xSeparatorED->get_text().isEmpty() ||
+ m_xChapterLevelLB->get_active() == 0;
+ EnableInsert(bEnable);
+}
+
+bool SwFieldVarPage::FillItemSet(SfxItemSet* )
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ OUString aVal(m_xValueED->get_text());
+ OUString aName(m_xNameED->get_text());
+
+ const sal_Int32 nSubPos = m_xSelectionLB->get_selected_index();
+ sal_uInt16 nSubType = (nSubPos == -1) ? 0 : m_xSelectionLB->get_id(nSubPos).toUInt32();
+
+ sal_uInt32 nFormat;
+
+ if (!m_xNumFormatLB->get_visible())
+ {
+ sal_Int32 nFormatPos = m_xFormatLB->get_selected_index();
+
+ if(nFormatPos == -1)
+ nFormat = 0;
+ else
+ nFormat = m_xFormatLB->get_id(nFormatPos).toUInt32();
+ }
+ else
+ {
+ nFormat = m_xNumFormatLB->GetFormat();
+
+ if (nFormat && nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND && m_xNumFormatLB->IsAutomaticLanguage())
+ {
+ // Switch language to office language because calculator expects
+ // String in office format and it should be fed into the dialog
+ // like that
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ nFormat = SwValueField::GetSystemFormat(pSh->GetNumberFormatter(), nFormat);
+ }
+ }
+ }
+ sal_Unicode cSeparator = ' ';
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User:
+ {
+ nSubType = (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR;
+
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND && m_xNumFormatLB->get_selected_text() == SwResId(FMT_USERVAR_CMD))
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+
+ if (m_xInvisibleCB->get_active())
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ break;
+ }
+ case SwFieldTypesEnum::Formel:
+ {
+ nSubType = nsSwGetSetExpType::GSE_FORMULA;
+ if (m_xNumFormatLB->get_visible() && nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+ break;
+ }
+ case SwFieldTypesEnum::Get:
+ {
+ nSubType &= 0xff00;
+ if (m_xNumFormatLB->get_visible() && nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+ break;
+ }
+ case SwFieldTypesEnum::Input:
+ {
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::User, aName);
+ nSubType = static_cast< sal_uInt16 >((nSubType & 0xff00) | (pType ? INP_USR : INP_VAR));
+ break;
+ }
+
+ case SwFieldTypesEnum::Set:
+ {
+ if (IsFieldDlgHtmlMode())
+ {
+ nSubType = 0x0100;
+ nSubType = (nSubType & 0xff00) | nsSwGetSetExpType::GSE_STRING;
+ }
+ else
+ nSubType = (nSubType & 0xff00) | ((nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR);
+
+ if (m_xInvisibleCB->get_active())
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ break;
+ }
+ case SwFieldTypesEnum::Sequence:
+ {
+ nSubType = static_cast< sal_uInt16 >(m_xChapterLevelLB->get_active());
+ if (nSubType == 0)
+ nSubType = 0x7f;
+ else
+ {
+ nSubType--;
+ OUString sSeparator(m_xSeparatorED->get_text()[0]);
+ cSeparator = !sSeparator.isEmpty() ? sSeparator[0] : ' ';
+ }
+ break;
+ }
+ case SwFieldTypesEnum::GetRefPage:
+ if( SVX_NUM_CHAR_SPECIAL == nFormat )
+ aVal = m_xValueED->get_text();
+ break;
+ default: break;
+ }
+
+ if (!IsFieldEdit() ||
+ m_xNameED->get_value_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xSelectionLB->get_value_changed_from_saved() ||
+ m_xFormatLB->get_value_changed_from_saved() ||
+ m_nOldFormat != m_xNumFormatLB->GetFormat() ||
+ m_xInvisibleCB->get_state_changed_from_saved() ||
+ m_xChapterLevelLB->get_value_changed_from_saved() ||
+ m_xSeparatorED->get_value_changed_from_saved())
+ {
+ InsertField( nTypeId, nSubType, aName, aVal, nFormat,
+ cSeparator, m_xNumFormatLB->IsAutomaticLanguage() );
+ }
+
+ UpdateSubType();
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldVarPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldVarPage>( pPage, pController, pAttrSet );
+}
+
+sal_uInt16 SwFieldVarPage::GetGroup()
+{
+ return GRP_VAR;
+}
+
+void SwFieldVarPage::FillUserData()
+{
+ OUString sData = USER_DATA_VERSION ";";
+ sal_Int32 nTypeSel = m_xTypeLB->get_selected_index();
+ if( -1 == nTypeSel )
+ nTypeSel = USHRT_MAX;
+ else
+ nTypeSel = m_xTypeLB->get_id(nTypeSel).toUInt32();
+ sData += OUString::number( nTypeSel );
+ SetUserData(sData);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldvar.hxx b/sw/source/ui/fldui/fldvar.hxx
new file mode 100644
index 0000000000..3eedfbf2cc
--- /dev/null
+++ b/sw/source/ui/fldui/fldvar.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDVAR_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDVAR_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include "fldpage.hxx"
+#include <condedit.hxx>
+#include <numfmtlb.hxx>
+
+class SwFieldVarPage;
+
+class SwFieldVarPage : public SwFieldPage
+{
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Label> m_xNameFT;
+ std::unique_ptr<weld::Entry> m_xNameED;
+ std::unique_ptr<weld::Label> m_xValueFT;
+ std::unique_ptr<ConditionEdit> m_xValueED;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<SwNumFormatTreeView> m_xNumFormatLB;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<weld::Widget> m_xChapterFrame;
+ std::unique_ptr<weld::ComboBox> m_xChapterLevelLB;
+ std::unique_ptr<weld::CheckButton> m_xInvisibleCB;
+ std::unique_ptr<weld::Label> m_xSeparatorFT;
+ std::unique_ptr<weld::Entry> m_xSeparatorED;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xDelPB;
+
+ OUString m_sOldValueFT;
+ OUString m_sOldNameFT;
+
+ sal_uInt32 m_nOldFormat;
+ bool m_bInit;
+
+ DECL_LINK( TypeHdl, weld::TreeView&, void );
+ DECL_LINK( SubTypeListBoxHdl, weld::TreeView&, void );
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( TBClickHdl, weld::Button&, void );
+ DECL_LINK( ChapterHdl, weld::ComboBox&, void );
+ DECL_LINK( SeparatorHdl, weld::Entry&, void );
+ DECL_LINK( SubTypeInsertHdl, weld::TreeView&, bool );
+ void SubTypeHdl(const weld::TreeView*);
+
+ void UpdateSubType();
+ void FillFormatLB(SwFieldTypesEnum nTypeId);
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldVarPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ virtual ~SwFieldVarPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/inpdlg.cxx b/sw/source/ui/fldui/inpdlg.cxx
new file mode 100644
index 0000000000..f5ed2c33e9
--- /dev/null
+++ b/sw/source/ui/fldui/inpdlg.cxx
@@ -0,0 +1,176 @@
+/* -*- 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/lineend.hxx>
+#include <unotools/charclass.hxx>
+#include <wrtsh.hxx>
+#include <fldbas.hxx>
+#include <expfld.hxx>
+#include <usrfld.hxx>
+#include <inpdlg.hxx>
+
+// edit field-insert
+SwFieldInputDlg::SwFieldInputDlg(weld::Widget *pParent, SwWrtShell &rS,
+ SwField* pField, bool bPrevButton, bool bNextButton)
+ : GenericDialogController(pParent, "modules/swriter/ui/inputfielddialog.ui", "InputFieldDialog")
+ , m_rSh( rS )
+ , m_pInpField(nullptr)
+ , m_pSetField(nullptr)
+ , m_pUsrType(nullptr)
+ , m_pPressedButton(nullptr)
+ , m_xLabelED(m_xBuilder->weld_entry("name"))
+ , m_xEditED(m_xBuilder->weld_text_view("text"))
+ , m_xPrevBT(m_xBuilder->weld_button("prev"))
+ , m_xNextBT(m_xBuilder->weld_button("next"))
+ , m_xOKBT(m_xBuilder->weld_button("ok"))
+{
+ m_xEditED->set_size_request(-1, m_xEditED->get_height_rows(8));
+
+ if( bPrevButton || bNextButton )
+ {
+ m_xPrevBT->show();
+ m_xPrevBT->connect_clicked(LINK(this, SwFieldInputDlg, PrevHdl));
+ m_xPrevBT->set_sensitive(bPrevButton);
+
+ m_xNextBT->show();
+ m_xNextBT->connect_clicked(LINK(this, SwFieldInputDlg, NextHdl));
+ m_xNextBT->set_sensitive(bNextButton);
+ }
+
+ // evaluation here
+ OUString aStr;
+ if( SwFieldIds::Input == pField->GetTyp()->Which() )
+ { // it is an input field
+
+ m_pInpField = static_cast<SwInputField*>(pField);
+ m_xLabelED->set_text(m_pInpField->GetPar2());
+ sal_uInt16 nSubType = m_pInpField->GetSubType();
+
+ switch(nSubType & 0xff)
+ {
+ case INP_TXT:
+ aStr = m_pInpField->GetPar1();
+ break;
+
+ case INP_USR:
+ // user field
+ m_pUsrType = static_cast<SwUserFieldType*>(m_rSh.GetFieldType(
+ SwFieldIds::User, m_pInpField->GetPar1() ));
+ if( nullptr != m_pUsrType )
+ aStr = m_pUsrType->GetContent();
+ break;
+ }
+ }
+ else
+ {
+ // it is a SetExpression
+ m_pSetField = static_cast<SwSetExpField*>(pField);
+ OUString sFormula(m_pSetField->GetFormula());
+ //values are formatted - formulas are not
+ CharClass aCC( LanguageTag( m_pSetField->GetLanguage() ));
+ if( aCC.isNumeric( sFormula ))
+ {
+ aStr = m_pSetField->ExpandField(true, rS.GetLayout());
+ }
+ else
+ aStr = sFormula;
+ m_xLabelED->set_text(m_pSetField->GetPromptText());
+ }
+
+ // JP 31.3.00: Inputfields in readonly regions must be allowed to
+ // input any content. - 74639
+ bool bEnable = !m_rSh.IsCursorReadonly();
+
+ m_xOKBT->set_sensitive( bEnable );
+ m_xEditED->set_editable( bEnable );
+
+ if( !aStr.isEmpty() )
+ m_xEditED->set_text(convertLineEnd(aStr, GetSystemLineEnd()));
+ m_xEditED->grab_focus();
+
+ // preselect all text to allow quickly changing the content
+ if (bEnable)
+ m_xEditED->select_region(0, -1);
+}
+
+SwFieldInputDlg::~SwFieldInputDlg()
+{
+}
+
+// Close
+void SwFieldInputDlg::Apply()
+{
+ OUString aTmp = m_xEditED->get_text().replaceAll("\r", "");
+ m_rSh.StartAllAction();
+ bool bModified = false;
+ if(m_pInpField)
+ {
+ if(m_pUsrType)
+ {
+ if( aTmp != m_pUsrType->GetContent() )
+ {
+ m_pUsrType->SetContent(aTmp);
+ m_pUsrType->UpdateFields();
+ bModified = true;
+ }
+ }
+ else if( aTmp != m_pInpField->GetPar1() )
+ {
+ m_pInpField->SetPar1(aTmp);
+ m_rSh.SwEditShell::UpdateOneField(*m_pInpField);
+ bModified = true;
+ }
+ }
+ else if( aTmp != m_pSetField->GetPar2())
+ {
+ m_pSetField->SetPar2(aTmp);
+ m_rSh.SwEditShell::UpdateOneField(*m_pSetField);
+ bModified = true;
+ }
+
+ if( bModified )
+ m_rSh.SetUndoNoResetModified();
+
+ m_rSh.EndAllAction();
+}
+
+bool SwFieldInputDlg::PrevButtonPressed() const
+{
+ return m_pPressedButton == m_xPrevBT.get();
+}
+
+bool SwFieldInputDlg::NextButtonPressed() const
+{
+ return m_pPressedButton == m_xNextBT.get();
+}
+
+IMPL_LINK_NOARG(SwFieldInputDlg, PrevHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xPrevBT.get();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwFieldInputDlg, NextHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xNextBT.get();
+ m_xDialog->response(RET_OK);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/javaedit.cxx b/sw/source/ui/fldui/javaedit.cxx
new file mode 100644
index 0000000000..b13c9828d8
--- /dev/null
+++ b/sw/source/ui/fldui/javaedit.cxx
@@ -0,0 +1,253 @@
+/* -*- 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/ui/dialogs/TemplateDescription.hpp>
+#include <svl/urihelper.hxx>
+#include <view.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <fldbas.hxx>
+#include <fldmgr.hxx>
+#include <docufld.hxx>
+#include <javaedit.hxx>
+
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+
+SwJavaEditDialog::SwJavaEditDialog(weld::Window* pParent, SwWrtShell* pWrtSh)
+ : GenericDialogController(pParent, "modules/swriter/ui/insertscript.ui", "InsertScriptDialog")
+ , m_bNew(true)
+ , m_bIsUrl(false)
+ , m_pSh(pWrtSh)
+ , m_xTypeED(m_xBuilder->weld_entry("scripttype"))
+ , m_xUrlRB(m_xBuilder->weld_radio_button("url"))
+ , m_xEditRB(m_xBuilder->weld_radio_button("text"))
+ , m_xUrlPB(m_xBuilder->weld_button("browse"))
+ , m_xUrlED(m_xBuilder->weld_entry("urlentry"))
+ , m_xEditED(m_xBuilder->weld_text_view("textentry"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xPrevBtn(m_xBuilder->weld_button("previous"))
+ , m_xNextBtn(m_xBuilder->weld_button("next"))
+{
+ // install handler
+ m_xPrevBtn->connect_clicked( LINK( this, SwJavaEditDialog, PrevHdl ) );
+ m_xNextBtn->connect_clicked( LINK( this, SwJavaEditDialog, NextHdl ) );
+ m_xOKBtn->connect_clicked( LINK( this, SwJavaEditDialog, OKHdl ) );
+
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwJavaEditDialog, RadioButtonHdl);
+ m_xUrlRB->connect_toggled(aLk);
+ m_xEditRB->connect_toggled(aLk);
+ m_xUrlPB->connect_clicked(LINK(this, SwJavaEditDialog, InsertFileHdl));
+
+ m_pMgr.reset(new SwFieldMgr(m_pSh));
+ m_pField = static_cast<SwScriptField*>(m_pMgr->GetCurField());
+
+ m_bNew = !(m_pField && m_pField->GetTyp()->Which() == SwFieldIds::Script);
+
+ CheckTravel();
+
+ if (!m_bNew)
+ m_xDialog->set_title(SwResId(STR_JAVA_EDIT));
+
+ UpdateFromRadioButtons();
+}
+
+SwJavaEditDialog::~SwJavaEditDialog()
+{
+ m_pSh->EnterStdMode();
+ m_pMgr.reset();
+ m_pFileDlg.reset();
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, PrevHdl, weld::Button&, void)
+{
+ m_pSh->EnterStdMode();
+
+ SetField();
+ m_pMgr->GoPrev();
+ m_pField = static_cast<SwScriptField*>(m_pMgr->GetCurField());
+ CheckTravel();
+ UpdateFromRadioButtons();
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, NextHdl, weld::Button&, void)
+{
+ m_pSh->EnterStdMode();
+
+ SetField();
+ m_pMgr->GoNext();
+ m_pField = static_cast<SwScriptField*>(m_pMgr->GetCurField());
+ CheckTravel();
+ UpdateFromRadioButtons();
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, OKHdl, weld::Button&, void)
+{
+ SetField();
+ m_xDialog->response(RET_OK);
+}
+
+void SwJavaEditDialog::CheckTravel()
+{
+ bool bTravel = false;
+ bool bNext(false), bPrev(false);
+
+ if (!m_bNew)
+ {
+ // Traveling only when more than one field
+ m_pSh->StartAction();
+ m_pSh->CreateCursor();
+
+ bNext = m_pMgr->GoNext();
+ if( bNext )
+ m_pMgr->GoPrev();
+
+ bPrev = m_pMgr->GoPrev();
+ if( bPrev )
+ m_pMgr->GoNext();
+ bTravel |= bNext || bPrev;
+
+ m_pSh->DestroyCursor();
+ m_pSh->EndAction();
+
+ if (m_pField->IsCodeURL())
+ {
+ OUString sURL(m_pField->GetPar2());
+ if(!sURL.isEmpty())
+ {
+ INetURLObject aINetURL(sURL);
+ if(INetProtocol::File == aINetURL.GetProtocol())
+ sURL = aINetURL.PathToFileName();
+ }
+ m_xUrlED->set_text(sURL);
+ m_xEditED->set_text(OUString());
+ m_xUrlRB->set_active(true);
+ }
+ else
+ {
+ m_xEditED->set_text(m_pField->GetPar2());
+ m_xUrlED->set_text(OUString());
+ m_xEditRB->set_active(true);
+ }
+ m_xTypeED->set_text(m_pField->GetPar1());
+ }
+
+ if ( !bTravel )
+ {
+ m_xPrevBtn->hide();
+ m_xNextBtn->hide();
+ }
+ else
+ {
+ m_xPrevBtn->set_sensitive(bPrev);
+ m_xNextBtn->set_sensitive(bNext);
+ }
+}
+
+void SwJavaEditDialog::SetField()
+{
+ if( !m_xOKBtn->get_sensitive() )
+ return ;
+
+ m_aType = m_xTypeED->get_text();
+ m_bIsUrl = m_xUrlRB->get_active();
+
+ if (m_bIsUrl)
+ {
+ m_aText = m_xUrlED->get_text();
+ if (!m_aText.isEmpty())
+ {
+ SfxMedium* pMedium = m_pSh->GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+
+ m_aText = URIHelper::SmartRel2Abs(
+ aAbs, m_aText, URIHelper::GetMaybeFileHdl());
+ }
+ }
+ else
+ m_aText = m_xEditED->get_text();
+
+ if (m_aType.isEmpty())
+ m_aType = "JavaScript";
+}
+
+bool SwJavaEditDialog::IsUpdate() const
+{
+ return m_pField && ( sal_uInt32(m_bIsUrl ? 1 : 0) != m_pField->GetFormat() || m_pField->GetPar2() != m_aType || m_pField->GetPar1() != m_aText );
+}
+
+IMPL_LINK(SwJavaEditDialog, RadioButtonHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ UpdateFromRadioButtons();
+}
+
+void SwJavaEditDialog::UpdateFromRadioButtons()
+{
+ bool bEnable = m_xUrlRB->get_active();
+ m_xUrlPB->set_sensitive(bEnable);
+ m_xUrlED->set_sensitive(bEnable);
+ m_xEditED->set_sensitive(!bEnable);
+
+ if (!m_bNew)
+ {
+ bEnable = !m_pSh->IsReadOnlyAvailable() || !m_pSh->HasReadonlySel();
+ m_xOKBtn->set_sensitive(bEnable);
+ m_xUrlED->set_editable(bEnable);
+ m_xEditED->set_editable(bEnable);
+ m_xTypeED->set_editable(bEnable);
+ if( m_xUrlPB->get_sensitive() && !bEnable )
+ m_xUrlPB->set_sensitive( false );
+ }
+}
+
+IMPL_LINK_NOARG( SwJavaEditDialog, InsertFileHdl, weld::Button&, void )
+{
+ if (!m_pFileDlg)
+ {
+ m_pFileDlg.reset(new ::sfx2::FileDialogHelper(
+ ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::Insert, "swriter", SfxFilterFlags::NONE, SfxFilterFlags::NONE, m_xDialog.get()));
+ }
+ m_pFileDlg->SetContext(sfx2::FileDialogHelper::WriterInsertScript);
+ m_pFileDlg->StartExecuteModal( LINK( this, SwJavaEditDialog, DlgClosedHdl ) );
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, DlgClosedHdl, sfx2::FileDialogHelper *, void)
+{
+ if (m_pFileDlg->GetError() == ERRCODE_NONE)
+ {
+ OUString sFileName = m_pFileDlg->GetPath();
+ if ( !sFileName.isEmpty() )
+ {
+ INetURLObject aINetURL( sFileName );
+ if ( INetProtocol::File == aINetURL.GetProtocol() )
+ sFileName = aINetURL.PathToFileName();
+ }
+ m_xUrlED->set_text(sFileName);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fmtui/tmpdlg.cxx b/sw/source/ui/fmtui/tmpdlg.cxx
new file mode 100644
index 0000000000..0a5d6686da
--- /dev/null
+++ b/sw/source/ui/fmtui/tmpdlg.cxx
@@ -0,0 +1,542 @@
+/* -*- 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 <hintids.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <svx/hdft.hxx>
+#include <editeng/flstitem.hxx>
+#include <osl/diagnose.h>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <svl/cjkoptions.hxx>
+#include <vcl/svapp.hxx>
+#include <numpara.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <wdocsh.hxx>
+#include <viewopt.hxx>
+#include <pgfnote.hxx>
+#include <pggrid.hxx>
+#include <tmpdlg.hxx>
+#include <column.hxx>
+#include <drpcps.hxx>
+#include <frmpage.hxx>
+#include <wrap.hxx>
+#include <swuiccoll.hxx>
+#include <docstyle.hxx>
+#include <fmtcol.hxx>
+#include <macassgn.hxx>
+#include <poolfmt.hxx>
+#include <uitool.hxx>
+#include <shellres.hxx>
+#include <strings.hrc>
+
+#include <cmdid.h>
+#include <SwStyleNameMapper.hxx>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/flagsdef.hxx>
+#include <officecfg/Office/Common.hxx>
+
+// the dialog's carrier
+SwTemplateDlgController::SwTemplateDlgController(weld::Window* pParent,
+ SfxStyleSheetBase& rBase,
+ SfxStyleFamily nRegion,
+ const OUString& sPage,
+ SwWrtShell* pActShell,
+ bool bNew)
+ : SfxStyleDialogController(pParent,
+ "modules/swriter/ui/templatedialog" +
+ OUString::number(static_cast<sal_uInt16>(nRegion)) + ".ui",
+ "TemplateDialog" + OUString::number(static_cast<sal_uInt16>(nRegion)),
+ rBase)
+ , m_nType(nRegion)
+ , m_pWrtShell(pActShell)
+ , m_bNewStyle(bNew)
+{
+ m_nHtmlMode = ::GetHtmlMode(m_pWrtShell->GetView().GetDocShell());
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+
+ GetStandardButton()->set_label(SwResId(STR_STANDARD_LABEL));
+ GetStandardButton()->set_tooltip_text(SwResId(STR_STANDARD_TOOLTIP));
+ GetStandardButton()->set_accessible_description(SwResId(STR_STANDARD_EXTENDEDTIP));
+
+ GetApplyButton()->set_label(SwResId(STR_APPLY_LABEL));
+ GetApplyButton()->set_tooltip_text(SwResId(STR_APPLY_TOOLTIP));
+ GetApplyButton()->set_accessible_description(SwResId(STR_APPLY_EXTENDEDTIP));
+
+ GetResetButton()->set_label(SwResId(STR_RESET_LABEL));
+ GetResetButton()->set_tooltip_text(SwResId(STR_RESET_TOOLTIP));
+ GetResetButton()->set_accessible_description(SwResId(STR_RESET_EXTENDEDTIP));
+
+ // stitch TabPages together
+ switch( nRegion )
+ {
+ // character styles
+ case SfxStyleFamily::Char:
+ {
+ AddTabPage("font", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_NAME ));
+ AddTabPage("fonteffect", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_EFFECTS ));
+ AddTabPage("position", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_POSITION ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_POSITION ));
+ AddTabPage("asianlayout", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_TWOLINES ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_TWOLINES ));
+ AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BKG ));
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ));
+ if(m_nHtmlMode & HTMLMODE_ON || !SvtCJKOptions::IsDoubleLinesEnabled())
+ RemoveTabPage("asianlayout");
+ }
+ break;
+ // paragraph styles
+ case SfxStyleFamily::Para:
+ {
+ AddTabPage("indents", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_STD_PARAGRAPH), pFact->GetTabPageRangesFunc(RID_SVXPAGE_STD_PARAGRAPH));
+
+ AddTabPage("alignment", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_ALIGN_PARAGRAPH), pFact->GetTabPageRangesFunc(RID_SVXPAGE_ALIGN_PARAGRAPH));
+
+ AddTabPage("textflow", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_EXT_PARAGRAPH), pFact->GetTabPageRangesFunc(RID_SVXPAGE_EXT_PARAGRAPH) );
+
+ AddTabPage("asiantypo", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PARA_ASIAN), pFact->GetTabPageRangesFunc(RID_SVXPAGE_PARA_ASIAN) );
+
+ AddTabPage("font", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_NAME ) );
+
+ AddTabPage("fonteffect", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_EFFECTS ) );
+
+ AddTabPage("position", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_POSITION ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_POSITION ) );
+
+ AddTabPage("asianlayout", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_TWOLINES ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_CHAR_TWOLINES ) );
+
+ AddTabPage("highlighting", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BKG ));
+
+ AddTabPage("tabs", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_TABULATOR), pFact->GetTabPageRangesFunc(RID_SVXPAGE_TABULATOR) );
+
+ AddTabPage("outline", SwParagraphNumTabPage::Create, SwParagraphNumTabPage::GetRanges);
+ AddTabPage("dropcaps", SwDropCapsPage::Create, SwDropCapsPage::GetRanges );
+
+ // add Area and Transparence TabPages
+ AddTabPage("area", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_AREA ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_AREA ));
+ AddTabPage("transparence", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TRANSPARENCE ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_TRANSPARENCE ) );
+
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ) );
+
+ AddTabPage("condition", SwCondCollPage::Create,
+ SwCondCollPage::GetRanges );
+ if( (!m_bNewStyle && RES_CONDTXTFMTCOLL != static_cast<SwDocStyleSheet&>(rBase).GetCollection()->Which())
+ || m_nHtmlMode & HTMLMODE_ON )
+ RemoveTabPage("condition");
+
+ if(m_nHtmlMode & HTMLMODE_ON)
+ {
+ if (!officecfg::Office::Common::Filter::HTML::Export::PrintLayout::get())
+ RemoveTabPage("textflow");
+ RemoveTabPage("asiantypo");
+ RemoveTabPage("tabs");
+ RemoveTabPage("outline");
+ RemoveTabPage("asianlayout");
+ if(!(m_nHtmlMode & HTMLMODE_FULL_STYLES))
+ {
+ RemoveTabPage("background");
+ RemoveTabPage("dropcaps");
+ }
+ }
+ else
+ {
+ if(!SvtCJKOptions::IsAsianTypographyEnabled())
+ RemoveTabPage("asiantypo");
+ if(!SvtCJKOptions::IsDoubleLinesEnabled())
+ RemoveTabPage("asianlayout");
+ }
+ }
+ break;
+ // page styles
+ case SfxStyleFamily::Page:
+ {
+ // add Area and Transparence TabPages
+ AddTabPage("area", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_AREA ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_AREA ));
+ AddTabPage("transparence", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TRANSPARENCE ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_TRANSPARENCE ) );
+ AddTabPage("header", SvxHeaderPage::Create, SvxHeaderPage::GetRanges);
+ AddTabPage("footer", SvxFooterPage::Create, SvxFooterPage::GetRanges);
+ AddTabPage("page", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PAGE), pFact->GetTabPageRangesFunc(RID_SVXPAGE_PAGE));
+ if (0 == ::GetHtmlMode(m_pWrtShell->GetView().GetDocShell()))
+ {
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ) );
+ AddTabPage("columns", SwColumnPage::Create, SwColumnPage::GetRanges );
+ AddTabPage("footnotes", SwFootNotePage::Create, SwFootNotePage::GetRanges );
+ AddTabPage("textgrid", SwTextGridPage::Create, SwTextGridPage::GetRanges );
+ if(!SvtCJKOptions::IsAsianTypographyEnabled())
+ RemoveTabPage("textgrid");
+ }
+ else
+ {
+ RemoveTabPage("borders");
+ RemoveTabPage("columns");
+ RemoveTabPage("footnotes");
+ RemoveTabPage("textgrid");
+ }
+ }
+ break;
+ // numbering styles
+ case SfxStyleFamily::Pseudo:
+ {
+ AddTabPage("numbering", RID_SVXPAGE_PICK_SINGLE_NUM);
+ AddTabPage("bullets", RID_SVXPAGE_PICK_BULLET);
+ AddTabPage("outline", RID_SVXPAGE_PICK_NUM);
+ AddTabPage("graphics", RID_SVXPAGE_PICK_BMP);
+ AddTabPage("customize", RID_SVXPAGE_NUM_OPTIONS );
+ AddTabPage("position", RID_SVXPAGE_NUM_POSITION );
+ }
+ break;
+ case SfxStyleFamily::Frame:
+ {
+ AddTabPage("type", SwFramePage::Create, SwFramePage::GetRanges);
+ AddTabPage("options", SwFrameAddPage::Create, SwFrameAddPage::GetRanges);
+ AddTabPage("wrap", SwWrapTabPage::Create, SwWrapTabPage::GetRanges);
+
+ // add Area and Transparence TabPages
+ AddTabPage("area", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_AREA ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_AREA ));
+ AddTabPage("transparence", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TRANSPARENCE ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_TRANSPARENCE ) );
+
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_BORDER ) );
+
+ AddTabPage("columns", SwColumnPage::Create, SwColumnPage::GetRanges );
+
+ AddTabPage("macros", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_MACROASSIGN), nullptr);
+ }
+ break;
+ default:
+ OSL_ENSURE(false, "wrong family");
+ }
+
+ if (bNew)
+ SetCurPageId("organizer");
+ else if (!sPage.isEmpty())
+ SetCurPageId(sPage);
+}
+
+short SwTemplateDlgController::Ok()
+{
+ short nRet = SfxTabDialogController::Ok();
+ if( RET_OK == nRet )
+ {
+ const SfxPoolItem *pOutItem, *pExItem;
+ if( SfxItemState::SET == m_xExampleSet->GetItemState(
+ SID_ATTR_NUMBERING_RULE, false, &pExItem ) &&
+ ( !GetOutputItemSet() ||
+ SfxItemState::SET != GetOutputItemSet()->GetItemState(
+ SID_ATTR_NUMBERING_RULE, false, &pOutItem ) ||
+ *pExItem != *pOutItem ))
+ {
+ if( GetOutputItemSet() )
+ const_cast<SfxItemSet*>(GetOutputItemSet())->Put( *pExItem );
+ else
+ nRet = RET_CANCEL;
+ }
+ }
+ else
+ {
+ //JP 09.01.98 Bug #46446#:
+ // that's the Ok-Handler, so OK has to be default!
+ nRet = RET_OK;
+ }
+ return nRet;
+}
+
+void SwTemplateDlgController::RefreshInputSet()
+{
+ SfxItemSet* pInSet = GetInputSetImpl();
+ pInSet->ClearItem();
+ pInSet->SetParent( &GetStyleSheet().GetItemSet() );
+}
+
+void SwTemplateDlgController::PageCreated(const OUString& rId, SfxTabPage &rPage )
+{
+ // set style's and metric's names
+ OUString sNumCharFormat, sBulletCharFormat;
+ SwStyleNameMapper::FillUIName( RES_POOLCHR_NUM_LEVEL, sNumCharFormat);
+ SwStyleNameMapper::FillUIName( RES_POOLCHR_BULLET_LEVEL, sBulletCharFormat);
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+
+ if (rId == "font")
+ {
+ if (SwView* pView = GetActiveView())
+ {
+ SvxFontListItem aFontListItem( *static_cast<const SvxFontListItem*>(pView->
+ GetDocShell()->GetItem( SID_ATTR_CHAR_FONTLIST ) ) );
+
+ aSet.Put (SvxFontListItem( aFontListItem.GetFontList(), SID_ATTR_CHAR_FONTLIST));
+ sal_uInt32 nFlags = 0;
+ if(rPage.GetItemSet().GetParent() && 0 == (m_nHtmlMode & HTMLMODE_ON ))
+ nFlags = SVX_RELATIVE_MODE;
+ if( SfxStyleFamily::Char == m_nType )
+ nFlags = nFlags|SVX_PREVIEW_CHARACTER;
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, nFlags));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "fonteffect")
+ {
+ sal_uInt32 nFlags = SVX_ENABLE_CHAR_TRANSPARENCY;
+ if( SfxStyleFamily::Char == m_nType )
+ nFlags = nFlags|SVX_PREVIEW_CHARACTER;
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, nFlags));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "position")
+ {
+ if( SfxStyleFamily::Char == m_nType )
+ {
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, SVX_PREVIEW_CHARACTER));
+ rPage.PageCreated(aSet);
+ }
+ else if (SfxStyleFamily::Pseudo == m_nType)
+ {
+ if (SwWrtShell* pSh = ::GetActiveWrtShell())
+ {
+ SwDocShell* pDocShell = pSh->GetView().GetDocShell();
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebDocShell*>( pDocShell) != nullptr );
+
+ aSet.Put ( SfxUInt16Item(SID_METRIC_ITEM, static_cast< sal_uInt16 >(eMetric)));
+ rPage.PageCreated(aSet);
+ }
+ }
+ }
+ else if (rId == "columns")
+ {
+ if( m_nType == SfxStyleFamily::Frame )
+ static_cast<SwColumnPage&>(rPage).SetFrameMode(true);
+ static_cast<SwColumnPage&>(rPage).SetFormatUsed( true );
+ }
+ // do not remove; many other style dialog combinations still use the SfxTabPage
+ // for the SvxBrushItem (see RID_SVXPAGE_BKG)
+ else if (rId == "background" || rId == "highlighting")
+ {
+ SvxBackgroundTabFlags nFlagType = SvxBackgroundTabFlags::NONE;
+ if( SfxStyleFamily::Char == m_nType || SfxStyleFamily::Para == m_nType )
+ nFlagType |= SvxBackgroundTabFlags::SHOW_HIGHLIGHTING;
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(nFlagType)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "condition")
+ {
+ static_cast<SwCondCollPage&>(rPage).SetCollection(
+ static_cast<SwDocStyleSheet&>(GetStyleSheet()).GetCollection() );
+ }
+ else if (rId == "page")
+ {
+ if(0 == (m_nHtmlMode & HTMLMODE_ON ))
+ {
+ std::vector<OUString> aList;
+ OUString aNew;
+ SwStyleNameMapper::FillUIName( RES_POOLCOLL_TEXT, aNew );
+ aList.push_back( aNew );
+ if( m_pWrtShell )
+ {
+ SfxStyleSheetBasePool* pStyleSheetPool = m_pWrtShell->
+ GetView().GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase *pFirstStyle = pStyleSheetPool->First(SfxStyleFamily::Para);
+ while(pFirstStyle)
+ {
+ aList.push_back( pFirstStyle->GetName() );
+ pFirstStyle = pStyleSheetPool->Next();
+ }
+ }
+ // set DrawingLayer FillStyles active
+ aSet.Put(SfxBoolItem(SID_DRAWINGLAYER_FILLSTYLES, true));
+ aSet.Put(SfxStringListItem(SID_COLLECT_LIST, &aList));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "header")
+ {
+ if(0 == (m_nHtmlMode & HTMLMODE_ON ))
+ {
+ static_cast<SvxHeaderPage&>(rPage).EnableDynamicSpacing();
+ }
+
+ // set DrawingLayer FillStyles active
+ aSet.Put(SfxBoolItem(SID_DRAWINGLAYER_FILLSTYLES, true));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "footer")
+ {
+ if(0 == (m_nHtmlMode & HTMLMODE_ON ))
+ {
+ static_cast<SvxFooterPage&>(rPage).EnableDynamicSpacing();
+ }
+
+ // set DrawingLayer FillStyles active
+ aSet.Put(SfxBoolItem(SID_DRAWINGLAYER_FILLSTYLES, true));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "border")
+ {
+ if( SfxStyleFamily::Para == m_nType )
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE,static_cast<sal_uInt16>(SwBorderModes::PARA)));
+ }
+ else if( SfxStyleFamily::Frame == m_nType )
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE,static_cast<sal_uInt16>(SwBorderModes::FRAME)));
+ }
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "borders")
+ {
+ if( SfxStyleFamily::Para == m_nType )
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE,static_cast<sal_uInt16>(SwBorderModes::PARA)));
+ }
+ else if( SfxStyleFamily::Frame == m_nType )
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE,static_cast<sal_uInt16>(SwBorderModes::FRAME)));
+ }
+ rPage.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 (rId == "area")
+ {
+ aSet.Put(GetStyleSheet().GetItemSet());
+
+ // add flag for direct graphic content selection
+ aSet.Put(SfxBoolItem(SID_OFFER_IMPORT, true));
+
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "transparence")
+ {
+ rPage.PageCreated(GetStyleSheet().GetItemSet());
+ }
+ else if (rId == "bullets")
+ {
+ aSet.Put (SfxStringItem(SID_BULLET_CHAR_FMT,sBulletCharFormat));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "outline")
+ {
+ if (SfxStyleFamily::Pseudo == m_nType)
+ {
+ aSet.Put (SfxStringItem(SID_NUM_CHAR_FMT,sNumCharFormat));
+ aSet.Put (SfxStringItem(SID_BULLET_CHAR_FMT,sBulletCharFormat));
+ rPage.PageCreated(aSet);
+ }
+ else if (SfxStyleFamily::Para == m_nType)
+ {
+ // handle if the current paragraph style is assigned to a list level of outline style,
+ SwTextFormatColl* pTmpColl = m_pWrtShell->FindTextFormatCollByName( GetStyleSheet().GetName() );
+ if( pTmpColl && pTmpColl->IsAssignedToListLevelOfOutlineStyle() )
+ {
+ static_cast<SwParagraphNumTabPage&>(rPage).DisableOutline() ;
+ static_cast<SwParagraphNumTabPage&>(rPage).DisableNumbering();
+ }//<-end
+ weld::ComboBox& rBox = static_cast<SwParagraphNumTabPage&>(rPage).GetStyleBox();
+ SfxStyleSheetBasePool* pPool = m_pWrtShell->GetView().GetDocShell()->GetStyleSheetPool();
+ const SfxStyleSheetBase* pBase = pPool->First(SfxStyleFamily::Pseudo);
+ std::set<OUString> aNames;
+ while(pBase)
+ {
+ aNames.insert(pBase->GetName());
+ pBase = pPool->Next();
+ }
+ aNames.erase(SwResId(STR_POOLNUMRULE_NOLIST));
+ for(std::set<OUString>::const_iterator it = aNames.begin(); it != aNames.end(); ++it)
+ rBox.append_text(*it);
+ }
+ }
+ else if (rId == "customize")
+ {
+ aSet.Put (SfxStringItem(SID_NUM_CHAR_FMT,sNumCharFormat));
+ aSet.Put (SfxStringItem(SID_BULLET_CHAR_FMT,sBulletCharFormat));
+
+ // collect character styles
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/comboboxfragment.ui"));
+ std::unique_ptr<weld::ComboBox> xCharFormatLB(xBuilder->weld_combo_box("combobox"));
+ xCharFormatLB->clear();
+ xCharFormatLB->append_text(SwViewShell::GetShellRes()->aStrNone);
+ if (SwWrtShell* pSh = ::GetActiveWrtShell())
+ {
+ SwDocShell* pDocShell = pSh->GetView().GetDocShell();
+ ::FillCharStyleListBox(*xCharFormatLB, pDocShell);
+
+ std::vector<OUString> aList;
+ aList.reserve(xCharFormatLB->get_count());
+ for (sal_Int32 j = 0; j < xCharFormatLB->get_count(); j++)
+ aList.push_back(xCharFormatLB->get_text(j));
+
+ aSet.Put( SfxStringListItem( SID_CHAR_FMT_LIST_BOX,&aList ) ) ;
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast< const SwWebDocShell *>( pDocShell ) != nullptr);
+ aSet.Put ( SfxUInt16Item(SID_METRIC_ITEM, static_cast< sal_uInt16 >(eMetric)));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "indents")
+ {
+ if( rPage.GetItemSet().GetParent() )
+ {
+ constexpr tools::Long constTwips_0_5mm = o3tl::toTwips(5, o3tl::Length::mm10);
+ aSet.Put(SfxUInt32Item(SID_SVXSTDPARAGRAPHTABPAGE_ABSLINEDIST, constTwips_0_5mm));
+ aSet.Put(SfxUInt32Item(SID_SVXSTDPARAGRAPHTABPAGE_FLAGSET,0x000F));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "alignment")
+ {
+ aSet.Put(SfxBoolItem(SID_SVXPARAALIGNTABPAGE_ENABLEJUSTIFYEXT,true));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "asianlayout")
+ {
+ if( SfxStyleFamily::Char == m_nType )
+ {
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, SVX_PREVIEW_CHARACTER));
+ rPage.PageCreated(aSet);
+ }
+ }
+ else if (rId == "type")
+ {
+ static_cast<SwFramePage&>(rPage).SetNewFrame( true );
+ static_cast<SwFramePage&>(rPage).SetFormatUsed( true );
+ }
+ else if (rId == "options")
+ {
+ static_cast<SwFrameAddPage&>(rPage).SetFormatUsed(true);
+ static_cast<SwFrameAddPage&>(rPage).SetNewFrame(true);
+ }
+ else if (rId == "wrap")
+ {
+ static_cast<SwWrapTabPage&>(rPage).SetFormatUsed( true, false );
+ }
+ else if (rId == "macros")
+ {
+ SfxAllItemSet aNewSet(*aSet.GetPool());
+ aNewSet.Put( SwMacroAssignDlg::AddEvents(MACASSGN_ALLFRM) );
+ if ( m_pWrtShell )
+ rPage.SetFrame( m_pWrtShell->GetView().GetViewFrame().GetFrame().GetFrameInterface() );
+ rPage.PageCreated(aNewSet);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/column.cxx b/sw/source/ui/frmdlg/column.cxx
new file mode 100644
index 0000000000..8caa69fade
--- /dev/null
+++ b/sw/source/ui/frmdlg/column.cxx
@@ -0,0 +1,1381 @@
+/* -*- 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 <column.hxx>
+
+#include <hintids.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <sfx2/htmlmode.hxx>
+#include <svx/colorbox.hxx>
+#include <editeng/borderline.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <svl/ctloptions.hxx>
+#include <svl/itemset.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/event.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <swmodule.hxx>
+
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <uitool.hxx>
+#include <cmdid.h>
+#include <viewopt.hxx>
+#include <fmtclbl.hxx>
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+#include <colmgr.hxx>
+#include <prcntfld.hxx>
+#include <strings.hrc>
+#include <section.hxx>
+#include <pagedesc.hxx>
+
+//to match associated data in ColumnPage.ui
+#define LISTBOX_SELECTION 0
+#define LISTBOX_SECTION 1
+#define LISTBOX_SECTIONS 2
+#define LISTBOX_PAGE 3
+#define LISTBOX_FRAME 4
+
+using namespace ::com::sun::star;
+
+#define FRAME_FORMAT_WIDTH 1000
+
+// static data
+const sal_uInt16 nVisCols = 3;
+
+static bool IsMarkInSameSection( SwWrtShell& rWrtSh, const SwSection* pSect )
+{
+ rWrtSh.SwapPam();
+ bool bRet = pSect == rWrtSh.GetCurrSection();
+ rWrtSh.SwapPam();
+ return bRet;
+}
+
+SwColumnDlg::SwColumnDlg(weld::Window* pParent, SwWrtShell& rSh)
+ : SfxDialogController(pParent, "modules/swriter/ui/columndialog.ui", "ColumnDialog")
+ , m_rWrtShell(rSh)
+ , m_pFrameSet(nullptr)
+ , m_nOldSelection(0)
+ , m_nSelectionWidth(0)
+ , m_bPageChanged(false)
+ , m_bSectionChanged(false)
+ , m_bSelSectionChanged(false)
+ , m_bFrameChanged(false)
+ , m_xContentArea(m_xBuilder->weld_container("content"))
+ , m_xOkButton(m_xBuilder->weld_button("ok"))
+{
+ SwRect aRect;
+ m_rWrtShell.CalcBoundRect(aRect, RndStdIds::FLY_AS_CHAR);
+
+ m_nSelectionWidth = aRect.Width();
+
+ SfxItemSet* pColPgSet = nullptr;
+ static const auto aSectIds = svl::Items<RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_COL, RES_COL,
+ RES_COLUMNBALANCE, RES_FRAMEDIR>;
+
+ const SwSection* pCurrSection = m_rWrtShell.GetCurrSection();
+ const sal_uInt16 nFullSectCnt = m_rWrtShell.GetFullSelectedSectionCount();
+ if( pCurrSection && ( !m_rWrtShell.HasSelection() || 0 != nFullSectCnt ))
+ {
+ m_nSelectionWidth = rSh.GetSectionWidth(*pCurrSection->GetFormat());
+ if ( !m_nSelectionWidth )
+ m_nSelectionWidth = USHRT_MAX;
+ m_pSectionSet.reset( new SfxItemSet( m_rWrtShell.GetAttrPool(), aSectIds ) );
+ m_pSectionSet->Put( pCurrSection->GetFormat()->GetAttrSet() );
+ pColPgSet = m_pSectionSet.get();
+ }
+
+ if( m_rWrtShell.HasSelection() && m_rWrtShell.IsInsRegionAvailable() &&
+ ( !pCurrSection || ( 1 != nFullSectCnt &&
+ IsMarkInSameSection( m_rWrtShell, pCurrSection ) )))
+ {
+ m_pSelectionSet.reset( new SfxItemSet( m_rWrtShell.GetAttrPool(), aSectIds ) );
+ pColPgSet = m_pSelectionSet.get();
+ }
+
+ if( m_rWrtShell.GetFlyFrameFormat() )
+ {
+ const SwFrameFormat* pFormat = rSh.GetFlyFrameFormat() ;
+ m_pFrameSet = new SfxItemSet(m_rWrtShell.GetAttrPool(), aSectIds );
+ m_pFrameSet->Put(pFormat->GetFrameSize());
+ m_pFrameSet->Put(pFormat->GetCol());
+ pColPgSet = m_pFrameSet;
+ }
+
+ const SwPageDesc* pPageDesc = m_rWrtShell.GetSelectedPageDescs();
+ if( pPageDesc )
+ {
+ m_pPageSet = std::make_unique<SfxItemSetFixed<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_LR_SPACE, RES_LR_SPACE,
+ RES_COL, RES_COL>>(m_rWrtShell.GetAttrPool());
+
+ const SwFrameFormat &rFormat = pPageDesc->GetMaster();
+ m_nPageWidth = rFormat.GetFrameSize().GetSize().Width();
+
+ const SvxLRSpaceItem& rLRSpace = rFormat.GetLRSpace();
+ const SvxBoxItem& rBox = rFormat.GetBox();
+ m_nPageWidth -= rLRSpace.GetLeft() + rLRSpace.GetRight() + rBox.GetSmallestDistance();
+
+ m_pPageSet->Put(rFormat.GetCol());
+ m_pPageSet->Put(rFormat.GetLRSpace());
+ pColPgSet = m_pPageSet.get();
+ }
+
+ assert(pColPgSet);
+
+ // create TabPage
+ m_xTabPage = std::make_unique<SwColumnPage>(m_xContentArea.get(), this, *pColPgSet);
+ m_xTabPage->GetApplyLabel()->show();
+ weld::ComboBox* pApplyToLB = m_xTabPage->GetApplyComboBox();
+ pApplyToLB->show();
+
+ if (pCurrSection && (!m_rWrtShell.HasSelection() || 0 != nFullSectCnt))
+ {
+ pApplyToLB->remove_id(1 >= nFullSectCnt ? OUString::number(LISTBOX_SECTIONS) : OUString::number(LISTBOX_SECTION));
+ }
+ else
+ {
+ pApplyToLB->remove_id(OUString::number(LISTBOX_SECTION));
+ pApplyToLB->remove_id(OUString::number(LISTBOX_SECTIONS));
+ }
+
+ if (!( m_rWrtShell.HasSelection() && m_rWrtShell.IsInsRegionAvailable() &&
+ ( !pCurrSection || ( 1 != nFullSectCnt &&
+ IsMarkInSameSection( m_rWrtShell, pCurrSection ) ))))
+ pApplyToLB->remove_id(OUString::number(LISTBOX_SELECTION));
+
+ if (!m_rWrtShell.GetFlyFrameFormat())
+ pApplyToLB->remove_id(OUString::number(LISTBOX_FRAME));
+
+ const int nPagePos = pApplyToLB->find_id(OUString::number(LISTBOX_PAGE));
+ if (m_pPageSet && pPageDesc)
+ {
+ const OUString sPageStr = pApplyToLB->get_text(nPagePos) + pPageDesc->GetName();
+ pApplyToLB->remove(nPagePos);
+ OUString sId(OUString::number(LISTBOX_PAGE));
+ pApplyToLB->insert(nPagePos, sPageStr, &sId, nullptr, nullptr);
+ }
+ else
+ pApplyToLB->remove( nPagePos );
+
+ pApplyToLB->set_active(0);
+ ObjectHdl(nullptr);
+
+ pApplyToLB->connect_changed(LINK(this, SwColumnDlg, ObjectListBoxHdl));
+ m_xOkButton->connect_clicked(LINK(this, SwColumnDlg, OkHdl));
+ //#i80458# if no columns can be set then disable OK
+ if (!pApplyToLB->get_count())
+ m_xOkButton->set_sensitive(false);
+ //#i97810# set focus to the TabPage
+ m_xTabPage->ActivateColumnControl();
+}
+
+SwColumnDlg::~SwColumnDlg()
+{
+ m_xTabPage.reset();
+}
+
+IMPL_LINK(SwColumnDlg, ObjectListBoxHdl, weld::ComboBox&, rBox, void)
+{
+ ObjectHdl(&rBox);
+}
+
+void SwColumnDlg::ObjectHdl(const weld::ComboBox* pBox)
+{
+ SfxItemSet* pSet = EvalCurrentSelection();
+
+ if (pBox)
+ {
+ m_xTabPage->FillItemSet(pSet);
+ }
+ weld::ComboBox* pApplyToLB = m_xTabPage->GetApplyComboBox();
+ m_nOldSelection = pApplyToLB->get_active_id().toInt32();
+ tools::Long nWidth = m_nSelectionWidth;
+ switch(m_nOldSelection)
+ {
+ case LISTBOX_SELECTION :
+ pSet = m_pSelectionSet.get();
+ if( m_pSelectionSet )
+ pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
+ break;
+ case LISTBOX_SECTION :
+ case LISTBOX_SECTIONS :
+ pSet = m_pSectionSet.get();
+ pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
+ break;
+ case LISTBOX_PAGE :
+ nWidth = m_nPageWidth;
+ pSet = m_pPageSet.get();
+ pSet->Put(SwFormatFrameSize(SwFrameSize::Variable, nWidth, nWidth));
+ break;
+ case LISTBOX_FRAME:
+ pSet = m_pFrameSet;
+ break;
+ }
+
+ bool bIsSection = pSet == m_pSectionSet.get() || pSet == m_pSelectionSet.get();
+ m_xTabPage->ShowBalance(bIsSection);
+ m_xTabPage->SetInSection(bIsSection);
+ m_xTabPage->SetFrameMode(true);
+ m_xTabPage->SetPageWidth(nWidth);
+ if( pSet )
+ m_xTabPage->Reset(pSet);
+}
+
+IMPL_LINK_NOARG(SwColumnDlg, OkHdl, weld::Button&, void)
+{
+ // evaluate current selection
+ SfxItemSet* pSet = EvalCurrentSelection();
+ m_xTabPage->FillItemSet(pSet);
+
+ if(m_pSelectionSet && SfxItemState::SET == m_pSelectionSet->GetItemState(RES_COL))
+ {
+ //insert region with columns
+ const SwFormatCol& rColItem = m_pSelectionSet->Get(RES_COL);
+ //only if there actually are columns!
+ if(rColItem.GetNumCols() > 1)
+ m_rWrtShell.GetView().GetViewFrame().GetDispatcher()->Execute(
+ FN_INSERT_REGION, SfxCallMode::ASYNCHRON, *m_pSelectionSet );
+ }
+
+ if(m_pSectionSet && m_pSectionSet->Count() && m_bSectionChanged )
+ {
+ const SwSection* pCurrSection = m_rWrtShell.GetCurrSection();
+ const SwSectionFormat* pFormat = pCurrSection->GetFormat();
+ const size_t nNewPos = m_rWrtShell.GetSectionFormatPos( *pFormat );
+ SwSectionData aData(*pCurrSection);
+ m_rWrtShell.UpdateSection( nNewPos, aData, m_pSectionSet.get() );
+ }
+
+ if(m_pSectionSet && m_pSectionSet->Count() && m_bSelSectionChanged )
+ {
+ m_rWrtShell.SetSectionAttr( *m_pSectionSet );
+ }
+
+ if(m_pPageSet && SfxItemState::SET == m_pPageSet->GetItemState(RES_COL) && m_bPageChanged)
+ {
+ // determine current PageDescriptor and fill the Set with it
+ const size_t nCurIdx = m_rWrtShell.GetCurPageDesc();
+ SwPageDesc aPageDesc(m_rWrtShell.GetPageDesc(nCurIdx));
+ SwFrameFormat &rFormat = aPageDesc.GetMaster();
+ rFormat.SetFormatAttr(m_pPageSet->Get(RES_COL));
+ m_rWrtShell.ChgPageDesc(nCurIdx, aPageDesc);
+ }
+ if(m_pFrameSet && SfxItemState::SET == m_pFrameSet->GetItemState(RES_COL) && m_bFrameChanged)
+ {
+ SfxItemSetFixed<RES_COL, RES_COL> aTmp(*m_pFrameSet->GetPool());
+ aTmp.Put(*m_pFrameSet);
+ m_rWrtShell.StartAction();
+ m_rWrtShell.Push();
+ m_rWrtShell.SetFlyFrameAttr( aTmp );
+ // undo the frame selection again
+ if(m_rWrtShell.IsFrameSelected())
+ {
+ m_rWrtShell.UnSelectFrame();
+ m_rWrtShell.LeaveSelFrameMode();
+ }
+ m_rWrtShell.Pop();
+ m_rWrtShell.EndAction();
+ }
+ m_xDialog->response(RET_OK);
+}
+
+SfxItemSet* SwColumnDlg::EvalCurrentSelection()
+{
+ SfxItemSet* pSet = nullptr;
+
+ switch(m_nOldSelection)
+ {
+ case LISTBOX_SELECTION :
+ pSet = m_pSelectionSet.get();
+ break;
+ case LISTBOX_SECTION :
+ pSet = m_pSectionSet.get();
+ m_bSectionChanged = true;
+ break;
+ case LISTBOX_SECTIONS :
+ pSet = m_pSectionSet.get();
+ m_bSelSectionChanged = true;
+ break;
+ case LISTBOX_PAGE :
+ pSet = m_pPageSet.get();
+ m_bPageChanged = true;
+ break;
+ case LISTBOX_FRAME:
+ pSet = m_pFrameSet;
+ m_bFrameChanged = true;
+ break;
+ }
+
+ return pSet;
+}
+
+static
+sal_uInt16 GetMaxWidth( SwColMgr const * pColMgr, sal_uInt16 nCols )
+{
+ sal_uInt16 nMax = pColMgr->GetActualSize();
+ if( --nCols )
+ nMax -= pColMgr->GetGutterWidth() * nCols;
+ return nMax;
+}
+
+const WhichRangesContainer SwColumnPage::s_aPageRg(svl::Items<RES_COL, RES_COL>);
+
+void SwColumnPage::ResetColWidth()
+{
+ if( m_nCols )
+ {
+ const sal_uInt16 nWidth = GetMaxWidth( m_xColMgr.get(), m_nCols ) / m_nCols;
+
+ for(sal_uInt16 i = 0; i < m_nCols; ++i)
+ m_nColWidth[i] = static_cast<tools::Long>(nWidth);
+ }
+
+}
+
+constexpr sal_uInt16 g_nMinWidth(MINLAY);
+
+// Now as TabPage
+SwColumnPage::SwColumnPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/columnpage.ui", "ColumnPage", &rSet)
+ , m_nFirstVis(0)
+ , m_pModifiedField(nullptr)
+ , m_bFormat(false)
+ , m_bFrame(false)
+ , m_bHtmlMode(false)
+ , m_bLockUpdate(false)
+ , m_xCLNrEdt(m_xBuilder->weld_spin_button("colsnf"))
+ , m_xBalanceColsCB(m_xBuilder->weld_check_button("balance"))
+ , m_xBtnBack(m_xBuilder->weld_button("back"))
+ , m_xLbl1(m_xBuilder->weld_label("1"))
+ , m_xLbl2(m_xBuilder->weld_label("2"))
+ , m_xLbl3(m_xBuilder->weld_label("3"))
+ , m_xBtnNext(m_xBuilder->weld_button("next"))
+ , m_xAutoWidthBox(m_xBuilder->weld_check_button("autowidth"))
+ , m_xLineTypeLbl(m_xBuilder->weld_label("linestyleft"))
+ , m_xLineWidthLbl(m_xBuilder->weld_label("linewidthft"))
+ , m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button("linewidthmf", FieldUnit::POINT))
+ , m_xLineColorLbl(m_xBuilder->weld_label("linecolorft"))
+ , m_xLineHeightLbl(m_xBuilder->weld_label("lineheightft"))
+ , m_xLineHeightEdit(m_xBuilder->weld_metric_spin_button("lineheightmf", FieldUnit::PERCENT))
+ , m_xLinePosLbl(m_xBuilder->weld_label("lineposft"))
+ , m_xLinePosDLB(m_xBuilder->weld_combo_box("lineposlb"))
+ , m_xTextDirectionFT(m_xBuilder->weld_label("textdirectionft"))
+ , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("textdirectionlb")))
+ , m_xLineColorDLB(new ColorListBox(m_xBuilder->weld_menu_button("colorlb"),
+ [this]{ return GetFrameWeld(); }))
+ , m_xLineTypeDLB(new SvtLineListBox(m_xBuilder->weld_menu_button("linestylelb")))
+ , m_xEd1(new SwPercentField(m_xBuilder->weld_metric_spin_button("width1mf", FieldUnit::CM)))
+ , m_xEd2(new SwPercentField(m_xBuilder->weld_metric_spin_button("width2mf", FieldUnit::CM)))
+ , m_xEd3(new SwPercentField(m_xBuilder->weld_metric_spin_button("width3mf", FieldUnit::CM)))
+ , m_xDistEd1(new SwPercentField(m_xBuilder->weld_metric_spin_button("spacing1mf", FieldUnit::CM)))
+ , m_xDistEd2(new SwPercentField(m_xBuilder->weld_metric_spin_button("spacing2mf", FieldUnit::CM)))
+ , m_xDefaultVS(new weld::CustomWeld(*m_xBuilder, "valueset", m_aDefaultVS))
+ , m_xPgeExampleWN(new weld::CustomWeld(*m_xBuilder, "pageexample", m_aPgeExampleWN))
+ , m_xFrameExampleWN(new weld::CustomWeld(*m_xBuilder, "frameexample", m_aFrameExampleWN))
+ , m_xApplyToFT(m_xBuilder->weld_label("applytoft"))
+ , m_xApplyToLB(m_xBuilder->weld_combo_box("applytolb"))
+{
+ connectPercentField(*m_xEd1);
+ connectPercentField(*m_xEd2);
+ connectPercentField(*m_xEd3);
+ connectPercentField(*m_xDistEd1);
+ connectPercentField(*m_xDistEd2);
+
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+ m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+
+ SetExchangeSupport();
+
+ m_aDefaultVS.SetColCount(5);
+
+ for (int i = 0; i < 5; ++i)
+ //Set accessible name one by one
+ {
+ OUString aItemText;
+ switch( i )
+ {
+ case 0:
+ aItemText = SwResId( STR_COLUMN_VALUESET_ITEM0 ) ;
+ break;
+ case 1:
+ aItemText = SwResId( STR_COLUMN_VALUESET_ITEM1 ) ;
+ break;
+ case 2:
+ aItemText = SwResId( STR_COLUMN_VALUESET_ITEM2 ) ;
+ break;
+ case 3:
+ aItemText = SwResId( STR_COLUMN_VALUESET_ITEM3 );
+ break;
+ default:
+ aItemText = SwResId( STR_COLUMN_VALUESET_ITEM4 );
+ break;
+ }
+ m_aDefaultVS.InsertItem( i + 1, aItemText, i );
+ }
+
+ m_aDefaultVS.SetSelectHdl(LINK(this, SwColumnPage, SetDefaultsHdl));
+
+ Link<weld::SpinButton&,void> aCLNrLk = LINK(this, SwColumnPage, ColModify);
+ m_xCLNrEdt->connect_value_changed(aCLNrLk);
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwColumnPage, GapModify);
+ m_xDistEd1->connect_value_changed(aLk);
+ m_xDistEd2->connect_value_changed(aLk);
+
+ aLk = LINK(this, SwColumnPage, EdModify);
+
+ m_xEd1->connect_value_changed(aLk);
+ m_xEd2->connect_value_changed(aLk);
+ m_xEd3->connect_value_changed(aLk);
+
+ m_xBtnBack->connect_clicked(LINK(this, SwColumnPage, Up));
+ m_xBtnNext->connect_clicked(LINK(this, SwColumnPage, Down));
+ m_xAutoWidthBox->connect_toggled(LINK(this, SwColumnPage, AutoWidthHdl));
+
+ Link<weld::MetricSpinButton&,void> aLk2 = LINK( this, SwColumnPage, UpdateColMgr );
+ m_xLineTypeDLB->SetSelectHdl(LINK(this, SwColumnPage, UpdateColMgrLineBox));
+ m_xLineWidthEdit->connect_value_changed(aLk2);
+ m_xLineColorDLB->SetSelectHdl(LINK( this, SwColumnPage, UpdateColMgrColorBox));
+ m_xLineHeightEdit->connect_value_changed(aLk2);
+ m_xLinePosDLB->connect_changed(LINK(this, SwColumnPage, UpdateColMgrListBox));
+
+ // Separator line
+ m_xLineTypeDLB->SetSourceUnit( FieldUnit::TWIP );
+
+ // Fill the line styles listbox
+ m_xLineTypeDLB->InsertEntry(
+ ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::SOLID),
+ SvxBorderLineStyle::SOLID );
+ m_xLineTypeDLB->InsertEntry(
+ ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DOTTED),
+ SvxBorderLineStyle::DOTTED );
+ m_xLineTypeDLB->InsertEntry(
+ ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DASHED),
+ SvxBorderLineStyle::DASHED );
+
+ sal_Int64 nLineWidth = m_xLineWidthEdit->get_value(FieldUnit::POINT);
+ nLineWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
+ nLineWidth,
+ m_xLineWidthEdit->get_digits(),
+ FieldUnit::POINT, MapUnit::MapTwip ));
+ m_xLineTypeDLB->SetWidth(nLineWidth);
+ m_xLineColorDLB->SelectEntry(COL_BLACK);
+}
+
+SwColumnPage::~SwColumnPage()
+{
+ m_xFrameExampleWN.reset();
+ m_xPgeExampleWN.reset();
+ m_xDefaultVS.reset();
+ m_xDistEd2.reset();
+ m_xDistEd1.reset();
+ m_xEd3.reset();
+ m_xEd2.reset();
+ m_xEd1.reset();
+ m_xLineTypeDLB.reset();
+ m_xLineColorDLB.reset();
+ m_xTextDirectionLB.reset();
+}
+
+void SwColumnPage::SetPageWidth(tools::Long nPageWidth)
+{
+ tools::Long nNewMaxWidth = static_cast< tools::Long >(m_xEd1->NormalizePercent(nPageWidth));
+
+ m_xDistEd1->set_max(nNewMaxWidth, FieldUnit::TWIP);
+ m_xDistEd2->set_max(nNewMaxWidth, FieldUnit::TWIP);
+ m_xEd1->set_max(nNewMaxWidth, FieldUnit::TWIP);
+ m_xEd2->set_max(nNewMaxWidth, FieldUnit::TWIP);
+ m_xEd3->set_max(nNewMaxWidth, FieldUnit::TWIP);
+}
+
+void SwColumnPage::connectPercentField(SwPercentField &rWrap)
+{
+ weld::MetricSpinButton *pField = rWrap.get();
+ assert(pField);
+ m_aPercentFieldsMap[pField] = &rWrap;
+}
+
+void SwColumnPage::Reset(const SfxItemSet *rSet)
+{
+ const sal_uInt16 nHtmlMode =
+ ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_bHtmlMode = true;
+ m_xAutoWidthBox->set_sensitive(false);
+ }
+ FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
+ m_xEd1->SetMetric(aMetric);
+ m_xEd2->SetMetric(aMetric);
+ m_xEd3->SetMetric(aMetric);
+ m_xDistEd1->SetMetric(aMetric);
+ m_xDistEd2->SetMetric(aMetric);
+ //default spacing between cols = 0.5cm
+ m_xDistEd1->set_value(50, FieldUnit::CM);
+ m_xDistEd2->set_value(50, FieldUnit::CM);
+
+ m_xColMgr.reset(new SwColMgr(*rSet));
+ m_nCols = m_xColMgr->GetCount() ;
+ m_xCLNrEdt->set_max(std::max(o3tl::narrowing<sal_uInt16>(m_xCLNrEdt->get_max()), m_nCols));
+
+ if(m_bFrame)
+ {
+ if(m_bFormat) // there is no size here
+ m_xColMgr->SetActualWidth(FRAME_FORMAT_WIDTH);
+ else
+ {
+ const SwFormatFrameSize& rSize = rSet->Get(RES_FRM_SIZE);
+ const SvxBoxItem& rBox = rSet->Get(RES_BOX);
+ m_xColMgr->SetActualWidth(o3tl::narrowing<sal_uInt16>(rSize.GetSize().Width()) - rBox.GetSmallestDistance());
+ }
+ }
+ if (m_xBalanceColsCB->get_visible())
+ {
+ if( const SwFormatNoBalancedColumns* pItem = rSet->GetItemIfSet( RES_COLUMNBALANCE, false ) )
+ m_xBalanceColsCB->set_active(!pItem->GetValue());
+ else
+ m_xBalanceColsCB->set_active(true);
+ }
+
+ //text direction
+ if( SfxItemState::DEFAULT <= rSet->GetItemState( RES_FRAMEDIR ) )
+ {
+ const SvxFrameDirectionItem& rItem = rSet->Get(RES_FRAMEDIR);
+ SvxFrameDirection nVal = rItem.GetValue();
+ m_xTextDirectionLB->set_active_id(nVal);
+ m_xTextDirectionLB->save_value();
+ }
+
+ Init();
+ ActivatePage( *rSet );
+}
+
+// create TabPage
+std::unique_ptr<SfxTabPage> SwColumnPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwColumnPage>(pPage, pController, *rSet);
+}
+
+// stuff attributes into the Set when OK
+bool SwColumnPage::FillItemSet(SfxItemSet *rSet)
+{
+ // set in ItemSet;
+ // the current settings are already present
+
+ const SfxPoolItem* pOldItem;
+ const SwFormatCol& rCol = m_xColMgr->GetColumns();
+ if(nullptr == (pOldItem = GetOldItem( *rSet, RES_COL )) ||
+ rCol != *pOldItem )
+ rSet->Put(rCol);
+
+ if (m_xBalanceColsCB->get_visible())
+ {
+ rSet->Put(SwFormatNoBalancedColumns(!m_xBalanceColsCB->get_active()));
+ }
+ if (m_xTextDirectionLB->get_visible())
+ {
+ if (m_xTextDirectionLB->get_value_changed_from_saved())
+ {
+ rSet->Put(SvxFrameDirectionItem(m_xTextDirectionLB->get_active_id(), RES_FRAMEDIR) );
+ }
+ }
+ return true;
+}
+
+// update ColumnManager
+IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrListBox, weld::ComboBox&, void )
+{
+ UpdateColMgr(*m_xLineWidthEdit);
+}
+
+IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrLineBox, SvtLineListBox&, void )
+{
+ UpdateColMgr(*m_xLineWidthEdit);
+}
+
+IMPL_LINK_NOARG( SwColumnPage, UpdateColMgrColorBox, ColorListBox&, void )
+{
+ UpdateColMgr(*m_xLineWidthEdit);
+}
+
+IMPL_LINK_NOARG( SwColumnPage, UpdateColMgr, weld::MetricSpinButton&, void )
+{
+ if (!m_xColMgr)
+ return;
+ tools::Long nGutterWidth = m_xColMgr->GetGutterWidth();
+ if (m_nCols > 1)
+ {
+ // Determine whether the most narrow column is too narrow
+ // for the adjusted column gap
+ tools::Long nMin = m_nColWidth[0];
+
+ for( sal_uInt16 i = 1; i < m_nCols; ++i )
+ nMin = std::min(nMin, m_nColWidth[i]);
+
+ bool bAutoWidth = m_xAutoWidthBox->get_active();
+ if(!bAutoWidth)
+ {
+ m_xColMgr->SetAutoWidth(false);
+ // when the user didn't allocate the whole width,
+ // add the missing amount to the last column.
+ tools::Long nSum = 0;
+ for(sal_uInt16 i = 0; i < m_nCols; ++i)
+ nSum += m_nColWidth[i];
+ nGutterWidth = 0;
+ for(sal_uInt16 i = 0; i < m_nCols - 1; ++i)
+ nGutterWidth += m_nColDist[i];
+ nSum += nGutterWidth;
+
+ tools::Long nMaxW = m_xColMgr->GetActualSize();
+
+ if( nSum < nMaxW )
+ m_nColWidth[m_nCols - 1] += nMaxW - nSum;
+
+ m_xColMgr->SetColWidth( 0, static_cast< sal_uInt16 >(m_nColWidth[0] + m_nColDist[0]/2) );
+ for( sal_uInt16 i = 1; i < m_nCols-1; ++i )
+ {
+ tools::Long nActDist = (m_nColDist[i] + m_nColDist[i - 1]) / 2;
+ m_xColMgr->SetColWidth( i, static_cast< sal_uInt16 >(m_nColWidth[i] + nActDist ));
+ }
+ m_xColMgr->SetColWidth( m_nCols-1, static_cast< sal_uInt16 >(m_nColWidth[m_nCols-1] + m_nColDist[m_nCols -2]/2) );
+
+ }
+
+ bool bEnable = isLineNotNone();
+ m_xLineHeightEdit->set_sensitive(bEnable);
+ m_xLineHeightLbl->set_sensitive(bEnable);
+ m_xLineWidthLbl->set_sensitive(bEnable);
+ m_xLineWidthEdit->set_sensitive(bEnable);
+ m_xLineColorDLB->set_sensitive(bEnable);
+ m_xLineColorLbl->set_sensitive(bEnable);
+
+ sal_Int64 nLineWidth = m_xLineWidthEdit->get_value(FieldUnit::PERCENT);
+ nLineWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
+ nLineWidth,
+ m_xLineWidthEdit->get_digits(),
+ m_xLineWidthEdit->get_unit(), MapUnit::MapTwip ));
+ if( !bEnable )
+ m_xColMgr->SetNoLine();
+ else
+ {
+ m_xColMgr->SetLineWidthAndColor(
+ m_xLineTypeDLB->GetSelectEntryStyle(),
+ nLineWidth,
+ m_xLineColorDLB->GetSelectEntryColor() );
+ m_xColMgr->SetAdjust(SwColLineAdj(m_xLinePosDLB->get_active() + 1));
+ m_xColMgr->SetLineHeightPercent(static_cast<short>(m_xLineHeightEdit->get_value(FieldUnit::PERCENT)));
+ bEnable = m_xColMgr->GetLineHeightPercent() != 100;
+ }
+ m_xLinePosLbl->set_sensitive(bEnable);
+ m_xLinePosDLB->set_sensitive(bEnable);
+
+ //fdo#66815 if the values are going to be the same, don't update
+ //them to avoid the listbox selection resetting
+ if (nLineWidth != m_xLineTypeDLB->GetWidth())
+ m_xLineTypeDLB->SetWidth(nLineWidth);
+ Color aColor(m_xLineColorDLB->GetSelectEntryColor());
+ if (aColor != m_xLineTypeDLB->GetColor())
+ m_xLineTypeDLB->SetColor(aColor);
+ }
+ else
+ {
+ m_xColMgr->NoCols();
+ m_nCols = 0;
+ }
+
+ //set maximum values
+ m_xCLNrEdt->set_max(std::max(tools::Long(1),
+ std::min(tools::Long(nMaxCols), tools::Long(m_xColMgr->GetActualSize() / (nGutterWidth + MINLAY)) )));
+
+ //prompt example window
+ if(!m_bLockUpdate)
+ {
+ if(m_bFrame)
+ {
+ m_aFrameExampleWN.SetColumns(m_xColMgr->GetColumns());
+ m_aFrameExampleWN.Invalidate();
+ }
+ else
+ m_aPgeExampleWN.Invalidate();
+ }
+}
+
+void SwColumnPage::Init()
+{
+ m_xCLNrEdt->set_value(m_nCols);
+
+ bool bAutoWidth = m_xColMgr->IsAutoWidth() || m_bHtmlMode;
+ m_xAutoWidthBox->set_active(bAutoWidth);
+
+ sal_Int32 nColumnWidthSum = 0;
+ // set the widths
+ for(sal_uInt16 i = 0; i < m_nCols; ++i)
+ {
+ m_nColWidth[i] = m_xColMgr->GetColWidth(i);
+ nColumnWidthSum += m_nColWidth[i];
+ if(i < m_nCols - 1)
+ m_nColDist[i] = m_xColMgr->GetGutterWidth(i);
+ }
+
+ if( 1 < m_nCols )
+ {
+ // #97495# make sure that the automatic column width's are always equal
+ if(bAutoWidth)
+ {
+ nColumnWidthSum /= m_nCols;
+ for(sal_uInt16 i = 0; i < m_nCols; ++i)
+ m_nColWidth[i] = nColumnWidthSum;
+ }
+ SwColLineAdj eAdj = m_xColMgr->GetAdjust();
+ if( COLADJ_NONE == eAdj ) // the dialog doesn't know a NONE!
+ {
+ eAdj = COLADJ_TOP;
+ //without Adjust no line type
+ m_xLineTypeDLB->SelectEntry(SvxBorderLineStyle::NONE);
+ m_xLineHeightEdit->set_value(100, FieldUnit::PERCENT);
+ }
+ else
+ {
+ // Need to multiply by 100 because of the 2 decimals
+ m_xLineWidthEdit->set_value( m_xColMgr->GetLineWidth() * 100, FieldUnit::TWIP);
+ m_xLineColorDLB->SelectEntry( m_xColMgr->GetLineColor() );
+ m_xLineTypeDLB->SelectEntry( m_xColMgr->GetLineStyle() );
+ m_xLineTypeDLB->SetWidth( m_xColMgr->GetLineWidth( ) );
+ m_xLineHeightEdit->set_value(m_xColMgr->GetLineHeightPercent(), FieldUnit::PERCENT);
+
+ }
+ m_xLinePosDLB->set_active( static_cast< sal_Int32 >(eAdj - 1) );
+ }
+ else
+ {
+ m_xLinePosDLB->set_active(0);
+ m_xLineTypeDLB->SelectEntry(SvxBorderLineStyle::NONE);
+ m_xLineHeightEdit->set_value(100, FieldUnit::PERCENT);
+ }
+
+ UpdateCols();
+ Update(nullptr);
+
+ // set maximum number of columns
+ // values below 1 are not allowed
+ m_xCLNrEdt->set_max(std::max(tools::Long(1),
+ std::min(tools::Long(nMaxCols), tools::Long(m_xColMgr->GetActualSize() / g_nMinWidth) )));
+}
+
+bool SwColumnPage::isLineNotNone() const
+{
+ // nothing is turned off
+ return m_xLineTypeDLB->GetSelectEntryStyle() != SvxBorderLineStyle::NONE;
+}
+
+/*
+ * The number of columns has changed -- here the controls for editing of the
+ * columns are en- or disabled according to the column number. In case there are
+ * more than nVisCols (=3) all Edit are being enabled and the buttons for
+ * scrolling too. Otherwise Edits are being enabled according to the column
+ * numbers; one column can not be edited.
+ */
+void SwColumnPage::UpdateCols()
+{
+ bool bEnableBtns= false;
+ bool bEnable12 = false;
+ bool bEnable3 = false;
+ const bool bEdit = !m_xAutoWidthBox->get_active();
+ if ( m_nCols > nVisCols )
+ {
+ bEnableBtns = !m_bHtmlMode;
+ bEnable12 = bEnable3 = bEdit;
+ }
+ else if( bEdit )
+ {
+ // here are purposely hardly any breaks
+ switch(m_nCols)
+ {
+ case 3: bEnable3 = true;
+ [[fallthrough]];
+ case 2: bEnable12= true; break;
+ default: /* do nothing */;
+ }
+ }
+ m_xEd1->set_sensitive(bEnable12);
+ bool bEnable = m_nCols > 1;
+ m_xDistEd1->set_sensitive(bEnable);
+ m_xAutoWidthBox->set_sensitive(bEnable && !m_bHtmlMode);
+ m_xEd2->set_sensitive(bEnable12);
+ m_xDistEd2->set_sensitive(bEnable3);
+ m_xEd3->set_sensitive(bEnable3);
+ m_xLbl1->set_sensitive(bEnable12);
+ m_xLbl2->set_sensitive(bEnable12);
+ m_xLbl3->set_sensitive(bEnable3);
+ m_xBtnBack->set_sensitive(bEnableBtns);
+ m_xBtnNext->set_sensitive(bEnableBtns);
+
+ m_xLineTypeDLB->set_sensitive( bEnable );
+ m_xLineTypeLbl->set_sensitive( bEnable );
+
+ if (bEnable)
+ {
+ bEnable = isLineNotNone();
+ }
+
+ //all these depend on > 1 column and line style != none
+ m_xLineHeightEdit->set_sensitive(bEnable);
+ m_xLineHeightLbl->set_sensitive(bEnable);
+ m_xLineWidthLbl->set_sensitive(bEnable);
+ m_xLineWidthEdit->set_sensitive(bEnable);
+ m_xLineColorDLB->set_sensitive(bEnable);
+ m_xLineColorLbl->set_sensitive(bEnable);
+
+ if (bEnable)
+ bEnable = m_xColMgr->GetLineHeightPercent() != 100;
+
+ //and these additionally depend on line height != 100%
+ m_xLinePosDLB->set_sensitive(bEnable);
+ m_xLinePosLbl->set_sensitive(bEnable);
+}
+
+void SwColumnPage::SetLabels( sal_uInt16 nVis )
+{
+ //insert ~ before the last character, e.g. 1 -> ~1, 10 -> 1~0
+ const OUString sLbl( '~' );
+
+ const OUString sLbl1(OUString::number( nVis + 1 ));
+ m_xLbl1->set_label(sLbl1.replaceAt(sLbl1.getLength()-1, 0, sLbl));
+
+ const OUString sLbl2(OUString::number( nVis + 2 ));
+ m_xLbl2->set_label(sLbl2.replaceAt(sLbl2.getLength()-1, 0, sLbl));
+
+ const OUString sLbl3(OUString::number( nVis + 3 ));
+ m_xLbl3->set_label(sLbl3.replaceAt(sLbl3.getLength()-1, 0, sLbl));
+
+ const OUString sColumnWidth = SwResId( STR_ACCESS_COLUMN_WIDTH ) ;
+ m_xEd1->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl1));
+ m_xEd2->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl2));
+ m_xEd3->set_accessible_name(sColumnWidth.replaceFirst("%1", sLbl3));
+
+ const OUString sDist = SwResId( STR_ACCESS_PAGESETUP_SPACING ) ;
+ m_xDistEd1->set_accessible_name(
+ sDist.replaceFirst("%1", sLbl1).replaceFirst("%2", sLbl2));
+
+ m_xDistEd2->set_accessible_name(
+ sDist.replaceFirst("%1", sLbl2).replaceFirst("%2", sLbl3));
+}
+
+/*
+ * Handler that is called at alteration of the column number. An alteration of
+ * the column number overwrites potential user's width settings; all columns
+ * are equally wide.
+ */
+IMPL_LINK_NOARG(SwColumnPage, ColModify, weld::SpinButton&, void)
+{
+ ColModify(/*bForceColReset=*/false);
+}
+
+void SwColumnPage::ColModify(bool bForceColReset)
+{
+ m_nCols = o3tl::narrowing<sal_uInt16>(m_xCLNrEdt->get_value());
+ //#107890# the handler is also called from LoseFocus()
+ //then no change has been made and thus no action should be taken
+ // #i17816# changing the displayed types within the ValueSet
+ //from two columns to two columns with different settings doesn't invalidate the
+ // example windows in ::ColModify()
+ if (!bForceColReset && m_xColMgr->GetCount() == m_nCols)
+ return;
+
+ if (!bForceColReset)
+ m_aDefaultVS.SetNoSelection();
+ tools::Long nDist = static_cast< tools::Long >(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
+ m_xColMgr->SetCount(m_nCols, o3tl::narrowing<sal_uInt16>(nDist));
+ for(sal_uInt16 i = 0; i < m_nCols; i++)
+ m_nColDist[i] = nDist;
+ m_nFirstVis = 0;
+ SetLabels( m_nFirstVis );
+ UpdateCols();
+ ResetColWidth();
+ Update(nullptr);
+}
+
+/*
+ * Modify handler for an alteration of the column width or the column gap.
+ * These changes take effect time-displaced. With an alteration of the column
+ * width the automatic calculation of the column width is overruled; only an
+ * alteration of the column number leads back to that default.
+ */
+IMPL_LINK(SwColumnPage, GapModify, weld::MetricSpinButton&, rMetricField, void)
+{
+ if (m_nCols < 2)
+ return;
+ SwPercentField *pField = m_aPercentFieldsMap[&rMetricField];
+ assert(pField);
+ tools::Long nActValue = static_cast< tools::Long >(pField->DenormalizePercent(pField->get_value(FieldUnit::TWIP)));
+ if (m_xAutoWidthBox->get_active())
+ {
+ const tools::Long nMaxGap = static_cast< tools::Long >
+ ((m_xColMgr->GetActualSize() - m_nCols * MINLAY)/(m_nCols - 1));
+ if(nActValue > nMaxGap)
+ {
+ nActValue = nMaxGap;
+ m_xDistEd1->set_value(m_xDistEd1->NormalizePercent(nMaxGap), FieldUnit::TWIP);
+ }
+ m_xColMgr->SetGutterWidth(o3tl::narrowing<sal_uInt16>(nActValue));
+ for(sal_uInt16 i = 0; i < m_nCols; i++)
+ m_nColDist[i] = nActValue;
+
+ ResetColWidth();
+ UpdateCols();
+ }
+ else
+ {
+ const sal_uInt16 nVis = m_nFirstVis + ((pField == m_xDistEd2.get()) ? 1 : 0);
+ tools::Long nDiff = nActValue - m_nColDist[nVis];
+ if(nDiff)
+ {
+ tools::Long nLeft = m_nColWidth[nVis];
+ tools::Long nRight = m_nColWidth[nVis + 1];
+ if(nLeft + nRight + 2 * MINLAY < nDiff)
+ nDiff = nLeft + nRight - 2 * MINLAY;
+ if(nDiff < nRight - MINLAY)
+ {
+ nRight -= nDiff;
+ }
+ else
+ {
+ tools::Long nTemp = nDiff - nRight + MINLAY;
+ nRight = MINLAY;
+ if(nLeft > nTemp - MINLAY)
+ {
+ nLeft -= nTemp;
+ nTemp = 0;
+ }
+ else
+ {
+ nTemp -= nLeft + MINLAY;
+ nLeft = MINLAY;
+ }
+ nDiff = nTemp;
+ }
+ m_nColWidth[nVis] = nLeft;
+ m_nColWidth[nVis + 1] = nRight;
+ m_nColDist[nVis] += nDiff;
+
+ m_xColMgr->SetColWidth( nVis, sal_uInt16(nLeft) );
+ m_xColMgr->SetColWidth( nVis + 1, sal_uInt16(nRight) );
+ m_xColMgr->SetGutterWidth( sal_uInt16(m_nColDist[nVis]), nVis );
+ }
+
+ }
+ Update(&rMetricField);
+}
+
+IMPL_LINK(SwColumnPage, EdModify, weld::MetricSpinButton&, rEdit, void)
+{
+ SwPercentField *pField = m_aPercentFieldsMap[&rEdit];
+ assert(pField);
+ m_pModifiedField = pField;
+ Timeout();
+}
+
+// Handler behind the Checkbox for automatic width. When the box is checked
+// no explicit values for the column width can be entered.
+IMPL_LINK(SwColumnPage, AutoWidthHdl, weld::Toggleable&, rBox, void)
+{
+ tools::Long nDist = static_cast< tools::Long >(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
+ m_xColMgr->SetCount(m_nCols, o3tl::narrowing<sal_uInt16>(nDist));
+ for(sal_uInt16 i = 0; i < m_nCols; i++)
+ m_nColDist[i] = nDist;
+ if (rBox.get_active())
+ {
+ m_xColMgr->SetGutterWidth(sal_uInt16(nDist));
+ ResetColWidth();
+ }
+ m_xColMgr->SetAutoWidth(rBox.get_active(), sal_uInt16(nDist));
+ UpdateCols();
+ Update(nullptr);
+}
+
+// scroll up the contents of the edits
+IMPL_LINK_NOARG(SwColumnPage, Up, weld::Button&, void)
+{
+ if( m_nFirstVis )
+ {
+ --m_nFirstVis;
+ SetLabels( m_nFirstVis );
+ Update(nullptr);
+ }
+}
+
+// scroll down the contents of the edits.
+IMPL_LINK_NOARG(SwColumnPage, Down, weld::Button&, void)
+{
+ if( m_nFirstVis + nVisCols < m_nCols )
+ {
+ ++m_nFirstVis;
+ SetLabels( m_nFirstVis );
+ Update(nullptr);
+ }
+}
+
+// relict from ancient times - now directly without time handler; triggered by
+// an alteration of the column width or the column gap.
+void SwColumnPage::Timeout()
+{
+ SwPercentField *pField = m_pModifiedField;
+ if (m_pModifiedField)
+ {
+ // find the changed column
+ sal_uInt16 nChanged = m_nFirstVis;
+ if (m_pModifiedField == m_xEd2.get())
+ ++nChanged;
+ else if (m_pModifiedField == m_xEd3.get())
+ nChanged += 2;
+
+ tools::Long nNewWidth = static_cast< tools::Long >
+ (m_pModifiedField->DenormalizePercent(m_pModifiedField->get_value(FieldUnit::TWIP)));
+ tools::Long nDiff = nNewWidth - m_nColWidth[nChanged];
+
+ // when it's the last column
+ if(nChanged == m_nCols - 1)
+ {
+ m_nColWidth[0] -= nDiff;
+ if(m_nColWidth[0] < static_cast<tools::Long>(g_nMinWidth))
+ {
+ nNewWidth -= g_nMinWidth - m_nColWidth[0];
+ m_nColWidth[0] = g_nMinWidth;
+ }
+
+ }
+ else if(nDiff)
+ {
+ m_nColWidth[nChanged + 1] -= nDiff;
+ if(m_nColWidth[nChanged + 1] < static_cast<tools::Long>(g_nMinWidth))
+ {
+ nNewWidth -= g_nMinWidth - m_nColWidth[nChanged + 1];
+ m_nColWidth[nChanged + 1] = g_nMinWidth;
+ }
+ }
+ m_nColWidth[nChanged] = nNewWidth;
+ m_pModifiedField = nullptr;
+ }
+
+ Update(pField ? pField->get() : nullptr);
+}
+
+// Update the view
+void SwColumnPage::Update(const weld::MetricSpinButton* pInteractiveField)
+{
+ m_xBalanceColsCB->set_sensitive(m_nCols > 1);
+ if(m_nCols >= 2)
+ {
+ sal_Int64 nCurrentValue, nNewValue;
+
+ nCurrentValue = m_xEd1->NormalizePercent(m_xEd1->DenormalizePercent(m_xEd1->get_value(FieldUnit::TWIP)));
+ nNewValue = m_xEd1->NormalizePercent(m_nColWidth[m_nFirstVis]);
+
+ //fdo#87612 if we're interacting with this widget and the value will be the same
+ //then leave it alone (i.e. don't change equivalent values of e.g. .8 -> 0.8)
+ if (nNewValue != nCurrentValue || pInteractiveField != m_xEd1->get())
+ m_xEd1->set_value(nNewValue, FieldUnit::TWIP);
+
+ nCurrentValue = m_xDistEd1->NormalizePercent(m_xDistEd1->DenormalizePercent(m_xDistEd1->get_value(FieldUnit::TWIP)));
+ nNewValue = m_xDistEd1->NormalizePercent(m_nColDist[m_nFirstVis]);
+ if (nNewValue != nCurrentValue || pInteractiveField != m_xDistEd1->get())
+ m_xDistEd1->set_value(nNewValue, FieldUnit::TWIP);
+
+ nCurrentValue = m_xEd2->NormalizePercent(m_xEd2->DenormalizePercent(m_xEd2->get_value(FieldUnit::TWIP)));
+ nNewValue = m_xEd2->NormalizePercent(m_nColWidth[m_nFirstVis+1]);
+ if (nNewValue != nCurrentValue || pInteractiveField != m_xEd2->get())
+ m_xEd2->set_value(nNewValue, FieldUnit::TWIP);
+
+ if(m_nCols >= 3)
+ {
+ nCurrentValue = m_xDistEd2->NormalizePercent(m_xDistEd2->DenormalizePercent(m_xDistEd2->get_value(FieldUnit::TWIP)));
+ nNewValue = m_xDistEd2->NormalizePercent(m_nColDist[m_nFirstVis+1]);
+ if (nNewValue != nCurrentValue || pInteractiveField != m_xDistEd2->get())
+ m_xDistEd2->set_value(nNewValue, FieldUnit::TWIP);
+
+ nCurrentValue = m_xEd3->NormalizePercent(m_xEd3->DenormalizePercent(m_xEd3->get_value(FieldUnit::TWIP)));
+ nNewValue = m_xEd3->NormalizePercent(m_nColWidth[m_nFirstVis+2]);
+ if (nNewValue != nCurrentValue || pInteractiveField != m_xEd3->get())
+ m_xEd3->set_value(nNewValue, FieldUnit::TWIP);
+ }
+ else
+ {
+ m_xEd3->set_text(OUString());
+ m_xDistEd2->set_text(OUString());
+ }
+ }
+ else
+ {
+ m_xEd1->set_text(OUString());
+ m_xEd2->set_text(OUString());
+ m_xEd3->set_text(OUString());
+ m_xDistEd1->set_text(OUString());
+ m_xDistEd2->set_text(OUString());
+ }
+ UpdateColMgr(*m_xLineWidthEdit);
+}
+
+// Update Bsp
+void SwColumnPage::ActivatePage(const SfxItemSet& rSet)
+{
+ bool bVertical = false;
+ if (SfxItemState::DEFAULT <= rSet.GetItemState(RES_FRAMEDIR))
+ {
+ const SvxFrameDirectionItem& rDirItem =
+ rSet.Get(RES_FRAMEDIR);
+ bVertical = rDirItem.GetValue() == SvxFrameDirection::Vertical_RL_TB||
+ rDirItem.GetValue() == SvxFrameDirection::Vertical_LR_TB;
+ }
+
+ if (!m_bFrame)
+ {
+ if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_PAGE_SIZE ))
+ {
+ const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
+
+ sal_uInt16 nActWidth;
+
+ if (!bVertical)
+ {
+ const SvxLRSpaceItem& rLRSpace = rSet.Get(RES_LR_SPACE);
+ const SvxBoxItem& rBox = rSet.Get(RES_BOX);
+ nActWidth = rSize.GetSize().Width()
+ - rLRSpace.GetLeft() - rLRSpace.GetRight() - rBox.GetSmallestDistance();
+ }
+ else
+ {
+ const SvxULSpaceItem& rULSpace = rSet.Get( RES_UL_SPACE );
+ const SvxBoxItem& rBox = rSet.Get(RES_BOX);
+ nActWidth = rSize.GetSize().Height()
+ - rULSpace.GetUpper() - rULSpace.GetLower() - rBox.GetSmallestDistance();
+
+ }
+
+ if( m_xColMgr->GetActualSize() != nActWidth)
+ {
+ m_xColMgr->SetActualWidth(nActWidth);
+ ColModify(/*bForceColReset=*/false);
+ UpdateColMgr( *m_xLineWidthEdit );
+ }
+ }
+ m_xFrameExampleWN->hide();
+ m_aPgeExampleWN.UpdateExample(rSet, m_xColMgr.get());
+ m_xPgeExampleWN->show();
+
+ }
+ else
+ {
+ m_xPgeExampleWN->hide();
+ m_xFrameExampleWN->show();
+
+ // Size
+ const SwFormatFrameSize& rSize = rSet.Get(RES_FRM_SIZE);
+ const SvxBoxItem& rBox = rSet.Get(RES_BOX);
+
+ sal_uInt16 nTotalWish;
+ if (m_bFormat)
+ nTotalWish = FRAME_FORMAT_WIDTH;
+ else
+ {
+ tools::Long const nDistance = rBox.GetSmallestDistance();
+ nTotalWish = (!bVertical ? rSize.GetWidth() : rSize.GetHeight()) - 2 * nDistance;
+ }
+
+ // set maximum values of column width
+ SetPageWidth(nTotalWish);
+
+ if(m_xColMgr->GetActualSize() != nTotalWish)
+ {
+ m_xColMgr->SetActualWidth(nTotalWish);
+ Init();
+ }
+ bool bPercent;
+ // only relative data in frame format
+ if ( m_bFormat || (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED) )
+ {
+ // set value for 100%
+ m_xEd1->SetRefValue(nTotalWish);
+ m_xEd2->SetRefValue(nTotalWish);
+ m_xEd3->SetRefValue(nTotalWish);
+ m_xDistEd1->SetRefValue(nTotalWish);
+ m_xDistEd2->SetRefValue(nTotalWish);
+
+ // switch to %-view
+ bPercent = true;
+ }
+ else
+ bPercent = false;
+
+ m_xEd1->ShowPercent(bPercent);
+ m_xEd2->ShowPercent(bPercent);
+ m_xEd3->ShowPercent(bPercent);
+ m_xDistEd1->ShowPercent(bPercent);
+ m_xDistEd2->ShowPercent(bPercent);
+ m_xDistEd1->SetMetricFieldMin(0);
+ m_xDistEd2->SetMetricFieldMin(0);
+ }
+ Update(nullptr);
+}
+
+DeactivateRC SwColumnPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+IMPL_LINK(SwColumnPage, SetDefaultsHdl, ValueSet *, pVS, void)
+{
+ const sal_uInt16 nItem = pVS->GetSelectedItemId();
+ if( nItem < 4 )
+ {
+ m_xCLNrEdt->set_value(nItem);
+ m_xAutoWidthBox->set_active(true);
+ m_xDistEd1->set_value(50, FieldUnit::CM);
+ ColModify(/*bForceColReset=*/true);
+ }
+ else
+ {
+ m_bLockUpdate = true;
+ m_xCLNrEdt->set_value(2);
+ m_xAutoWidthBox->set_active(false);
+ m_xDistEd1->set_value(50, FieldUnit::CM);
+ ColModify(/*bForceColReset=*/true);
+ // now set the width ratio to 2 : 1 or 1 : 2 respectively
+ const tools::Long nSmall = static_cast< tools::Long >(m_xColMgr->GetActualSize() / 3);
+ if(nItem == 4)
+ {
+ m_xEd2->set_value(m_xEd2->NormalizePercent(nSmall), FieldUnit::TWIP);
+ m_pModifiedField = m_xEd2.get();
+ }
+ else
+ {
+ m_xEd1->set_value(m_xEd1->NormalizePercent(nSmall), FieldUnit::TWIP);
+ m_pModifiedField = m_xEd1.get();
+ }
+ m_bLockUpdate = false;
+ Timeout();
+
+ }
+}
+
+void SwColumnPage::SetFrameMode(bool bMod)
+{
+ m_bFrame = bMod;
+}
+
+void SwColumnPage::SetInSection(bool bSet)
+{
+ if(!SvtCTLOptions::IsCTLFontEnabled())
+ return;
+
+ m_xTextDirectionFT->set_visible(bSet);
+ m_xTextDirectionLB->set_visible(bSet);
+}
+
+void ColumnValueSet::UserDraw(const UserDrawEvent& rUDEvt)
+{
+ vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ tools::Rectangle aRect = rUDEvt.GetRect();
+ const sal_uInt16 nItemId = rUDEvt.GetItemId();
+ tools::Long nRectWidth = aRect.GetWidth();
+ tools::Long nRectHeight = aRect.GetHeight();
+
+ Point aBLPos = aRect.TopLeft();
+ Color aFillColor(pDev->GetFillColor());
+ Color aLineColor(pDev->GetLineColor());
+ pDev->SetFillColor(rStyleSettings.GetFieldColor());
+ pDev->SetLineColor(rStyleSettings.GetFieldTextColor());
+
+ tools::Long nStep = std::abs(std::abs(nRectHeight * 95 /100) / 11);
+ tools::Long nTop = (nRectHeight - 11 * nStep ) / 2;
+ sal_uInt16 nCols = 0;
+ tools::Long nStarts[3];
+ tools::Long nEnds[3];
+ nStarts[0] = nRectWidth * 10 / 100;
+ switch( nItemId )
+ {
+ case 1:
+ nEnds[0] = nRectWidth * 9 / 10;
+ nCols = 1;
+ break;
+ case 2: nCols = 2;
+ nEnds[0] = nRectWidth * 45 / 100;
+ nStarts[1] = nEnds[0] + nStep;
+ nEnds[1] = nRectWidth * 9 / 10;
+ break;
+ case 3: nCols = 3;
+ nEnds[0] = nRectWidth * 30 / 100;
+ nStarts[1] = nEnds[0] + nStep;
+ nEnds[1] = nRectWidth * 63 / 100;
+ nStarts[2] = nEnds[1] + nStep;
+ nEnds[2] = nRectWidth * 9 / 10;
+ break;
+ case 4: nCols = 2;
+ nEnds[0] = nRectWidth * 63 / 100;
+ nStarts[1] = nEnds[0] + nStep;
+ nEnds[1] = nRectWidth * 9 / 10;
+ break;
+ case 5: nCols = 2;
+ nEnds[0] = nRectWidth * 30 / 100;
+ nStarts[1] = nEnds[0] + nStep;
+ nEnds[1] = nRectWidth * 9 / 10;
+ break;
+ }
+ for(sal_uInt16 j = 0; j < nCols; j++ )
+ {
+ Point aStart(aBLPos.X() + nStarts[j], 0);
+ Point aEnd(aBLPos.X() + nEnds[j], 0);
+ for( sal_uInt16 i = 0; i < 12; i ++)
+ {
+ aStart.setY( aBLPos.Y() + nTop + i * nStep);
+ aEnd.setY( aStart.Y() );
+ pDev->DrawLine(aStart, aEnd);
+ }
+ }
+ pDev->SetFillColor(aFillColor);
+ pDev->SetLineColor(aLineColor);
+}
+
+void ColumnValueSet::StyleUpdated()
+{
+ SetFormat();
+ Invalidate();
+ ValueSet::StyleUpdated();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/cption.cxx b/sw/source/ui/frmdlg/cption.cxx
new file mode 100644
index 0000000000..e6b387a429
--- /dev/null
+++ b/sw/source/ui/frmdlg/cption.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 <utility>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <cption.hxx>
+#include <fldmgr.hxx>
+#include <expfld.hxx>
+#include <numrule.hxx>
+#include <poolfmt.hxx>
+#include <docsh.hxx>
+#include <calc.hxx>
+#include <uitool.hxx>
+#include <doc.hxx>
+#include <modcfg.hxx>
+#include <swmodule.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
+#include <com/sun/star/text/XTextFramesSupplier.hpp>
+#include <comphelper/string.hxx>
+#include <vcl/weld.hxx>
+#include <strings.hrc>
+#include <SwStyleNameMapper.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class SwSequenceOptionDialog : public weld::GenericDialogController
+{
+ SwView& m_rView;
+ OUString m_aFieldTypeName;
+
+ std::unique_ptr<weld::ComboBox> m_xLbLevel;
+ std::unique_ptr<weld::Entry> m_xEdDelim;
+
+ std::unique_ptr<weld::ComboBox> m_xLbCharStyle;
+ std::unique_ptr<weld::CheckButton> m_xApplyBorderAndShadowCB;
+
+ //#i61007# order of captions
+ std::unique_ptr<weld::ComboBox> m_xLbCaptionOrder;
+
+public:
+ SwSequenceOptionDialog(weld::Window *pParent, SwView &rV, OUString aSeqFieldType);
+ void Apply();
+
+ bool IsApplyBorderAndShadow() const { return m_xApplyBorderAndShadowCB->get_active(); }
+ void SetApplyBorderAndShadow( bool bSet ) { m_xApplyBorderAndShadowCB->set_active(bSet); }
+
+ //#i61007# order of captions
+ bool IsOrderNumberingFirst() const { return m_xLbCaptionOrder->get_active() == 1; }
+ void SetOrderNumberingFirst(bool bSet) { m_xLbCaptionOrder->set_active(bSet ? 1 : 0); }
+
+ void SetCharacterStyle(const OUString& rStyle);
+ OUString GetCharacterStyle() const;
+};
+
+}
+
+OUString SwCaptionDialog::s_aSepTextSave(": "); // Caption separator text
+
+//Resolves: tdf#47427 disallow typing *or* pasting invalid content into the category box
+OUString TextFilterAutoConvert::filter(const OUString &rText)
+{
+ if (!rText.isEmpty() && rText != m_sNone && !SwCalc::IsValidVarName(rText))
+ return m_sLastGoodText;
+ m_sLastGoodText = rText;
+ return rText;
+}
+
+SwCaptionDialog::SwCaptionDialog(weld::Window *pParent, SwView &rV)
+ : SfxDialogController(pParent, "modules/swriter/ui/insertcaption.ui", "InsertCaptionDialog")
+ , m_sNone(SwResId(SW_STR_NONE))
+ , m_aTextFilter(m_sNone)
+ , m_rView(rV)
+ , m_pMgr(new SwFieldMgr(m_rView.GetWrtShellPtr()))
+ , m_bCopyAttributes(false)
+ , m_bOrderNumberingFirst(SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst())
+ , m_xTextEdit(m_xBuilder->weld_entry("caption_edit"))
+ , m_xCategoryBox(m_xBuilder->weld_combo_box("category"))
+ , m_xFormatText(m_xBuilder->weld_label("numbering_label"))
+ , m_xFormatBox(m_xBuilder->weld_combo_box("numbering"))
+ , m_xNumberingSeparatorFT(m_xBuilder->weld_label("num_separator"))
+ , m_xNumberingSeparatorED(m_xBuilder->weld_entry("num_separator_edit"))
+ , m_xSepText(m_xBuilder->weld_label("separator_label"))
+ , m_xSepEdit(m_xBuilder->weld_entry("separator_edit"))
+ , m_xPosBox(m_xBuilder->weld_combo_box("position"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xAutoCaptionButton(m_xBuilder->weld_button("auto"))
+ , m_xOptionButton(m_xBuilder->weld_button("options"))
+ , m_xPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreview))
+{
+ //#i61007# order of captions
+ ApplyCaptionOrder();
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ uno::Reference< frame::XModel > xModel = m_rView.GetDocShell()->GetBaseModel();
+
+ SelectionType eType = rSh.GetSelectionType();
+ if ( eType & SelectionType::Ole )
+ {
+ eType = SelectionType::Graphic;
+ uno::Reference< text::XTextEmbeddedObjectsSupplier > xObjs(xModel, uno::UNO_QUERY);
+ m_xNameAccess = xObjs->getEmbeddedObjects();
+ }
+
+ m_xCategoryBox->connect_changed(LINK(this, SwCaptionDialog, ModifyComboHdl));
+ Link<weld::Entry&,void> aLk = LINK(this, SwCaptionDialog, ModifyEntryHdl);
+ m_xTextEdit->connect_changed(aLk);
+ m_xNumberingSeparatorED->connect_changed(aLk);
+ m_xSepEdit->connect_changed(aLk);
+
+ m_xFormatBox->connect_changed(LINK(this, SwCaptionDialog, SelectListBoxHdl));
+ m_xOKButton->connect_clicked(LINK(this, SwCaptionDialog, OKHdl));
+ m_xOptionButton->connect_clicked(LINK(this, SwCaptionDialog, OptionHdl));
+ m_xAutoCaptionButton->connect_clicked(LINK(this, SwCaptionDialog, CaptionHdl));
+ m_xAutoCaptionButton->set_accessible_description(SwResId(STR_A11Y_DESC_AUTO));
+
+ m_xCategoryBox->append_text(m_sNone);
+ size_t nCount = m_pMgr->GetFieldTypeCount();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ SwFieldType *pType = m_pMgr->GetFieldType( SwFieldIds::Unknown, i );
+ if( pType->Which() == SwFieldIds::SetExp &&
+ static_cast<SwSetExpFieldType *>( pType)->GetType() & nsSwGetSetExpType::GSE_SEQ )
+ m_xCategoryBox->append_text(pType->GetName());
+ }
+
+ OUString sString;
+ sal_uInt16 nPoolId = 0;
+ if (eType & SelectionType::Graphic)
+ {
+ nPoolId = RES_POOLCOLL_LABEL_FIGURE;
+
+ SwSetExpFieldType* pTypeIll= static_cast<SwSetExpFieldType*>(rSh.GetFieldType(SwFieldIds::SetExp, SwResId(STR_POOLCOLL_LABEL_ABB)));
+ if(rSh.IsUsed(*pTypeIll)) //default to illustration for legacy docs
+ {
+ nPoolId = RES_POOLCOLL_LABEL_ABB;
+
+ }
+
+ sString = m_rView.GetOldGrfCat();
+ m_bCopyAttributes = true;
+ //if not OLE
+ if(!m_xNameAccess.is())
+ {
+ uno::Reference< text::XTextGraphicObjectsSupplier > xGraphics(xModel, uno::UNO_QUERY);
+ m_xNameAccess = xGraphics->getGraphicObjects();
+ }
+
+ }
+ else if( eType & SelectionType::Table )
+ {
+ nPoolId = RES_POOLCOLL_LABEL_TABLE;
+ sString = m_rView.GetOldTabCat();
+ uno::Reference< text::XTextTablesSupplier > xTables(xModel, uno::UNO_QUERY);
+ m_xNameAccess = xTables->getTextTables();
+ }
+ else if( eType & SelectionType::Frame )
+ {
+ nPoolId = RES_POOLCOLL_LABEL_FRAME;
+ sString = m_rView.GetOldFrameCat();
+ uno::Reference< text::XTextFramesSupplier > xFrames(xModel, uno::UNO_QUERY);
+ m_xNameAccess = xFrames->getTextFrames();
+ }
+ else if( eType == SelectionType::Text )
+ {
+ nPoolId = RES_POOLCOLL_LABEL_FRAME;
+ sString = m_rView.GetOldFrameCat();
+ }
+ else if( eType & SelectionType::DrawObject )
+ {
+ nPoolId = RES_POOLCOLL_LABEL_DRAWING;
+ sString = m_rView.GetOldDrwCat();
+ }
+ if( nPoolId )
+ {
+ if (sString.isEmpty())
+ sString = SwStyleNameMapper::GetUIName(nPoolId, OUString());
+ auto nIndex = m_xCategoryBox->find_text(sString);
+ if (nIndex != -1)
+ m_xCategoryBox->set_active(nIndex);
+ else
+ m_xCategoryBox->set_entry_text(sString);
+ }
+
+ // aFormatBox
+ sal_uInt16 nSelFormat = SVX_NUM_ARABIC;
+ nCount = m_pMgr->GetFieldTypeCount();
+ for ( size_t i = nCount; i; )
+ {
+ SwFieldType* pFieldType = m_pMgr->GetFieldType(SwFieldIds::Unknown, --i);
+ if (pFieldType->GetName() == m_xCategoryBox->get_active_text())
+ {
+ nSelFormat = o3tl::narrowing<sal_uInt16>(static_cast<SwSetExpFieldType*>(pFieldType)->GetSeqFormat());
+ break;
+ }
+ }
+
+ sal_uInt16 nFormatCount = m_pMgr->GetFormatCount(SwFieldTypesEnum::Sequence, false);
+ for ( sal_uInt16 i = 0; i < nFormatCount; ++i )
+ {
+ const sal_uInt16 nFormatId = m_pMgr->GetFormatId(SwFieldTypesEnum::Sequence, i);
+ m_xFormatBox->append(OUString::number(nFormatId), m_pMgr->GetFormatStr(SwFieldTypesEnum::Sequence, i));
+ if (nFormatId == nSelFormat)
+ m_xFormatBox->set_active(i);
+ }
+
+ // aPosBox
+ if (eType == SelectionType::Graphic
+ || eType == SelectionType::Table
+ || eType == (SelectionType::Table | SelectionType::NumberList)
+ || eType == (SelectionType::Table | SelectionType::Text)
+ || eType == (SelectionType::Table | SelectionType::NumberList | SelectionType::Text)
+ || eType == SelectionType::DrawObject
+ || eType == (SelectionType::DrawObject | SelectionType::Ornament))
+ {
+ m_xPosBox->append_text(SwResId(STR_CAPTION_ABOVE));
+ m_xPosBox->append_text(SwResId(STR_CAPTION_BELOW));
+ }
+ else if(eType == SelectionType::Frame
+ || eType == SelectionType::Text)
+ {
+ m_xPosBox->append_text(SwResId(STR_CAPTION_BEGINNING));
+ m_xPosBox->append_text(SwResId(STR_CAPTION_END));
+ }
+
+ if (eType & SelectionType::Table)
+ {
+ m_xPosBox->set_active(0);
+ }
+ else
+ {
+ m_xPosBox->set_active(1);
+ }
+
+ ModifyHdl();
+
+ m_xSepEdit->set_text(s_aSepTextSave);
+ m_xTextEdit->grab_focus();
+ DrawSample();
+}
+
+IMPL_LINK_NOARG(SwCaptionDialog, OKHdl, weld::Button&, void)
+{
+ Apply();
+ m_xDialog->response(RET_OK);
+}
+
+void SwCaptionDialog::Apply()
+{
+ InsCaptionOpt aOpt;
+ aOpt.UseCaption() = true;
+ OUString aName(m_xCategoryBox->get_active_text());
+ if ( aName == m_sNone )
+ {
+ aOpt.SetCategory( OUString() );
+ aOpt.SetNumSeparator( OUString() );
+ }
+ else
+ {
+ aOpt.SetCategory(comphelper::string::strip(aName, ' '));
+ aOpt.SetNumSeparator(m_xNumberingSeparatorED->get_text());
+ }
+ aOpt.SetNumType(m_xFormatBox->get_active_id().toUInt32());
+ aOpt.SetSeparator(m_xSepEdit->get_sensitive() ? m_xSepEdit->get_text() : OUString());
+ aOpt.SetCaption(m_xTextEdit->get_text());
+ aOpt.SetPos(m_xPosBox->get_active());
+ aOpt.IgnoreSeqOpts() = true;
+ aOpt.CopyAttributes() = m_bCopyAttributes;
+ aOpt.SetCharacterStyle( m_sCharacterStyle );
+ m_rView.InsertCaption( &aOpt );
+ s_aSepTextSave = m_xSepEdit->get_text();
+}
+
+short SwCaptionDialog::run()
+{
+ short nRet = SfxDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+IMPL_LINK_NOARG(SwCaptionDialog, OptionHdl, weld::Button&, void)
+{
+ OUString sFieldTypeName = m_xCategoryBox->get_active_text();
+ if(sFieldTypeName == m_sNone)
+ sFieldTypeName.clear();
+ auto pDlg = std::make_shared<SwSequenceOptionDialog>(m_xDialog.get(), m_rView, sFieldTypeName);
+ pDlg->SetApplyBorderAndShadow(m_bCopyAttributes);
+ pDlg->SetCharacterStyle( m_sCharacterStyle );
+ pDlg->SetOrderNumberingFirst( m_bOrderNumberingFirst );
+
+ GenericDialogController::runAsync(pDlg, [pDlg, this](sal_Int32 nResult){
+ if (nResult == RET_OK) {
+ pDlg->Apply();
+ m_bCopyAttributes = pDlg->IsApplyBorderAndShadow();
+ m_sCharacterStyle = pDlg->GetCharacterStyle();
+ //#i61007# order of captions
+ if( m_bOrderNumberingFirst != pDlg->IsOrderNumberingFirst() )
+ {
+ m_bOrderNumberingFirst = pDlg->IsOrderNumberingFirst();
+ SW_MOD()->GetModuleConfig()->SetCaptionOrderNumberingFirst(m_bOrderNumberingFirst);
+ ApplyCaptionOrder();
+ }
+ DrawSample();
+ }
+ });
+}
+
+IMPL_LINK_NOARG(SwCaptionDialog, SelectListBoxHdl, weld::ComboBox&, void)
+{
+ DrawSample();
+}
+
+void SwCaptionDialog::ModifyHdl()
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ OUString sFieldTypeName = m_xCategoryBox->get_active_text();
+ bool bCorrectFieldName = !sFieldTypeName.isEmpty();
+ bool bNone = sFieldTypeName == m_sNone;
+ SwFieldType* pType = (bCorrectFieldName && !bNone)
+ ? rSh.GetFieldType( SwFieldIds::SetExp, sFieldTypeName )
+ : nullptr;
+ m_xOKButton->set_sensitive( bCorrectFieldName &&
+ (!pType ||
+ static_cast<SwSetExpFieldType*>(pType)->GetType() == nsSwGetSetExpType::GSE_SEQ) );
+ m_xOptionButton->set_sensitive(m_xOKButton->get_sensitive() && !bNone);
+ m_xNumberingSeparatorFT->set_sensitive(m_bOrderNumberingFirst && !bNone);
+ m_xNumberingSeparatorED->set_sensitive(m_bOrderNumberingFirst && !bNone);
+ m_xFormatText->set_sensitive(!bNone);
+ m_xFormatBox->set_sensitive(!bNone);
+ m_xSepText->set_sensitive(!bNone);
+ m_xSepEdit->set_sensitive(!bNone);
+ DrawSample();
+}
+
+IMPL_LINK_NOARG(SwCaptionDialog, ModifyEntryHdl, weld::Entry&, void)
+{
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwCaptionDialog, ModifyComboHdl, weld::ComboBox&, void)
+{
+ OUString sText = m_xCategoryBox->get_active_text();
+ OUString sAllowedText = m_aTextFilter.filter(sText);
+ if (sText != sAllowedText)
+ {
+ m_xCategoryBox->set_entry_text(sAllowedText);
+ m_xCategoryBox->select_entry_region(sAllowedText.getLength(), sAllowedText.getLength());
+ }
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwCaptionDialog, CaptionHdl, weld::Button&, void)
+{
+ SfxItemSet aSet(m_rView.GetDocShell()->GetDoc()->GetAttrPool());
+ SwCaptionOptDlg aDlg(m_xDialog.get(), aSet);
+ aDlg.run();
+}
+
+void SwCaptionDialog::DrawSample()
+{
+ OUString aStr;
+ OUString sCaption = m_xTextEdit->get_text();
+
+ // number
+ OUString sFieldTypeName = m_xCategoryBox->get_active_text();
+ bool bNone = sFieldTypeName == m_sNone;
+ if( !bNone )
+ {
+ const sal_uInt16 nNumFormat = m_xFormatBox->get_active_id().toUInt32();
+ if (SVX_NUM_NUMBER_NONE != nNumFormat)
+ {
+ // category
+ //#i61007# order of captions
+ if( !m_bOrderNumberingFirst )
+ {
+ aStr = sFieldTypeName;
+ if ( !aStr.isEmpty() )
+ aStr += " ";
+ }
+
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(rSh.GetFieldType(
+ SwFieldIds::SetExp, sFieldTypeName ));
+ if( pFieldType && pFieldType->GetOutlineLvl() < MAXLEVEL )
+ {
+ SwNumberTree::tNumberVector aNumVector;
+ aNumVector.insert(aNumVector.end(), pFieldType->GetOutlineLvl() + 1, 1);
+
+ OUString sNumber( rSh.GetOutlineNumRule()->
+ MakeNumString(aNumVector, false ));
+ if( !sNumber.isEmpty() )
+ aStr += sNumber + pFieldType->GetDelimiter();
+ }
+
+ switch( nNumFormat )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER: aStr += "A"; break;
+ case SVX_NUM_CHARS_UPPER_LETTER_N: aStr += "A"; break;
+ case SVX_NUM_CHARS_LOWER_LETTER: aStr += "a"; break;
+ case SVX_NUM_CHARS_LOWER_LETTER_N: aStr += "a"; break;
+ case SVX_NUM_ROMAN_UPPER: aStr += "I"; break;
+ case SVX_NUM_ROMAN_LOWER: aStr += "i"; break;
+ default: aStr += "1"; break;
+ }
+ //#i61007# order of captions
+ if( m_bOrderNumberingFirst )
+ {
+ aStr += m_xNumberingSeparatorED->get_text() + sFieldTypeName;
+ }
+
+ }
+ if( !sCaption.isEmpty() )
+ {
+ aStr += m_xSepEdit->get_text();
+ }
+ }
+ aStr += sCaption;
+ // do preview!
+ m_aPreview.SetPreviewText(aStr);
+}
+
+SwCaptionDialog::~SwCaptionDialog()
+{
+}
+
+SwSequenceOptionDialog::SwSequenceOptionDialog(weld::Window *pParent, SwView &rV, OUString aSeqFieldType )
+ : GenericDialogController(pParent, "modules/swriter/ui/captionoptions.ui", "CaptionOptionsDialog")
+ , m_rView(rV)
+ , m_aFieldTypeName(std::move(aSeqFieldType))
+ , m_xLbLevel(m_xBuilder->weld_combo_box("level"))
+ , m_xEdDelim(m_xBuilder->weld_entry("separator"))
+ , m_xLbCharStyle(m_xBuilder->weld_combo_box("style"))
+ , m_xApplyBorderAndShadowCB(m_xBuilder->weld_check_button("border_and_shadow"))
+ , m_xLbCaptionOrder(m_xBuilder->weld_combo_box("caption_order"))
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+
+ const OUString sNone(SwResId(SW_STR_NONE));
+
+ m_xLbLevel->append_text(sNone);
+ for (sal_uInt16 n = 0; n < MAXLEVEL; ++n)
+ m_xLbLevel->append_text(OUString::number(n + 1));
+
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(rSh.GetFieldType(
+ SwFieldIds::SetExp, m_aFieldTypeName ));
+
+ sal_Unicode nLvl = MAXLEVEL;
+ OUString sDelim(": ");
+ if( pFieldType )
+ {
+ sDelim = pFieldType->GetDelimiter();
+ nLvl = pFieldType->GetOutlineLvl();
+ }
+
+ m_xLbLevel->set_active(nLvl < MAXLEVEL ? nLvl + 1 : 0);
+ m_xEdDelim->set_text(sDelim);
+
+ m_xLbCharStyle->append_text(sNone);
+ ::FillCharStyleListBox(*m_xLbCharStyle, m_rView.GetDocShell(), true, true);
+ m_xLbCharStyle->set_active(0);
+}
+
+void SwSequenceOptionDialog::Apply()
+{
+ SwWrtShell &rSh = m_rView.GetWrtShell();
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(rSh.GetFieldType(
+ SwFieldIds::SetExp, m_aFieldTypeName ));
+
+ sal_Int8 nLvl = static_cast<sal_Int8>(m_xLbLevel->get_active() - 1);
+ sal_Unicode cDelim = m_xEdDelim->get_text()[0];
+
+ bool bUpdate = true;
+ if( pFieldType )
+ {
+ pFieldType->SetDelimiter( OUString(cDelim) );
+ pFieldType->SetOutlineLvl( nLvl );
+ }
+ else if( !m_aFieldTypeName.isEmpty() && nLvl < MAXLEVEL )
+ {
+ // then we have to insert that
+ SwSetExpFieldType aFieldType( rSh.GetDoc(), m_aFieldTypeName, nsSwGetSetExpType::GSE_SEQ );
+ aFieldType.SetDelimiter( OUString(cDelim) );
+ aFieldType.SetOutlineLvl( nLvl );
+ rSh.InsertFieldType( aFieldType );
+ }
+ else
+ bUpdate = false;
+
+ if( bUpdate )
+ rSh.UpdateExpFields();
+}
+
+OUString SwSequenceOptionDialog::GetCharacterStyle() const
+{
+ if (m_xLbCharStyle->get_active() != -1)
+ return m_xLbCharStyle->get_active_text();
+ return OUString();
+}
+
+void SwSequenceOptionDialog::SetCharacterStyle(const OUString& rStyle)
+{
+ const int nPos = m_xLbCharStyle->find_text(rStyle);
+ if (nPos == -1)
+ m_xLbCharStyle->set_active(0);
+ else
+ m_xLbCharStyle->set_active(nPos);
+}
+
+// #i61007# order of captions
+void SwCaptionDialog::ApplyCaptionOrder()
+{
+ m_xNumberingSeparatorFT->set_sensitive(m_bOrderNumberingFirst);
+ m_xNumberingSeparatorED->set_sensitive(m_bOrderNumberingFirst);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/frmdlg.cxx b/sw/source/ui/frmdlg/frmdlg.cxx
new file mode 100644
index 0000000000..0eaf29dfe6
--- /dev/null
+++ b/sw/source/ui/frmdlg/frmdlg.cxx
@@ -0,0 +1,201 @@
+/* -*- 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/dialogs.hrc>
+#include <hintids.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <fmtfsize.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <frmdlg.hxx>
+#include <frmpage.hxx>
+#include <wrap.hxx>
+#include <column.hxx>
+#include <macassgn.hxx>
+#include <IDocumentSettingAccess.hxx>
+
+#include <strings.hrc>
+#include <svl/eitem.hxx>
+#include <svx/svxids.hrc>
+#include <svx/flagsdef.hxx>
+#include <svx/drawitem.hxx>
+#include <comphelper/lok.hxx>
+
+// the dialog's carrier
+SwFrameDlg::SwFrameDlg(const SfxViewFrame& rViewFrame,
+ weld::Window* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bNewFrame,
+ const OUString& sResType,
+ bool bFormat,
+ const OUString& sDefPage,
+ const OUString* pStr)
+
+ : SfxTabDialogController(pParent, "modules/swriter/ui/" + sResType.toAsciiLowerCase() + ".ui",
+ sResType, &rCoreSet, pStr != nullptr)
+ , m_bFormat(bFormat)
+ , m_bNew(bNewFrame)
+ , m_rSet(rCoreSet)
+ , m_sDlgType(sResType)
+ , m_pWrtShell(static_cast<SwView*>(rViewFrame.GetViewShell())->GetWrtShellPtr())
+{
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(m_pWrtShell->GetView().GetDocShell());
+ bool bHTMLMode = (nHtmlMode & HTMLMODE_ON) != 0;
+
+ // example font for both example TabPages
+
+ if (pStr)
+ {
+ m_xDialog->set_title(m_xDialog->get_title() + SwResId(STR_FRMUI_COLL_HEADER) + *pStr + ")");
+ }
+
+ AddTabPage("type", SwFramePage::Create, nullptr);
+ AddTabPage("options", SwFrameAddPage::Create, nullptr);
+ AddTabPage("wrap", SwWrapTabPage::Create, nullptr);
+ AddTabPage("hyperlink", SwFrameURLPage::Create, nullptr);
+ if (m_sDlgType == "PictureDialog")
+ {
+ AddTabPage("picture", SwGrfExtPage::Create, nullptr);
+ AddTabPage("crop", RID_SVXPAGE_GRFCROP);
+ }
+ if (m_sDlgType == "FrameDialog")
+ {
+ AddTabPage("columns", SwColumnPage::Create, nullptr);
+ }
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+
+ // add Area and Transparence TabPages
+ AddTabPage("area", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_AREA ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_AREA ));
+ AddTabPage("transparence", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TRANSPARENCE ), pFact->GetTabPageRangesFunc( RID_SVXPAGE_TRANSPARENCE ) );
+
+ AddTabPage("macro", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_MACROASSIGN), nullptr);
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BORDER ), nullptr);
+
+ if(bHTMLMode)
+ {
+ if (m_sDlgType == "FrameDialog" || m_sDlgType == "ObjectDialog")
+ {
+ if (m_sDlgType == "FrameDialog")
+ RemoveTabPage("columns");
+ RemoveTabPage("hyperlink");
+ RemoveTabPage("macro");
+ }
+ else if (m_sDlgType == "PictureDialog")
+ RemoveTabPage("crop");
+ if( m_sDlgType != "FrameDialog" )
+ {
+ // RemoveTabPage("background");
+ RemoveTabPage("area");
+ RemoveTabPage("transparence");
+ }
+ }
+
+ if(comphelper::LibreOfficeKit::isActive())
+ RemoveTabPage("macro");
+
+ if (m_bNew)
+ SetCurPageId("type");
+
+ if (!sDefPage.isEmpty())
+ SetCurPageId(sDefPage);
+}
+
+SwFrameDlg::~SwFrameDlg()
+{
+}
+
+void SwFrameDlg::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ if (rId == "type")
+ {
+ static_cast<SwFramePage&>(rPage).SetNewFrame(m_bNew);
+ static_cast<SwFramePage&>(rPage).SetFormatUsed(m_bFormat);
+ static_cast<SwFramePage&>(rPage).SetFrameType(m_sDlgType);
+ }
+ else if (rId == "options")
+ {
+ static_cast<SwFrameAddPage&>(rPage).SetFormatUsed(m_bFormat);
+ static_cast<SwFrameAddPage&>(rPage).SetFrameType(m_sDlgType);
+ static_cast<SwFrameAddPage&>(rPage).SetNewFrame(m_bNew);
+ static_cast<SwFrameAddPage&>(rPage).SetShell(m_pWrtShell);
+ }
+ else if (rId == "wrap")
+ {
+ static_cast<SwWrapTabPage&>(rPage).SetNewFrame(m_bNew);
+ static_cast<SwWrapTabPage&>(rPage).SetFormatUsed(m_bFormat, false);
+ static_cast<SwWrapTabPage&>(rPage).SetShell(m_pWrtShell);
+ }
+ else if (rId == "columns")
+ {
+ static_cast<SwColumnPage&>(rPage).SetFrameMode(true);
+ static_cast<SwColumnPage&>(rPage).SetFormatUsed(m_bFormat);
+
+ const SwFormatFrameSize& rSize = m_rSet.Get( RES_FRM_SIZE );
+ static_cast<SwColumnPage&>(rPage).SetPageWidth( rSize.GetWidth() );
+ }
+ else if (rId == "macro")
+ {
+ SfxAllItemSet aNewSet(*aSet.GetPool());
+ aNewSet.Put( SwMacroAssignDlg::AddEvents(
+ m_sDlgType == "PictureDialog" ? MACASSGN_GRAPHIC : m_sDlgType == "ObjectDialog" ? MACASSGN_OLE : MACASSGN_FRMURL ) );
+ if (m_pWrtShell)
+ rPage.SetFrame( m_pWrtShell->GetView().GetViewFrame().GetFrame().GetFrameInterface() );
+ rPage.PageCreated(aNewSet);
+ }
+ else if (rId == "borders")
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE,static_cast<sal_uInt16>(SwBorderModes::FRAME)));
+ rPage.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. SvxColorListItem) to make
+ // these pages find the needed attributes for fill style suggestions.
+ // These are set in preparation to trigger this dialog (FN_FORMAT_FRAME_DLG and
+ // FN_DRAW_WRAP_DLG), but could also be directly added from the DrawModel.
+ else if (rId == "area")
+ {
+ SfxItemSetFixed<SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_OFFER_IMPORT, SID_OFFER_IMPORT>
+ aNew(*GetInputSetImpl()->GetPool());
+
+ aNew.Put(m_rSet);
+
+ // add flag for direct graphic content selection
+ aNew.Put(SfxBoolItem(SID_OFFER_IMPORT, true));
+
+ rPage.PageCreated(aNew);
+ }
+ else if (rId == "transparence")
+ {
+ rPage.PageCreated(m_rSet);
+ }
+ else if (rId == "crop")
+ {
+ sal_Int32 nPreferredDPI = m_pWrtShell->GetDoc()->getIDocumentSettingAccess().getImagePreferredDPI();
+ if (nPreferredDPI)
+ rPage.getAdditionalProperties().emplace("PreferredDPI", css::uno::Any(nPreferredDPI));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/frmpage.cxx b/sw/source/ui/frmdlg/frmpage.cxx
new file mode 100644
index 0000000000..b3e2a873ad
--- /dev/null
+++ b/sw/source/ui/frmdlg/frmpage.cxx
@@ -0,0 +1,3285 @@
+/* -*- 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/embed/Aspects.hpp>
+#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+
+#include <cmdid.h>
+#include <hintids.hxx>
+#include <bitmaps.hlst>
+#include <o3tl/safeint.hxx>
+#include <vcl/mnemonic.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/protitem.hxx>
+#include <editeng/prntitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/swframeposstrings.hxx>
+#include <svx/swframevalidation.hxx>
+#include <svx/sdangitm.hxx>
+#include <comphelper/classids.hxx>
+#include <tools/globname.hxx>
+#include <tools/urlobj.hxx>
+#include <fmturl.hxx>
+#include <fmteiro.hxx>
+#include <fmtcnct.hxx>
+#include <fmtsrnd.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <swmodule.hxx>
+#include <uitool.hxx>
+#include <docsh.hxx>
+#include <viewopt.hxx>
+#include <frmdlg.hxx>
+#include <frmmgr.hxx>
+#include <frmpage.hxx>
+#include <colmgr.hxx>
+#include <grfatr.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <svx/sdtaitm.hxx>
+#include <sal/macros.h>
+#include <osl/diagnose.h>
+
+#include <strings.hrc>
+#include <formatflysplit.hxx>
+#include <fmtcntnt.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/graphichelper.hxx>
+#include <sfx2/filedlghelper.hxx>
+#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/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <vcl/graphicfilter.hxx>
+#include <svtools/embedhlp.hxx>
+#include <comphelper/lok.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::sfx2;
+
+#define SwFPos SvxSwFramePosString
+
+namespace {
+
+struct StringIdPair_Impl
+{
+ SvxSwFramePosString::StringId eHori;
+ SvxSwFramePosString::StringId eVert;
+};
+
+}
+
+#define MAX_PERCENT_WIDTH SAL_CONST_INT64(254)
+#define MAX_PERCENT_HEIGHT SAL_CONST_INT64(254)
+
+namespace {
+
+enum class LB {
+ NONE = 0x00000000L,
+ Frame = 0x00000001L, // text region of the paragraph
+ PrintArea = 0x00000002L, // text region of the paragraph + indentions
+ VertFrame = 0x00000004L, // vertical text region of the paragraph
+ VertPrintArea = 0x00000008L, // vertical text region of the paragraph + indentions
+ RelFrameLeft = 0x00000010L, // left paragraph edge
+ RelFrameRight = 0x00000020L, // right paragraph edge
+
+ RelPageLeft = 0x00000040L, // left page edge
+ RelPageRight = 0x00000080L, // right page edge
+ RelPageFrame = 0x00000100L, // whole page
+ RelPagePrintArea = 0x00000200L, // text region of the page
+
+ FlyRelPageLeft = 0x00000400L, // left frame edge
+ FlyRelPageRight = 0x00000800L, // right frame edge
+ FlyRelPageFrame = 0x00001000L, // whole frame
+ FlyRelPagePrintArea = 0x00002000L, // inside of the frame
+
+ RelBase = 0x00010000L, // character alignment Base
+ RelChar = 0x00020000L, // character alignment Character
+ RelRow = 0x00040000L, // character alignment Row
+
+ FlyVertFrame = 0x00100000L, // vertical entire frame
+ FlyVertPrintArea = 0x00200000L, // vertical frame text area
+
+ VertLine = 0x00400000L, // vertical text line
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<LB> : is_typed_flags<LB, 0x00773fffL> {};
+}
+
+namespace {
+
+struct RelationMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ LB nLBRelation;
+ sal_Int16 nRelation;
+};
+
+}
+
+struct FrameMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ sal_Int16 nAlign;
+ LB nLBRelations;
+};
+
+
+RelationMap const aRelationMap[] =
+{
+ {SwFPos::FRAME, SwFPos::FRAME, LB::Frame, text::RelOrientation::FRAME},
+ {SwFPos::PRTAREA, SwFPos::PRTAREA, LB::PrintArea, text::RelOrientation::PRINT_AREA},
+ {SwFPos::REL_PG_LEFT, SwFPos::MIR_REL_PG_LEFT, LB::RelPageLeft, text::RelOrientation::PAGE_LEFT},
+ {SwFPos::REL_PG_RIGHT, SwFPos::MIR_REL_PG_RIGHT, LB::RelPageRight, text::RelOrientation::PAGE_RIGHT},
+ {SwFPos::REL_FRM_LEFT, SwFPos::MIR_REL_FRM_LEFT, LB::RelFrameLeft, text::RelOrientation::FRAME_LEFT},
+ {SwFPos::REL_FRM_RIGHT, SwFPos::MIR_REL_FRM_RIGHT, LB::RelFrameRight, text::RelOrientation::FRAME_RIGHT},
+ {SwFPos::REL_PG_FRAME, SwFPos::REL_PG_FRAME, LB::RelPageFrame, text::RelOrientation::PAGE_FRAME},
+ {SwFPos::REL_PG_PRTAREA, SwFPos::REL_PG_PRTAREA, LB::RelPagePrintArea, text::RelOrientation::PAGE_PRINT_AREA},
+ {SwFPos::REL_CHAR, SwFPos::REL_CHAR, LB::RelChar, text::RelOrientation::CHAR},
+
+ {SwFPos::FLY_REL_PG_LEFT, SwFPos::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, text::RelOrientation::PAGE_LEFT},
+ {SwFPos::FLY_REL_PG_RIGHT, SwFPos::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, text::RelOrientation::PAGE_RIGHT},
+ {SwFPos::FLY_REL_PG_FRAME, SwFPos::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, text::RelOrientation::PAGE_FRAME},
+ {SwFPos::FLY_REL_PG_PRTAREA, SwFPos::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, text::RelOrientation::PAGE_PRINT_AREA},
+
+ {SwFPos::REL_BORDER, SwFPos::REL_BORDER, LB::VertFrame, text::RelOrientation::FRAME},
+ {SwFPos::REL_PRTAREA, SwFPos::REL_PRTAREA, LB::VertPrintArea, text::RelOrientation::PRINT_AREA},
+
+ {SwFPos::FLY_REL_PG_FRAME, SwFPos::FLY_REL_PG_FRAME, LB::FlyVertFrame, text::RelOrientation::FRAME},
+ {SwFPos::FLY_REL_PG_PRTAREA, SwFPos::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, text::RelOrientation::PRINT_AREA},
+
+ {SwFPos::REL_LINE, SwFPos::REL_LINE, LB::VertLine, text::RelOrientation::TEXT_LINE}
+};
+
+RelationMap const aAsCharRelationMap[] =
+{
+ {SwFPos::REL_BASE, SwFPos::REL_BASE, LB::RelBase, text::RelOrientation::FRAME},
+ {SwFPos::REL_CHAR, SwFPos::REL_CHAR, LB::RelChar, text::RelOrientation::FRAME},
+ {SwFPos::REL_ROW, SwFPos::REL_ROW, LB::RelRow, text::RelOrientation::FRAME}
+};
+
+// site anchored
+constexpr auto HORI_PAGE_REL = LB::RelPageFrame | LB::RelPagePrintArea | LB::RelPageLeft |
+ LB::RelPageRight;
+
+FrameMap const aHPageMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, HORI_PAGE_REL},
+ {SwFPos::RIGHT, SwFPos::MIR_RIGHT, text::HoriOrientation::RIGHT, HORI_PAGE_REL},
+ {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, text::HoriOrientation::CENTER, HORI_PAGE_REL},
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, HORI_PAGE_REL}
+};
+
+FrameMap const aHPageHtmlMap[] =
+{
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+#define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
+
+FrameMap const aVPageMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, VERT_PAGE_REL},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::BOTTOM, VERT_PAGE_REL},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CENTER, VERT_PAGE_REL},
+ {SwFPos::FROMTOP, SwFPos::FROMTOP, text::VertOrientation::NONE, VERT_PAGE_REL}
+};
+
+FrameMap const aVPageHtmlMap[] =
+{
+ {SwFPos::FROMTOP, SwFPos::FROMTOP, text::VertOrientation::NONE, LB::RelPageFrame}
+};
+
+// frame anchored
+constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame | LB::FlyRelPagePrintArea |
+ LB::FlyRelPageLeft | LB::FlyRelPageRight;
+
+FrameMap const aHFrameMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, HORI_FRAME_REL},
+ {SwFPos::RIGHT, SwFPos::MIR_RIGHT, text::HoriOrientation::RIGHT, HORI_FRAME_REL},
+ {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, text::HoriOrientation::CENTER, HORI_FRAME_REL},
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, HORI_FRAME_REL}
+};
+
+FrameMap const aHFlyHtmlMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, LB::FlyRelPageFrame},
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, LB::FlyRelPageFrame}
+};
+
+// own vertical alignment map for objects anchored to frame
+#define VERT_FRAME_REL (LB::FlyVertFrame|LB::FlyVertPrintArea)
+
+FrameMap const aVFrameMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, VERT_FRAME_REL},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::BOTTOM, VERT_FRAME_REL},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CENTER, VERT_FRAME_REL},
+ {SwFPos::FROMTOP, SwFPos::FROMTOP, text::VertOrientation::NONE, VERT_FRAME_REL}
+};
+
+FrameMap const aVFlyHtmlMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, LB::FlyVertFrame},
+ {SwFPos::FROMTOP, SwFPos::FROMTOP, text::VertOrientation::NONE, LB::FlyVertFrame}
+};
+
+// paragraph anchored
+constexpr auto HORI_PARA_REL = LB::Frame | LB::PrintArea | LB::RelPageLeft | LB::RelPageRight |
+ LB::RelPageFrame | LB::RelPagePrintArea | LB::RelFrameLeft |
+ LB::RelFrameRight;
+
+FrameMap const aHParaMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, HORI_PARA_REL},
+ {SwFPos::RIGHT, SwFPos::MIR_RIGHT, text::HoriOrientation::RIGHT, HORI_PARA_REL},
+ {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, text::HoriOrientation::CENTER, HORI_PARA_REL},
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, HORI_PARA_REL}
+};
+
+#define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
+
+FrameMap const aHParaHtmlMap[] =
+{
+ {SwFPos::LEFT, SwFPos::LEFT, text::HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SwFPos::RIGHT, SwFPos::RIGHT, text::HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+FrameMap const aHParaHtmlAbsMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SwFPos::RIGHT, SwFPos::MIR_RIGHT, text::HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+// allow vertical alignment at page areas
+constexpr auto VERT_PARA_REL = LB::VertFrame | LB::VertPrintArea |
+ LB::RelPageFrame | LB::RelPagePrintArea;
+
+FrameMap const aVParaMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, VERT_PARA_REL},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::BOTTOM, VERT_PARA_REL},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CENTER, VERT_PARA_REL},
+ {SwFPos::FROMTOP, SwFPos::FROMTOP, text::VertOrientation::NONE, VERT_PARA_REL}
+};
+
+FrameMap const aVParaHtmlMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, LB::VertPrintArea}
+};
+
+// anchored relative to the character
+constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea | LB::RelPageLeft | LB::RelPageRight |
+ LB::RelPageFrame | LB::RelPagePrintArea | LB::RelFrameLeft |
+ LB::RelFrameRight | LB::RelChar;
+
+FrameMap const aHCharMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, HORI_CHAR_REL},
+ {SwFPos::RIGHT, SwFPos::MIR_RIGHT, text::HoriOrientation::RIGHT, HORI_CHAR_REL},
+ {SwFPos::CENTER_HORI, SwFPos::CENTER_HORI, text::HoriOrientation::CENTER, HORI_CHAR_REL},
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, HORI_CHAR_REL}
+};
+
+#define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
+
+FrameMap const aHCharHtmlMap[] =
+{
+ {SwFPos::LEFT, SwFPos::LEFT, text::HoriOrientation::LEFT, HTML_HORI_CHAR_REL},
+ {SwFPos::RIGHT, SwFPos::RIGHT, text::HoriOrientation::RIGHT, HTML_HORI_CHAR_REL}
+};
+
+FrameMap const aHCharHtmlAbsMap[] =
+{
+ {SwFPos::LEFT, SwFPos::MIR_LEFT, text::HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
+ {SwFPos::RIGHT, SwFPos::MIR_RIGHT, text::HoriOrientation::RIGHT, LB::PrintArea},
+ {SwFPos::FROMLEFT, SwFPos::MIR_FROMLEFT, text::HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+// allow vertical alignment at page areas
+constexpr auto VERT_CHAR_REL = LB::VertFrame | LB::VertPrintArea |
+ LB::RelPageFrame | LB::RelPagePrintArea;
+
+FrameMap const aVCharMap[] =
+{
+ // 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 <SwFramePage::FillRelLB(..)>, <SwFramePage::GetAlignment(..)>
+ // and <SwFramePage::FillPosLB(..)>
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
+ {SwFPos::BELOW, SwFPos::BELOW, text::VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CENTER, VERT_CHAR_REL|LB::RelChar},
+ {SwFPos::FROMTOP, SwFPos::FROMTOP, text::VertOrientation::NONE, VERT_CHAR_REL},
+ {SwFPos::FROMBOTTOM, SwFPos::FROMBOTTOM, text::VertOrientation::NONE, LB::RelChar|LB::VertLine},
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::LINE_TOP, LB::VertLine},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::LINE_BOTTOM, LB::VertLine},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::LINE_CENTER, LB::VertLine}
+};
+
+FrameMap const aVCharHtmlMap[] =
+{
+ {SwFPos::BELOW, SwFPos::BELOW, text::VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+
+FrameMap const aVCharHtmlAbsMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, LB::RelChar},
+ {SwFPos::BELOW, SwFPos::BELOW, text::VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+
+// anchored as character
+FrameMap const aVAsCharMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, LB::RelBase},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::BOTTOM, LB::RelBase},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CENTER, LB::RelBase},
+
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::CHAR_TOP, LB::RelChar},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CHAR_CENTER, LB::RelChar},
+
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::LINE_TOP, LB::RelRow},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::LINE_CENTER, LB::RelRow},
+
+ {SwFPos::FROMBOTTOM, SwFPos::FROMBOTTOM, text::VertOrientation::NONE, LB::RelBase}
+};
+
+FrameMap const aVAsCharHtmlMap[] =
+{
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::TOP, LB::RelBase},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::CENTER, LB::RelBase},
+
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::CHAR_TOP, LB::RelChar},
+
+ {SwFPos::TOP, SwFPos::TOP, text::VertOrientation::LINE_TOP, LB::RelRow},
+ {SwFPos::BOTTOM, SwFPos::BOTTOM, text::VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_VERT, text::VertOrientation::LINE_CENTER, LB::RelRow}
+};
+
+const WhichRangesContainer SwFramePage::s_aPageRg(svl::Items<
+ RES_FRM_SIZE, RES_FRM_SIZE,
+ RES_VERT_ORIENT, RES_ANCHOR,
+ RES_COL, RES_COL,
+ RES_FOLLOW_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW
+>);
+const WhichRangesContainer SwFrameAddPage::s_aAddPgRg(svl::Items<
+ RES_PRINT, RES_PRINT,
+ RES_PROTECT, RES_PROTECT,
+ FN_SET_FRM_NAME, FN_SET_FRM_NAME,
+ FN_SET_FRM_ALT_NAME, FN_SET_FRM_ALT_NAME,
+ FN_UNO_DESCRIPTION, FN_UNO_DESCRIPTION
+>);
+
+static size_t lcl_GetFrameMapCount( const FrameMap* pMap)
+{
+ if ( pMap )
+ {
+ 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);
+ return std::size(aHPageMap);
+ }
+ return 0;
+}
+
+static void lcl_InsertVectors(weld::ComboBox& rBox,
+ const std::vector< OUString >& rPrev, const std::vector< OUString >& rThis,
+ const std::vector< OUString >& rNext, const std::vector< OUString >& rRemain)
+{
+ for(const auto& rItem : rPrev)
+ rBox.append_text(rItem);
+ for(const auto& rItem : rThis)
+ rBox.append_text(rItem);
+ for(const auto& rItem : rNext)
+ rBox.append_text(rItem);
+ rBox.append_separator("");
+ //now insert all strings sorted
+ const auto nStartPos = rBox.get_count();
+
+ for(const auto& rItem : rPrev)
+ ::InsertStringSorted("", rItem, rBox, nStartPos );
+ for(const auto& rItem : rThis)
+ ::InsertStringSorted("", rItem, rBox, nStartPos );
+ for(const auto& rItem : rNext)
+ ::InsertStringSorted("", rItem, rBox, nStartPos );
+ for(const auto& rItem : rRemain)
+ ::InsertStringSorted("", rItem, rBox, nStartPos );
+}
+
+// --> OD 2009-08-31 #mongolianlayout#
+// add input parameter
+static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(SvxSwFramePosString::StringId eStringId, bool bVertical, bool bVerticalL2R, bool bRTL)
+{
+ //special handling of STR_FROMLEFT
+ if ( SwFPos::FROMLEFT == eStringId )
+ {
+ eStringId = bVertical
+ ? ( bRTL
+ ? SwFPos::FROMBOTTOM
+ : SwFPos::FROMTOP )
+ : ( bRTL
+ ? SwFPos::FROMRIGHT
+ : SwFPos::FROMLEFT );
+ return eStringId;
+ }
+ // --> OD 2009-08-31 #mongolianlayout#
+ // special handling of STR_FROMTOP in case of mongolianlayout (vertical left-to-right)
+ if ( SwFPos::FROMTOP == eStringId &&
+ bVertical && bVerticalL2R )
+ {
+ eStringId = SwFPos::FROMLEFT;
+ return eStringId;
+ }
+ if ( bVertical )
+ {
+ //exchange horizontal strings with vertical strings and vice versa
+ static const StringIdPair_Impl aHoriIds[] =
+ {
+ {SwFPos::LEFT, SwFPos::TOP},
+ {SwFPos::RIGHT, SwFPos::BOTTOM},
+ {SwFPos::CENTER_HORI, SwFPos::CENTER_VERT},
+ {SwFPos::FROMTOP, SwFPos::FROMRIGHT},
+ {SwFPos::REL_PG_LEFT, SwFPos::REL_PG_TOP},
+ {SwFPos::REL_PG_RIGHT, SwFPos::REL_PG_BOTTOM} ,
+ {SwFPos::REL_FRM_LEFT, SwFPos::REL_FRM_TOP},
+ {SwFPos::REL_FRM_RIGHT, SwFPos::REL_FRM_BOTTOM}
+ };
+ static const StringIdPair_Impl aVertIds[] =
+ {
+ {SwFPos::TOP, SwFPos::RIGHT},
+ {SwFPos::BOTTOM, SwFPos::LEFT },
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_HORI},
+ {SwFPos::FROMTOP, SwFPos::FROMRIGHT },
+ {SwFPos::REL_PG_TOP, SwFPos::REL_PG_LEFT },
+ {SwFPos::REL_PG_BOTTOM, SwFPos::REL_PG_RIGHT } ,
+ {SwFPos::REL_FRM_TOP, SwFPos::REL_FRM_LEFT },
+ {SwFPos::REL_FRM_BOTTOM, SwFPos::REL_FRM_RIGHT }
+ };
+ // --> OD 2009-08-31 #monglianlayout#
+ static const StringIdPair_Impl aVertL2RIds[] =
+ {
+ {SwFPos::TOP, SwFPos::LEFT },
+ {SwFPos::BOTTOM, SwFPos::RIGHT },
+ {SwFPos::CENTER_VERT, SwFPos::CENTER_HORI },
+ {SwFPos::FROMTOP, SwFPos::FROMLEFT },
+ {SwFPos::REL_PG_TOP, SwFPos::REL_PG_LEFT },
+ {SwFPos::REL_PG_BOTTOM, SwFPos::REL_PG_RIGHT } ,
+ {SwFPos::REL_FRM_TOP, SwFPos::REL_FRM_LEFT },
+ {SwFPos::REL_FRM_BOTTOM, SwFPos::REL_FRM_RIGHT }
+ };
+ for(const StringIdPair_Impl & rHoriId : aHoriIds)
+ {
+ if(rHoriId.eHori == eStringId)
+ {
+ eStringId = rHoriId.eVert;
+ return eStringId;
+ }
+ }
+ for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aVertIds); ++nIndex)
+ {
+ // --> OD 2009-08-31 #mongolianlayout#
+ if ( !bVerticalL2R )
+ {
+ if(aVertIds[nIndex].eHori == eStringId)
+ {
+ eStringId = aVertIds[nIndex].eVert;
+ break;
+ }
+ }
+ else
+ {
+ if(aVertL2RIds[nIndex].eHori == eStringId)
+ {
+ eStringId = aVertL2RIds[nIndex].eVert;
+ break;
+ }
+ }
+ }
+ }
+ return eStringId;
+}
+
+// helper method in order to determine all possible
+// listbox relations in a relation map for a given relation
+static LB lcl_GetLBRelationsForRelations( const sal_Int16 _nRel )
+{
+ LB nLBRelations = LB::NONE;
+
+ for (RelationMap const & i : aRelationMap)
+ {
+ if ( i.nRelation == _nRel )
+ {
+ nLBRelations |= i.nLBRelation;
+ }
+ }
+
+ return nLBRelations;
+}
+
+// helper method on order to determine all possible
+// listbox relations in a relation map for a given string ID
+static LB lcl_GetLBRelationsForStrID( const FrameMap* _pMap,
+ const SvxSwFramePosString::StringId _eStrId,
+ const bool _bUseMirrorStr )
+{
+ LB nLBRelations = LB::NONE;
+
+ size_t nRelMapSize = lcl_GetFrameMapCount( _pMap );
+ for ( size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
+ {
+ if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
+ ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
+ {
+ nLBRelations |= _pMap[nRelMapPos].nLBRelations;
+ }
+ }
+
+ return nLBRelations;
+}
+
+// standard frame TabPage
+namespace
+{
+ void HandleAutoCB(bool _bChecked, weld::Label& _rFT_man, weld::Label& _rFT_auto, weld::MetricSpinButton& _rPF_Edit)
+ {
+ _rFT_man.set_visible( !_bChecked );
+ _rFT_auto.set_visible( _bChecked );
+ OUString accName = _bChecked ? _rFT_auto.get_label() : _rFT_man.get_label();
+ _rPF_Edit.set_accessible_name(accName);
+ }
+}
+
+SwFramePage::SwFramePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/frmtypepage.ui", "FrameTypePage", &rSet)
+ , m_bAtHorzPosModified(false)
+ , m_bAtVertPosModified(false)
+ , m_bFormat(false)
+ , m_bNew(true)
+ , m_bNoModifyHdl(true)
+ , m_bIsVerticalFrame(false)
+ , m_bIsVerticalL2R(false)
+ , m_bIsInRightToLeft(false)
+ , m_bHtmlMode(false)
+ , m_nHtmlMode(0)
+ , m_nUpperBorder(0)
+ , m_nLowerBorder(0)
+ , m_fWidthHeightRatio(1.0)
+ , mpToCharContentPos(nullptr)
+ , m_nOldH(text::HoriOrientation::CENTER)
+ , m_nOldHRel(text::RelOrientation::FRAME)
+ , m_nOldV(text::VertOrientation::TOP)
+ , m_nOldVRel(text::RelOrientation::PRINT_AREA)
+ , m_pVMap(nullptr)
+ , m_pHMap(nullptr)
+ , m_bAllowVertPositioning( true )
+ , m_bIsMathOLE(false)
+ , m_bIsMathBaselineAlignment(true)
+ , m_xWidthFT(m_xBuilder->weld_label("widthft"))
+ , m_xWidthAutoFT(m_xBuilder->weld_label("autowidthft"))
+ , m_xRelWidthCB(m_xBuilder->weld_check_button("relwidth"))
+ , m_xRelWidthRelationLB(m_xBuilder->weld_combo_box("relwidthrelation"))
+ , m_xAutoWidthCB(m_xBuilder->weld_check_button("autowidth"))
+ , m_xHeightFT(m_xBuilder->weld_label("heightft"))
+ , m_xHeightAutoFT(m_xBuilder->weld_label("autoheightft"))
+ , m_xRelHeightCB(m_xBuilder->weld_check_button("relheight"))
+ , m_xRelHeightRelationLB(m_xBuilder->weld_combo_box("relheightrelation"))
+ , m_xAutoHeightCB(m_xBuilder->weld_check_button("autoheight"))
+ , m_xFixedRatioCB(m_xBuilder->weld_check_button("ratio"))
+ , m_xRealSizeBT(m_xBuilder->weld_button("origsize"))
+ , m_xAnchorFrame(m_xBuilder->weld_widget("anchorframe"))
+ , m_xAnchorAtPageRB(m_xBuilder->weld_radio_button("topage"))
+ , m_xAnchorAtParaRB(m_xBuilder->weld_radio_button("topara"))
+ , m_xAnchorAtCharRB(m_xBuilder->weld_radio_button("tochar"))
+ , m_xAnchorAsCharRB(m_xBuilder->weld_radio_button("aschar"))
+ , m_xAnchorAtFrameRB(m_xBuilder->weld_radio_button("toframe"))
+ , m_xHorizontalFT(m_xBuilder->weld_label("horiposft"))
+ , m_xHorizontalDLB(m_xBuilder->weld_combo_box("horipos"))
+ , m_xAtHorzPosFT(m_xBuilder->weld_label("horibyft"))
+ , m_xAtHorzPosED(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
+ , m_xHoriRelationFT(m_xBuilder->weld_label("horitoft"))
+ , m_xHoriRelationLB(m_xBuilder->weld_combo_box("horianchor"))
+ , m_xMirrorPagesCB(m_xBuilder->weld_check_button("mirror"))
+ , m_xVerticalFT(m_xBuilder->weld_label("vertposft"))
+ , m_xVerticalDLB(m_xBuilder->weld_combo_box("vertpos"))
+ , m_xAtVertPosFT(m_xBuilder->weld_label("vertbyft"))
+ , m_xAtVertPosED(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
+ , m_xVertRelationFT(m_xBuilder->weld_label("verttoft"))
+ , m_xVertRelationLB(m_xBuilder->weld_combo_box("vertanchor"))
+ , m_xFollowTextFlowCB(m_xBuilder->weld_check_button("followtextflow"))
+ , m_xFlySplitCB(m_xBuilder->weld_check_button("flysplit"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+ , m_xWidthED(new SwPercentField(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM)))
+ , m_xHeightED(new SwPercentField(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM)))
+{
+ const auto nWidthRequest = m_xAtHorzPosED->get_preferred_size().Width();
+ m_xAtHorzPosED->set_size_request(nWidthRequest, -1);
+ m_xAtVertPosED->set_size_request(nWidthRequest, -1);
+
+ setOptimalFrameWidth();
+ setOptimalRelWidth();
+
+ SetExchangeSupport();
+
+ Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SwFramePage, ModifyHdl);
+ m_xWidthED->connect_value_changed( aLk3 );
+ m_xHeightED->connect_value_changed( aLk3 );
+ m_xAtHorzPosED->connect_value_changed( aLk3 );
+ m_xAtVertPosED->connect_value_changed( aLk3 );
+ m_xFollowTextFlowCB->connect_toggled(LINK(this, SwFramePage, RangeModifyClickHdl));
+
+ Link<weld::Toggleable&,void> aLk2 = LINK(this, SwFramePage, AnchorTypeHdl);
+ m_xAnchorAtPageRB->connect_toggled( aLk2 );
+ m_xAnchorAtParaRB->connect_toggled( aLk2 );
+ m_xAnchorAtCharRB->connect_toggled( aLk2 );
+ m_xAnchorAsCharRB->connect_toggled( aLk2 );
+ m_xAnchorAtFrameRB->connect_toggled( aLk2 );
+
+ m_xHorizontalDLB->connect_changed(LINK(this, SwFramePage, PosHdl));
+ m_xVerticalDLB->connect_changed(LINK(this, SwFramePage, PosHdl));
+
+ m_xHoriRelationLB->connect_changed(LINK(this, SwFramePage, RelHdl));
+ m_xVertRelationLB->connect_changed(LINK(this, SwFramePage, RelHdl));
+
+ m_xMirrorPagesCB->connect_toggled(LINK(this, SwFramePage, MirrorHdl));
+
+ aLk2 = LINK(this, SwFramePage, RelSizeClickHdl);
+ m_xRelWidthCB->connect_toggled(aLk2);
+ m_xRelHeightCB->connect_toggled(aLk2);
+
+ m_xAutoWidthCB->connect_toggled(LINK(this, SwFramePage, AutoWidthClickHdl));
+ m_xAutoHeightCB->connect_toggled(LINK(this, SwFramePage, AutoHeightClickHdl));
+
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ m_xAnchorAtPageRB->hide();
+ m_xAnchorAtFrameRB->hide();
+ }
+}
+
+SwFramePage::~SwFramePage()
+{
+}
+
+namespace
+{
+ struct FrameMaps
+ {
+ FrameMap const * pMap;
+ size_t nCount;
+ };
+}
+
+void SwFramePage::setOptimalFrameWidth()
+{
+ static FrameMaps const 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 FrameMaps & rMap : aMaps)
+ {
+ for (size_t j = 0; j < rMap.nCount; ++j)
+ {
+ aFrames.push_back(rMap.pMap[j].eStrId);
+ aFrames.push_back(rMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aFrames.begin(), aFrames.end());
+ aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
+
+ for (const auto& rFrame : aFrames)
+ {
+ m_xHorizontalDLB->append_text(SvxSwFramePosString::GetString(rFrame));
+ }
+
+ Size aBiggest(m_xHorizontalDLB->get_preferred_size());
+ m_xHorizontalDLB->set_size_request(aBiggest.Width(), -1);
+ m_xVerticalDLB->set_size_request(aBiggest.Width(), -1);
+ m_xHorizontalDLB->clear();
+}
+
+namespace
+{
+ struct RelationMaps
+ {
+ RelationMap const * pMap;
+ size_t nCount;
+ };
+
+/// Checks if the current fly frame contains exactly one table.
+bool ContainsSingleTable(const SwFrameFormat& rFlyFormat)
+{
+ const SwNodeIndex* pStartNode = rFlyFormat.GetContent().GetContentIdx();
+ if (!pStartNode)
+ {
+ return false;
+ }
+
+ // Check if the frame content starts with a table.
+ SwNodeIndex aNodeIndex(*pStartNode);
+ ++aNodeIndex;
+ if (!aNodeIndex.GetNode().IsTableNode())
+ {
+ return false;
+ }
+
+ // Check if the frame content ends with the same table.
+ SwNodeIndex aEndIndex(*aNodeIndex.GetNode().EndOfSectionNode());
+ ++aEndIndex;
+ if (&aEndIndex.GetNode() != pStartNode->GetNode().EndOfSectionNode())
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ContainsChain(const SwFrameFormat& rFlyFormat)
+{
+ const SwFormatChain& rChain = rFlyFormat.GetChain();
+ return rChain.GetPrev() || rChain.GetNext();
+}
+
+/// Determines if rFlyFormat is anchored in a fly frame that is part of a draw-format + fly-format
+/// ("textbox") pair.
+bool InTextBox(const SwFrameFormat& rFlyFormat)
+{
+ const SwFormatAnchor& rAnchor = rFlyFormat.GetAnchor();
+ SwNode* pAnchorNode = rAnchor.GetAnchorNode();
+ if (!pAnchorNode)
+ {
+ return false;
+ }
+
+ const SwStartNode* pFlyNode = pAnchorNode->FindFlyStartNode();
+ if (!pFlyNode)
+ {
+ return false;
+ }
+
+ if (!pFlyNode->GetFlyFormat()->GetOtherTextBoxFormats())
+ {
+ return false;
+ }
+
+ return true;
+}
+}
+
+void SwFramePage::setOptimalRelWidth()
+{
+ static const RelationMaps aMaps[] = {
+ { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
+ { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aRels;
+ for (const RelationMaps & rMap : aMaps)
+ {
+ for (size_t j = 0; j < rMap.nCount; ++j)
+ {
+ aRels.push_back(rMap.pMap[j].eStrId);
+ aRels.push_back(rMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aRels.begin(), aRels.end());
+ aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
+
+ for (const auto& rRel : aRels)
+ {
+ m_xHoriRelationLB->append_text(SvxSwFramePosString::GetString(rRel));
+ }
+
+ Size aBiggest(m_xHoriRelationLB->get_preferred_size());
+ m_xHoriRelationLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertRelationLB->set_size_request(aBiggest.Width(), -1);
+ m_xRelWidthRelationLB->set_size_request(aBiggest.Width(), -1);
+ m_xRelHeightRelationLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriRelationLB->clear();
+}
+
+std::unique_ptr<SfxTabPage> SwFramePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwFramePage>(pPage, pController, *rSet);
+}
+
+void SwFramePage::EnableGraficMode()
+{
+ // i#39692 - mustn't be called more than once
+ if (!m_xRealSizeBT->get_visible())
+ {
+ m_xWidthFT->show();
+ m_xWidthAutoFT->hide();
+ m_xAutoHeightCB->hide();
+
+ m_xHeightFT->show();
+ m_xHeightAutoFT->hide();
+ m_xAutoWidthCB->hide();
+
+ m_xRealSizeBT->show();
+ }
+}
+
+SwWrtShell *SwFramePage::getFrameDlgParentShell()
+{
+ return static_cast<SwFrameDlg*>(GetDialogController())->GetWrtShell();
+}
+
+void SwFramePage::Reset( const SfxItemSet *rSet )
+{
+ SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell() :
+ getFrameDlgParentShell();
+ OSL_ENSURE(pSh , "shell not found");
+ if (!pSh)
+ return;
+
+ m_nHtmlMode = ::GetHtmlMode(pSh->GetView().GetDocShell());
+ m_bHtmlMode = (m_nHtmlMode & HTMLMODE_ON) != 0;
+
+ FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
+ m_xWidthED->SetMetric(aMetric);
+ m_xHeightED->SetMetric(aMetric);
+ ::SetFieldUnit(*m_xAtHorzPosED, aMetric);
+ ::SetFieldUnit(*m_xAtVertPosED, aMetric);
+
+ const SwFormatAnchor& rAnchor = rSet->Get(RES_ANCHOR);
+
+ if (const SfxBoolItem* pMathItem = rSet->GetItemIfSet(FN_OLE_IS_MATH, false))
+ m_bIsMathOLE = pMathItem->GetValue();
+ if (const SfxBoolItem* pAlignItem = rSet->GetItemIfSet(FN_MATH_BASELINE_ALIGNMENT, false))
+ m_bIsMathBaselineAlignment = pAlignItem->GetValue();
+ EnableVerticalPositioning( !(m_bIsMathOLE && m_bIsMathBaselineAlignment
+ && RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) );
+
+ if (m_bFormat)
+ {
+ // at formats no to-fly anchor
+ m_xAnchorAtFrameRB->set_sensitive(false);
+ if (rSet->GetItemState(FN_KEEP_ASPECT_RATIO) != SfxItemState::SET)
+ {
+ m_xFixedRatioCB->set_sensitive(false);
+ }
+ }
+ else
+ {
+ if (rAnchor.GetAnchorId() != RndStdIds::FLY_AT_FLY && !pSh->IsFlyInFly())
+ m_xAnchorAtFrameRB->hide();
+ if ( pSh->IsFrameVertical( true, m_bIsInRightToLeft, m_bIsVerticalL2R ) )
+ {
+ OUString sHLabel = m_xHorizontalFT->get_label();
+ m_xHorizontalFT->set_label(m_xVerticalFT->get_label());
+ m_xVerticalFT->set_label(sHLabel);
+ m_bIsVerticalFrame = true;
+ }
+ }
+
+ if ( m_sDlgType == "PictureDialog" || m_sDlgType == "ObjectDialog" )
+ {
+ pSh->GetGrfSize( m_aGrfSize );
+
+ if ( !m_bNew )
+ {
+ m_xRealSizeBT->connect_clicked(LINK(this, SwFramePage, RealSizeHdl));
+ EnableGraficMode();
+ }
+
+ if (m_sDlgType == "PictureDialog")
+ m_xFixedRatioCB->set_active(false);
+ else
+ {
+ if ( m_bNew )
+ SetPageTitle(SwResId(STR_FRMUI_OLE_INSERT));
+ else
+ SetPageTitle(SwResId(STR_FRMUI_OLE_EDIT));
+ }
+ }
+ else
+ {
+ m_aGrfSize = rSet->Get(RES_FRM_SIZE).GetSize();
+ }
+
+ // entering percent value made possible
+
+ // the available space is not yet known so the RefValue has to be calculated from size and relative size values
+ // this is needed only if relative values are already set
+ const SwFormatFrameSize& rFrameSize = rSet->Get(RES_FRM_SIZE);
+
+ m_xRelWidthRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::FRAME));
+ m_xRelWidthRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::REL_PG_FRAME));
+ if (rFrameSize.GetWidthPercent() != SwFormatFrameSize::SYNCED && rFrameSize.GetWidthPercent() != 0)
+ {
+ //calculate the reference value from the width and relative width values
+ sal_Int32 nSpace = rFrameSize.GetWidth() * 100 / rFrameSize.GetWidthPercent();
+ m_xWidthED->SetRefValue( nSpace );
+
+ m_xRelWidthRelationLB->set_sensitive(true);
+ }
+ else
+ m_xRelWidthRelationLB->set_sensitive(false);
+
+ m_xRelHeightRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::FRAME));
+ m_xRelHeightRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::REL_PG_FRAME));
+ if (rFrameSize.GetHeightPercent() != SwFormatFrameSize::SYNCED && rFrameSize.GetHeightPercent() != 0)
+ {
+ //calculate the reference value from the with and relative width values
+ sal_Int32 nSpace = rFrameSize.GetHeight() * 100 / rFrameSize.GetHeightPercent();
+ m_xHeightED->SetRefValue( nSpace );
+
+ m_xRelHeightRelationLB->set_sensitive(true);
+ }
+ else
+ m_xRelHeightRelationLB->set_sensitive(false);
+
+ // general initialisation part
+ switch(rAnchor.GetAnchorId())
+ {
+ case RndStdIds::FLY_AT_PAGE: m_xAnchorAtPageRB->set_active(true); break;
+ case RndStdIds::FLY_AT_PARA: m_xAnchorAtParaRB->set_active(true); break;
+ case RndStdIds::FLY_AT_CHAR: m_xAnchorAtCharRB->set_active(true); break;
+ case RndStdIds::FLY_AS_CHAR: m_xAnchorAsCharRB->set_active(true); break;
+ case RndStdIds::FLY_AT_FLY: m_xAnchorAtFrameRB->set_active(true);break;
+ default:; //prevent warning
+ }
+
+ // i#22341 - determine content position of character
+ // Note: content position can be NULL
+ mpToCharContentPos = rAnchor.GetAnchorNode() ? &rAnchor : nullptr;
+
+ // i#18732 - init checkbox value
+ {
+ const bool bFollowTextFlow =
+ rSet->Get(RES_FOLLOW_TEXT_FLOW).GetValue();
+ m_xFollowTextFlowCB->set_active(bFollowTextFlow);
+ }
+ {
+ const bool bFlySplit = rSet->Get(RES_FLY_SPLIT).GetValue();
+ m_xFlySplitCB->set_active(bFlySplit);
+ }
+
+ if(m_bHtmlMode)
+ {
+ m_xAutoHeightCB->set_sensitive(false);
+ m_xAutoWidthCB->set_sensitive(false);
+ m_xMirrorPagesCB->hide();
+ if (m_sDlgType == "FrameDialog")
+ m_xFixedRatioCB->set_sensitive(false);
+ // i#18732 hide checkbox in HTML mode
+ m_xFollowTextFlowCB->hide();
+ }
+ else
+ {
+ // enable/disable of check box 'Mirror on..'
+ m_xMirrorPagesCB->set_sensitive(!m_xAnchorAsCharRB->get_active());
+
+ // enable/disable check box 'Follow text flow'.
+ // enable check box 'Follow text
+ // flow' also for anchor type to-frame.
+ m_xFollowTextFlowCB->set_sensitive(m_xAnchorAtParaRB->get_active() ||
+ m_xAnchorAtCharRB->get_active() ||
+ m_xAnchorAtFrameRB->get_active());
+ m_xFlySplitCB->set_sensitive(m_xAnchorAtParaRB->get_active());
+ }
+
+ const SwFrameFormat* pFlyFormat = pSh->GetFlyFrameFormat();
+ if (!pFlyFormat || !ContainsSingleTable(*pFlyFormat) || ContainsChain(*pFlyFormat))
+ {
+ bool bSingleTable = false;
+ if (!pFlyFormat && m_bNew)
+ {
+ // No fly is selected: check if a whole table is selected. If so, allow moving that into
+ // a split fly.
+ if (SwFlyFrameAttrMgr::SingleTableSelected(*pSh))
+ {
+ bSingleTable = true;
+ }
+ }
+
+ // Only allow fly split if the frame contains a single table, otherwise it would be hard to
+ // save the resulting model to Word formats.
+ if (!bSingleTable)
+ {
+ m_xFlySplitCB->hide();
+ }
+ }
+ else if (pFlyFormat && !m_bNew && InTextBox(*pFlyFormat))
+ {
+ // Disallow split flys in fly frames which form a textbox, i.e. non-editeng shape text.
+ m_xFlySplitCB->hide();
+ }
+
+ Init(*rSet);
+ m_xAtVertPosED->save_value();
+ m_xAtHorzPosED->save_value();
+ m_xFollowTextFlowCB->save_state();
+ m_xFlySplitCB->save_state();
+
+ m_xWidthED->save_value();
+ m_xHeightED->save_value();
+
+ m_bNoModifyHdl = false;
+ //lock PercentFields
+ m_xWidthED->LockAutoCalculation(true);
+ m_xHeightED->LockAutoCalculation(true);
+ RangeModifyHdl(); // set all maximum values initially
+ m_xHeightED->LockAutoCalculation(false);
+ m_xWidthED->LockAutoCalculation(false);
+
+ m_xAutoHeightCB->save_state();
+ m_xAutoWidthCB->save_state();
+
+ SwTwips nWidth = static_cast< SwTwips >(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
+ SwTwips nHeight = static_cast< SwTwips >(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
+ m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
+}
+
+// stuff attributes into the set when OK
+bool SwFramePage::FillItemSet(SfxItemSet *rSet)
+{
+ bool bRet = false;
+
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SfxPoolItem* pOldItem = nullptr;
+
+ RndStdIds eAnchorId = GetAnchor();
+
+ if ( !m_bFormat || eAnchorId != RndStdIds::FLY_AT_FLY )
+ {
+ pOldItem = GetOldItem(*rSet, RES_ANCHOR);
+ if (m_bNew || !pOldItem || eAnchorId != static_cast<const SwFormatAnchor*>(pOldItem)->GetAnchorId())
+ {
+ SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell()
+ : getFrameDlgParentShell();
+ OSL_ENSURE( pSh , "shell not found");
+ if (pSh)
+ {
+ SwFormatAnchor aAnc( eAnchorId, eAnchorId == RndStdIds::FLY_AT_PAGE ? pSh->GetPhyPageNum() : 0 );
+ bRet = nullptr != rSet->Put( aAnc );
+ }
+ }
+ }
+
+ if ( m_pHMap )
+ {
+ SwFormatHoriOrient aHoriOrient( rOldSet.Get(RES_HORI_ORIENT) );
+
+ const sal_Int32 nMapPos = GetMapPos(m_pHMap, *m_xHorizontalDLB);
+ const sal_Int16 eHOri = GetAlignment(m_pHMap, nMapPos, *m_xHoriRelationLB);
+ const sal_Int16 eRel = GetRelation(*m_xHoriRelationLB);
+
+ aHoriOrient.SetHoriOrient( eHOri );
+ aHoriOrient.SetRelationOrient( eRel );
+ aHoriOrient.SetPosToggle(m_xMirrorPagesCB->get_active());
+
+ bool bMod = m_xAtHorzPosED->get_value_changed_from_saved();
+ bMod |= m_xMirrorPagesCB->get_state_changed_from_saved();
+
+ if ( eHOri == text::HoriOrientation::NONE &&
+ (m_bNew || (m_bAtHorzPosModified || bMod) || m_nOldH != eHOri ) )
+ {
+ SwTwips nX = static_cast< SwTwips >(m_xAtHorzPosED->denormalize(m_xAtHorzPosED->get_value(FieldUnit::TWIP)));
+ aHoriOrient.SetPos( nX );
+ }
+
+ pOldItem = GetOldItem(*rSet, FN_HORI_ORIENT);
+ bool bSame = false;
+ if ((m_bNew == m_bFormat) && pOldItem)
+ {
+ bSame = aHoriOrient == static_cast<const SwFormatHoriOrient&>(*pOldItem);
+ }
+ if ((m_bNew && !m_bFormat) || ((m_bAtHorzPosModified || bMod) && !bSame))
+ {
+ bRet |= nullptr != rSet->Put( aHoriOrient );
+ }
+ }
+
+ if ( m_pVMap )
+ {
+ // alignment vertical
+ SwFormatVertOrient aVertOrient( rOldSet.Get(RES_VERT_ORIENT) );
+
+ const sal_Int32 nMapPos = GetMapPos(m_pVMap, *m_xVerticalDLB);
+ const sal_Int16 eVOri = GetAlignment(m_pVMap, nMapPos, *m_xVertRelationLB);
+ const sal_Int16 eRel = GetRelation(*m_xVertRelationLB);
+
+ aVertOrient.SetVertOrient ( eVOri);
+ aVertOrient.SetRelationOrient( eRel );
+
+ bool bMod = m_xAtVertPosED->get_value_changed_from_saved();
+
+ if ( eVOri == text::VertOrientation::NONE &&
+ ( m_bNew || (m_bAtVertPosModified || bMod) || m_nOldV != eVOri) )
+ {
+ // vertical position
+ // recalculate offset for character bound frames
+ SwTwips nY = static_cast< SwTwips >(m_xAtVertPosED->denormalize(m_xAtVertPosED->get_value(FieldUnit::TWIP)));
+ if (eAnchorId == RndStdIds::FLY_AS_CHAR)
+ {
+ nY *= -1;
+ }
+ aVertOrient.SetPos( nY );
+ }
+ pOldItem = GetOldItem(*rSet, FN_VERT_ORIENT);
+ bool bSame = false;
+ if((m_bNew == m_bFormat) && pOldItem)
+ {
+ bSame = m_bFormat ?
+ aVertOrient.GetVertOrient() == static_cast<const SwFormatVertOrient*>(pOldItem)->GetVertOrient() &&
+ aVertOrient.GetRelationOrient() == static_cast<const SwFormatVertOrient*>(pOldItem)->GetRelationOrient() &&
+ aVertOrient.GetPos() == static_cast<const SwFormatVertOrient*>(pOldItem)->GetPos()
+ : aVertOrient == static_cast<const SwFormatVertOrient&>(*pOldItem);
+ }
+ if( ( m_bNew && !m_bFormat ) || ((m_bAtVertPosModified || bMod) && !bSame ))
+ {
+ bRet |= nullptr != rSet->Put( aVertOrient );
+ }
+ }
+
+ // set size
+ // new exception: when the size of pMgr(, 0), then the properties
+ // for a graphic that isn't even loaded, are set. Then no SetSize
+ // is done here when the size settings were not changed by the
+ // user.
+ const SwFormatFrameSize& rOldSize = rOldSet.Get(RES_FRM_SIZE);
+ SwFormatFrameSize aSz( rOldSize );
+
+ auto nRelWidthRelation = m_xRelWidthRelationLB->get_active();
+ if (nRelWidthRelation != -1)
+ {
+ if (nRelWidthRelation == 0)
+ aSz.SetWidthPercentRelation(text::RelOrientation::FRAME);
+ else if (nRelWidthRelation == 1)
+ aSz.SetWidthPercentRelation(text::RelOrientation::PAGE_FRAME);
+ }
+ auto nRelHeightRelation = m_xRelHeightRelationLB->get_active();
+ if (nRelHeightRelation != -1)
+ {
+ if (nRelHeightRelation == 0)
+ aSz.SetHeightPercentRelation(text::RelOrientation::FRAME);
+ else if (nRelHeightRelation == 1)
+ aSz.SetHeightPercentRelation(text::RelOrientation::PAGE_FRAME);
+ }
+
+ bool bValueModified = m_xWidthED->get_value_changed_from_saved() ||
+ m_xHeightED->get_value_changed_from_saved();
+ bool bCheckChanged = m_xRelWidthCB->get_state_changed_from_saved() ||
+ m_xRelHeightCB->get_state_changed_from_saved() ||
+ m_xFixedRatioCB->get_state_changed_from_saved();
+
+ bool bLegalValue = !(!rOldSize.GetWidth () && !rOldSize.GetHeight() &&
+ m_xWidthED->get_value() == m_xWidthED->get_min() &&
+ m_xHeightED->get_value() == m_xHeightED->get_min());
+
+ if ((m_bNew && !m_bFormat) || ((bValueModified || bCheckChanged) && bLegalValue))
+ {
+ sal_Int64 nNewWidth = m_xWidthED->DenormalizePercent(m_xWidthED->GetRealValue(FieldUnit::TWIP));
+ sal_Int64 nNewHeight = m_xHeightED->DenormalizePercent(m_xHeightED->GetRealValue(FieldUnit::TWIP));
+ aSz.SetWidth (static_cast< SwTwips >(nNewWidth));
+ aSz.SetHeight(static_cast< SwTwips >(nNewHeight));
+
+ if (m_xRelWidthCB->get_active())
+ {
+ aSz.SetWidthPercent(static_cast<sal_uInt8>(std::min(MAX_PERCENT_WIDTH, m_xWidthED->Convert(m_xWidthED->NormalizePercent(nNewWidth), FieldUnit::TWIP, FieldUnit::PERCENT))));
+ }
+ else
+ aSz.SetWidthPercent(0);
+ if (m_xRelHeightCB->get_active())
+ aSz.SetHeightPercent(static_cast<sal_uInt8>(std::min(MAX_PERCENT_HEIGHT, m_xHeightED->Convert(m_xHeightED->NormalizePercent(nNewHeight), FieldUnit::TWIP, FieldUnit::PERCENT))));
+ else
+ aSz.SetHeightPercent(0);
+
+ if (m_xFixedRatioCB->get_active() && (m_xRelWidthCB->get_active() != m_xRelHeightCB->get_active()))
+ {
+ if (m_xRelWidthCB->get_active())
+ aSz.SetHeightPercent(SwFormatFrameSize::SYNCED);
+ else
+ aSz.SetWidthPercent(SwFormatFrameSize::SYNCED);
+ }
+ }
+
+ if( !IsInGraficMode() )
+ {
+ if (m_xAutoHeightCB->get_state_changed_from_saved())
+ {
+ SwFrameSize eFrameSize = m_xAutoHeightCB->get_active()? SwFrameSize::Minimum : SwFrameSize::Fixed;
+ if( eFrameSize != aSz.GetHeightSizeType() )
+ aSz.SetHeightSizeType(eFrameSize);
+ }
+ if (m_xAutoWidthCB->get_state_changed_from_saved())
+ {
+ SwFrameSize eFrameSize = m_xAutoWidthCB->get_active()? SwFrameSize::Minimum : SwFrameSize::Fixed;
+ if( eFrameSize != aSz.GetWidthSizeType() )
+ aSz.SetWidthSizeType( eFrameSize );
+ }
+ }
+ if (m_xFixedRatioCB->get_state_changed_from_saved())
+ bRet |= nullptr != rSet->Put(SfxBoolItem(FN_KEEP_ASPECT_RATIO, m_xFixedRatioCB->get_active()));
+
+ pOldItem = GetOldItem(*rSet, RES_FRM_SIZE);
+
+ bool bSizeChanged = pOldItem && aSz != *pOldItem;
+ if (!bSizeChanged && m_bNew)
+ {
+ // If no custom size is provided, always set a size for a new frame, to avoid ~zero width.
+ bSizeChanged = true;
+ }
+ if (bSizeChanged || (!pOldItem && !m_bFormat) ||
+ (m_bFormat &&
+ (aSz.GetWidth() > 0 || aSz.GetWidthPercent() > 0) &&
+ (aSz.GetHeight() > 0 || aSz.GetHeightPercent() > 0)))
+ {
+ if (aSz.GetHeightSizeType() == SwFrameSize::Variable) // there is no VAR_SIZE in frames
+ aSz.SetHeightSizeType(SwFrameSize::Minimum);
+
+ bRet |= nullptr != rSet->Put( aSz );
+ }
+ if (m_xFollowTextFlowCB->get_state_changed_from_saved())
+ {
+ bRet |= nullptr != rSet->Put(SwFormatFollowTextFlow(m_xFollowTextFlowCB->get_active()));
+ }
+ if (m_xFlySplitCB->get_state_changed_from_saved())
+ {
+ bRet |= rSet->Put(SwFormatFlySplit(m_xFlySplitCB->get_active())) != nullptr;
+ }
+ return bRet;
+}
+
+// initialise horizontal and vertical Pos
+void SwFramePage::InitPos(RndStdIds eId,
+ sal_Int16 nH,
+ sal_Int16 nHRel,
+ sal_Int16 nV,
+ sal_Int16 nVRel,
+ tools::Long nX,
+ tools::Long nY)
+{
+ auto nPos = m_xVerticalDLB->get_active();
+ if (nPos != -1 && m_pVMap)
+ {
+ m_nOldV = m_pVMap[nPos].nAlign;
+
+ nPos = m_xVertRelationLB->get_active();
+ if (nPos != -1)
+ m_nOldVRel = weld::fromId<RelationMap*>(m_xVertRelationLB->get_id(nPos))->nRelation;
+ }
+
+ nPos = m_xHorizontalDLB->get_active();
+ if (nPos != -1 && m_pHMap)
+ {
+ m_nOldH = m_pHMap[nPos].nAlign;
+
+ nPos = m_xHoriRelationLB->get_active();
+ if (nPos != -1)
+ m_nOldHRel = weld::fromId<RelationMap*>(m_xHoriRelationLB->get_id(nPos))->nRelation;
+ }
+
+ bool bEnable = true;
+ if ( eId == RndStdIds::FLY_AT_PAGE )
+ {
+ m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
+ m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
+ }
+ else if ( eId == RndStdIds::FLY_AT_FLY )
+ {
+ // own vertical alignment map for to frame
+ // anchored objects.
+ m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
+ m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
+ }
+ else if ( eId == RndStdIds::FLY_AT_PARA )
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVParaHtmlMap;
+ m_pHMap = aHParaHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVParaMap;
+ m_pHMap = aHParaMap;
+ }
+ }
+ else if ( eId == RndStdIds::FLY_AT_CHAR )
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVCharHtmlAbsMap;
+ m_pHMap = aHCharHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVCharMap;
+ m_pHMap = aHCharMap;
+ }
+ }
+ else if ( eId == RndStdIds::FLY_AS_CHAR )
+ {
+ m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
+ m_pHMap = nullptr;
+ bEnable = false;
+ }
+ m_xHorizontalDLB->set_sensitive( bEnable );
+ m_xHorizontalFT->set_sensitive( bEnable );
+
+ // select current Pos
+ // horizontal
+ if ( nH < 0 )
+ {
+ nH = m_nOldH;
+ nHRel = m_nOldHRel;
+ }
+ sal_Int32 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHorizontalDLB);
+ FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriRelationLB, *m_xHoriRelationFT);
+
+ // vertical
+ if ( nV < 0 )
+ {
+ nV = m_nOldV;
+ nVRel = m_nOldVRel;
+ }
+ nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVerticalDLB);
+ FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertRelationLB, *m_xVertRelationFT);
+
+ bEnable = nH == text::HoriOrientation::NONE && eId != RndStdIds::FLY_AS_CHAR;
+ if (!bEnable)
+ m_xAtHorzPosED->set_value(0, FieldUnit::TWIP);
+ else
+ {
+ if (nX != LONG_MAX)
+ m_xAtHorzPosED->set_value(m_xAtHorzPosED->normalize(nX), FieldUnit::TWIP);
+ }
+ m_xAtHorzPosFT->set_sensitive( bEnable );
+ m_xAtHorzPosED->set_sensitive( bEnable );
+
+ bEnable = nV == text::VertOrientation::NONE;
+ if ( !bEnable )
+ m_xAtVertPosED->set_value(0, FieldUnit::TWIP);
+ else
+ {
+ if (eId == RndStdIds::FLY_AS_CHAR)
+ {
+ if ( nY == LONG_MAX )
+ nY = 0;
+ else
+ nY *= -1;
+ }
+ if ( nY != LONG_MAX )
+ m_xAtVertPosED->set_value(m_xAtVertPosED->normalize(nY), FieldUnit::TWIP);
+ }
+ m_xAtVertPosFT->set_sensitive( bEnable && m_bAllowVertPositioning );
+ m_xAtVertPosED->set_sensitive( bEnable && m_bAllowVertPositioning );
+ UpdateExample();
+}
+
+sal_Int32 SwFramePage::FillPosLB(const FrameMap* _pMap,
+ const sal_Int16 _nAlign,
+ const sal_Int16 _nRel,
+ weld::ComboBox& _rLB )
+{
+ OUString sSelEntry;
+ const OUString sOldEntry = _rLB.get_active_text();
+
+ _rLB.clear();
+
+ // i#22341 determine all possible listbox relations for
+ // given relation for map <aVCharMap>
+ const LB nLBRelations = (_pMap != aVCharMap)
+ ? LB::NONE
+ : ::lcl_GetLBRelationsForRelations( _nRel );
+
+ // fill Listbox
+ size_t nCount = ::lcl_GetFrameMapCount(_pMap);
+ for (size_t i = 0; _pMap && i < nCount; ++i)
+ {
+// Why not from the left/from inside or from above?
+ SvxSwFramePosString::StringId eStrId = m_xMirrorPagesCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
+ // --> OD 2009-08-31 #mongolianlayout#
+ eStrId = lcl_ChangeResIdToVerticalOrRTL( eStrId,
+ m_bIsVerticalFrame,
+ m_bIsVerticalL2R,
+ m_bIsInRightToLeft);
+ OUString sEntry(SvxSwFramePosString::GetString(eStrId));
+ if (_rLB.find_text(sEntry) == -1)
+ {
+ // don't insert entries when frames are character bound
+ _rLB.append_text(sEntry);
+ }
+ // i#22341 - 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.get_count())
+ _rLB.set_active(0);
+
+ PosHdl(_rLB);
+
+ return GetMapPos(_pMap, _rLB);
+}
+
+void SwFramePage::FillRelLB(const FrameMap* _pMap,
+ const sal_uInt16 _nLBSelPos,
+ const sal_Int16 _nAlign,
+ const sal_Int16 _nRel,
+ weld::ComboBox& _rLB,
+ weld::Label& _rFT)
+{
+ OUString sSelEntry;
+ LB nLBRelations = LB::NONE;
+ size_t nMapCount = ::lcl_GetFrameMapCount(_pMap);
+
+ _rLB.clear();
+
+ if (_nLBSelPos < nMapCount)
+ {
+ if (_pMap == aVAsCharHtmlMap || _pMap == aVAsCharMap)
+ {
+ const OUString sOldEntry(_rLB.get_active_text());
+ SvxSwFramePosString::StringId eStrId = _pMap[_nLBSelPos].eStrId;
+
+ for (size_t nMapPos = 0; nMapPos < nMapCount; nMapPos++)
+ {
+ if (_pMap[nMapPos].eStrId == eStrId)
+ {
+ nLBRelations = _pMap[nMapPos].nLBRelations;
+ for (RelationMap const & rCharMap : aAsCharRelationMap)
+ {
+ if (nLBRelations & rCharMap.nLBRelation)
+ {
+ // --> OD 2009-08-31 #mongolianlayout#
+ SvxSwFramePosString::StringId sStrId1 =
+ lcl_ChangeResIdToVerticalOrRTL( rCharMap.eStrId,
+ m_bIsVerticalFrame,
+ m_bIsVerticalL2R,
+ m_bIsInRightToLeft);
+ const OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ _rLB.append(weld::toId(&rCharMap), 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
+ {
+ // special handling for map <aVCharMap>,
+ // because its ambiguous in its <eStrId>/<eMirrorStrId>.
+ if ( _pMap == aVCharMap )
+ {
+ nLBRelations = ::lcl_GetLBRelationsForStrID( _pMap,
+ ( m_xMirrorPagesCB->get_active()
+ ? _pMap[_nLBSelPos].eMirrorStrId
+ : _pMap[_nLBSelPos].eStrId),
+ m_xMirrorPagesCB->get_active() );
+ }
+ else
+ {
+ nLBRelations = _pMap[_nLBSelPos].nLBRelations;
+ }
+
+ for (sal_uLong nBit = 1; nBit < 0x80000000; nBit <<= 1)
+ {
+ if (nLBRelations & static_cast<LB>(nBit))
+ {
+ for (RelationMap const & rMap : aRelationMap)
+ {
+ if (rMap.nLBRelation == static_cast<LB>(nBit))
+ {
+ SvxSwFramePosString::StringId eStrId1 = m_xMirrorPagesCB->get_active() ?
+ rMap.eMirrorStrId : rMap.eStrId;
+ // --> OD 2009-08-31 #mongolianlayout#
+ eStrId1 =
+ lcl_ChangeResIdToVerticalOrRTL( eStrId1,
+ m_bIsVerticalFrame,
+ m_bIsVerticalL2R,
+ m_bIsInRightToLeft);
+ const OUString sEntry = SvxSwFramePosString::GetString(eStrId1);
+ _rLB.append(weld::toId(&rMap), sEntry);
+ if (sSelEntry.isEmpty() && rMap.nRelation == _nRel)
+ sSelEntry = sEntry;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ _rLB.set_active_text(sSelEntry);
+ else
+ {
+ // Probably anchor switch. So look for similar relation
+ sal_Int16 nSimRel = -1;
+ switch (_nRel)
+ {
+ case text::RelOrientation::FRAME:
+ nSimRel = text::RelOrientation::PAGE_FRAME;
+ break;
+ case text::RelOrientation::PRINT_AREA:
+ nSimRel = text::RelOrientation::PAGE_PRINT_AREA;
+ break;
+ case text::RelOrientation::PAGE_LEFT:
+ nSimRel = text::RelOrientation::FRAME_LEFT;
+ break;
+ case text::RelOrientation::PAGE_RIGHT:
+ nSimRel = text::RelOrientation::FRAME_RIGHT;
+ break;
+ case text::RelOrientation::FRAME_LEFT:
+ nSimRel = text::RelOrientation::PAGE_LEFT;
+ break;
+ case text::RelOrientation::FRAME_RIGHT:
+ nSimRel = text::RelOrientation::PAGE_RIGHT;
+ break;
+ case text::RelOrientation::PAGE_FRAME:
+ nSimRel = text::RelOrientation::FRAME;
+ break;
+ case text::RelOrientation::PAGE_PRINT_AREA:
+ nSimRel = text::RelOrientation::PRINT_AREA;
+ break;
+
+ default:
+ if (_rLB.get_active() != -1)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(_rLB.get_id(_rLB.get_count() - 1));
+ nSimRel = pEntry->nRelation;
+ }
+ break;
+ }
+
+ for (int i = 0; i < _rLB.get_count(); i++)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap*>(_rLB.get_id(i));
+ if (pEntry->nRelation == nSimRel)
+ {
+ _rLB.set_active(i);
+ break;
+ }
+ }
+
+ if (_rLB.get_active() == -1)
+ _rLB.set_active(0);
+ }
+ }
+ }
+
+ const bool bEnable = _rLB.get_count() != 0
+ && (&_rLB != m_xVertRelationLB.get() || m_bAllowVertPositioning);
+ _rLB.set_sensitive( bEnable );
+ _rFT.set_sensitive( bEnable );
+
+ RelHdl(_rLB);
+}
+
+sal_Int16 SwFramePage::GetRelation(const weld::ComboBox& rRelationLB)
+{
+ const auto nPos = rRelationLB.get_active();
+ if (nPos != -1)
+ {
+ RelationMap *pEntry = weld::fromId<RelationMap *>(rRelationLB.get_id(nPos));
+ return pEntry->nRelation;
+ }
+
+ return 0;
+}
+
+sal_Int16 SwFramePage::GetAlignment(FrameMap const *pMap, sal_Int32 nMapPos,
+ const weld::ComboBox& rRelationLB)
+{
+ if (!pMap || nMapPos < 0)
+ return 0;
+
+ const size_t nMapCount = ::lcl_GetFrameMapCount(pMap);
+
+ if (o3tl::make_unsigned(nMapPos) >= nMapCount)
+ return 0;
+
+ // i#22341 special handling also for map <aVCharMap>,
+ // because it contains ambiguous items for alignment
+ if ( pMap != aVAsCharHtmlMap && pMap != aVAsCharMap && pMap != aVCharMap )
+ return pMap[nMapPos].nAlign;
+
+ if (rRelationLB.get_active() == -1)
+ return 0;
+
+ const RelationMap *const pRelationMap = weld::fromId<const RelationMap*>(
+ rRelationLB.get_active_id());
+ const LB nRel = pRelationMap->nLBRelation;
+ const SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (size_t i = 0; i < nMapCount; ++i)
+ {
+ if (pMap[i].eStrId == eStrId && (pMap[i].nLBRelations & nRel))
+ return pMap[i].nAlign;
+ }
+
+ return 0;
+}
+
+sal_Int32 SwFramePage::GetMapPos(const FrameMap *pMap, const weld::ComboBox& rAlignLB)
+{
+ sal_Int32 nMapPos = 0;
+ auto nLBSelPos = rAlignLB.get_active();
+
+ if (nLBSelPos != -1)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ const size_t nMapCount = ::lcl_GetFrameMapCount(pMap);
+ const OUString sSelEntry(rAlignLB.get_active_text());
+
+ for (size_t i = 0; i < nMapCount; i++)
+ {
+ SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
+
+ OUString sEntry = SvxSwFramePosString::GetString(eResId);
+ sEntry = MnemonicGenerator::EraseAllMnemonicChars( sEntry );
+
+ if (sEntry == sSelEntry)
+ {
+ nMapPos = static_cast< sal_Int32 >(i);
+ break;
+ }
+ }
+ }
+ else
+ nMapPos = nLBSelPos;
+ }
+
+ return nMapPos;
+}
+
+RndStdIds SwFramePage::GetAnchor() const
+{
+ RndStdIds nRet = RndStdIds::FLY_AT_PAGE;
+ if (m_xAnchorAtParaRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PARA;
+ }
+ else if (m_xAnchorAtCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_CHAR;
+ }
+ else if (m_xAnchorAsCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AS_CHAR;
+ }
+ else if (m_xAnchorAtFrameRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_FLY;
+ }
+ return nRet;
+}
+
+// Bsp - Update
+void SwFramePage::ActivatePage(const SfxItemSet& rSet)
+{
+ m_bNoModifyHdl = true;
+ Init(rSet);
+ m_bNoModifyHdl = false;
+ //lock PercentFields
+ m_xWidthED->LockAutoCalculation(true);
+ m_xHeightED->LockAutoCalculation(true);
+ RangeModifyHdl(); // set all maximum values initially
+ m_xHeightED->LockAutoCalculation(false);
+ m_xWidthED->LockAutoCalculation(false);
+ m_xFollowTextFlowCB->save_state();
+ m_xFlySplitCB->save_state();
+}
+
+DeactivateRC SwFramePage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if ( _pSet )
+ {
+ FillItemSet( _pSet );
+
+ if (!m_bFormat) // tdf#112574 no anchor in styles
+ {
+ //FillItemSet doesn't set the anchor into the set when it matches
+ //the original. But for the other pages we need the current anchor.
+ SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell()
+ : getFrameDlgParentShell();
+ if (pSh)
+ {
+ RndStdIds eAnchorId = GetAnchor();
+ SwFormatAnchor aAnc( eAnchorId, eAnchorId == RndStdIds::FLY_AT_PAGE ? pSh->GetPhyPageNum() : 0 );
+ _pSet->Put( aAnc );
+ }
+ }
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+// swap left/right with inside/outside
+IMPL_LINK_NOARG(SwFramePage, MirrorHdl, weld::Toggleable&, void)
+{
+ RndStdIds eId = GetAnchor();
+ InitPos(eId, -1, 0, -1, 0, LONG_MAX, LONG_MAX);
+}
+
+IMPL_LINK( SwFramePage, RelSizeClickHdl, weld::Toggleable&, rBtn, void )
+{
+ if (&rBtn == m_xRelWidthCB.get())
+ {
+ m_xWidthED->ShowPercent(rBtn.get_active());
+ m_xRelWidthRelationLB->set_sensitive(rBtn.get_active());
+ if (rBtn.get_active())
+ m_xWidthED->get()->set_max(MAX_PERCENT_WIDTH, FieldUnit::NONE);
+ }
+ else // rBtn == m_xRelHeightCB.get()
+ {
+ m_xHeightED->ShowPercent(rBtn.get_active());
+ m_xRelHeightRelationLB->set_sensitive(rBtn.get_active());
+ if (rBtn.get_active())
+ m_xHeightED->get()->set_max(MAX_PERCENT_HEIGHT, FieldUnit::NONE);
+ }
+
+ RangeModifyHdl(); // correct the values again
+
+ if (&rBtn == m_xRelWidthCB.get())
+ ModifyHdl(*m_xWidthED->get());
+ else // rBtn == m_xRelHeightCB.get()
+ ModifyHdl(*m_xHeightED->get());
+}
+
+// range check
+IMPL_LINK_NOARG(SwFramePage, RangeModifyClickHdl, weld::Toggleable&, void)
+{
+ RangeModifyHdl();
+}
+
+void SwFramePage::RangeModifyHdl()
+{
+ if (m_bNoModifyHdl)
+ return;
+
+ SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell()
+ : getFrameDlgParentShell();
+ OSL_ENSURE(pSh , "shell not found");
+ if (!pSh)
+ return;
+
+ SwFlyFrameAttrMgr aMgr( m_bNew, pSh, GetItemSet() );
+ SvxSwFrameValidation aVal;
+
+ aVal.nAnchorType = GetAnchor();
+ aVal.bAutoHeight = m_xAutoHeightCB->get_active();
+ aVal.bMirror = m_xMirrorPagesCB->get_active();
+ aVal.bFollowTextFlow = m_xFollowTextFlowCB->get_active();
+
+ if ( m_pHMap )
+ {
+ // alignment horizontal
+ const sal_Int32 nMapPos = GetMapPos(m_pHMap, *m_xHorizontalDLB);
+ aVal.nHoriOrient = GetAlignment(m_pHMap, nMapPos, *m_xHoriRelationLB);
+ aVal.nHRelOrient = GetRelation(*m_xHoriRelationLB);
+ }
+ else
+ aVal.nHoriOrient = text::HoriOrientation::NONE;
+
+ if ( m_pVMap )
+ {
+ // alignment vertical
+ const sal_Int32 nMapPos = GetMapPos(m_pVMap, *m_xVerticalDLB);
+ aVal.nVertOrient = GetAlignment(m_pVMap, nMapPos, *m_xVertRelationLB);
+ aVal.nVRelOrient = GetRelation(*m_xVertRelationLB);
+ }
+ else
+ aVal.nVertOrient = text::VertOrientation::NONE;
+
+ const tools::Long nAtHorzPosVal = static_cast< tools::Long >(
+ m_xAtHorzPosED->denormalize(m_xAtHorzPosED->get_value(FieldUnit::TWIP)) );
+ const tools::Long nAtVertPosVal = static_cast< tools::Long >(
+ m_xAtVertPosED->denormalize(m_xAtVertPosED->get_value(FieldUnit::TWIP)) );
+
+ aVal.nHPos = nAtHorzPosVal;
+ aVal.nVPos = nAtVertPosVal;
+
+ aMgr.ValidateMetrics(aVal, mpToCharContentPos, true); // one time, to get reference values for percental values
+
+ // set reference values for percental values (100%) ...
+ m_xWidthED->SetRefValue(aVal.aPercentSize.Width());
+ m_xHeightED->SetRefValue(aVal.aPercentSize.Height());
+
+ // ... and correctly convert width and height with it
+ SwTwips nWidth = static_cast< SwTwips >(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
+ SwTwips nHeight = static_cast< SwTwips >(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
+ aVal.nWidth = nWidth;
+ aVal.nHeight = nHeight;
+
+ aMgr.ValidateMetrics(aVal, mpToCharContentPos); // one more time, to determine all remaining values with correct width and height.
+
+ // all columns have to be correct
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if (pExampleSet && SfxItemState::DEFAULT <= pExampleSet->GetItemState(RES_COL))
+ {
+ const SwFormatCol& rCol = pExampleSet->Get(RES_COL);
+ if ( rCol.GetColumns().size() > 1 )
+ {
+ for (const SwColumn & i : rCol.GetColumns())
+ {
+ aVal.nMinWidth += i.GetLeft() +
+ i.GetRight() +
+ MINFLY;
+ }
+ aVal.nMinWidth -= MINFLY;//one was already in there!
+ }
+ }
+
+ nWidth = aVal.nWidth;
+ nHeight = aVal.nHeight;
+
+ // minimum range also for template
+ m_xHeightED->set_min(m_xHeightED->NormalizePercent(aVal.nMinHeight), FieldUnit::TWIP);
+ m_xWidthED->set_min(m_xWidthED->NormalizePercent(aVal.nMinWidth), FieldUnit::TWIP);
+
+ SwTwips nMaxWidth(aVal.nMaxWidth);
+ SwTwips nMaxHeight(aVal.nMaxHeight);
+
+ if (aVal.bAutoHeight && (m_sDlgType == "PictureDialog" || m_sDlgType == "ObjectDialog"))
+ {
+ SwTwips nTmp = std::min(nWidth * nMaxHeight / std::max(nHeight, SwTwips(1)), nMaxHeight);
+ m_xWidthED->set_max(m_xWidthED->NormalizePercent(nTmp), FieldUnit::TWIP);
+
+ nTmp = std::min(nHeight * nMaxWidth / std::max(nWidth, SwTwips(1)), nMaxWidth);
+ m_xHeightED->set_max(m_xWidthED->NormalizePercent(nTmp), FieldUnit::TWIP);
+ }
+ else
+ {
+ SwTwips nTmp = static_cast< SwTwips >(m_xHeightED->NormalizePercent(nMaxHeight));
+ m_xHeightED->set_max(nTmp, FieldUnit::TWIP);
+
+ nTmp = static_cast< SwTwips >(m_xWidthED->NormalizePercent(nMaxWidth));
+ m_xWidthED->set_max(nTmp, FieldUnit::TWIP);
+ }
+
+ m_xAtHorzPosED->set_range(m_xAtHorzPosED->normalize(aVal.nMinHPos),
+ m_xAtHorzPosED->normalize(aVal.nMaxHPos),
+ FieldUnit::TWIP);
+ if (aVal.nHPos != nAtHorzPosVal)
+ m_xAtHorzPosED->set_value(m_xAtHorzPosED->normalize(aVal.nHPos), FieldUnit::TWIP);
+
+ const SwTwips nUpperOffset = (aVal.nAnchorType == RndStdIds::FLY_AS_CHAR)
+ ? m_nUpperBorder : 0;
+ const SwTwips nLowerOffset = (aVal.nAnchorType == RndStdIds::FLY_AS_CHAR)
+ ? m_nLowerBorder : 0;
+
+ m_xAtVertPosED->set_range(m_xAtVertPosED->normalize(aVal.nMinVPos + nLowerOffset + nUpperOffset),
+ m_xAtVertPosED->normalize(aVal.nMaxVPos),
+ FieldUnit::TWIP);
+ if (aVal.nVPos != nAtVertPosVal)
+ m_xAtVertPosED->set_value(m_xAtVertPosED->normalize(aVal.nVPos), FieldUnit::TWIP);
+}
+
+IMPL_LINK_NOARG(SwFramePage, AnchorTypeHdl, weld::Toggleable&, void)
+{
+ m_xMirrorPagesCB->set_sensitive(!m_xAnchorAsCharRB->get_active());
+
+ // i#18732 - enable check box 'Follow text flow' for anchor
+ // type to-paragraph' and to-character
+ // i#22305 - enable check box 'Follow text
+ // flow' also for anchor type to-frame.
+ m_xFollowTextFlowCB->set_sensitive(m_xAnchorAtParaRB->get_active() ||
+ m_xAnchorAtCharRB->get_active() ||
+ m_xAnchorAtFrameRB->get_active());
+ m_xFlySplitCB->set_sensitive(m_xAnchorAtParaRB->get_active());
+
+ RndStdIds eId = GetAnchor();
+
+ InitPos( eId, -1, 0, -1, 0, LONG_MAX, LONG_MAX);
+ RangeModifyHdl();
+
+ if(m_bHtmlMode)
+ {
+ PosHdl(*m_xHorizontalDLB);
+ PosHdl(*m_xVerticalDLB);
+ }
+
+ EnableVerticalPositioning( !(m_bIsMathOLE && m_bIsMathBaselineAlignment
+ && RndStdIds::FLY_AS_CHAR == eId) );
+}
+
+IMPL_LINK( SwFramePage, PosHdl, weld::ComboBox&, rLB, void )
+{
+ bool bHori = &rLB == m_xHorizontalDLB.get();
+ weld::ComboBox *pRelLB = bHori ? m_xHoriRelationLB.get() : m_xVertRelationLB.get();
+ weld::Label *pRelFT = bHori ? m_xHoriRelationFT.get() : m_xVertRelationFT.get();
+ FrameMap const *pMap = bHori ? m_pHMap : m_pVMap;
+
+ const sal_Int32 nMapPos = GetMapPos(pMap, rLB);
+ const sal_Int16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
+
+ if (bHori)
+ {
+ bool bEnable = text::HoriOrientation::NONE == nAlign;
+ m_xAtHorzPosED->set_sensitive( bEnable );
+ m_xAtHorzPosFT->set_sensitive( bEnable );
+ }
+ else
+ {
+ bool bEnable = text::VertOrientation::NONE == nAlign && m_bAllowVertPositioning;
+ m_xAtVertPosED->set_sensitive( bEnable );
+ m_xAtVertPosFT->set_sensitive( bEnable );
+ }
+
+ RangeModifyHdl();
+
+ sal_Int16 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();
+
+ if (bHori)
+ m_bAtHorzPosModified = true;
+ else
+ m_bAtVertPosModified = true;
+
+ // special treatment for HTML-Mode with horizontal-vertical-dependencies
+ if(!(m_bHtmlMode && (RndStdIds::FLY_AT_CHAR == GetAnchor())))
+ return;
+
+ bool bSet = false;
+ if(bHori)
+ {
+ // right is allowed only above - from the left only above
+ // from the left at character -> below
+ if((text::HoriOrientation::LEFT == nAlign || text::HoriOrientation::RIGHT == nAlign) &&
+ 0 == m_xVerticalDLB->get_active())
+ {
+ if(text::RelOrientation::FRAME == nRel)
+ m_xVerticalDLB->set_active(1);
+ else
+ m_xVerticalDLB->set_active(0);
+ bSet = true;
+ }
+ else if(text::HoriOrientation::LEFT == nAlign && 1 == m_xVerticalDLB->get_active())
+ {
+ m_xVerticalDLB->set_active(0);
+ bSet = true;
+ }
+ else if(text::HoriOrientation::NONE == nAlign && 1 == m_xVerticalDLB->get_active())
+ {
+ m_xVerticalDLB->set_active(0);
+ bSet = true;
+ }
+ if(bSet)
+ PosHdl(*m_xVerticalDLB);
+ }
+ else
+ {
+ if(text::VertOrientation::TOP == nAlign)
+ {
+ if (1 == m_xHorizontalDLB->get_active())
+ {
+ m_xHorizontalDLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriRelationLB->set_active(1);
+ }
+ else if(text::VertOrientation::CHAR_BOTTOM == nAlign)
+ {
+ if (2 == m_xHorizontalDLB->get_active())
+ {
+ m_xHorizontalDLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriRelationLB->set_active(0) ;
+ }
+ if(bSet)
+ PosHdl(*m_xHorizontalDLB);
+ }
+}
+
+// horizontal Pos
+IMPL_LINK( SwFramePage, RelHdl, weld::ComboBox&, rLB, void )
+{
+ bool bHori = &rLB == m_xHoriRelationLB.get();
+
+ UpdateExample();
+
+ if (bHori)
+ m_bAtHorzPosModified = true;
+ else
+ m_bAtVertPosModified = true;
+
+ if (m_bHtmlMode && (RndStdIds::FLY_AT_CHAR == GetAnchor()))
+ {
+ if(bHori)
+ {
+ const sal_Int16 nRel = GetRelation(*m_xHoriRelationLB);
+ if(text::RelOrientation::PRINT_AREA == nRel && 0 == m_xVerticalDLB->get_active())
+ {
+ m_xVerticalDLB->set_active(1);
+ }
+ else if(text::RelOrientation::CHAR == nRel && 1 == m_xVerticalDLB->get_active())
+ {
+ m_xVerticalDLB->set_active(0);
+ }
+ }
+ }
+ RangeModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwFramePage, RealSizeHdl, weld::Button&, void)
+{
+ m_xWidthED->set_value(m_xWidthED->NormalizePercent(m_aGrfSize.Width()), FieldUnit::TWIP);
+ m_xHeightED->set_value(m_xHeightED->NormalizePercent(m_aGrfSize.Height()), FieldUnit::TWIP);
+ m_fWidthHeightRatio = m_aGrfSize.Height() ? double(m_aGrfSize.Width()) / double(m_aGrfSize.Height()) : 1.0;
+ UpdateExample();
+}
+
+IMPL_LINK_NOARG(SwFramePage, AutoWidthClickHdl, weld::Toggleable&, void)
+{
+ if( !IsInGraficMode() )
+ HandleAutoCB( m_xAutoWidthCB->get_active(), *m_xWidthFT, *m_xWidthAutoFT, *m_xWidthED->get() );
+}
+
+IMPL_LINK_NOARG(SwFramePage, AutoHeightClickHdl, weld::Toggleable&, void)
+{
+ if (!IsInGraficMode())
+ HandleAutoCB(m_xAutoHeightCB->get_active(), *m_xHeightFT, *m_xHeightAutoFT, *m_xWidthED->get());
+}
+
+IMPL_LINK( SwFramePage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
+{
+ SwTwips nWidth = static_cast< SwTwips >(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
+ SwTwips nHeight = static_cast< SwTwips >(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
+ if (m_xFixedRatioCB->get_active())
+ {
+ if (&rEdit == m_xWidthED->get())
+ {
+ nHeight = SwTwips(static_cast<double>(nWidth) / m_fWidthHeightRatio);
+ m_xHeightED->set_value(m_xHeightED->NormalizePercent(nHeight), FieldUnit::TWIP);
+ }
+ else if (&rEdit == m_xHeightED->get())
+ {
+ nWidth = SwTwips(static_cast<double>(nHeight) * m_fWidthHeightRatio);
+ m_xWidthED->set_value(m_xWidthED->NormalizePercent(nWidth), FieldUnit::TWIP);
+ }
+ }
+ m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
+ UpdateExample();
+}
+
+void SwFramePage::UpdateExample()
+{
+ auto nPos = m_xHorizontalDLB->get_active();
+ if (m_pHMap && nPos != -1)
+ {
+ const sal_Int32 nMapPos = GetMapPos(m_pHMap, *m_xHorizontalDLB);
+ m_aExampleWN.SetHAlign(GetAlignment(m_pHMap, nMapPos, *m_xHoriRelationLB));
+ m_aExampleWN.SetHoriRel(GetRelation(*m_xHoriRelationLB));
+ }
+
+ nPos = m_xVerticalDLB->get_active();
+ if (m_pVMap && nPos != -1)
+ {
+ const sal_Int32 nMapPos = GetMapPos(m_pVMap, *m_xVerticalDLB);
+ m_aExampleWN.SetVAlign(GetAlignment(m_pVMap, nMapPos, *m_xVertRelationLB));
+ m_aExampleWN.SetVertRel(GetRelation(*m_xVertRelationLB));
+ }
+
+ // size
+ auto nXPos = m_xAtHorzPosED->denormalize(m_xAtHorzPosED->get_value(FieldUnit::TWIP));
+ auto nYPos = m_xAtVertPosED->denormalize(m_xAtVertPosED->get_value(FieldUnit::TWIP));
+ m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
+
+ m_aExampleWN.SetAnchor(GetAnchor());
+ m_aExampleWN.Invalidate();
+}
+
+void SwFramePage::Init(const SfxItemSet& rSet)
+{
+ if(!m_bFormat)
+ {
+ SwWrtShell* pSh = getFrameDlgParentShell();
+
+ // size
+ const bool bSizeFixed = pSh->IsSelObjProtected( FlyProtectFlags::Fixed ) != FlyProtectFlags::NONE;
+
+ m_xWidthED->set_sensitive( !bSizeFixed );
+ m_xHeightED->set_sensitive( !bSizeFixed );
+
+ // size controls for math OLE objects
+ if ( m_sDlgType == "ObjectDialog" && ! m_bNew )
+ {
+ // disable width and height for math objects
+ const SvGlobalName& rFactNm( pSh->GetOLEObject()->getClassID() );
+
+ static struct GlobalNameId {
+ sal_uInt32 n1;
+ sal_uInt16 n2, n3;
+ sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
+ } const aGlbNmIds[] = { { SO3_SM_CLASSID_60 }, { SO3_SM_CLASSID_50 },
+ { SO3_SM_CLASSID_40 }, { SO3_SM_CLASSID_30 } };
+
+ for (const GlobalNameId & rId : aGlbNmIds) {
+ SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
+ rId.b8, rId.b9, rId.b10, rId.b11,
+ rId.b12, rId.b13, rId.b14, rId.b15 );
+
+ if( rFactNm == aGlbNm )
+ {
+ // disable size controls for math OLE objects
+ m_xWidthFT->set_sensitive(false);
+ m_xWidthED->set_sensitive(false);
+ m_xRelWidthCB->set_sensitive(false);
+ m_xHeightFT->set_sensitive(false);
+ m_xHeightED->set_sensitive(false);
+ m_xRelHeightCB->set_sensitive(false);
+ m_xFixedRatioCB->set_sensitive(false);
+ m_xRealSizeBT->set_sensitive(false);
+ break;
+ }
+ }
+
+ // TODO/LATER: get correct aspect
+ if(0 != (pSh->GetOLEObject()->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
+ m_xRealSizeBT->set_sensitive(false);
+ }
+ }
+
+ const SwFormatFrameSize& rSize = rSet.Get(RES_FRM_SIZE);
+ sal_Int64 nWidth = m_xWidthED->NormalizePercent(rSize.GetWidth());
+ sal_Int64 nHeight = m_xHeightED->NormalizePercent(rSize.GetHeight());
+
+ if (nWidth != m_xWidthED->get_value(FieldUnit::TWIP))
+ m_xWidthED->set_value(nWidth, FieldUnit::TWIP);
+
+ if (nHeight != m_xHeightED->get_value(FieldUnit::TWIP))
+ m_xHeightED->set_value(nHeight, FieldUnit::TWIP);
+
+ if (!IsInGraficMode())
+ {
+ SwFrameSize eSize = rSize.GetHeightSizeType();
+ bool bCheck = eSize != SwFrameSize::Fixed;
+ m_xAutoHeightCB->set_active(bCheck);
+ HandleAutoCB( bCheck, *m_xHeightFT, *m_xHeightAutoFT, *m_xWidthED->get() );
+ if( eSize == SwFrameSize::Variable )
+ m_xHeightED->set_value(m_xHeightED->get_min());
+
+ eSize = rSize.GetWidthSizeType();
+ bCheck = eSize != SwFrameSize::Fixed;
+ m_xAutoWidthCB->set_active(bCheck);
+ HandleAutoCB( bCheck, *m_xWidthFT, *m_xWidthAutoFT, *m_xWidthED->get() );
+ if( eSize == SwFrameSize::Variable )
+ m_xWidthED->set_value(m_xWidthED->get_min());
+
+ if ( !m_bFormat )
+ {
+ SwWrtShell* pSh = getFrameDlgParentShell();
+ const SwFrameFormat* pFormat = pSh->GetFlyFrameFormat();
+ if( pFormat && pFormat->GetChain().GetNext() )
+ m_xAutoHeightCB->set_sensitive( false );
+ }
+ }
+ else
+ m_xAutoHeightCB->hide();
+
+ // organise circulation-gap for character bound frames
+ const SvxULSpaceItem &rUL = rSet.Get(RES_UL_SPACE);
+ m_nUpperBorder = rUL.GetUpper();
+ m_nLowerBorder = rUL.GetLower();
+
+ if (SfxItemState::SET == rSet.GetItemState(FN_KEEP_ASPECT_RATIO))
+ m_xFixedRatioCB->set_active(rSet.Get(FN_KEEP_ASPECT_RATIO).GetValue());
+
+ // columns
+ SwFormatCol aCol( rSet.Get(RES_COL) );
+ ::FitToActualSize( aCol, o3tl::narrowing<sal_uInt16>(rSize.GetWidth()) );
+
+ RndStdIds eAnchorId = GetAnchor();
+
+ if ( m_bNew && !m_bFormat )
+ InitPos(eAnchorId, -1, 0, -1, 0, LONG_MAX, LONG_MAX);
+ else
+ {
+ const SwFormatHoriOrient& rHori = rSet.Get(RES_HORI_ORIENT);
+ const SwFormatVertOrient& rVert = rSet.Get(RES_VERT_ORIENT);
+ m_nOldH = rHori.GetHoriOrient();
+ m_nOldHRel = rHori.GetRelationOrient();
+ m_nOldV = rVert.GetVertOrient();
+ m_nOldVRel = rVert.GetRelationOrient();
+
+ if (eAnchorId == RndStdIds::FLY_AT_PAGE)
+ {
+ if (m_nOldHRel == text::RelOrientation::FRAME)
+ m_nOldHRel = text::RelOrientation::PAGE_FRAME;
+ else if (m_nOldHRel == text::RelOrientation::PRINT_AREA)
+ m_nOldHRel = text::RelOrientation::PAGE_PRINT_AREA;
+ if (m_nOldVRel == text::RelOrientation::FRAME)
+ m_nOldVRel = text::RelOrientation::PAGE_FRAME;
+ else if (m_nOldVRel == text::RelOrientation::PRINT_AREA)
+ m_nOldVRel = text::RelOrientation::PAGE_PRINT_AREA;
+ }
+
+ m_xMirrorPagesCB->set_active(rHori.IsPosToggle());
+ m_xMirrorPagesCB->save_state();
+
+ InitPos(eAnchorId,
+ m_nOldH,
+ m_nOldHRel,
+ m_nOldV,
+ m_nOldVRel,
+ rHori.GetPos(),
+ rVert.GetPos());
+ }
+
+ // transparent for example
+ // circulation for example
+ const SwFormatSurround& rSurround = rSet.Get(RES_SURROUND);
+ m_aExampleWN.SetWrap( rSurround.GetSurround() );
+
+ if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH )
+ {
+ const SvxOpaqueItem& rOpaque = rSet.Get(RES_OPAQUE);
+ m_aExampleWN.SetTransparent(!rOpaque.GetValue());
+ }
+
+ // switch to percent if applicable
+ RangeModifyHdl(); // set reference values (for 100%)
+
+ if (rSize.GetWidthPercent() == SwFormatFrameSize::SYNCED || rSize.GetHeightPercent() == SwFormatFrameSize::SYNCED)
+ m_xFixedRatioCB->set_active(true);
+ m_xFixedRatioCB->save_state();
+ if (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED &&
+ !m_xRelWidthCB->get_active())
+ {
+ m_xRelWidthCB->set_active(true);
+ RelSizeClickHdl(*m_xRelWidthCB);
+ m_xWidthED->set_value(rSize.GetWidthPercent(), FieldUnit::PERCENT);
+ }
+ if (rSize.GetHeightPercent() && rSize.GetHeightPercent() != SwFormatFrameSize::SYNCED &&
+ !m_xRelHeightCB->get_active())
+ {
+ m_xRelHeightCB->set_active(true);
+ RelSizeClickHdl(*m_xRelHeightCB);
+ m_xHeightED->set_value(rSize.GetHeightPercent(), FieldUnit::PERCENT);
+ }
+ m_xRelWidthCB->save_state();
+ m_xRelHeightCB->save_state();
+
+ if (rSize.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME)
+ m_xRelWidthRelationLB->set_active(1);
+ else
+ m_xRelWidthRelationLB->set_active(0);
+
+ if (rSize.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME)
+ m_xRelHeightRelationLB->set_active(1);
+ else
+ m_xRelHeightRelationLB->set_active(0);
+}
+
+void SwFramePage::SetFormatUsed(bool bFormatUsed)
+{
+ m_bFormat = bFormatUsed;
+ if (m_bFormat)
+ m_xAnchorAtFrameRB->hide();
+}
+
+void SwFramePage::EnableVerticalPositioning( bool bEnable )
+{
+ m_bAllowVertPositioning = bEnable;
+ m_xVerticalFT->set_sensitive( bEnable );
+ m_xVerticalDLB->set_sensitive( bEnable );
+ m_xAtVertPosFT->set_sensitive( bEnable );
+ m_xAtVertPosED->set_sensitive( bEnable );
+ m_xVertRelationFT->set_sensitive( bEnable );
+ m_xVertRelationLB->set_sensitive( bEnable );
+}
+
+SwGrfExtPage::SwGrfExtPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/picturepage.ui", "PicturePage", &rSet)
+ , m_bHtmlMode(false)
+ , m_xMirror(m_xBuilder->weld_widget("flipframe"))
+ , m_xMirrorVertBox(m_xBuilder->weld_check_button("vert"))
+ , m_xMirrorHorzBox(m_xBuilder->weld_check_button("hori"))
+ , m_xAllPagesRB(m_xBuilder->weld_radio_button("allpages"))
+ , m_xLeftPagesRB(m_xBuilder->weld_radio_button("leftpages"))
+ , m_xRightPagesRB(m_xBuilder->weld_radio_button("rightpages"))
+ , m_xConnectED(m_xBuilder->weld_entry("entry"))
+ , m_xBrowseBT(m_xBuilder->weld_button("browse"))
+ , m_xLinkFrame(m_xBuilder->weld_frame("linkframe"))
+ // RotGrfFlyFrame: Need Angle and RotateControls now
+ , m_xFlAngle(m_xBuilder->weld_frame("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))
+ , m_xBmpWin(new weld::CustomWeld(*m_xBuilder, "preview", m_aBmpWin))
+ // tdf#138843 place holder for the graphic type
+ , m_xLabelGraphicType(m_xBuilder->weld_label("label-graphic-type"))
+{
+ m_aBmpWin.SetBitmapEx(BitmapEx(RID_BMP_PREVIEW_FALLBACK));
+
+ m_xCtlAngle->SetLinkedField(m_xNfAngle.get(), 2);
+
+ SetExchangeSupport();
+ m_xMirrorHorzBox->connect_toggled(LINK(this, SwGrfExtPage, MirrorHdl));
+ m_xMirrorVertBox->connect_toggled(LINK(this, SwGrfExtPage, MirrorHdl));
+ m_xBrowseBT->connect_clicked(LINK(this, SwGrfExtPage, BrowseHdl));
+}
+
+SwGrfExtPage::~SwGrfExtPage()
+{
+ m_xBmpWin.reset();
+ m_xCtlAngleWin.reset();
+ m_xCtlAngle.reset();
+ m_xGrfDlg.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwGrfExtPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwGrfExtPage>(pPage, pController, *rSet);
+}
+
+void SwGrfExtPage::Reset(const SfxItemSet *rSet)
+{
+ const sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ m_bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
+
+ const SfxBoolItem* pConnectItem = rSet->GetItemIfSet( FN_PARAM_GRF_CONNECT );
+ if( pConnectItem && pConnectItem->GetValue() )
+ {
+ m_xBrowseBT->set_sensitive(true);
+ m_xConnectED->set_editable(true);
+ }
+
+ // RotGrfFlyFrame: Get RotationAngle and set at control
+ if(const SdrAngleItem* pAngleItem = rSet->GetItemIfSet( SID_ATTR_TRANSFORM_ANGLE, false))
+ {
+ m_xCtlAngle->SetRotation(pAngleItem->GetValue());
+ }
+ else
+ {
+ m_xCtlAngle->SetRotation(0_deg100);
+ }
+ m_xCtlAngle->SaveValue();
+
+ ActivatePage(*rSet);
+}
+
+void SwGrfExtPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SvxProtectItem& rProt = rSet.Get(RES_PROTECT);
+ bool bProtContent = rProt.IsContentProtected();
+
+ const SfxPoolItem* pItem = nullptr;
+ bool bEnable = false;
+ bool bEnableMirrorRB = false;
+
+ SfxItemState eState = rSet.GetItemState(RES_GRFATR_MIRRORGRF, true, &pItem);
+ if (SfxItemState::UNKNOWN != eState && !bProtContent && !m_bHtmlMode)
+ {
+ if( SfxItemState::SET != eState )
+ pItem = &rSet.Get( RES_GRFATR_MIRRORGRF );
+
+ bEnable = true;
+
+ MirrorGraph eMirror = static_cast<const SwMirrorGrf* >(pItem)->GetValue();
+ switch( eMirror )
+ {
+ case MirrorGraph::Dont: break;
+ case MirrorGraph::Vertical: m_xMirrorHorzBox->set_active(true); break;
+ case MirrorGraph::Horizontal: m_xMirrorVertBox->set_active(true); break;
+ case MirrorGraph::Both: m_xMirrorHorzBox->set_active(true);
+ m_xMirrorVertBox->set_active(true);
+ break;
+ default:
+ ;
+ }
+
+ const int nPos = (static_cast<const SwMirrorGrf* >(pItem)->IsGrfToggle() ? 1 : 0)
+ + ((eMirror == MirrorGraph::Vertical || eMirror == MirrorGraph::Both) ? 2 : 0);
+
+ bEnableMirrorRB = nPos != 0;
+
+ switch (nPos)
+ {
+ case 1: // mirror at left / even pages
+ m_xLeftPagesRB->set_active(true);
+ m_xMirrorHorzBox->set_active(true);
+ break;
+ case 2: // mirror on all pages
+ m_xAllPagesRB->set_active(true);
+ break;
+ case 3: // mirror on right / odd pages
+ m_xRightPagesRB->set_active(true);
+ break;
+ default:
+ m_xAllPagesRB->set_active(true);
+ break;
+ }
+ }
+
+ if( const SvxBrushItem* pGraphicBrushItem = rSet.GetItemIfSet( SID_ATTR_GRAF_GRAPHIC, false ) )
+ {
+ if( !pGraphicBrushItem->GetGraphicLink().isEmpty() )
+ {
+ m_aGrfName = m_aNewGrfName = pGraphicBrushItem->GetGraphicLink();
+ m_xConnectED->set_text(m_aNewGrfName);
+ }
+ OUString referer;
+ SfxStringItem const * it = rSet.GetItem(SID_REFERER);
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = pGraphicBrushItem->GetGraphic(referer);
+ if( pGrf )
+ {
+ m_aBmpWin.SetGraphic( *pGrf );
+ m_xLabelGraphicType->set_label(GraphicHelper::GetImageType(*pGrf));
+ }
+ }
+
+ m_xConnectED->save_value();
+
+ m_xMirror->set_sensitive(bEnable);
+ m_xAllPagesRB->set_sensitive(bEnableMirrorRB);
+ m_xLeftPagesRB->set_sensitive(bEnableMirrorRB);
+ m_xRightPagesRB->set_sensitive(bEnableMirrorRB);
+
+ m_xAllPagesRB->save_state();
+ m_xLeftPagesRB->save_state();
+ m_xRightPagesRB->save_state();
+ m_xMirrorHorzBox->save_state();
+ m_xMirrorVertBox->save_state();
+
+ m_aBmpWin.MirrorHorz( m_xMirrorVertBox->get_active() );
+ m_aBmpWin.MirrorVert( m_xMirrorHorzBox->get_active() );
+ m_aBmpWin.Invalidate();
+}
+
+bool SwGrfExtPage::FillItemSet( SfxItemSet *rSet )
+{
+ bool bModified = false;
+ if ( m_xMirrorHorzBox->get_state_changed_from_saved() ||
+ m_xMirrorVertBox->get_state_changed_from_saved() ||
+ m_xAllPagesRB->get_state_changed_from_saved() ||
+ m_xLeftPagesRB->get_state_changed_from_saved() ||
+ m_xRightPagesRB->get_state_changed_from_saved() )
+ {
+ bModified = true;
+
+ bool bHori = false;
+
+ if (m_xMirrorHorzBox->get_active() &&
+ !m_xLeftPagesRB->get_active())
+ bHori = true;
+
+ MirrorGraph eMirror;
+ eMirror = m_xMirrorVertBox->get_active() && bHori ?
+ MirrorGraph::Both : bHori ?
+ MirrorGraph::Vertical : m_xMirrorVertBox->get_active() ?
+ MirrorGraph::Horizontal : MirrorGraph::Dont;
+
+ bool bMirror = !m_xAllPagesRB->get_active();
+ SwMirrorGrf aMirror( eMirror );
+ aMirror.SetGrfToggle(bMirror );
+ rSet->Put( aMirror );
+ }
+
+ if (m_aGrfName != m_aNewGrfName || m_xConnectED->get_value_changed_from_saved())
+ {
+ bModified = true;
+ m_aGrfName = m_xConnectED->get_text();
+ rSet->Put( SvxBrushItem( m_aGrfName, m_aFilterName, GPOS_LT,
+ SID_ATTR_GRAF_GRAPHIC ));
+ }
+
+ // RotGrfFlyFrame: Safe rotation if modified
+ if(m_xCtlAngle->IsValueModified())
+ {
+ rSet->Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, m_xCtlAngle->GetRotation()));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+DeactivateRC SwGrfExtPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+IMPL_LINK_NOARG(SwGrfExtPage, BrowseHdl, weld::Button&, void)
+{
+ if(!m_xGrfDlg)
+ {
+ m_xGrfDlg.reset(new FileDialogHelper(
+ ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
+ FileDialogFlags::Graphic, GetFrameWeld()));
+ m_xGrfDlg->SetTitle(m_xLinkFrame->get_label());
+ }
+ m_xGrfDlg->SetDisplayDirectory(m_xConnectED->get_text());
+ uno::Reference < ui::dialogs::XFilePicker3 > xFP = m_xGrfDlg->GetFilePicker();
+ uno::Reference < ui::dialogs::XFilePickerControlAccess > xCtrlAcc(xFP, uno::UNO_QUERY);
+ xCtrlAcc->setValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, uno::Any(true) );
+
+ if ( m_xGrfDlg->Execute() != ERRCODE_NONE )
+ return;
+
+// remember selected filter
+ m_aFilterName = m_xGrfDlg->GetCurrentFilter();
+ m_aNewGrfName = INetURLObject::decode( m_xGrfDlg->GetPath(),
+ INetURLObject::DecodeMechanism::Unambiguous );
+ m_xConnectED->set_text(m_aNewGrfName);
+ //reset mirrors because maybe a Bitmap was swapped with
+ //another type of graphic that cannot be mirrored.
+ m_xMirrorVertBox->set_active(false);
+ m_xMirrorHorzBox->set_active(false);
+ m_xAllPagesRB->set_sensitive(false);
+ m_xLeftPagesRB->set_sensitive(false);
+ m_xRightPagesRB->set_sensitive(false);
+ m_aBmpWin.MirrorHorz(false);
+ m_aBmpWin.MirrorVert(false);
+
+ Graphic aGraphic;
+ (void)GraphicFilter::LoadGraphic(m_xGrfDlg->GetPath(), OUString(), aGraphic);
+ m_aBmpWin.SetGraphic(aGraphic);
+ m_xLabelGraphicType->set_label(GraphicHelper::GetImageType(aGraphic));
+
+ bool bEnable = GraphicType::Bitmap == aGraphic.GetType() ||
+ GraphicType::GdiMetafile == aGraphic.GetType();
+ m_xMirrorVertBox->set_sensitive(bEnable);
+ m_xMirrorHorzBox->set_sensitive(bEnable);
+ m_xAllPagesRB->set_sensitive(bEnable);
+ m_xLeftPagesRB->set_sensitive(bEnable);
+ m_xRightPagesRB->set_sensitive(bEnable);
+
+}
+
+IMPL_LINK_NOARG(SwGrfExtPage, MirrorHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xMirrorHorzBox->get_active();
+
+ m_aBmpWin.MirrorHorz( m_xMirrorVertBox->get_active() );
+ m_aBmpWin.MirrorVert( bEnable );
+
+ m_xAllPagesRB->set_sensitive(bEnable);
+ m_xLeftPagesRB->set_sensitive(bEnable);
+ m_xRightPagesRB->set_sensitive(bEnable);
+
+ if (!m_xAllPagesRB->get_active() && !m_xLeftPagesRB->get_active() && !m_xRightPagesRB->get_active())
+ m_xAllPagesRB->set_active(true);
+}
+
+// example window
+BmpWindow::BmpWindow()
+ : m_bHorz(false)
+ , m_bVert(false)
+ , m_bGraphic(false)
+{
+}
+
+void BmpWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ Size aSize = pDrawingArea->get_ref_device().LogicToPixel(Size(127 , 66), MapMode(MapUnit::MapAppFont));
+ set_size_request(aSize.Width(), aSize.Height());
+ SetOutputSizePixel(aSize);
+}
+
+void BmpWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ // Setup
+ rRenderContext.SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetDialogColor()));
+ rRenderContext.Erase();
+ // #i119307# the graphic might have transparency, set up white as the color
+ // to use when drawing a rectangle under the image
+ rRenderContext.SetLineColor(COL_WHITE);
+ rRenderContext.SetFillColor(COL_WHITE);
+
+ // Paint
+ Point aPntPos;
+ Size aPntSz(GetOutputSizePixel());
+ Size aGrfSize;
+ if (m_bGraphic)
+ aGrfSize = ::GetGraphicSizeTwip(m_aGraphic, &rRenderContext);
+ //it should show the default bitmap also if no graphic can be found
+ if (!aGrfSize.Width() && !aGrfSize.Height())
+ aGrfSize = rRenderContext.PixelToLogic(m_aBmp.GetSizePixel());
+
+ tools::Long nRelGrf = aGrfSize.Width() * 100 / aGrfSize.Height();
+ tools::Long nRelWin = aPntSz.Width() * 100 / aPntSz.Height();
+ if (nRelGrf < nRelWin)
+ {
+ const tools::Long nWidth = aPntSz.Width();
+ // if we use a replacement preview, try to draw at original size
+ if (!m_bGraphic && (aGrfSize.Width() <= aPntSz.Width())
+ && (aGrfSize.Height() <= aPntSz.Height()))
+ {
+ const tools::Long nHeight = aPntSz.Height();
+ aPntSz.setWidth( aGrfSize.Width() );
+ aPntSz.setHeight( aGrfSize.Height() );
+ aPntPos.AdjustY((nHeight - aPntSz.Height()) / 2 );
+ }
+ else
+ aPntSz.setWidth( aPntSz.Height() * nRelGrf /100 );
+
+ aPntPos.AdjustX(nWidth - aPntSz.Width() ) ;
+ }
+
+ // #i119307# clear window background, the graphic might have transparency
+ rRenderContext.DrawRect(tools::Rectangle(aPntPos, aPntSz));
+
+ if (m_bHorz || m_bVert)
+ {
+ BitmapEx aTmpBmp(m_bGraphic ? m_aGraphic.GetBitmapEx() : m_aBmp);
+ BmpMirrorFlags nMirrorFlags(BmpMirrorFlags::NONE);
+ if (m_bHorz)
+ nMirrorFlags |= BmpMirrorFlags::Vertical;
+ if (m_bVert)
+ nMirrorFlags |= BmpMirrorFlags::Horizontal;
+ aTmpBmp.Mirror(nMirrorFlags);
+ rRenderContext.DrawBitmapEx(aPntPos, aPntSz, aTmpBmp);
+ }
+ else if (m_bGraphic) //draw unmirrored preview graphic
+ {
+ m_aGraphic.Draw(rRenderContext, aPntPos, aPntSz);
+ }
+ else //draw unmirrored stock sample image
+ {
+ rRenderContext.DrawBitmapEx(aPntPos, aPntSz, m_aBmp);
+ }
+}
+
+BmpWindow::~BmpWindow()
+{
+}
+
+void BmpWindow::SetGraphic(const Graphic& rGraphic)
+{
+ m_aGraphic = rGraphic;
+ Size aSize = m_aGraphic.GetPrefSize();
+ m_bGraphic = aSize.Width() && aSize.Height();
+ Invalidate();
+}
+
+void BmpWindow::SetBitmapEx(const BitmapEx& rBmp)
+{
+ m_aBmp = rBmp;
+ Invalidate();
+}
+
+// set URL and ImageMap at frames
+SwFrameURLPage::SwFrameURLPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/frmurlpage.ui", "FrameURLPage", &rSet)
+ , m_xURLED(m_xBuilder->weld_entry("url"))
+ , m_xSearchPB(m_xBuilder->weld_button("search"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xFrameCB(m_xBuilder->weld_combo_box("frame"))
+ , m_xServerCB(m_xBuilder->weld_check_button("server"))
+ , m_xClientCB(m_xBuilder->weld_check_button("client"))
+{
+ m_xSearchPB->connect_clicked(LINK(this, SwFrameURLPage, InsertFileHdl));
+}
+
+SwFrameURLPage::~SwFrameURLPage()
+{
+}
+
+void SwFrameURLPage::Reset( const SfxItemSet *rSet )
+{
+ if ( SfxItemState::SET == rSet->GetItemState( SID_DOCFRAME ))
+ {
+ TargetList aList;
+ SfxFrame::GetDefaultTargetList(aList);
+ size_t nCount = aList.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ m_xFrameCB->append_text(aList.at(i));
+ }
+ }
+
+ if ( const SwFormatURL* pFormatURL = rSet->GetItemIfSet( RES_URL ) )
+ {
+ m_xURLED->set_text(INetURLObject::decode(pFormatURL->GetURL(),
+ INetURLObject::DecodeMechanism::Unambiguous));
+ m_xNameED->set_text(pFormatURL->GetName());
+
+ m_xClientCB->set_sensitive(pFormatURL->GetMap() != nullptr);
+ m_xClientCB->set_active(pFormatURL->GetMap() != nullptr);
+ m_xServerCB->set_active(pFormatURL->IsServerMap());
+
+ m_xFrameCB->set_entry_text(pFormatURL->GetTargetFrameName());
+ m_xFrameCB->save_value();
+ }
+ else
+ m_xClientCB->set_sensitive(false);
+
+ m_xServerCB->save_state();
+ m_xClientCB->save_state();
+}
+
+bool SwFrameURLPage::FillItemSet(SfxItemSet *rSet)
+{
+ bool bModified = false;
+ const SwFormatURL* pOldURL = GetOldItem(*rSet, RES_URL);
+ std::unique_ptr<SwFormatURL> pFormatURL;
+ if(pOldURL)
+ pFormatURL.reset(pOldURL->Clone());
+ else
+ pFormatURL.reset(new SwFormatURL());
+
+ {
+ const OUString sText = m_xURLED->get_text();
+
+ if( pFormatURL->GetURL() != sText ||
+ pFormatURL->GetName() != m_xNameED->get_text() ||
+ m_xServerCB->get_active() != pFormatURL->IsServerMap() )
+ {
+ pFormatURL->SetURL(sText, m_xServerCB->get_active());
+ pFormatURL->SetName(m_xNameED->get_text());
+ bModified = true;
+ }
+ }
+
+ if (!m_xClientCB->get_active() && pFormatURL->GetMap() != nullptr)
+ {
+ pFormatURL->SetMap(nullptr);
+ bModified = true;
+ }
+
+ if(pFormatURL->GetTargetFrameName() != m_xFrameCB->get_active_text())
+ {
+ pFormatURL->SetTargetFrameName(m_xFrameCB->get_active_text());
+ bModified = true;
+ }
+ rSet->Put(std::move(pFormatURL));
+ return bModified;
+}
+
+std::unique_ptr<SfxTabPage> SwFrameURLPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwFrameURLPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK_NOARG(SwFrameURLPage, InsertFileHdl, weld::Button&, void)
+{
+ FileDialogHelper aDlgHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ uno::Reference < ui::dialogs::XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+
+ try
+ {
+ const OUString sTemp(m_xURLED->get_text());
+ if(!sTemp.isEmpty())
+ xFP->setDisplayDirectory(sTemp);
+ }
+ catch( const uno::Exception& ) {}
+ if( aDlgHelper.Execute() == ERRCODE_NONE )
+ {
+ m_xURLED->set_text(xFP->getSelectedFiles().getConstArray()[0]);
+ }
+}
+
+SwFrameAddPage::SwFrameAddPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/frmaddpage.ui", "FrameAddPage", &rSet)
+ , m_pWrtSh(nullptr)
+ , m_bHtmlMode(false)
+ , m_bFormat(false)
+ , m_bNew(false)
+ , m_xNameFrame(m_xBuilder->weld_widget("nameframe"))
+ , m_xNameFT(m_xBuilder->weld_label("name_label"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xAltNameFT(m_xBuilder->weld_label("altname_label"))
+ , m_xAltNameED(m_xBuilder->weld_entry("altname"))
+ , m_xDescriptionFT(m_xBuilder->weld_label("description_label"))
+ , m_xDescriptionED(m_xBuilder->weld_text_view("description"))
+ , m_xDecorativeCB(m_xBuilder->weld_check_button("decorative"))
+ , m_xSequenceFrame(m_xBuilder->weld_widget("frmSequence"))
+ , m_xPrevLB(m_xBuilder->weld_combo_box("prev"))
+ , m_xNextLB(m_xBuilder->weld_combo_box("next"))
+ , m_xProtectFrame(m_xBuilder->weld_widget("protect"))
+ , m_xProtectContentCB(m_xBuilder->weld_check_button("protectcontent"))
+ , m_xProtectFrameCB(m_xBuilder->weld_check_button("protectframe"))
+ , m_xProtectSizeCB(m_xBuilder->weld_check_button("protectsize"))
+ , m_xContentAlignFrame(m_xBuilder->weld_widget("contentalign"))
+ , m_xVertAlignLB(m_xBuilder->weld_combo_box("vertalign"))
+ , m_xPropertiesFrame(m_xBuilder->weld_widget("properties"))
+ , m_xEditInReadonlyCB(m_xBuilder->weld_check_button("editinreadonly"))
+ , m_xPrintFrameCB(m_xBuilder->weld_check_button("printframe"))
+ , m_xTextFlowFT(m_xBuilder->weld_label("textflow_label"))
+ , m_xTextFlowLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("textflow")))
+{
+ m_xTextFlowLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xTextFlowLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+ m_xTextFlowLB->append(SvxFrameDirection::Vertical_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_VERT));
+ m_xTextFlowLB->append(SvxFrameDirection::Vertical_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_VERT));
+ m_xTextFlowLB->append(SvxFrameDirection::Vertical_LR_BT, SvxResId(RID_SVXSTR_PAGEDIR_LTR_BTT_VERT));
+ m_xTextFlowLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+ m_xDescriptionED->set_size_request(-1, m_xDescriptionED->get_preferred_size().Height());
+
+ m_xDecorativeCB->connect_toggled(LINK(this, SwFrameAddPage, DecorativeHdl));
+}
+
+SwFrameAddPage::~SwFrameAddPage()
+{
+ m_xTextFlowLB.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwFrameAddPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwFrameAddPage>(pPage, pController, *rSet);
+}
+
+void SwFrameAddPage::Reset(const SfxItemSet *rSet )
+{
+ sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ m_bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
+ if (m_bHtmlMode)
+ {
+ m_xProtectFrame->hide();
+ m_xEditInReadonlyCB->hide();
+ m_xPrintFrameCB->hide();
+ }
+ if (m_sDlgType == "PictureDialog" || m_sDlgType == "ObjectDialog")
+ {
+ m_xSequenceFrame->hide();
+ m_xEditInReadonlyCB->hide();
+ if (m_bHtmlMode)
+ {
+ m_xPropertiesFrame->hide();
+ }
+ m_xContentAlignFrame->hide();
+ }
+
+ if(const SfxStringItem* pNameItem = rSet->GetItemIfSet(FN_SET_FRM_ALT_NAME, false))
+ {
+ m_xAltNameED->set_text(pNameItem->GetValue());
+ m_xAltNameED->save_value();
+ }
+
+ if(const SfxStringItem* pDescriptionItem = rSet->GetItemIfSet(FN_UNO_DESCRIPTION, false))
+ {
+ m_xDescriptionED->set_text(pDescriptionItem->GetValue());
+ m_xDescriptionED->save_value();
+ }
+
+ if(!m_bFormat)
+ {
+ // insert graphic - properties
+ // bNew is not set, so recognise by selection
+ OUString aTmpName1;
+ if(const SfxStringItem* pNameItem = rSet->GetItemIfSet(FN_SET_FRM_NAME, false))
+ {
+ aTmpName1 = pNameItem->GetValue();
+ }
+
+ OSL_ENSURE(m_pWrtSh, "no Shell?");
+ if( m_bNew || aTmpName1.isEmpty() )
+ {
+ if (m_sDlgType == "PictureDialog")
+ aTmpName1 = m_pWrtSh->GetUniqueGrfName();
+ else if (m_sDlgType == "ObjectDialog")
+ aTmpName1 = m_pWrtSh->GetUniqueOLEName();
+ else
+ aTmpName1 = m_pWrtSh->GetUniqueFrameName();
+
+ m_pWrtSh->SetFlyName(aTmpName1);
+ }
+
+ m_xNameED->set_text( aTmpName1 );
+ m_xNameED->save_value();
+ }
+ else
+ {
+ m_xNameED->set_sensitive( false );
+ m_xAltNameED->set_sensitive(false);
+ m_xNameFT->set_sensitive( false );
+ m_xAltNameFT->set_sensitive(false);
+ }
+ if (m_sDlgType == "FrameDialog" && m_xAltNameFT->get_visible())
+ {
+ m_xAltNameFT->hide();
+ m_xAltNameED->hide();
+ }
+ else
+ {
+ m_xNameED->connect_changed(LINK(this, SwFrameAddPage, EditModifyHdl));
+ }
+
+ if (!m_bNew)
+ {
+ SwFrameFormat* pFormat = m_pWrtSh->GetFlyFrameFormat();
+
+ if (pFormat)
+ {
+ const SwFormatChain &rChain = pFormat->GetChain();
+ const SwFlyFrameFormat* pFlyFormat;
+ OUString sNextChain, sPrevChain;
+ pFlyFormat = rChain.GetPrev();
+ if (pFlyFormat != nullptr)
+ {
+ sPrevChain = pFlyFormat->GetName();
+ }
+
+ pFlyFormat = rChain.GetNext();
+ if (pFlyFormat != nullptr)
+ {
+ sNextChain = pFlyFormat->GetName();
+ }
+ //determine chainable frames
+ std::vector< OUString > aPrevPageFrames;
+ std::vector< OUString > aThisPageFrames;
+ std::vector< OUString > aNextPageFrames;
+ std::vector< OUString > aRemainFrames;
+ m_pWrtSh->GetConnectableFrameFormats(*pFormat, sNextChain, false,
+ aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames );
+ for (sal_Int32 nEntry = m_xPrevLB->get_count(); nEntry > 1; nEntry--)
+ m_xPrevLB->remove(nEntry - 1);
+ lcl_InsertVectors(*m_xPrevLB, aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames);
+ if(!sPrevChain.isEmpty())
+ {
+ if (m_xPrevLB->find_text(sPrevChain) == -1)
+ m_xPrevLB->insert_text(1, sPrevChain);
+ m_xPrevLB->set_active_text(sPrevChain);
+ }
+ else
+ m_xPrevLB->set_active(0);
+ aPrevPageFrames.clear();
+ aNextPageFrames.clear();
+ aThisPageFrames.clear();
+ aRemainFrames.clear();
+
+ m_pWrtSh->GetConnectableFrameFormats(*pFormat, sPrevChain, true,
+ aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames );
+ for (sal_Int32 nEntry = m_xNextLB->get_count(); nEntry > 1; nEntry--)
+ m_xNextLB->remove(nEntry - 1);
+ lcl_InsertVectors(*m_xNextLB, aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames);
+ if(!sNextChain.isEmpty())
+ {
+ if (m_xNextLB->find_text(sNextChain) == -1)
+ m_xNextLB->insert_text(1, sNextChain);
+ m_xNextLB->set_active_text(sNextChain);
+ }
+ else
+ m_xNextLB->set_active(0);
+ Link<weld::ComboBox&,void> aLink(LINK(this, SwFrameAddPage, ChainModifyHdl));
+ m_xPrevLB->connect_changed(aLink);
+ m_xNextLB->connect_changed(aLink);
+ }
+ }
+ // Pos Protected
+ const SvxProtectItem& rProt = rSet->Get(RES_PROTECT);
+ m_xProtectFrameCB->set_active(rProt.IsPosProtected());
+ m_xProtectContentCB->set_active(rProt.IsContentProtected());
+ m_xProtectSizeCB->set_active(rProt.IsSizeProtected());
+
+ const SwFormatEditInReadonly& rEdit = rSet->Get(RES_EDIT_IN_READONLY);
+ m_xEditInReadonlyCB->set_active(rEdit.GetValue());
+ m_xEditInReadonlyCB->save_state();
+
+ // print
+ const SvxPrintItem& rPrt = rSet->Get(RES_PRINT);
+ m_xPrintFrameCB->set_active(rPrt.GetValue());
+ m_xPrintFrameCB->save_state();
+
+ SfxBoolItem const& rDecorative = rSet->Get(RES_DECORATIVE);
+ m_xDecorativeCB->set_active(rDecorative.GetValue());
+ m_xDecorativeCB->save_state();
+
+ // textflow
+ if( (!m_bHtmlMode || (0 != (nHtmlMode&HTMLMODE_SOME_STYLES)))
+ && m_sDlgType != "PictureDialog" && m_sDlgType != "ObjectDialog"
+ && SfxItemState::UNKNOWN != rSet->GetItemState( RES_FRAMEDIR ) )
+ {
+ m_xTextFlowFT->show();
+ m_xTextFlowLB->show();
+
+ //vertical text flow is not possible in HTML
+ if(m_bHtmlMode)
+ {
+ m_xTextFlowLB->remove_id(SvxFrameDirection::Vertical_RL_TB);
+ }
+ SvxFrameDirection nVal = rSet->Get(RES_FRAMEDIR).GetValue();
+ m_xTextFlowLB->set_active_id(nVal);
+ m_xTextFlowLB->save_value();
+ }
+ else
+ {
+ m_xTextFlowFT->hide();
+ m_xTextFlowLB->hide();
+ }
+
+ // Content alignment
+ if ( rSet->GetItemState(RES_TEXT_VERT_ADJUST) > SfxItemState::DEFAULT )
+ {
+ SdrTextVertAdjust nAdjust = rSet->Get(RES_TEXT_VERT_ADJUST).GetValue();
+ sal_Int32 nPos = 0;
+ switch(nAdjust)
+ {
+ case SDRTEXTVERTADJUST_TOP: nPos = 0; break;
+ case SDRTEXTVERTADJUST_CENTER:
+ case SDRTEXTVERTADJUST_BLOCK: nPos = 1; break;
+ case SDRTEXTVERTADJUST_BOTTOM: nPos = 2; break;
+ }
+ m_xVertAlignLB->set_active(nPos);
+ }
+ m_xVertAlignLB->save_value();
+
+ DecorativeHdl(*m_xDecorativeCB);
+}
+
+bool SwFrameAddPage::FillItemSet(SfxItemSet *rSet)
+{
+ bool bRet = false;
+ if (m_xNameED->get_value_changed_from_saved())
+ bRet |= nullptr != rSet->Put(SfxStringItem(FN_SET_FRM_NAME, m_xNameED->get_text()));
+ if (m_xAltNameED->get_value_changed_from_saved())
+ bRet |= nullptr != rSet->Put(SfxStringItem(FN_SET_FRM_ALT_NAME, m_xAltNameED->get_text()));
+ if (m_xDescriptionED->get_value_changed_from_saved())
+ bRet |= nullptr != rSet->Put(SfxStringItem(FN_UNO_DESCRIPTION, m_xDescriptionED->get_text()));
+
+ const SfxPoolItem* pOldItem;
+ SvxProtectItem aProt ( GetItemSet().Get(RES_PROTECT) );
+ aProt.SetContentProtect( m_xProtectContentCB->get_active() );
+ aProt.SetSizeProtect ( m_xProtectSizeCB->get_active() );
+ aProt.SetPosProtect ( m_xProtectFrameCB->get_active() );
+ if ( nullptr == (pOldItem = GetOldItem(*rSet, FN_SET_PROTECT)) ||
+ aProt != *pOldItem )
+ bRet |= nullptr != rSet->Put( aProt);
+
+ if ( m_xEditInReadonlyCB->get_state_changed_from_saved() )
+ bRet |= nullptr != rSet->Put( SwFormatEditInReadonly( RES_EDIT_IN_READONLY, m_xEditInReadonlyCB->get_active()));
+
+ if ( m_xPrintFrameCB->get_state_changed_from_saved() )
+ bRet |= nullptr != rSet->Put( SvxPrintItem( RES_PRINT, m_xPrintFrameCB->get_active()));
+
+ if (m_xDecorativeCB->get_state_changed_from_saved())
+ {
+ bRet |= nullptr != rSet->Put(SfxBoolItem(RES_DECORATIVE, m_xDecorativeCB->get_active()));
+ }
+
+ // textflow
+ if (m_xTextFlowLB->get_visible() && m_xTextFlowLB->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDirection = m_xTextFlowLB->get_active_id();
+ bRet |= nullptr != rSet->Put( SvxFrameDirectionItem(eDirection, RES_FRAMEDIR ));
+ }
+ if(m_pWrtSh)
+ {
+ const SwFrameFormat* pFormat = m_pWrtSh->GetFlyFrameFormat();
+ if (pFormat)
+ {
+ OUString sCurrentPrevChain, sCurrentNextChain;
+ if (m_xPrevLB->get_active())
+ sCurrentPrevChain = m_xPrevLB->get_active_text();
+ if (m_xNextLB->get_active())
+ sCurrentNextChain = m_xNextLB->get_active_text();
+ const SwFormatChain &rChain = pFormat->GetChain();
+ const SwFlyFrameFormat* pFlyFormat;
+ OUString sNextChain, sPrevChain;
+ pFlyFormat = rChain.GetPrev();
+ if (pFlyFormat != nullptr)
+ sPrevChain = pFlyFormat->GetName();
+
+ pFlyFormat = rChain.GetNext();
+ if (pFlyFormat != nullptr)
+ sNextChain = pFlyFormat->GetName();
+ if(sPrevChain != sCurrentPrevChain)
+ bRet |= nullptr != rSet->Put(SfxStringItem(FN_PARAM_CHAIN_PREVIOUS, sCurrentPrevChain));
+ if(sNextChain != sCurrentNextChain)
+ bRet |= nullptr != rSet->Put(SfxStringItem(FN_PARAM_CHAIN_NEXT, sCurrentNextChain));
+ }
+ }
+
+ if (m_xVertAlignLB->get_value_changed_from_saved())
+ {
+ SdrTextVertAdjust nAdjust;
+ switch (m_xVertAlignLB->get_active())
+ {
+ default:
+ case 0 : nAdjust = SDRTEXTVERTADJUST_TOP; break;
+ case 1 : nAdjust = SDRTEXTVERTADJUST_CENTER; break;
+ case 2 : nAdjust = SDRTEXTVERTADJUST_BOTTOM; break;
+ }
+ bRet |= nullptr != rSet->Put(SdrTextVertAdjustItem(nAdjust, RES_TEXT_VERT_ADJUST));
+ }
+
+ return bRet;
+}
+
+IMPL_LINK_NOARG(SwFrameAddPage, EditModifyHdl, weld::Entry&, void)
+{
+ bool bEnable = !m_xNameED->get_text().isEmpty();
+ m_xAltNameED->set_sensitive(bEnable);
+ m_xAltNameFT->set_sensitive(bEnable);
+}
+
+IMPL_LINK_NOARG(SwFrameAddPage, DecorativeHdl, weld::Toggleable&, void)
+{
+ bool const bEnable(!m_xDecorativeCB->get_active());
+ m_xAltNameED->set_sensitive(bEnable);
+ m_xAltNameFT->set_sensitive(bEnable);
+ m_xDescriptionED->set_sensitive(bEnable);
+ m_xDescriptionFT->set_sensitive(bEnable);
+}
+
+void SwFrameAddPage::SetFormatUsed(bool bFormatUsed)
+{
+ m_bFormat = bFormatUsed;
+ if (m_bFormat)
+ {
+ m_xNameFrame->hide();
+ }
+}
+
+IMPL_LINK(SwFrameAddPage, ChainModifyHdl, weld::ComboBox&, rBox, void)
+{
+ OUString sCurrentPrevChain, sCurrentNextChain;
+ if (m_xPrevLB->get_active())
+ sCurrentPrevChain = m_xPrevLB->get_active_text();
+ if (m_xNextLB->get_active())
+ sCurrentNextChain = m_xNextLB->get_active_text();
+ SwFrameFormat* pFormat = m_pWrtSh->GetFlyFrameFormat();
+ if (!pFormat)
+ return;
+
+ bool bNextBox = m_xNextLB.get() == &rBox;
+ weld::ComboBox& rChangeLB = bNextBox ? *m_xPrevLB : *m_xNextLB;
+ for (sal_Int32 nEntry = rChangeLB.get_count(); nEntry > 1; nEntry--)
+ rChangeLB.remove(nEntry - 1);
+ //determine chainable frames
+ std::vector< OUString > aPrevPageFrames;
+ std::vector< OUString > aThisPageFrames;
+ std::vector< OUString > aNextPageFrames;
+ std::vector< OUString > aRemainFrames;
+ m_pWrtSh->GetConnectableFrameFormats(*pFormat, bNextBox ? sCurrentNextChain : sCurrentPrevChain, !bNextBox,
+ aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames );
+ lcl_InsertVectors(rChangeLB,
+ aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames);
+ const OUString sToSelect = bNextBox ? sCurrentPrevChain : sCurrentNextChain;
+ if (rChangeLB.find_text(sToSelect) != -1)
+ rChangeLB.set_active_text(sToSelect);
+ else
+ rChangeLB.set_active(0);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/pattern.cxx b/sw/source/ui/frmdlg/pattern.cxx
new file mode 100644
index 0000000000..097ed18230
--- /dev/null
+++ b/sw/source/ui/frmdlg/pattern.cxx
@@ -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 .
+ */
+
+#include <sfx2/sfxdlg.hxx>
+#include <svx/dialogs.hrc>
+#include <swtypes.hxx>
+#include <pattern.hxx>
+#include <strings.hrc>
+
+SwBackgroundDlg::SwBackgroundDlg(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet)
+
+{
+ m_xDialog->set_title(SwResId(STR_FRMUI_PATTERN));
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG);
+ if (fnCreatePage)
+ {
+ std::unique_ptr<SfxTabPage> xRet = (*fnCreatePage)(get_content_area(), this, &rSet);
+ xRet->PageCreated(rSet);
+ xRet->ActivatePage(rSet);
+ SetTabPage(std::move(xRet));
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/uiborder.cxx b/sw/source/ui/frmdlg/uiborder.cxx
new file mode 100644
index 0000000000..73c55b0e3c
--- /dev/null
+++ b/sw/source/ui/frmdlg/uiborder.cxx
@@ -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 .
+ */
+
+#include <svx/svxids.hrc>
+#include <svx/dialogs.hrc>
+#include <svl/itemset.hxx>
+#include <svx/flagsdef.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svl/intitem.hxx>
+
+#include <swtypes.hxx>
+#include <uiborder.hxx>
+#include <strings.hrc>
+
+SwBorderDlg::SwBorderDlg(weld::Window* pParent, const SfxItemSet& rSet, SwBorderModes nType)
+ : SfxSingleTabDialogController(pParent, &rSet)
+{
+ m_xDialog->set_title(SwResId(STR_FRMUI_BORDER));
+
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BORDER);
+
+ if (fnCreatePage)
+ {
+ std::unique_ptr<SfxTabPage> xNewPage = (*fnCreatePage)(get_content_area(), this, &rSet);
+ SfxAllItemSet aSet(*(rSet.GetPool()));
+ aSet.Put(SfxUInt16Item(SID_SWMODE_TYPE, static_cast<sal_uInt16>(nType)));
+ if (SwBorderModes::TABLE == nType)
+ aSet.Put(SfxUInt32Item(SID_FLAG_TYPE, SVX_HIDESHADOWCTL));
+ xNewPage->PageCreated(aSet);
+ SetTabPage(std::move(xNewPage));
+ }
+}
+
+SwBorderDlg::~SwBorderDlg() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/frmdlg/wrap.cxx b/sw/source/ui/frmdlg/wrap.cxx
new file mode 100644
index 0000000000..684fe38b22
--- /dev/null
+++ b/sw/source/ui/frmdlg/wrap.cxx
@@ -0,0 +1,631 @@
+/* -*- 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 <hintids.hxx>
+#include <vcl/graph.hxx>
+
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/intitem.hxx>
+#include <editeng/opaqitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <fmtfollowtextflow.hxx>
+#include <svtools/unitconv.hxx>
+#include <svx/swframevalidation.hxx>
+
+#include <cmdid.h>
+#include <docsh.hxx>
+#include <uitool.hxx>
+#include <wrtsh.hxx>
+#include <swmodule.hxx>
+#include <viewopt.hxx>
+#include <fmtsrnd.hxx>
+#include <frmmgr.hxx>
+#include <wrap.hxx>
+#include <bitmaps.hlst>
+#include <fmtwrapinfluenceonobjpos.hxx>
+
+using namespace ::com::sun::star;
+
+const WhichRangesContainer SwWrapTabPage::s_aWrapPageRg(svl::Items<
+ RES_LR_SPACE, RES_UL_SPACE,
+ RES_PRINT, RES_PRINT,
+ RES_PROTECT, RES_SURROUND
+>);
+
+SwWrapDlg::SwWrapDlg(weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell* pWrtShell, bool bDrawMode)
+ : SfxSingleTabDialogController(pParent, &rSet, "modules/swriter/ui/wrapdialog.ui", "WrapDialog")
+{
+ // create TabPage
+ auto xNewPage = SwWrapTabPage::Create(get_content_area(), this, &rSet);
+ SwWrapTabPage* pWrapPage = static_cast<SwWrapTabPage*>(xNewPage.get());
+ pWrapPage->SetFormatUsed(false, bDrawMode);
+ pWrapPage->SetShell(pWrtShell);
+ SetTabPage(std::move(xNewPage));
+}
+
+SwWrapTabPage::SwWrapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/wrappage.ui", "WrapPage", &rSet)
+ , m_nAnchorId(RndStdIds::FLY_AT_PARA)
+ , m_nHtmlMode(0)
+ , m_pWrtSh(nullptr)
+ , m_bFormat(false)
+ , m_bNew(true)
+ , m_bHtmlMode(false)
+ , m_bDrawMode(false)
+ , m_bContourImage(false)
+ , m_xNoWrapImg(m_xBuilder->weld_image("noneimg"))
+ , m_xNoWrapRB(m_xBuilder->weld_radio_button("none"))
+ , m_xWrapLeftImg(m_xBuilder->weld_image("beforeimg"))
+ , m_xWrapLeftRB(m_xBuilder->weld_radio_button("before"))
+ , m_xWrapRightImg(m_xBuilder->weld_image("afterimg"))
+ , m_xWrapRightRB(m_xBuilder->weld_radio_button("after"))
+ , m_xWrapParallelImg(m_xBuilder->weld_image("parallelimg"))
+ , m_xWrapParallelRB(m_xBuilder->weld_radio_button("parallel"))
+ , m_xWrapThroughImg(m_xBuilder->weld_image("throughimg"))
+ , m_xWrapThroughRB(m_xBuilder->weld_radio_button("through"))
+ , m_xIdealWrapImg(m_xBuilder->weld_image("optimalimg"))
+ , m_xIdealWrapRB(m_xBuilder->weld_radio_button("optimal"))
+ , m_xLeftMarginED(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
+ , m_xRightMarginED(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
+ , m_xTopMarginED(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
+ , m_xBottomMarginED(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
+ , m_xWrapAnchorOnlyCB(m_xBuilder->weld_check_button("anchoronly"))
+ , m_xWrapTransparentCB(m_xBuilder->weld_check_button("transparent"))
+ , m_xWrapOutlineCB(m_xBuilder->weld_check_button("outline"))
+ , m_xWrapOutsideCB(m_xBuilder->weld_check_button("outside"))
+ , m_xAllowOverlapCB(m_xBuilder->weld_check_button("allowoverlap"))
+{
+ SetExchangeSupport();
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwWrapTabPage, RangeModifyHdl);
+ m_xLeftMarginED->connect_value_changed(aLk);
+ m_xRightMarginED->connect_value_changed(aLk);
+ m_xTopMarginED->connect_value_changed(aLk);
+ m_xBottomMarginED->connect_value_changed(aLk);
+
+ Link<weld::Toggleable&,void> aLk2 = LINK(this, SwWrapTabPage, WrapTypeHdl);
+ m_xNoWrapRB->connect_toggled(aLk2);
+ m_xWrapLeftRB->connect_toggled(aLk2);
+ m_xWrapRightRB->connect_toggled(aLk2);
+ m_xWrapParallelRB->connect_toggled(aLk2);
+ m_xWrapThroughRB->connect_toggled(aLk2);
+ m_xIdealWrapRB->connect_toggled(aLk2);
+ SetImages();
+ m_xWrapOutlineCB->connect_toggled(LINK(this, SwWrapTabPage, ContourHdl));
+}
+
+SwWrapTabPage::~SwWrapTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwWrapTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwWrapTabPage>(pPage, pController, *rSet);
+}
+
+void SwWrapTabPage::Reset(const SfxItemSet *rSet)
+{
+ // contour for Draw, Graphic and OLE (Insert/Graphic/Properties still missing!)
+ if( m_bDrawMode )
+ {
+ m_xWrapOutlineCB->show();
+ m_xWrapOutsideCB->show();
+
+ m_xWrapTransparentCB->set_active( 0 == rSet->Get(FN_DRAW_WRAP_DLG).GetValue() );
+ m_xWrapTransparentCB->save_state();
+ }
+ else
+ {
+ bool bShowCB = m_bFormat;
+ if( !m_bFormat )
+ {
+ SelectionType nSelType = m_pWrtSh->GetSelectionType();
+ if( ( nSelType & SelectionType::Graphic ) ||
+ ( nSelType & SelectionType::Ole && GraphicType::NONE !=
+ m_pWrtSh->GetIMapGraphic().GetType() ))
+ bShowCB = true;
+ }
+ if( bShowCB )
+ {
+ m_xWrapOutlineCB->show();
+ m_xWrapOutsideCB->show();
+ }
+ }
+
+ m_nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
+ m_bHtmlMode = (m_nHtmlMode & HTMLMODE_ON) != 0;
+
+ FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
+ SetFieldUnit(*m_xLeftMarginED, aMetric);
+ SetFieldUnit(*m_xRightMarginED, aMetric);
+ SetFieldUnit(*m_xTopMarginED, aMetric);
+ SetFieldUnit(*m_xBottomMarginED, aMetric);
+
+ const SwFormatSurround& rSurround = rSet->Get(RES_SURROUND);
+
+ css::text::WrapTextMode nSur = rSurround.GetSurround();
+ const SwFormatAnchor &rAnch = rSet->Get(RES_ANCHOR);
+ m_nAnchorId = rAnch.GetAnchorId();
+
+ if (((m_nAnchorId == RndStdIds::FLY_AT_PARA) || (m_nAnchorId == RndStdIds::FLY_AT_CHAR))
+ && (nSur != css::text::WrapTextMode_NONE))
+ {
+ m_xWrapAnchorOnlyCB->set_active(rSurround.IsAnchorOnly());
+ }
+ else
+ {
+ m_xWrapAnchorOnlyCB->set_sensitive(false);
+ }
+
+ const bool bContour = rSurround.IsContour();
+ m_xWrapOutlineCB->set_active(bContour);
+ m_xWrapOutsideCB->set_active(rSurround.IsOutside());
+ m_xWrapThroughRB->set_sensitive(!m_xWrapOutlineCB->get_active());
+ m_bContourImage = !bContour;
+
+ weld::RadioButton* pBtn = nullptr;
+
+ switch (nSur)
+ {
+ case css::text::WrapTextMode_NONE:
+ {
+ pBtn = m_xNoWrapRB.get();
+ break;
+ }
+
+ case css::text::WrapTextMode_THROUGH:
+ {
+ // transparent ?
+ pBtn = m_xWrapThroughRB.get();
+
+ if (!m_bDrawMode)
+ {
+ const SvxOpaqueItem& rOpaque = rSet->Get(RES_OPAQUE);
+ m_xWrapTransparentCB->set_active(!rOpaque.GetValue());
+ }
+ break;
+ }
+
+ case css::text::WrapTextMode_PARALLEL:
+ {
+ pBtn = m_xWrapParallelRB.get();
+ break;
+ }
+
+ case css::text::WrapTextMode_DYNAMIC:
+ {
+ pBtn = m_xIdealWrapRB.get();
+ break;
+ }
+
+ default:
+ {
+ if (nSur == css::text::WrapTextMode_LEFT)
+ pBtn = m_xWrapLeftRB.get();
+ else if (nSur == css::text::WrapTextMode_RIGHT)
+ pBtn = m_xWrapRightRB.get();
+ }
+ }
+ if (pBtn)
+ {
+ pBtn->set_active(true);
+ WrapTypeHdl(*pBtn);
+ // For character objects that currently are in passage, the default
+ // "contour on" is prepared here, in case we switch to any other
+ // passage later.
+ if (m_bDrawMode && !m_xWrapOutlineCB->get_sensitive())
+ m_xWrapOutlineCB->set_active(true);
+ }
+ m_xWrapTransparentCB->set_sensitive(pBtn == m_xWrapThroughRB.get() && !m_bHtmlMode);
+
+ const SvxULSpaceItem& rUL = rSet->Get(RES_UL_SPACE);
+ const SvxLRSpaceItem& rLR = rSet->Get(RES_LR_SPACE);
+
+ // gap to text
+ m_xLeftMarginED->set_value(m_xLeftMarginED->normalize(rLR.GetLeft()), FieldUnit::TWIP);
+ m_xRightMarginED->set_value(m_xRightMarginED->normalize(rLR.GetRight()), FieldUnit::TWIP);
+ m_xTopMarginED->set_value(m_xTopMarginED->normalize(rUL.GetUpper()), FieldUnit::TWIP);
+ m_xBottomMarginED->set_value(m_xBottomMarginED->normalize(rUL.GetLower()), FieldUnit::TWIP);
+
+ m_xLeftMarginED->save_value();
+ m_xRightMarginED->save_value();
+ m_xTopMarginED->save_value();
+ m_xBottomMarginED->save_value();
+
+ ContourHdl(*m_xWrapOutlineCB);
+
+ const SwFormatWrapInfluenceOnObjPos& rInfluence = rSet->Get(RES_WRAP_INFLUENCE_ON_OBJPOS);
+ m_xAllowOverlapCB->set_active(rInfluence.GetAllowOverlap());
+
+ ActivatePage( *rSet );
+}
+
+// stuff attributes into the set when OK
+bool SwWrapTabPage::FillItemSet(SfxItemSet *rSet)
+{
+ bool bModified = false;
+ const SfxPoolItem* pOldItem;
+ const SwFormatSurround& rOldSur = GetItemSet().Get(RES_SURROUND);
+ SwFormatSurround aSur( rOldSur );
+
+ std::shared_ptr<SvxOpaqueItem> aOp(std::make_shared<SvxOpaqueItem>(RES_OPAQUE));
+
+ if (!m_bDrawMode)
+ {
+ aOp.reset(GetItemSet().Get(RES_OPAQUE).Clone());
+ aOp->SetValue(true);
+ }
+
+ if (m_xNoWrapRB->get_active())
+ aSur.SetSurround(css::text::WrapTextMode_NONE);
+ else if (m_xWrapLeftRB->get_active())
+ aSur.SetSurround(css::text::WrapTextMode_LEFT);
+ else if (m_xWrapRightRB->get_active())
+ aSur.SetSurround(css::text::WrapTextMode_RIGHT);
+ else if (m_xWrapParallelRB->get_active())
+ aSur.SetSurround(css::text::WrapTextMode_PARALLEL);
+ else if (m_xWrapThroughRB->get_active())
+ {
+ aSur.SetSurround(css::text::WrapTextMode_THROUGH);
+ if (m_xWrapTransparentCB->get_active() && !m_bDrawMode)
+ aOp->SetValue(false);
+ }
+ else if (m_xIdealWrapRB->get_active())
+ aSur.SetSurround(css::text::WrapTextMode_DYNAMIC);
+
+ aSur.SetAnchorOnly( m_xWrapAnchorOnlyCB->get_active() );
+ bool bContour = m_xWrapOutlineCB->get_active() && m_xWrapOutlineCB->get_sensitive();
+ aSur.SetContour( bContour );
+
+ if ( bContour )
+ aSur.SetOutside(m_xWrapOutsideCB->get_active());
+
+ if(nullptr == (pOldItem = GetOldItem( *rSet, RES_SURROUND )) ||
+ aSur != *pOldItem )
+ {
+ rSet->Put(aSur);
+ bModified = true;
+ }
+
+ if (!m_bDrawMode)
+ {
+ if(nullptr == (pOldItem = GetOldItem( *rSet, FN_OPAQUE )) ||
+ *aOp != *pOldItem )
+ {
+ rSet->Put(*aOp);
+ bModified = true;
+ }
+ }
+
+ bool bTopMod = m_xTopMarginED->get_value_changed_from_saved();
+ bool bBottomMod = m_xBottomMarginED->get_value_changed_from_saved();
+
+ SvxULSpaceItem aUL( RES_UL_SPACE );
+ aUL.SetUpper(o3tl::narrowing<sal_uInt16>(m_xTopMarginED->denormalize(m_xTopMarginED->get_value(FieldUnit::TWIP))));
+ aUL.SetLower(o3tl::narrowing<sal_uInt16>(m_xBottomMarginED->denormalize(m_xBottomMarginED->get_value(FieldUnit::TWIP))));
+
+ if ( bTopMod || bBottomMod )
+ {
+ if(nullptr == (pOldItem = GetOldItem(*rSet, RES_UL_SPACE)) ||
+ aUL != *pOldItem )
+ {
+ rSet->Put( aUL );
+ bModified = true;
+ }
+ }
+
+ bool bLeftMod = m_xLeftMarginED->get_value_changed_from_saved();
+ bool bRightMod = m_xRightMarginED->get_value_changed_from_saved();
+
+ SvxLRSpaceItem aLR( RES_LR_SPACE );
+ aLR.SetLeft(o3tl::narrowing<sal_uInt16>(m_xLeftMarginED->denormalize(m_xLeftMarginED->get_value(FieldUnit::TWIP))));
+ aLR.SetRight(o3tl::narrowing<sal_uInt16>(m_xRightMarginED->denormalize(m_xRightMarginED->get_value(FieldUnit::TWIP))));
+
+ if ( bLeftMod || bRightMod )
+ {
+ if( nullptr == (pOldItem = GetOldItem(*rSet, RES_LR_SPACE)) ||
+ aLR != *pOldItem )
+ {
+ rSet->Put(aLR);
+ bModified = true;
+ }
+ }
+
+ if ( m_bDrawMode )
+ {
+ bool bChecked = m_xWrapTransparentCB->get_active() && m_xWrapTransparentCB->get_sensitive();
+ if ((m_xWrapTransparentCB->get_saved_state() == TRISTATE_TRUE) != bChecked)
+ bModified |= nullptr != rSet->Put(SfxInt16Item(FN_DRAW_WRAP_DLG, bChecked ? 0 : 1));
+ }
+
+ const SwFormatWrapInfluenceOnObjPos& rOldInfluence
+ = GetItemSet().Get(RES_WRAP_INFLUENCE_ON_OBJPOS);
+ SwFormatWrapInfluenceOnObjPos aInfluence(rOldInfluence);
+ aInfluence.SetAllowOverlap(m_xAllowOverlapCB->get_active());
+
+ pOldItem = GetOldItem(*rSet, RES_WRAP_INFLUENCE_ON_OBJPOS);
+ if (!pOldItem || aInfluence != *pOldItem)
+ {
+ rSet->Put(aInfluence);
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+// example update
+void SwWrapTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ // anchor
+ const SwFormatAnchor &rAnch = rSet.Get(RES_ANCHOR);
+ m_nAnchorId = rAnch.GetAnchorId();
+ bool bEnable = (m_nAnchorId != RndStdIds::FLY_AS_CHAR);
+
+ SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell() : m_pWrtSh;
+ if (pSh && !m_bDrawMode)
+ {
+ SwFlyFrameAttrMgr aMgr( m_bNew, pSh, GetItemSet() );
+ SvxSwFrameValidation aVal;
+
+ // size
+ const SwFormatFrameSize& rFrameSize = rSet.Get(RES_FRM_SIZE);
+ Size aSize = rFrameSize.GetSize();
+
+ // position
+ const SwFormatHoriOrient& rHori = rSet.Get(RES_HORI_ORIENT);
+ const SwFormatVertOrient& rVert = rSet.Get(RES_VERT_ORIENT);
+
+ aVal.nAnchorType = m_nAnchorId;
+ aVal.bAutoHeight = rFrameSize.GetHeightSizeType() == SwFrameSize::Minimum;
+ aVal.bMirror = rHori.IsPosToggle();
+ // #i18732#
+ aVal.bFollowTextFlow = rSet.Get(RES_FOLLOW_TEXT_FLOW).GetValue();
+
+ aVal.nHoriOrient = static_cast<short>(rHori.GetHoriOrient());
+ aVal.nVertOrient = static_cast<short>(rVert.GetVertOrient());
+
+ aVal.nHPos = rHori.GetPos();
+ aVal.nHRelOrient = rHori.GetRelationOrient();
+ aVal.nVPos = rVert.GetPos();
+ aVal.nVRelOrient = rVert.GetRelationOrient();
+
+ if (rFrameSize.GetWidthPercent() && rFrameSize.GetWidthPercent() != SwFormatFrameSize::SYNCED)
+ aSize.setWidth( aSize.Width() * rFrameSize.GetWidthPercent() / 100 );
+
+ if (rFrameSize.GetHeightPercent() && rFrameSize.GetHeightPercent() != SwFormatFrameSize::SYNCED)
+ aSize.setHeight( aSize.Height() * rFrameSize.GetHeightPercent() / 100 );
+
+ aVal.nWidth = aSize.Width();
+ aVal.nHeight = aSize.Height();
+
+ aMgr.ValidateMetrics(aVal, nullptr);
+
+ SwTwips nLeft;
+ SwTwips nRight;
+ SwTwips nTop;
+ SwTwips nBottom;
+
+ nLeft = aVal.nHPos - aVal.nMinHPos;
+ nRight = aVal.nMaxWidth - aVal.nWidth;
+ nTop = aVal.nVPos - aVal.nMinVPos;
+ nBottom = aVal.nMaxHeight - aVal.nHeight;
+
+ {
+ if (aVal.nAnchorType == RndStdIds::FLY_AS_CHAR)
+ {
+ nLeft = nRight;
+
+ if (aVal.nVPos < 0)
+ {
+ if (aVal.nVPos <= aVal.nMaxHeight)
+ nTop = aVal.nMaxVPos - aVal.nHeight;
+ else
+ nTop = 0; // no passage
+ }
+ else
+ nTop = aVal.nMaxVPos - aVal.nHeight - aVal.nVPos;
+ }
+ else
+ {
+ nLeft += nRight;
+ nTop += nBottom;
+ }
+
+ nBottom = nTop;
+ nRight = nLeft;
+ }
+
+ m_xLeftMarginED->set_max(m_xLeftMarginED->normalize(nLeft), FieldUnit::TWIP);
+ m_xRightMarginED->set_max(m_xRightMarginED->normalize(nRight), FieldUnit::TWIP);
+
+ m_xTopMarginED->set_max(m_xTopMarginED->normalize(nTop), FieldUnit::TWIP);
+ m_xBottomMarginED->set_max(m_xBottomMarginED->normalize(nBottom), FieldUnit::TWIP);
+
+ RangeModifyHdl(*m_xLeftMarginED);
+ RangeModifyHdl(*m_xTopMarginED);
+ }
+
+ const SwFormatSurround& rSurround = rSet.Get(RES_SURROUND);
+ css::text::WrapTextMode nSur = rSurround.GetSurround();
+
+ m_xWrapTransparentCB->set_sensitive(bEnable && !m_bHtmlMode && nSur == css::text::WrapTextMode_THROUGH);
+ if(m_bHtmlMode)
+ {
+ const SwFormatHoriOrient& rHori = rSet.Get(RES_HORI_ORIENT);
+ sal_Int16 eHOrient = rHori.GetHoriOrient();
+ sal_Int16 eHRelOrient = rHori.GetRelationOrient();
+ m_xWrapOutlineCB->hide();
+ const bool bAllHtmlModes =
+ ((m_nAnchorId == RndStdIds::FLY_AT_PARA) || (m_nAnchorId == RndStdIds::FLY_AT_CHAR)) &&
+ (eHOrient == text::HoriOrientation::RIGHT || eHOrient == text::HoriOrientation::LEFT);
+ m_xWrapAnchorOnlyCB->set_sensitive(bAllHtmlModes && nSur != css::text::WrapTextMode_NONE);
+ m_xWrapOutsideCB->hide();
+ m_xIdealWrapRB->set_sensitive(false);
+
+ m_xWrapTransparentCB->set_sensitive(false);
+ m_xNoWrapRB->set_sensitive(RndStdIds::FLY_AT_PARA == m_nAnchorId);
+ m_xWrapParallelRB->set_sensitive(false);
+ m_xWrapLeftRB->set_sensitive
+ ( (RndStdIds::FLY_AT_PARA == m_nAnchorId)
+ || ( (RndStdIds::FLY_AT_CHAR == m_nAnchorId)
+ && (eHOrient == text::HoriOrientation::RIGHT)
+ && (eHRelOrient == text::RelOrientation::PRINT_AREA)));
+ m_xWrapRightRB->set_sensitive
+ ( (RndStdIds::FLY_AT_PARA == m_nAnchorId)
+ || ( (RndStdIds::FLY_AT_CHAR == m_nAnchorId)
+ && (eHOrient == text::HoriOrientation::LEFT)
+ && (eHRelOrient == text::RelOrientation::PRINT_AREA)));
+
+ m_xWrapThroughRB->set_sensitive
+ ( ( (RndStdIds::FLY_AT_PAGE == m_nAnchorId)
+ || ( (RndStdIds::FLY_AT_CHAR == m_nAnchorId)
+ && (eHRelOrient != text::RelOrientation::PRINT_AREA))
+ || (RndStdIds::FLY_AT_PARA == m_nAnchorId))
+ && (eHOrient != text::HoriOrientation::RIGHT));
+ if (m_xNoWrapRB->get_active() && !m_xNoWrapRB->get_sensitive())
+ {
+ if(m_xWrapThroughRB->get_sensitive())
+ m_xWrapThroughRB->set_active(true);
+ else if(m_xWrapLeftRB->get_sensitive())
+ m_xWrapLeftRB->set_active(true);
+ else if(m_xWrapRightRB->get_sensitive())
+ m_xWrapRightRB->set_active(true);
+
+ }
+ if (m_xWrapLeftRB->get_active() && !m_xWrapLeftRB->get_sensitive())
+ {
+ if(m_xWrapRightRB->get_sensitive())
+ m_xWrapRightRB->set_active(true);
+ else if(m_xWrapThroughRB->get_sensitive())
+ m_xWrapThroughRB->set_active(true);
+ }
+ if (m_xWrapRightRB->get_active() && !m_xWrapRightRB->get_sensitive())
+ {
+ if(m_xWrapLeftRB->get_sensitive())
+ m_xWrapLeftRB->set_active(true);
+ else if(m_xWrapThroughRB->get_sensitive())
+ m_xWrapThroughRB->set_active(true);
+ }
+ if (m_xWrapThroughRB->get_active() && !m_xWrapThroughRB->get_sensitive())
+ if(m_xNoWrapRB->get_sensitive())
+ m_xNoWrapRB->set_active(true);
+
+ if (m_xWrapParallelRB->get_active() && !m_xWrapParallelRB->get_sensitive())
+ m_xWrapThroughRB->set_active(true);
+ }
+ else
+ {
+ m_xNoWrapRB->set_sensitive(bEnable);
+ m_xWrapLeftRB->set_sensitive(bEnable);
+ m_xWrapRightRB->set_sensitive(bEnable);
+ m_xIdealWrapRB->set_sensitive(bEnable);
+ m_xWrapThroughRB->set_sensitive(bEnable);
+ m_xWrapParallelRB->set_sensitive(bEnable);
+ m_xWrapAnchorOnlyCB->set_sensitive(
+ ((m_nAnchorId == RndStdIds::FLY_AT_PARA) || (m_nAnchorId == RndStdIds::FLY_AT_CHAR))
+ && nSur != css::text::WrapTextMode_NONE );
+ }
+ ContourHdl(*m_xWrapOutlineCB);
+}
+
+DeactivateRC SwWrapTabPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+IMPL_LINK(SwWrapTabPage, RangeModifyHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ auto nValue = rEdit.get_value(FieldUnit::NONE);
+ weld::MetricSpinButton* pOpposite = nullptr;
+ if (&rEdit == m_xLeftMarginED.get())
+ pOpposite = m_xRightMarginED.get();
+ else if (&rEdit == m_xRightMarginED.get())
+ pOpposite = m_xLeftMarginED.get();
+ else if (&rEdit == m_xTopMarginED.get())
+ pOpposite = m_xBottomMarginED.get();
+ else if (&rEdit == m_xBottomMarginED.get())
+ pOpposite = m_xTopMarginED.get();
+
+ assert(pOpposite);
+
+ if (pOpposite)
+ {
+ auto nOpposite = pOpposite->get_value(FieldUnit::NONE);
+
+ if (nValue + nOpposite > std::max(rEdit.get_max(FieldUnit::NONE), pOpposite->get_max(FieldUnit::NONE)))
+ pOpposite->set_value(pOpposite->get_max(FieldUnit::NONE) - nValue, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SwWrapTabPage, WrapTypeHdl, weld::Toggleable&, void)
+{
+ bool bWrapThrough = m_xWrapThroughRB->get_active();
+ m_xWrapTransparentCB->set_sensitive(bWrapThrough && !m_bHtmlMode);
+ bWrapThrough |= ( m_nAnchorId == RndStdIds::FLY_AS_CHAR );
+ m_xWrapOutlineCB->set_sensitive(!bWrapThrough && !m_xNoWrapRB->get_active());
+ m_xWrapOutsideCB->set_sensitive(!bWrapThrough && m_xWrapOutlineCB->get_active());
+ m_xWrapAnchorOnlyCB->set_sensitive(
+ ((m_nAnchorId == RndStdIds::FLY_AT_PARA) || (m_nAnchorId == RndStdIds::FLY_AT_CHAR)) &&
+ (!m_xNoWrapRB->get_active()) );
+
+ ContourHdl(*m_xWrapOutlineCB);
+}
+
+IMPL_LINK_NOARG(SwWrapTabPage, ContourHdl, weld::Toggleable&, void)
+{
+ bool bEnable = !(m_xWrapOutlineCB->get_active() && m_xWrapOutlineCB->get_sensitive());
+
+ m_xWrapOutsideCB->set_sensitive(!bEnable);
+
+ bEnable = !m_xWrapOutlineCB->get_active();
+ if (bEnable == m_bContourImage) // so that it doesn't always flicker
+ {
+ m_bContourImage = !bEnable;
+ SetImages();
+ }
+}
+
+void SwWrapTabPage::SetImages()
+{
+ m_xWrapThroughImg->set_from_icon_name(RID_BMP_WRAP_THROUGH);
+ bool bWrapOutline = !m_xWrapOutlineCB->get_active();
+ if (bWrapOutline)
+ {
+ m_xNoWrapImg->set_from_icon_name(RID_BMP_WRAP_NONE);
+ m_xWrapLeftImg->set_from_icon_name(RID_BMP_WRAP_LEFT);
+ m_xWrapRightImg->set_from_icon_name(RID_BMP_WRAP_RIGHT);
+ m_xWrapParallelImg->set_from_icon_name(RID_BMP_WRAP_PARALLEL);
+ m_xIdealWrapImg->set_from_icon_name(RID_BMP_WRAP_IDEAL);
+ }
+ else
+ {
+ m_xNoWrapImg->set_from_icon_name(RID_BMP_WRAP_CONTOUR_NONE);
+ m_xWrapLeftImg->set_from_icon_name(RID_BMP_WRAP_CONTOUR_LEFT);
+ m_xWrapRightImg->set_from_icon_name(RID_BMP_WRAP_CONTOUR_RIGHT);
+ m_xWrapParallelImg->set_from_icon_name(RID_BMP_WRAP_CONTOUR_PARALLEL);
+ m_xIdealWrapImg->set_from_icon_name(RID_BMP_WRAP_CONTOUR_IDEAL);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/inc/mmresultdialogs.hxx b/sw/source/ui/inc/mmresultdialogs.hxx
new file mode 100644
index 0000000000..3af52dc4c5
--- /dev/null
+++ b/sw/source/ui/inc/mmresultdialogs.hxx
@@ -0,0 +1,189 @@
+/* -*- 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 <vcl/print.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <mailmergehelper.hxx>
+
+class SwMailMergeWizard;
+class SfxPrinter;
+class SwSendMailDialog;
+class Timer;
+namespace com::sun::star::mail { class XMailMessage; }
+
+
+/// Dialog implementing the saving as of the result document.
+class SwMMResultSaveDialog final : public SfxDialogController
+{
+ bool m_bCancelSaving;
+
+ std::unique_ptr<weld::RadioButton> m_xSaveAsOneRB;
+ std::unique_ptr<weld::RadioButton> m_xSaveIndividualRB;
+ std::unique_ptr<weld::CheckButton> m_xFromRB;
+ std::unique_ptr<weld::SpinButton> m_xFromNF;
+ std::unique_ptr<weld::Label> m_xToFT;
+ std::unique_ptr<weld::SpinButton> m_xToNF;
+ std::unique_ptr<weld::Button> m_xOKButton;
+
+ DECL_LINK(SaveOutputHdl_Impl, weld::Button& , void);
+ DECL_LINK(DocumentSelectionHdl_Impl, weld::Toggleable&, void);
+
+public:
+ SwMMResultSaveDialog(weld::Window* pParent);
+ virtual ~SwMMResultSaveDialog() override;
+};
+
+/// Dialog implementing the printing of the result document.
+class SwMMResultPrintDialog final : public SfxDialogController
+{
+ VclPtr<Printer> m_pTempPrinter;
+
+ std::unique_ptr<weld::ComboBox> m_xPrinterLB;
+ std::unique_ptr<weld::Button> m_xPrinterSettingsPB;
+ std::unique_ptr<weld::RadioButton> m_xPrintAllRB;
+ std::unique_ptr<weld::RadioButton> m_xFromRB;
+ std::unique_ptr<weld::SpinButton> m_xFromNF;
+ std::unique_ptr<weld::Label> m_xToFT;
+ std::unique_ptr<weld::SpinButton> m_xToNF;
+ std::unique_ptr<weld::Button> m_xOKButton;
+
+ DECL_LINK(PrinterChangeHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK(PrintHdl_Impl, weld::Button&, void);
+ DECL_LINK(PrinterSetupHdl_Impl, weld::Button&, void );
+ DECL_LINK(DocumentSelectionHdl_Impl, weld::Toggleable&, void);
+
+ void FillInPrinterSettings();
+
+public:
+ SwMMResultPrintDialog(weld::Window* pParent);
+ virtual ~SwMMResultPrintDialog() override;
+};
+
+/// Dialog implementing the sending as email of the result document.
+class SwMMResultEmailDialog final : public SfxDialogController
+{
+ OUString m_sConfigureMail;
+ OUString m_sCC;
+ OUString m_sBCC;
+ OUString m_sBody;
+
+ std::unique_ptr<weld::ComboBox> m_xMailToLB;
+ std::unique_ptr<weld::Button> m_xCopyToPB;
+ std::unique_ptr<weld::Entry> m_xSubjectED;
+ std::unique_ptr<weld::ComboBox> m_xSendAsLB;
+ std::unique_ptr<weld::Button> m_xSendAsPB;
+ std::unique_ptr<weld::Widget> m_xAttachmentGroup;
+ std::unique_ptr<weld::Entry> m_xAttachmentED;
+ std::unique_ptr<weld::Label> m_xPasswordFT;
+ std::unique_ptr<weld::ComboBox> m_xPasswordLB;
+ std::unique_ptr<weld::CheckButton> m_xPasswordCB;
+ std::unique_ptr<weld::RadioButton> m_xSendAllRB;
+ std::unique_ptr<weld::RadioButton> m_xFromRB;
+ std::unique_ptr<weld::SpinButton> m_xFromNF;
+ std::unique_ptr<weld::Label> m_xToFT;
+ std::unique_ptr<weld::SpinButton> m_xToNF;
+ std::unique_ptr<weld::Button> m_xOKButton;
+
+ DECL_LINK(CopyToHdl_Impl, weld::Button&, void);
+ DECL_LINK(SendTypeHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SendAsHdl_Impl, weld::Button&, void);
+ DECL_LINK(SendDocumentsHdl_Impl, weld::Button&, void);
+ DECL_LINK(DocumentSelectionHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(CheckHdl, weld::Toggleable&, void );
+
+ void FillInEmailSettings();
+
+public:
+ SwMMResultEmailDialog(weld::Window *pParent);
+ virtual ~SwMMResultEmailDialog() override;
+};
+
+struct SwMailDescriptor
+{
+ OUString sEMail;
+ OUString sAttachmentURL;
+ OUString sAttachmentName;
+ OUString sMimeType;
+ OUString sSubject;
+ OUString sBodyMimeType;
+ OUString sBodyContent;
+
+ OUString sCC;
+ OUString sBCC;
+};
+struct SwSendMailDialog_Impl;
+class SwMailMergeConfigItem;
+class SwSendMailDialog final : public weld::GenericDialogController
+{
+ OUString m_sContinue;
+ OUString m_sStop;
+ OUString m_sClose;
+ OUString m_sTransferStatus;
+ OUString m_sErrorStatus;
+ OUString m_sSendingTo;
+ OUString m_sCompleted;
+ OUString m_sFailed;
+ OUString m_sAddressInvalid;
+
+ bool m_bCancel;
+ bool m_bDestructionEnabled;
+
+ std::unique_ptr<SwSendMailDialog_Impl> m_pImpl;
+ SwMailMergeConfigItem* m_pConfigItem;
+ sal_Int32 m_nExpectedCount;
+ sal_Int32 m_nProcessedCount;
+ sal_Int32 m_nErrorCount;
+
+ std::unique_ptr<weld::Label> m_xTransferStatus;
+ std::unique_ptr<weld::Label> m_xPaused;
+ std::unique_ptr<weld::ProgressBar> m_xProgressBar;
+ std::unique_ptr<weld::Label> m_xErrorStatus;
+ std::unique_ptr<weld::TreeView> m_xStatus;
+ std::unique_ptr<weld::Button> m_xStop;
+ std::unique_ptr<weld::Button> m_xCancel;
+
+ DECL_LINK( StopHdl_Impl, weld::Button&, void );
+ DECL_LINK( CancelHdl_Impl, weld::Button& , void);
+ DECL_STATIC_LINK( SwSendMailDialog, StartSendMails, void*, void );
+ DECL_STATIC_LINK( SwSendMailDialog, StopSendMails, void*, void );
+ DECL_LINK( RemoveThis, Timer*, void );
+
+ void IterateMails();
+ void SendMails();
+ void UpdateTransferStatus();
+
+public:
+ SwSendMailDialog( weld::Window* pParent, SwMailMergeConfigItem& );
+ virtual ~SwSendMailDialog() override;
+
+ void AddDocument( SwMailDescriptor const & rDesc );
+ void EnableDestruction() {m_bDestructionEnabled = true;}
+ void StartSend(sal_Int32 nExpectedCount);
+
+ void DocumentSent( css::uno::Reference< css::mail::XMailMessage> const & xMessage,
+ bool bResult,
+ const OUString* pError );
+ void AllMailsSent();
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/inc/swuiexp.hxx b/sw/source/ui/inc/swuiexp.hxx
new file mode 100644
index 0000000000..a5fa95e7a0
--- /dev/null
+++ b/sw/source/ui/inc/swuiexp.hxx
@@ -0,0 +1,29 @@
+/* -*- 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 <swabstdlg.hxx>
+
+namespace swui
+{
+SwAbstractDialogFactory& GetFactory();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/index/cntex.cxx b/sw/source/ui/index/cntex.cxx
new file mode 100644
index 0000000000..d2e6b751cf
--- /dev/null
+++ b/sw/source/ui/index/cntex.cxx
@@ -0,0 +1,395 @@
+/* -*- 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/XDocumentIndexesSupplier.hpp>
+#include <com/sun/star/text/XTextSectionsSupplier.hpp>
+#include <com/sun/star/text/XDependentTextField.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/text/ChapterFormat.hpp>
+#include <com/sun/star/text/XTextSection.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <comphelper/string.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <tools/UnitConversion.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <cnttab.hxx>
+#include <unoprnms.hxx>
+#include <unotools.hxx>
+#include <unotxdoc.hxx>
+#include <docsh.hxx>
+
+#include <SwStyleNameMapper.hxx>
+#include <swuicnttab.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace com::sun::star::ui::dialogs;
+
+static void lcl_SetProp( uno::Reference< XPropertySetInfo > const & xInfo,
+ uno::Reference< XPropertySet > const & xProps,
+ OUString const & aPropName, const OUString& rValue)
+{
+ if(xInfo->hasPropertyByName(aPropName))
+ {
+ uno::Any aValue;
+ aValue <<= rValue;
+ xProps->setPropertyValue(aPropName, aValue);
+ }
+}
+
+static void lcl_SetProp( uno::Reference< XPropertySetInfo > const & xInfo,
+ uno::Reference< XPropertySet > const & xProps,
+ OUString const & aPropName, sal_Int16 nValue )
+{
+ if(xInfo->hasPropertyByName(aPropName))
+ {
+ uno::Any aValue;
+ aValue <<= nValue;
+ xProps->setPropertyValue(aPropName, aValue);
+ }
+}
+
+static void lcl_SetBOOLProp(
+ uno::Reference< beans::XPropertySetInfo > const & xInfo,
+ uno::Reference< beans::XPropertySet > const & xProps,
+ OUString const & aPropName, bool bValue )
+{
+ if(xInfo->hasPropertyByName(aPropName))
+ {
+ xProps->setPropertyValue(aPropName, Any(bValue));
+ }
+}
+
+IMPL_LINK_NOARG(SwMultiTOXTabDialog, CreateExample_Hdl, SwOneExampleFrame&, void)
+{
+ try
+ {
+ uno::Reference< frame::XModel > & xModel = m_xExampleFrame->GetModel();
+ auto pDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xModel);
+
+ if( pDoc )
+ pDoc->GetDocShell()->LoadStyles_( *m_rWrtShell.GetView().GetDocShell(), true );
+
+ uno::Reference< text::XTextSectionsSupplier > xSectionSupplier(
+ xModel, uno::UNO_QUERY);
+ uno::Reference< container::XNameAccess > xSections =
+ xSectionSupplier->getTextSections();
+
+ for(int i = 0; i < 7; ++i )
+ {
+ OUString sTmp = "IndexSection_" + OUString::number(i);
+ uno::Any aSection = xSections->getByName( sTmp );
+ aSection >>= m_vTypeData[i].m_oIndexSections->xContainerSection;
+ }
+ uno::Reference< text::XDocumentIndexesSupplier > xIdxSupp(xModel, uno::UNO_QUERY);
+ uno::Reference< container::XIndexAccess > xIdxs = xIdxSupp->getDocumentIndexes();
+ int n = xIdxs->getCount();
+ while(n)
+ {
+ n--;
+ uno::Any aIdx = xIdxs->getByIndex(n);
+ uno::Reference< text::XDocumentIndex > xIdx;
+ aIdx >>= xIdx;
+ xIdx->dispose();
+ }
+ CreateOrUpdateExample(m_eCurrentTOXType.eType);
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "::CreateExample()");
+ }
+}
+
+void SwMultiTOXTabDialog::CreateOrUpdateExample(
+ TOXTypes nTOXIndex, sal_uInt16 nPage, sal_uInt16 nCurrentLevel)
+{
+ if(!m_xExampleFrame || !m_xExampleFrame->IsInitialized())
+ return;
+
+ try
+ {
+ static const char* IndexServiceNames[] =
+ {
+ "com.sun.star.text.DocumentIndex",
+ "com.sun.star.text.UserIndex",
+ "com.sun.star.text.ContentIndex",
+ "com.sun.star.text.IllustrationsIndex",
+ "com.sun.star.text.ObjectIndex",
+ "com.sun.star.text.TableIndex",
+ "com.sun.star.text.Bibliography"
+ };
+
+ OSL_ENSURE(m_vTypeData[nTOXIndex].m_oIndexSections &&
+ m_vTypeData[nTOXIndex].m_oIndexSections->xContainerSection.is(),
+ "Section not created");
+ uno::Reference< frame::XModel > & xModel = m_xExampleFrame->GetModel();
+ bool bInitialCreate = true;
+ if(!m_vTypeData[nTOXIndex].m_oIndexSections->xDocumentIndex.is())
+ {
+ bInitialCreate = true;
+ if(!m_vTypeData[nTOXIndex].m_oIndexSections->xContainerSection.is())
+ throw uno::RuntimeException();
+ uno::Reference< text::XTextRange > xAnchor = m_vTypeData[nTOXIndex].m_oIndexSections->xContainerSection->getAnchor();
+ xAnchor = xAnchor->getStart();
+ uno::Reference< text::XTextCursor > xCursor = xAnchor->getText()->createTextCursorByRange(xAnchor);
+
+ uno::Reference< lang::XMultiServiceFactory > xFact(xModel, uno::UNO_QUERY);
+
+ OUString sIndexTypeName(OUString::createFromAscii( IndexServiceNames[
+ nTOXIndex <= TOX_AUTHORITIES ? nTOXIndex : TOX_USER] ));
+ m_vTypeData[nTOXIndex].m_oIndexSections->xDocumentIndex.set(xFact->createInstance(sIndexTypeName), uno::UNO_QUERY);
+ uno::Reference< text::XTextContent > xContent = m_vTypeData[nTOXIndex].m_oIndexSections->xDocumentIndex;
+ xCursor->getText()->insertTextContent(xCursor, xContent, false);
+ }
+ for(sal_uInt16 i = 0 ; i <= TOX_AUTHORITIES; i++)
+ {
+ uno::Reference< beans::XPropertySet > xSectPr(m_vTypeData[i].m_oIndexSections->xContainerSection, uno::UNO_QUERY);
+ if(xSectPr.is())
+ {
+ xSectPr->setPropertyValue(UNO_NAME_IS_VISIBLE, Any(i == nTOXIndex));
+ }
+ }
+ // set properties
+ uno::Reference< beans::XPropertySet > xIdxProps(m_vTypeData[nTOXIndex].m_oIndexSections->xDocumentIndex, uno::UNO_QUERY);
+ uno::Reference< beans::XPropertySetInfo > xInfo = xIdxProps->getPropertySetInfo();
+ SwTOXDescription& rDesc = GetTOXDescription(m_eCurrentTOXType);
+ SwTOIOptions nIdxOptions = rDesc.GetIndexOptions();
+ if(bInitialCreate || !nPage || nPage == TOX_PAGE_SELECT)
+ {
+ //title
+ if(rDesc.GetTitle())
+ lcl_SetProp(xInfo, xIdxProps, UNO_NAME_TITLE, *rDesc.GetTitle());
+
+ //stylenames
+ SwTOXElement nContentOptions = rDesc.GetContentOptions();
+ if(xInfo->hasPropertyByName(UNO_NAME_LEVEL_PARAGRAPH_STYLES))
+ {
+ bool bOn( nContentOptions&SwTOXElement::Template );
+ uno::Any aStyleNames(xIdxProps->getPropertyValue(UNO_NAME_LEVEL_PARAGRAPH_STYLES));
+ uno::Reference< container::XIndexReplace > xAcc;
+ aStyleNames >>= xAcc;
+
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ OUString sLevel;
+ if(bOn)
+ sLevel = rDesc.GetStyleNames(i);
+ const sal_Int32 nStyles =
+ comphelper::string::getTokenCount(sLevel, TOX_STYLE_DELIMITER);
+ uno::Sequence<OUString> aStyles(nStyles);
+ OUString* pArr = aStyles.getArray();
+ sal_Int32 nPos {0};
+ for(sal_Int32 nStyle = 0; nStyle < nStyles; ++nStyle)
+ pArr[nStyle] = sLevel.getToken(0, TOX_STYLE_DELIMITER, nPos);
+ uno::Any aAny(&aStyles, cppu::UnoType<uno::Sequence<OUString>>::get());
+ xAcc->replaceByIndex(i, aAny);
+ }
+ }
+ lcl_SetProp(xInfo, xIdxProps, UNO_NAME_LEVEL, static_cast<sal_Int16>(rDesc.GetLevel()));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_MARKS, bool(nContentOptions & SwTOXElement::Mark ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_OUTLINE, bool(nContentOptions & SwTOXElement::OutlineLevel));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_EMBEDDED_OBJECTS,bool(nContentOptions & SwTOXElement::Ole ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_TABLES , bool(nContentOptions & SwTOXElement::Table ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_GRAPHIC_OBJECTS, bool(nContentOptions & SwTOXElement::Graphic ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_TEXT_FRAMES, bool(nContentOptions & SwTOXElement::Frame ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_LABELS, bool(nContentOptions & SwTOXElement::Sequence ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_HIDE_TAB_LEADER_AND_PAGE_NUMBERS, bool(nContentOptions & SwTOXElement::TableLeader ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_TAB_IN_TOC, bool(nContentOptions & SwTOXElement::TableInToc ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_TOC_NEWLINE, bool(nContentOptions & SwTOXElement::Newline));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_TOC_PARAGRAPH_OUTLINE_LEVEL, bool(nContentOptions & SwTOXElement::ParagraphOutlineLevel));
+
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_CHAPTER, rDesc.IsFromChapter());
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_IS_PROTECTED, rDesc.IsReadonly());
+
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_COMBINED_ENTRIES, bool(nIdxOptions & SwTOIOptions::SameEntry ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_P_P, bool(nIdxOptions & SwTOIOptions::FF ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_IS_CASE_SENSITIVE, bool(nIdxOptions & SwTOIOptions::CaseSensitive ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_KEY_AS_ENTRY, bool(nIdxOptions & SwTOIOptions::KeyAsEntry ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_ALPHABETICAL_SEPARATORS, bool(nIdxOptions & SwTOIOptions::AlphaDelimiter));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_DASH, bool(nIdxOptions & SwTOIOptions::Dash ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_UPPER_CASE, bool(nIdxOptions & SwTOIOptions::InitialCaps ));
+
+ OUString aTmpName( SwStyleNameMapper::GetSpecialExtraProgName( rDesc.GetSequenceName() ) );
+ lcl_SetProp(xInfo, xIdxProps, UNO_NAME_LABEL_CATEGORY, aTmpName );
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_LABELS, !rDesc.IsCreateFromObjectNames());
+
+ sal_Int16 nSet = text::ChapterFormat::NAME_NUMBER;
+ switch (rDesc.GetCaptionDisplay())
+ {
+ case CAPTION_COMPLETE: nSet = text::ChapterFormat::NAME_NUMBER;break;
+ case CAPTION_NUMBER : nSet = text::ChapterFormat::NUMBER; break;
+ case CAPTION_TEXT : nSet = text::ChapterFormat::NAME; break;
+ }
+ lcl_SetProp(xInfo, xIdxProps, UNO_NAME_LABEL_DISPLAY_TYPE, nSet);
+
+ SwTOOElements nOLEOptions = rDesc.GetOLEOptions();
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_STAR_MATH, bool(SwTOOElements::Math &nOLEOptions ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_STAR_CHART, bool(SwTOOElements::Chart &nOLEOptions ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_STAR_CALC, bool(SwTOOElements::Calc &nOLEOptions ));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_STAR_DRAW, bool(SwTOOElements::DrawImpress&nOLEOptions));
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_CREATE_FROM_OTHER_EMBEDDED_OBJECTS, bool(SwTOOElements::Other & nOLEOptions));
+ }
+ const SwForm* pForm = GetForm(m_eCurrentTOXType);
+ if(bInitialCreate || !nPage || nPage == TOX_PAGE_ENTRY)
+ {
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_IS_COMMA_SEPARATED, pForm->IsCommaSeparated());
+ lcl_SetBOOLProp(xInfo, xIdxProps, UNO_NAME_USE_ALPHABETICAL_SEPARATORS, bool(nIdxOptions&SwTOIOptions::AlphaDelimiter));
+ const bool bUseCurrent = nCurrentLevel < pForm->GetFormMax();
+ const sal_uInt16 nStartLevel = bUseCurrent ? nCurrentLevel : 0;
+ const sal_uInt16 nEndLevel = bUseCurrent ? nCurrentLevel : pForm->GetFormMax() - 1;
+ if(xInfo->hasPropertyByName(UNO_NAME_LEVEL_FORMAT))
+ {
+ for(sal_uInt16 nCurrLevel = nStartLevel; nCurrLevel <= nEndLevel; nCurrLevel++)
+ {
+ OUString sTokenType;
+ uno::Sequence< beans::PropertyValues> aSequPropVals(10);
+ tools::Long nTokenIndex = 0;
+ tools::Long nParamCount = 2;
+
+ // #i24377#
+ SwFormTokens aPattern = pForm->GetPattern(nCurrLevel);
+
+ for(const auto& aToken : aPattern)
+ {
+ if( aSequPropVals.getLength() <= nTokenIndex)
+ aSequPropVals.realloc(nTokenIndex + 10);
+
+ switch(aToken.eTokenType)
+ {
+ case TOKEN_ENTRY_NO :
+ sTokenType = "TokenEntryNumber";
+ // numbering for content index
+ break;
+ case TOKEN_ENTRY_TEXT :
+ case TOKEN_ENTRY :
+ sTokenType = "TokenEntryText";
+ break;
+ case TOKEN_TAB_STOP :
+ nParamCount += 3;
+ sTokenType = "TokenTabStop";
+ break;
+ case TOKEN_TEXT :
+ sTokenType = "TokenText";
+ nParamCount += 1;
+ break;
+ case TOKEN_PAGE_NUMS :
+ sTokenType = "TokenPageNumber";
+ break;
+ case TOKEN_CHAPTER_INFO :
+ sTokenType = "TokenChapterInfo";
+ break;
+ case TOKEN_LINK_START :
+ sTokenType = "TokenHyperlinkStart";
+ break;
+ case TOKEN_LINK_END :
+ sTokenType = "TokenHyperlinkEnd";
+ break;
+ case TOKEN_AUTHORITY :
+ {
+ sTokenType = "TokenBibliographyDataField";
+ }
+ break;
+ default:; //prevent warning
+ }
+ beans::PropertyValues aPropVals(nParamCount);
+ beans::PropertyValue* pPropValArr = aPropVals.getArray();
+ pPropValArr[0].Name = "TokenType";
+ pPropValArr[0].Value <<= sTokenType;
+ pPropValArr[1].Name = "CharacterStyleName";
+ pPropValArr[1].Value <<= aToken.sCharStyleName;
+ if(TOKEN_TAB_STOP == aToken.eTokenType)
+ {
+ pPropValArr[2].Name = "TabStopRightAligned";
+ pPropValArr[2].Value <<= SvxTabAdjust::End == aToken.eTabAlign;
+ pPropValArr[3].Name = "TabStopFillCharacter";
+ pPropValArr[3].Value <<= OUString(aToken.cTabFillChar);
+ pPropValArr[4].Name = "TabStopPosition";
+ SwTwips nTempPos = aToken.nTabStopPosition >= 0 ?
+ aToken.nTabStopPosition : 0;
+ nTempPos = convertTwipToMm100(nTempPos);
+ pPropValArr[4].Value <<= static_cast<sal_Int32>(nTempPos);
+ }
+ else if(TOKEN_TEXT == aToken.eTokenType)
+ {
+ pPropValArr[2].Name = "Text";
+ pPropValArr[2].Value <<= aToken.sText;
+ }
+ beans::PropertyValues* pValues = aSequPropVals.getArray();
+ pValues[nTokenIndex] = aPropVals;
+ nTokenIndex++;
+ }
+ aSequPropVals.realloc(nTokenIndex);
+
+ uno::Any aFormatAccess = xIdxProps->getPropertyValue(UNO_NAME_LEVEL_FORMAT);
+ OSL_ENSURE(aFormatAccess.getValueType() == cppu::UnoType<container::XIndexReplace>::get(),
+ "wrong property type");
+
+ uno::Reference< container::XIndexReplace > xFormatAccess;
+ aFormatAccess >>= xFormatAccess;
+ uno::Any aLevelProp(&aSequPropVals, cppu::UnoType<uno::Sequence<beans::PropertyValues>>::get());
+ xFormatAccess->replaceByIndex(nCurrLevel, aLevelProp);
+ }
+ }
+ }
+ if(bInitialCreate || !nPage || nPage == TOX_PAGE_STYLES)
+ {
+ lcl_SetProp(xInfo, xIdxProps, "ParaStyleHeading", pForm->GetTemplate(0));
+ sal_uInt16 nOffset = 0;
+ sal_uInt16 nEndLevel = 2;
+ switch(m_eCurrentTOXType.eType)
+ {
+ case TOX_INDEX:
+ {
+ nOffset = 1;
+ nEndLevel = 4;
+ lcl_SetProp(xInfo, xIdxProps, "ParaStyleSeparator", pForm->GetTemplate(1));
+ }
+ break;
+ case TOX_CONTENT :
+ nEndLevel = 11;
+ break;
+ default:; //prevent warning
+ }
+ for(sal_uInt16 i = 1; i < nEndLevel; i++)
+ {
+ lcl_SetProp(xInfo,
+ xIdxProps,
+ "ParaStyleLevel" + OUString::number( i ),
+ pForm->GetTemplate(i + nOffset));
+ }
+ }
+ m_vTypeData[nTOXIndex].m_oIndexSections->xDocumentIndex->update();
+
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "sw", "::CreateExample()");
+ }
+ m_xExampleFrame->Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/index/cnttab.cxx b/sw/source/ui/index/cnttab.cxx
new file mode 100644
index 0000000000..a5d3bf92dd
--- /dev/null
+++ b/sw/source/ui/index/cnttab.cxx
@@ -0,0 +1,4136 @@
+/* -*- 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 <o3tl/safeint.hxx>
+#include <sal/log.hxx>
+#include <svl/style.hxx>
+#include <utility>
+#include <vcl/weld.hxx>
+#include <svl/stritem.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/flagsdef.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <svtools/indexentryres.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <column.hxx>
+#include <fmtfsize.hxx>
+#include <authfld.hxx>
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <cnttab.hxx>
+#include <swuicnttab.hxx>
+#include <poolfmt.hxx>
+#include <strings.hrc>
+#include <uitool.hxx>
+#include <fmtcol.hxx>
+#include <fldbas.hxx>
+#include <expfld.hxx>
+#include <unotools.hxx>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <modcfg.hxx>
+#include <iodetect.hxx>
+
+#include <cmdid.h>
+#include <cnttab.hrc>
+#include <SwStyleNameMapper.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <toxwrap.hxx>
+#include <chpfld.hxx>
+#include <svtools/editbrowsebox.hxx>
+
+#include <cmath>
+#include <memory>
+#include <string_view>
+#include <vector>
+#include <numeric>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace com::sun::star::ui::dialogs;
+using namespace ::sfx2;
+
+const sal_Unicode aDeliStart = '['; // for the form
+const sal_Unicode aDeliEnd = ']'; // for the form
+
+static OUString lcl_CreateAutoMarkFileDlg(weld::Window* pParent, const OUString& rURL,
+ const OUString& rFileString, bool bOpen)
+{
+ OUString sRet;
+
+ FileDialogHelper aDlgHelper( bOpen ?
+ TemplateDescription::FILEOPEN_SIMPLE : TemplateDescription::FILESAVE_AUTOEXTENSION,
+ FileDialogFlags::NONE, pParent);
+ uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+
+ xFP->appendFilter( rFileString, "*.sdi" );
+ xFP->setCurrentFilter( rFileString ) ;
+
+ if( !rURL.isEmpty() )
+ xFP->setDisplayDirectory( rURL );
+ else
+ {
+ SvtPathOptions aPathOpt;
+ xFP->setDisplayDirectory( aPathOpt.GetUserConfigPath() );
+ }
+
+ const ErrCode aErrCode = aDlgHelper.Execute();
+ if (aErrCode == ERRCODE_NONE)
+ {
+ sRet = xFP->getSelectedFiles().getConstArray()[0];
+ }
+ // tdf#120405 - use previously selected file, if selection is aborted
+ else if (aErrCode == ERRCODE_ABORT && !rURL.isEmpty())
+ {
+ sRet = rURL;
+ }
+
+ return sRet;
+}
+
+namespace {
+
+struct AutoMarkEntry
+{
+ OUString sSearch;
+ OUString sAlternative;
+ OUString sPrimKey;
+ OUString sSecKey;
+ OUString sComment;
+ bool bCase;
+ bool bWord;
+
+ AutoMarkEntry() :
+ bCase(false),
+ bWord(false){}
+};
+
+}
+
+typedef ::svt::EditBrowseBox SwEntryBrowseBox_Base;
+
+namespace {
+
+class SwEntryBrowseBox : public SwEntryBrowseBox_Base
+{
+ VclPtr<svt::EditControl> m_aCellEdit;
+ VclPtr<svt::CheckBoxControl> m_aCellCheckBox;
+
+ OUString m_sYes;
+ OUString m_sNo;
+
+ std::vector<std::unique_ptr<AutoMarkEntry>> m_Entries;
+
+ ::svt::CellControllerRef m_xController;
+ ::svt::CellControllerRef m_xCheckController;
+
+ sal_Int32 m_nCurrentRow;
+ bool m_bModified;
+
+protected:
+ virtual bool SeekRow( sal_Int32 nRow ) override;
+ virtual void PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId) const override;
+ virtual void InitController(::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol) override;
+ virtual ::svt::CellController* GetController(sal_Int32 nRow, sal_uInt16 nCol) override;
+ virtual bool SaveModified() override;
+
+ std::vector<tools::Long> GetOptimalColWidths() const;
+
+public:
+ SwEntryBrowseBox(const css::uno::Reference<css::awt::XWindow> &rParent);
+ virtual ~SwEntryBrowseBox() override;
+ virtual void dispose() override;
+ void ReadEntries(SvStream& rInStr);
+ void WriteEntries(SvStream& rOutStr);
+
+ bool IsModified()const override;
+
+ virtual OUString GetCellText( sal_Int32 nRow, sal_uInt16 nColumn ) const override;
+ virtual void Resize() override;
+ virtual Size GetOptimalSize() const override;
+};
+
+class SwAutoMarkDlg_Impl : public weld::GenericDialogController
+{
+ OUString m_sAutoMarkURL;
+ bool m_bCreateMode;
+
+ std::unique_ptr<weld::Button> m_xOKPB;
+ std::unique_ptr<weld::Container> m_xTable;
+ css::uno::Reference<css::awt::XWindow> m_xTableCtrlParent;
+ VclPtr<SwEntryBrowseBox> m_xEntriesBB;
+
+ DECL_LINK(OkHdl, weld::Button&, void);
+public:
+ SwAutoMarkDlg_Impl(weld::Window* pParent, OUString aAutoMarkURL,
+ bool bCreate);
+ virtual ~SwAutoMarkDlg_Impl() override;
+};
+
+}
+
+sal_uInt16 CurTOXType::GetFlatIndex() const
+{
+ return static_cast< sal_uInt16 >( (eType == TOX_USER && nIndex)
+ ? TOX_AUTHORITIES + nIndex : eType );
+}
+
+SwMultiTOXTabDialog::SwMultiTOXTabDialog(weld::Widget* pParent, const SfxItemSet& rSet,
+ SwWrtShell &rShell, SwTOXBase* pCurTOX,
+ sal_uInt16 nToxType, bool bGlobal)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/tocdialog.ui", "TocDialog", &rSet)
+ , m_pMgr( new SwTOXMgr( &rShell ) )
+ , m_rWrtShell(rShell)
+ , m_pParamTOXBase(pCurTOX)
+ , m_sUserDefinedIndex(SwResId(STR_USER_DEFINED_INDEX))
+ , m_nInitialTOXType(nToxType)
+ , m_bEditTOX(false)
+ , m_bExampleCreated(false)
+ , m_bGlobalFlag(bGlobal)
+ , m_xShowExampleCB(m_xBuilder->weld_check_button("showexample"))
+{
+ m_eCurrentTOXType.eType = TOX_CONTENT;
+ m_eCurrentTOXType.nIndex = 0;
+
+ const sal_uInt16 nUserTypeCount = m_rWrtShell.GetTOXTypeCount(TOX_USER);
+ m_vTypeData.resize(nUserTypeCount + 6);
+ //the standard user index is on position TOX_USER
+ //all user indexes follow after position TOX_AUTHORITIES
+ if(pCurTOX)
+ {
+ m_bEditTOX = true;
+ }
+ for(int i = m_vTypeData.size() - 1; i > -1; i--)
+ {
+ m_vTypeData[i].m_oIndexSections.emplace();
+ if(pCurTOX)
+ {
+ m_eCurrentTOXType.eType = pCurTOX->GetType();
+ sal_uInt16 nArrayIndex = static_cast< sal_uInt16 >(m_eCurrentTOXType.eType);
+ if(m_eCurrentTOXType.eType == TOX_USER)
+ {
+ //which user type is it?
+ for(sal_uInt16 nUser = 0; nUser < nUserTypeCount; nUser++)
+ {
+ const SwTOXType* pTemp = m_rWrtShell.GetTOXType(TOX_USER, nUser);
+ if(pCurTOX->GetTOXType() == pTemp)
+ {
+ m_eCurrentTOXType.nIndex = nUser;
+ nArrayIndex = static_cast< sal_uInt16 >(nUser > 0 ? TOX_AUTHORITIES + nUser : TOX_USER);
+ break;
+ }
+ }
+ }
+ m_vTypeData[nArrayIndex].m_pForm.reset(new SwForm(pCurTOX->GetTOXForm()));
+ m_vTypeData[nArrayIndex].m_pDescription = CreateTOXDescFromTOXBase(pCurTOX);
+ if(TOX_AUTHORITIES == m_eCurrentTOXType.eType)
+ {
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_rWrtShell.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ if(pFType)
+ {
+ OUString sBrackets;
+ if(pFType->GetPrefix())
+ sBrackets += OUStringChar(pFType->GetPrefix());
+ if(pFType->GetSuffix())
+ sBrackets += OUStringChar(pFType->GetSuffix());
+ m_vTypeData[nArrayIndex].m_pDescription->SetAuthBrackets(sBrackets);
+ m_vTypeData[nArrayIndex].m_pDescription->SetAuthSequence(pFType->IsSequence());
+ }
+ else
+ {
+ m_vTypeData[nArrayIndex].m_pDescription->SetAuthBrackets("[]");
+ }
+ }
+ }
+ }
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ AddTabPage("index", SwTOXSelectTabPage::Create, nullptr);
+ AddTabPage("styles", SwTOXStylesTabPage::Create, nullptr);
+ AddTabPage("columns", SwColumnPage::Create, nullptr);
+ AddTabPage("background", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG), nullptr);
+ AddTabPage("entries", SwTOXEntryTabPage::Create, nullptr);
+ if (!pCurTOX)
+ SetCurPageId("index");
+
+ m_xShowExampleCB->connect_toggled(LINK(this, SwMultiTOXTabDialog, ShowPreviewHdl));
+ m_xShowExampleCB->set_active(SW_MOD()->GetModuleConfig()->IsShowIndexPreview());
+
+ ShowPreview();
+}
+
+SwMultiTOXTabDialog::~SwMultiTOXTabDialog()
+{
+ SW_MOD()->GetModuleConfig()->SetShowIndexPreview(m_xShowExampleCB->get_active());
+}
+
+void SwMultiTOXTabDialog::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ if (rId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "columns")
+ {
+ const SwFormatFrameSize& rSize = GetInputSetImpl()->Get(RES_FRM_SIZE);
+
+ static_cast<SwColumnPage&>(rPage).SetPageWidth(rSize.GetWidth());
+ }
+ else if (rId == "entries")
+ static_cast<SwTOXEntryTabPage&>(rPage).SetWrtShell(m_rWrtShell);
+ else if (rId == "index")
+ {
+ static_cast<SwTOXSelectTabPage&>(rPage).SetWrtShell(m_rWrtShell);
+ if(USHRT_MAX != m_nInitialTOXType)
+ static_cast<SwTOXSelectTabPage&>(rPage).SelectType(static_cast<TOXTypes>(m_nInitialTOXType));
+ }
+}
+
+short SwMultiTOXTabDialog::Ok()
+{
+ short nRet = SfxTabDialogController::Ok();
+ SwTOXDescription& rDesc = GetTOXDescription(m_eCurrentTOXType);
+ SwTOXBase aNewDef(*m_rWrtShell.GetDefaultTOXBase( m_eCurrentTOXType.eType, true ));
+
+ const sal_uInt16 nIndex = m_eCurrentTOXType.GetFlatIndex();
+ if(m_vTypeData[nIndex].m_pForm)
+ {
+ rDesc.SetForm(*m_vTypeData[nIndex].m_pForm);
+ aNewDef.SetTOXForm(*m_vTypeData[nIndex].m_pForm);
+ }
+ rDesc.ApplyTo(aNewDef);
+ if(!m_bGlobalFlag)
+ m_pMgr->UpdateOrInsertTOX(
+ rDesc, nullptr, GetOutputItemSet());
+ else if(m_bEditTOX)
+ m_pMgr->UpdateOrInsertTOX(
+ rDesc, &m_pParamTOXBase, GetOutputItemSet());
+
+ if(!m_eCurrentTOXType.nIndex)
+ m_rWrtShell.SetDefaultTOXBase(aNewDef);
+
+ return nRet;
+}
+
+SwForm* SwMultiTOXTabDialog::GetForm(CurTOXType eType)
+{
+ const sal_uInt16 nIndex = eType.GetFlatIndex();
+ if(!m_vTypeData[nIndex].m_pForm)
+ m_vTypeData[nIndex].m_pForm.reset(new SwForm(eType.eType));
+ return m_vTypeData[nIndex].m_pForm.get();
+}
+
+SwTOXDescription& SwMultiTOXTabDialog::GetTOXDescription(CurTOXType eType)
+{
+ const sal_uInt16 nIndex = eType.GetFlatIndex();
+ if(!m_vTypeData[nIndex].m_pDescription)
+ {
+ const SwTOXBase* pDef = m_rWrtShell.GetDefaultTOXBase( eType.eType );
+ if(pDef)
+ m_vTypeData[nIndex].m_pDescription = CreateTOXDescFromTOXBase(pDef);
+ else
+ {
+ m_vTypeData[nIndex].m_pDescription.reset(new SwTOXDescription(eType.eType));
+ if(eType.eType == TOX_USER)
+ m_vTypeData[nIndex].m_pDescription->SetTitle(m_sUserDefinedIndex);
+ else
+ m_vTypeData[nIndex].m_pDescription->SetTitle(
+ m_rWrtShell.GetTOXType(eType.eType, 0)->GetTypeName());
+ }
+ if(TOX_AUTHORITIES == eType.eType)
+ {
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_rWrtShell.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ if(pFType)
+ {
+ m_vTypeData[nIndex].m_pDescription->SetAuthBrackets(OUStringChar(pFType->GetPrefix()) +
+ OUStringChar(pFType->GetSuffix()));
+ m_vTypeData[nIndex].m_pDescription->SetAuthSequence(pFType->IsSequence());
+ }
+ else
+ {
+ m_vTypeData[nIndex].m_pDescription->SetAuthBrackets("[]");
+ }
+ }
+ else if(TOX_INDEX == eType.eType)
+ m_vTypeData[nIndex].m_pDescription->SetMainEntryCharStyle(SwResId(STR_POOLCHR_IDX_MAIN_ENTRY));
+
+ }
+ return *m_vTypeData[nIndex].m_pDescription;
+}
+
+std::unique_ptr<SwTOXDescription> SwMultiTOXTabDialog::CreateTOXDescFromTOXBase(
+ const SwTOXBase*pCurTOX)
+{
+ std::unique_ptr<SwTOXDescription> pDesc(new SwTOXDescription(pCurTOX->GetType()));
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ pDesc->SetStyleNames(pCurTOX->GetStyleNames(i), i);
+ pDesc->SetAutoMarkURL(m_rWrtShell.GetTOIAutoMarkURL());
+ pDesc->SetTitle(pCurTOX->GetTitle());
+
+ pDesc->SetContentOptions(pCurTOX->GetCreateType());
+ if(pDesc->GetTOXType() == TOX_INDEX)
+ pDesc->SetIndexOptions(pCurTOX->GetOptions());
+ pDesc->SetMainEntryCharStyle(pCurTOX->GetMainEntryCharStyle());
+ if(pDesc->GetTOXType() != TOX_INDEX)
+ pDesc->SetLevel(static_cast<sal_uInt8>(pCurTOX->GetLevel()));
+ pDesc->SetCreateFromObjectNames(pCurTOX->IsFromObjectNames());
+ pDesc->SetSequenceName(pCurTOX->GetSequenceName());
+ pDesc->SetCaptionDisplay(pCurTOX->GetCaptionDisplay());
+ pDesc->SetFromChapter(pCurTOX->IsFromChapter());
+ pDesc->SetReadonly(pCurTOX->IsProtected());
+ pDesc->SetOLEOptions(pCurTOX->GetOLEOptions());
+ pDesc->SetLevelFromChapter(pCurTOX->IsLevelFromChapter());
+ pDesc->SetLanguage(pCurTOX->GetLanguage());
+ pDesc->SetSortAlgorithm(pCurTOX->GetSortAlgorithm());
+ return pDesc;
+}
+
+void SwMultiTOXTabDialog::ShowPreview()
+{
+ if (m_xShowExampleCB->get_active())
+ {
+ if(!m_xExampleFrame && !m_bExampleCreated)
+ {
+ m_bExampleCreated = true;
+ OUString sTemplate("internal/idxexample.odt");
+
+ SvtPathOptions aOpt;
+ bool bExist = aOpt.SearchFile( sTemplate, SvtPathOptions::Paths::Template );
+
+ if(!bExist)
+ {
+ OUString sInfo(SwResId(STR_FILE_NOT_FOUND));
+ sInfo = sInfo.replaceFirst( "%1", sTemplate );
+ sInfo = sInfo.replaceFirst( "%2", aOpt.GetTemplatePath() );
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ sInfo));
+ xInfoBox->run();
+ }
+ else
+ {
+ Link<SwOneExampleFrame&,void> aLink(LINK(this, SwMultiTOXTabDialog, CreateExample_Hdl));
+ m_xExampleFrame.reset(new SwOneExampleFrame(EX_SHOW_ONLINE_LAYOUT | EX_LOCALIZE_TOC_STRINGS, &aLink, &sTemplate));
+ m_xExampleFrameWin.reset(new weld::CustomWeld(*m_xBuilder, "example", *m_xExampleFrame));
+ }
+ m_xShowExampleCB->set_visible(m_xExampleFrame != nullptr);
+ }
+ }
+
+ if (m_xExampleFrame)
+ {
+ const bool bSetViewWindow = m_xShowExampleCB->get_active();
+ if (bSetViewWindow)
+ m_xExampleFrame->Show();
+ else
+ m_xExampleFrame->Hide();
+ }
+}
+
+IMPL_LINK_NOARG(SwMultiTOXTabDialog, ShowPreviewHdl, weld::Toggleable&, void)
+{
+ ShowPreview();
+ m_xDialog->resize_to_request();
+}
+
+bool SwMultiTOXTabDialog::IsNoNum(SwWrtShell& rSh, const OUString& rName)
+{
+ SwTextFormatColl* pColl = rSh.GetParaStyle(rName);
+ if(pColl && ! pColl->IsAssignedToListLevelOfOutlineStyle())
+ return true;
+
+ const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
+ rName, SwGetPoolIdFromName::TxtColl);
+ return nId != USHRT_MAX &&
+ ! rSh.GetTextCollFromPool(nId)->IsAssignedToListLevelOfOutlineStyle();
+}
+
+namespace {
+
+class SwAddStylesDlg_Impl : public SfxDialogController
+{
+ OUString* m_pStyleArr;
+
+ std::unique_ptr<weld::Button> m_xOk;
+ std::unique_ptr<weld::Button> m_xLeftPB;
+ std::unique_ptr<weld::Button> m_xRightPB;
+ std::unique_ptr<weld::TreeView> m_xHeaderTree;
+
+ void ToggleOn(int nEntry, int nToggleColumn);
+
+ DECL_LINK(OkHdl, weld::Button&, void);
+ DECL_LINK(LeftRightHdl, weld::Button&, void);
+ DECL_LINK(KeyInput, const KeyEvent&, bool);
+ DECL_LINK(TreeSizeAllocHdl, const Size&, void);
+ DECL_LINK(RadioToggleOnHdl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(HeaderBarClick, int, void);
+
+public:
+ SwAddStylesDlg_Impl(weld::Window* pParent, SwWrtShell const & rWrtSh, OUString rStringArr[]);
+};
+
+}
+
+SwAddStylesDlg_Impl::SwAddStylesDlg_Impl(weld::Window* pParent,
+ SwWrtShell const & rWrtSh, OUString rStringArr[])
+ : SfxDialogController(pParent, "modules/swriter/ui/assignstylesdialog.ui", "AssignStylesDialog")
+ , m_pStyleArr(rStringArr)
+ , m_xOk(m_xBuilder->weld_button("ok"))
+ , m_xLeftPB(m_xBuilder->weld_button("left"))
+ , m_xRightPB(m_xBuilder->weld_button("right"))
+ , m_xHeaderTree(m_xBuilder->weld_tree_view("styles"))
+{
+ m_xOk->connect_clicked(LINK(this, SwAddStylesDlg_Impl, OkHdl));
+ m_xLeftPB->connect_clicked(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
+ m_xRightPB->connect_clicked(LINK(this, SwAddStylesDlg_Impl, LeftRightHdl));
+
+ m_xHeaderTree->connect_size_allocate(LINK(this, SwAddStylesDlg_Impl, TreeSizeAllocHdl));
+ m_xHeaderTree->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ m_xHeaderTree->connect_toggled(LINK(this, SwAddStylesDlg_Impl, RadioToggleOnHdl));
+ m_xHeaderTree->connect_column_clicked(LINK(this, SwAddStylesDlg_Impl, HeaderBarClick));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xHeaderTree->get_approximate_digit_width() * 30)
+ };
+ int nPadding = m_xHeaderTree->get_approximate_digit_width() * 2;
+ OUString sTitle(m_xHeaderTree->get_column_title(1));
+ for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+ {
+ sTitle = OUString::number(i);
+ m_xHeaderTree->set_column_title(i + 1, sTitle);
+ aWidths.push_back(m_xHeaderTree->get_pixel_size(sTitle).Width() + nPadding);
+ }
+ m_xHeaderTree->set_column_fixed_widths(aWidths);
+ auto nWidth = std::accumulate(aWidths.begin(), aWidths.end(),
+ Application::GetSettings().GetStyleSettings().GetScrollBarSize());
+ m_xHeaderTree->set_size_request(nWidth, m_xHeaderTree->get_height_rows(15));
+
+ int nRow(0);
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ const OUString &rStyles{rStringArr[i]};
+ if (rStyles.isEmpty())
+ continue;
+ sal_Int32 nPos(0);
+ do
+ {
+ OUString sEntry = rStyles.getToken(0, TOX_STYLE_DELIMITER, nPos);
+ m_xHeaderTree->append_text(sEntry);
+ for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+ {
+ TriState eState = i == j - 1 ? TRISTATE_TRUE : TRISTATE_FALSE;
+ m_xHeaderTree->set_toggle(nRow, eState, j + 1);
+ }
+ ++nRow;
+ } while (nPos>=0);
+ }
+ // now the other styles
+
+ const sal_uInt16 nSz = rWrtSh.GetTextFormatCollCount();
+ for (sal_uInt16 j = 0; j < nSz; ++j)
+ {
+ const SwTextFormatColl& rColl = rWrtSh.GetTextFormatColl(j);
+ if (rColl.IsDefault())
+ continue;
+
+ const OUString aName = rColl.GetName();
+ if (!aName.isEmpty())
+ {
+ bool bEntry = false;
+ int nChildren = m_xHeaderTree->n_children();
+ for (int i = 0; i < nChildren; ++i)
+ {
+ if (m_xHeaderTree->get_text(i, 0) == aName)
+ {
+ bEntry = true;
+ break;
+ }
+ }
+ if (!bEntry)
+ {
+ m_xHeaderTree->append_text(aName);
+ for (sal_uInt16 k = 0; k <= MAXLEVEL; ++k)
+ {
+ TriState eState = k == 0 ? TRISTATE_TRUE : TRISTATE_FALSE;
+ m_xHeaderTree->set_toggle(nRow, eState, k + 1);
+ }
+ ++nRow;
+ }
+ }
+ }
+
+ m_xHeaderTree->make_sorted();
+ m_xHeaderTree->set_sort_column(0);
+ m_xHeaderTree->set_sort_order(true);
+ m_xHeaderTree->set_sort_indicator(TRISTATE_TRUE, 0);
+
+ m_xHeaderTree->select(0);
+ m_xHeaderTree->connect_key_release(LINK(this, SwAddStylesDlg_Impl, KeyInput));
+}
+
+IMPL_LINK(SwAddStylesDlg_Impl, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = m_xHeaderTree->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xHeaderTree->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xHeaderTree->set_sort_order(bSortAtoZ);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xHeaderTree->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+IMPL_LINK(SwAddStylesDlg_Impl, TreeSizeAllocHdl, const Size&, rSize, void)
+{
+ auto nWidth = rSize.Width() - Application::GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ std::vector<int> aWidths { 0 };
+ int nPadding = m_xHeaderTree->get_approximate_digit_width() * 2;
+ for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+ {
+ OUString sTitle(m_xHeaderTree->get_column_title(i + 1));
+ aWidths.push_back(m_xHeaderTree->get_pixel_size(sTitle).Width() + nPadding);
+ }
+ auto nOtherWidth = std::accumulate(aWidths.begin(), aWidths.end(), 0);
+ aWidths[0] = nWidth - nOtherWidth;
+ m_xHeaderTree->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(SwAddStylesDlg_Impl, RadioToggleOnHdl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ for (sal_uInt16 i = 0; i <= MAXLEVEL; ++i)
+ {
+ TriState eState = rRowCol.second == i + 1 ? TRISTATE_TRUE : TRISTATE_FALSE;
+ m_xHeaderTree->set_toggle(rRowCol.first, eState, i + 1);
+ }
+}
+
+IMPL_LINK(SwAddStylesDlg_Impl, KeyInput, const KeyEvent&, rKEvt, bool)
+{
+ vcl::KeyCode aCode = rKEvt.GetKeyCode();
+ bool bHandled = false;
+
+ sal_uInt16 nCode = aCode.GetCode();
+ switch (nCode)
+ {
+ case KEY_ADD:
+ LeftRightHdl(*m_xRightPB);
+ bHandled = true;
+ break;
+ case KEY_SUBTRACT:
+ LeftRightHdl(*m_xLeftPB);
+ bHandled = true;
+ break;
+ case KEY_0:
+ case KEY_1:
+ case KEY_2:
+ case KEY_3:
+ case KEY_4:
+ case KEY_5:
+ case KEY_6:
+ case KEY_7:
+ case KEY_8:
+ case KEY_9:
+ case KEY_A:
+ {
+ int nEntry = m_xHeaderTree->get_selected_index();
+ if (nEntry != -1)
+ {
+ ToggleOn(nEntry, nCode != KEY_A ? nCode - KEY_0 : 10);
+ bHandled = true;
+ }
+ break;
+ }
+ }
+
+ return bHandled;
+}
+
+IMPL_LINK_NOARG(SwAddStylesDlg_Impl, OkHdl, weld::Button&, void)
+{
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ m_pStyleArr[i].clear();
+
+ int nChildren = m_xHeaderTree->n_children();
+ for (int i = 0; i < nChildren; ++i)
+ {
+ int nToggleColumn = 0;
+ for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+ {
+ if (m_xHeaderTree->get_toggle(i, j + 1) == TRISTATE_TRUE)
+ {
+ nToggleColumn = j;
+ break;
+ }
+ }
+ if (nToggleColumn)
+ {
+ int nLevel = nToggleColumn - 1;
+ if(!m_pStyleArr[nLevel].isEmpty())
+ m_pStyleArr[nLevel] += OUStringChar(TOX_STYLE_DELIMITER);
+ m_pStyleArr[nLevel] += m_xHeaderTree->get_text(i, 0);
+ }
+ }
+
+ //TODO write back style names
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwAddStylesDlg_Impl, LeftRightHdl, weld::Button&, rBtn, void)
+{
+ bool bLeft = &rBtn == m_xLeftPB.get();
+ int nEntry = m_xHeaderTree->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ int nToggleColumn = 0;
+ for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+ {
+ if (m_xHeaderTree->get_toggle(nEntry, j + 1) == TRISTATE_TRUE)
+ {
+ nToggleColumn = j;
+ break;
+ }
+ }
+
+ if (bLeft)
+ {
+ if (nToggleColumn)
+ --nToggleColumn;
+ }
+ else
+ {
+ if (nToggleColumn < MAXLEVEL)
+ ++nToggleColumn;
+ }
+
+ ToggleOn(nEntry, nToggleColumn);
+}
+
+void SwAddStylesDlg_Impl::ToggleOn(int nEntry, int nToggleColumn)
+{
+ for (sal_uInt16 j = 0; j <= MAXLEVEL; ++j)
+ {
+ m_xHeaderTree->set_toggle(nEntry, j == nToggleColumn ? TRISTATE_TRUE : TRISTATE_FALSE, j + 1);
+ }
+}
+
+SwTOXSelectTabPage::SwTOXSelectTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/tocindexpage.ui", "TocIndexPage", &rAttrSet)
+ , m_sAutoMarkType(SwResId(STR_AUTOMARK_TYPE))
+ , m_bWaitingInitialSettings(true)
+ , m_xTitleED(m_xBuilder->weld_entry("title"))
+ , m_xTypeFT(m_xBuilder->weld_label("typeft"))
+ , m_xTypeLB(m_xBuilder->weld_combo_box("type"))
+ , m_xReadOnlyCB(m_xBuilder->weld_check_button("readonly"))
+ , m_xAreaFrame(m_xBuilder->weld_widget("areaframe"))
+ , m_xAreaLB(m_xBuilder->weld_combo_box("scope"))
+ , m_xLevelFT(m_xBuilder->weld_label("levelft"))
+ , m_xLevelNF(m_xBuilder->weld_spin_button("level"))
+ , m_xCreateFrame(m_xBuilder->weld_widget("createframe"))
+ , m_xFromHeadingsCB(m_xBuilder->weld_check_button("fromheadings"))
+ , m_xStylesCB(m_xBuilder->weld_check_button("stylescb"))
+ , m_xAddStylesCB(m_xBuilder->weld_check_button("addstylescb"))
+ , m_xAddStylesPB(m_xBuilder->weld_button("styles"))
+ , m_xFromTablesCB(m_xBuilder->weld_check_button("fromtables"))
+ , m_xFromFramesCB(m_xBuilder->weld_check_button("fromframes"))
+ , m_xFromGraphicsCB(m_xBuilder->weld_check_button("fromgraphics"))
+ , m_xFromOLECB(m_xBuilder->weld_check_button("fromoles"))
+ , m_xLevelFromChapterCB(m_xBuilder->weld_check_button("uselevel"))
+ , m_xFromCaptionsRB(m_xBuilder->weld_radio_button("captions"))
+ , m_xFromObjectNamesRB(m_xBuilder->weld_radio_button("objnames"))
+ , m_xCaptionSequenceFT(m_xBuilder->weld_label("categoryft"))
+ , m_xCaptionSequenceLB(m_xBuilder->weld_combo_box("category"))
+ , m_xDisplayTypeFT(m_xBuilder->weld_label("displayft"))
+ , m_xDisplayTypeLB(m_xBuilder->weld_combo_box("display"))
+ , m_xParaStyleCB(m_xBuilder->weld_check_button("useparastyle"))
+ , m_xParaStyleLB(m_xBuilder->weld_combo_box("parastyle"))
+ , m_xTOXMarksCB(m_xBuilder->weld_check_button("indexmarks"))
+ , m_xIdxOptionsFrame(m_xBuilder->weld_widget("optionsframe"))
+ , m_xCollectSameCB(m_xBuilder->weld_check_button("combinesame"))
+ , m_xUseFFCB(m_xBuilder->weld_check_button("useff"))
+ , m_xUseDashCB(m_xBuilder->weld_check_button("usedash"))
+ , m_xCaseSensitiveCB(m_xBuilder->weld_check_button("casesens"))
+ , m_xInitialCapsCB(m_xBuilder->weld_check_button("initcaps"))
+ , m_xKeyAsEntryCB(m_xBuilder->weld_check_button("keyasentry"))
+ , m_xFromFileCB(m_xBuilder->weld_check_button("fromfile"))
+ , m_xAutoMarkPB(m_xBuilder->weld_menu_button("file"))
+ , m_xFromObjCLB(m_xBuilder->weld_tree_view("objects"))
+ , m_xFromObjFrame(m_xBuilder->weld_widget("objectframe"))
+ , m_xSequenceCB(m_xBuilder->weld_check_button("numberentries"))
+ , m_xBracketLB(m_xBuilder->weld_combo_box("brackets"))
+ , m_xAuthorityFrame(m_xBuilder->weld_widget("authframe"))
+ , m_xSortFrame(m_xBuilder->weld_widget("sortframe"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+ , m_xSortAlgorithmLB(m_xBuilder->weld_combo_box("keytype"))
+{
+ m_sAddStyleUser = m_xStylesCB->get_label();
+ m_pIndexEntryWrapper.reset(new IndexEntrySupplierWrapper());
+
+ m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
+ false );
+
+ //Default mode is arranged to be the tallest mode
+ //of alphabetical index, lock that size in now
+ LanguageHdl(nullptr); //fill sort algorithm list
+ Size aPrefSize(m_xContainer->get_preferred_size());
+ m_xContainer->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+
+ m_sAddStyleContent = m_xAddStylesCB->get_label();
+
+ m_xFromObjCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(RES_SRCTYPES); ++i)
+ {
+ OUString sId(OUString::number(static_cast<sal_uInt32>(RES_SRCTYPES[i].second)));
+ m_xFromObjCLB->append();
+ m_xFromObjCLB->set_toggle(i, TRISTATE_FALSE);
+ m_xFromObjCLB->set_text(i, SwResId(RES_SRCTYPES[i].first), 0);
+ m_xFromObjCLB->set_id(i, sId);
+ }
+ m_xFromObjCLB->set_size_request(-1, std::max<int>(m_xFromObjCLB->get_preferred_size().Height(),
+ m_xFromObjCLB->get_height_rows(SAL_N_ELEMENTS(RES_SRCTYPES))) + 2);
+
+ SetExchangeSupport();
+ m_xTypeLB->connect_changed(LINK(this, SwTOXSelectTabPage, TOXTypeHdl));
+
+ m_xAddStylesPB->connect_clicked(LINK(this, SwTOXSelectTabPage, AddStylesHdl));
+
+ m_xAutoMarkPB->connect_toggled(LINK(this, SwTOXSelectTabPage, MenuEnableHdl));
+ m_xAutoMarkPB->connect_selected(LINK(this, SwTOXSelectTabPage, MenuExecuteHdl));
+
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwTOXSelectTabPage, CheckBoxHdl);
+ m_xAddStylesCB->connect_toggled(aLk);
+ m_xFromHeadingsCB->connect_toggled(aLk);
+ m_xTOXMarksCB->connect_toggled(aLk);
+ m_xFromFileCB->connect_toggled(aLk);
+ m_xCollectSameCB->connect_toggled(aLk);
+ m_xUseFFCB->connect_toggled(aLk);
+ m_xUseDashCB->connect_toggled(aLk);
+ m_xInitialCapsCB->connect_toggled(aLk);
+ m_xKeyAsEntryCB->connect_toggled(aLk);
+ m_xParaStyleCB->connect_toggled(aLk);
+
+ m_xTitleED->connect_changed(LINK(this, SwTOXSelectTabPage, ModifyEntryHdl));
+ m_xLevelNF->connect_value_changed(LINK(this, SwTOXSelectTabPage, ModifySpinHdl));
+ m_xSortAlgorithmLB->connect_changed(LINK(this, SwTOXSelectTabPage, ModifyListBoxHdl));
+ m_xParaStyleLB->connect_changed(LINK(this, SwTOXSelectTabPage, ModifyListBoxHdl));
+
+ aLk = LINK(this, SwTOXSelectTabPage, RadioButtonHdl);
+ m_xFromCaptionsRB->connect_toggled(aLk);
+ m_xFromObjectNamesRB->connect_toggled(aLk);
+ RadioButtonHdl(*m_xFromCaptionsRB);
+
+ m_xLanguageLB->connect_changed(LINK(this, SwTOXSelectTabPage, LanguageListBoxHdl));
+ m_xTypeLB->set_active(0);
+ m_xTitleED->save_value();
+}
+
+SwTOXSelectTabPage::~SwTOXSelectTabPage()
+{
+ m_pIndexRes.reset();
+ m_pIndexEntryWrapper.reset();
+ m_xLanguageLB.reset();
+}
+
+void SwTOXSelectTabPage::SetWrtShell(SwWrtShell const & rSh)
+{
+ const sal_uInt16 nUserTypeCount = rSh.GetTOXTypeCount(TOX_USER);
+ if(nUserTypeCount <= 1)
+ return;
+
+ //insert all new user indexes names after the standard user index
+ sal_Int32 nPos = m_xTypeLB->find_id(OUString::number(sal_uInt32(TO_USER))) + 1;
+ for (sal_uInt16 nUser = 1; nUser < nUserTypeCount; nUser++)
+ {
+ sal_uInt32 nEntryData = nUser << 8;
+ nEntryData |= TO_USER;
+ OUString sId(OUString::number(nEntryData));
+ m_xTypeLB->insert(nPos++, rSh.GetTOXType(TOX_USER, nUser)->GetTypeName(),
+ &sId, nullptr, nullptr);
+ }
+}
+
+bool SwTOXSelectTabPage::FillItemSet( SfxItemSet* )
+{
+ return true;
+}
+
+static tools::Long lcl_TOXTypesToUserData(CurTOXType eType)
+{
+ sal_uInt16 nRet = TOX_INDEX;
+ switch(eType.eType)
+ {
+ case TOX_INDEX : nRet = TO_INDEX; break;
+ case TOX_USER :
+ {
+ nRet = eType.nIndex << 8;
+ nRet |= TO_USER;
+ }
+ break;
+ case TOX_CONTENT : nRet = TO_CONTENT; break;
+ case TOX_ILLUSTRATIONS:nRet = TO_ILLUSTRATION; break;
+ case TOX_OBJECTS : nRet = TO_OBJECT; break;
+ case TOX_TABLES : nRet = TO_TABLE; break;
+ case TOX_AUTHORITIES : nRet = TO_AUTHORITIES; break;
+ case TOX_BIBLIOGRAPHY : nRet = TO_BIBLIOGRAPHY; break;
+ case TOX_CITATION :break;
+ }
+ return nRet;
+}
+
+void SwTOXSelectTabPage::SelectType(TOXTypes eSet)
+{
+ CurTOXType eCurType (eSet);
+
+ sal_uInt32 nData = lcl_TOXTypesToUserData(eCurType);
+ m_xTypeLB->set_active_id(OUString::number(nData));
+ m_xTypeFT->set_sensitive(false);
+ m_xTypeLB->set_sensitive(false);
+ TOXTypeHdl(*m_xTypeLB);
+}
+
+static CurTOXType lcl_UserData2TOXTypes(sal_uInt16 nData)
+{
+ CurTOXType eRet;
+
+ switch(nData&0xff)
+ {
+ case TO_INDEX : eRet.eType = TOX_INDEX; break;
+ case TO_USER :
+ {
+ eRet.eType = TOX_USER;
+ eRet.nIndex = (nData&0xff00) >> 8;
+ }
+ break;
+ case TO_CONTENT : eRet.eType = TOX_CONTENT; break;
+ case TO_ILLUSTRATION: eRet.eType = TOX_ILLUSTRATIONS; break;
+ case TO_OBJECT : eRet.eType = TOX_OBJECTS; break;
+ case TO_TABLE : eRet.eType = TOX_TABLES; break;
+ case TO_AUTHORITIES : eRet.eType = TOX_AUTHORITIES; break;
+ case TO_BIBLIOGRAPHY : eRet.eType = TOX_BIBLIOGRAPHY; break;
+ default: OSL_FAIL("what a type?");
+ }
+ return eRet;
+}
+
+void SwTOXSelectTabPage::ApplyTOXDescription()
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
+ SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(aCurType);
+
+ m_xReadOnlyCB->set_active(rDesc.IsReadonly());
+ if (!m_xTitleED->get_value_changed_from_saved())
+ {
+ if (rDesc.GetTitle())
+ m_xTitleED->set_text(*rDesc.GetTitle());
+ else
+ m_xTitleED->set_text(OUString());
+ m_xTitleED->save_value();
+ }
+
+ m_xAreaLB->set_active(rDesc.IsFromChapter() ? 1 : 0);
+
+ if (aCurType.eType != TOX_INDEX)
+ m_xLevelNF->set_value(rDesc.GetLevel()); //content, user
+
+ SwTOXElement nCreateType = rDesc.GetContentOptions();
+
+ //user + content
+ bool bHasStyleNames = false;
+
+ for( sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ if(!rDesc.GetStyleNames(i).isEmpty())
+ {
+ bHasStyleNames = true;
+ break;
+ }
+ m_xAddStylesCB->set_active(bHasStyleNames && (nCreateType & SwTOXElement::Template));
+
+ m_xFromOLECB->set_active( bool(nCreateType & SwTOXElement::Ole) );
+ m_xFromTablesCB->set_active( bool(nCreateType & SwTOXElement::Table) );
+ m_xFromGraphicsCB->set_active( bool(nCreateType & SwTOXElement::Graphic) );
+ m_xFromFramesCB->set_active( bool(nCreateType & SwTOXElement::Frame) );
+
+ m_xLevelFromChapterCB->set_active(rDesc.IsLevelFromChapter());
+
+ //all but illustration and table
+ m_xTOXMarksCB->set_active( bool(nCreateType & SwTOXElement::Mark) );
+
+ if (TOX_ILLUSTRATIONS == aCurType.eType || TOX_TABLES == aCurType.eType
+ || TOX_OBJECTS== aCurType.eType)
+ {
+ // load all para styles...
+ m_xParaStyleLB->clear();
+ SwWrtShell const& rWrtSh(static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell());
+ const sal_uInt16 nSz = rWrtSh.GetTextFormatCollCount();
+ for (sal_uInt16 j = 0; j < nSz; ++j)
+ {
+ SwTextFormatColl const& rColl = rWrtSh.GetTextFormatColl(j);
+ if (rColl.IsDefault())
+ continue;
+
+ OUString const name(rColl.GetName());
+ if (!name.isEmpty())
+ {
+ m_xParaStyleLB->append_text(name);
+ }
+ }
+ // first, init ParaStyle - because any later init (e.g. m_xFromCaptionsRB)
+ // ends up calling FillTOXDescription() resetting rDesc!
+ OUString const& rStyle(rDesc.GetStyleNames(0));
+ assert(rStyle.indexOf(TOX_STYLE_DELIMITER) == -1);
+ if (rStyle.isEmpty())
+ {
+ m_xParaStyleCB->set_active(false);
+ m_xParaStyleLB->set_sensitive(false);
+ }
+ else
+ {
+ m_xParaStyleCB->set_active(true);
+ m_xParaStyleLB->set_sensitive(true);
+ m_xParaStyleLB->set_active_text(rStyle);
+ }
+ }
+
+ //content
+ if(TOX_CONTENT == aCurType.eType)
+ {
+ m_xFromHeadingsCB->set_active( bool(nCreateType & SwTOXElement::OutlineLevel) );
+ m_xAddStylesCB->set_label(m_sAddStyleContent);
+ m_xAddStylesPB->set_sensitive(m_xAddStylesCB->get_active());
+ }
+ //index only
+ else if(TOX_INDEX == aCurType.eType)
+ {
+ const SwTOIOptions nIndexOptions = rDesc.GetIndexOptions();
+ m_xCollectSameCB->set_active( bool(nIndexOptions & SwTOIOptions::SameEntry) );
+ m_xUseFFCB->set_active( bool(nIndexOptions & SwTOIOptions::FF) );
+ m_xUseDashCB->set_active( bool(nIndexOptions & SwTOIOptions::Dash) );
+ if (m_xUseFFCB->get_active())
+ m_xUseDashCB->set_sensitive(false);
+ else if (m_xUseDashCB->get_active())
+ m_xUseFFCB->set_sensitive(false);
+
+ m_xCaseSensitiveCB->set_active( bool(nIndexOptions & SwTOIOptions::CaseSensitive) );
+ m_xInitialCapsCB->set_active( bool(nIndexOptions & SwTOIOptions::InitialCaps) );
+ m_xKeyAsEntryCB->set_active( bool(nIndexOptions & SwTOIOptions::KeyAsEntry) );
+ }
+ else if (TOX_ILLUSTRATIONS == aCurType.eType || TOX_TABLES == aCurType.eType)
+ {
+ OUString sName(rDesc.GetSequenceName());
+ int nIndex = m_xCaptionSequenceLB->find_text(sName);
+ if (nIndex != -1)
+ m_xCaptionSequenceLB->set_active(nIndex);
+ m_xDisplayTypeLB->set_active(static_cast<sal_Int32>(rDesc.GetCaptionDisplay()));
+ if (m_xDisplayTypeLB->get_active() == -1)
+ m_xDisplayTypeLB->set_active(0);
+ m_xFromObjectNamesRB->set_active(rDesc.IsCreateFromObjectNames());
+ m_xFromCaptionsRB->set_active(!rDesc.IsCreateFromObjectNames());
+ RadioButtonHdl(*m_xFromCaptionsRB);
+ }
+ else if(TOX_OBJECTS == aCurType.eType)
+ {
+ SwTOOElements nOLEData = rDesc.GetOLEOptions();
+ for (int nFromObj = 0, nCount = m_xFromObjCLB->n_children(); nFromObj < nCount; ++nFromObj)
+ {
+ SwTOOElements nData = static_cast<SwTOOElements>(m_xFromObjCLB->get_id(nFromObj).toInt32());
+ m_xFromObjCLB->set_toggle(nFromObj, bool(nData & nOLEData) ? TRISTATE_TRUE : TRISTATE_FALSE);
+ }
+ }
+ else if(TOX_AUTHORITIES == aCurType.eType)
+ {
+ const OUString& sBrackets(rDesc.GetAuthBrackets());
+ if(sBrackets.isEmpty() || sBrackets == " ")
+ m_xBracketLB->set_active(0);
+ else
+ m_xBracketLB->set_active_text(sBrackets);
+ m_xSequenceCB->set_active(rDesc.IsAuthSequence());
+ }
+ m_xAutoMarkPB->set_sensitive(m_xFromFileCB->get_active());
+
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ m_aStyleArr[i] = rDesc.GetStyleNames(i);
+
+ m_xLanguageLB->set_active_id(rDesc.GetLanguage());
+ LanguageHdl(nullptr);
+ for (int nCnt = 0, nEntryCount = m_xSortAlgorithmLB->get_count(); nCnt < nEntryCount; ++nCnt)
+ {
+ const OUString& rEntryData = m_xSortAlgorithmLB->get_id(nCnt);
+ if (rEntryData == rDesc.GetSortAlgorithm())
+ {
+ m_xSortAlgorithmLB->set_active(nCnt);
+ break;
+ }
+ }
+}
+
+void SwTOXSelectTabPage::FillTOXDescription()
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
+ SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(aCurType);
+ rDesc.SetTitle(m_xTitleED->get_text());
+ rDesc.SetFromChapter(1 == m_xAreaLB->get_active());
+ SwTOXElement nContentOptions = SwTOXElement::NONE;
+ if (m_xTOXMarksCB->get_visible() && m_xTOXMarksCB->get_active())
+ nContentOptions |= SwTOXElement::Mark;
+
+ SwTOIOptions nIndexOptions = rDesc.GetIndexOptions()&SwTOIOptions::AlphaDelimiter;
+ switch(rDesc.GetTOXType())
+ {
+ case TOX_CONTENT:
+ if(m_xFromHeadingsCB->get_active())
+ nContentOptions |= SwTOXElement::OutlineLevel;
+ break;
+ case TOX_USER:
+ {
+ rDesc.SetTOUName(m_xTypeLB->get_active_text());
+
+ if(m_xFromOLECB->get_active())
+ nContentOptions |= SwTOXElement::Ole;
+ if(m_xFromTablesCB->get_active())
+ nContentOptions |= SwTOXElement::Table;
+ if(m_xFromFramesCB->get_active())
+ nContentOptions |= SwTOXElement::Frame;
+ if(m_xFromGraphicsCB->get_active())
+ nContentOptions |= SwTOXElement::Graphic;
+ }
+ break;
+ case TOX_INDEX:
+ {
+ nContentOptions = SwTOXElement::Mark;
+
+ if(m_xCollectSameCB->get_active())
+ nIndexOptions |= SwTOIOptions::SameEntry;
+ if(m_xUseFFCB->get_active())
+ nIndexOptions |= SwTOIOptions::FF;
+ if(m_xUseDashCB->get_active())
+ nIndexOptions |= SwTOIOptions::Dash;
+ if(m_xCaseSensitiveCB->get_active())
+ nIndexOptions |= SwTOIOptions::CaseSensitive;
+ if(m_xInitialCapsCB->get_active())
+ nIndexOptions |= SwTOIOptions::InitialCaps;
+ if(m_xKeyAsEntryCB->get_active())
+ nIndexOptions |= SwTOIOptions::KeyAsEntry;
+ if(m_xFromFileCB->get_active())
+ rDesc.SetAutoMarkURL(m_sAutoMarkURL);
+ else
+ rDesc.SetAutoMarkURL(OUString());
+ }
+ break;
+ case TOX_ILLUSTRATIONS:
+ case TOX_TABLES :
+ rDesc.SetCreateFromObjectNames(m_xFromObjectNamesRB->get_active());
+ rDesc.SetSequenceName(m_xCaptionSequenceLB->get_active_text());
+ rDesc.SetCaptionDisplay(static_cast<SwCaptionDisplay>(m_xDisplayTypeLB->get_active()));
+ if (m_xParaStyleCB->get_active())
+ {
+ m_aStyleArr[0] = m_xParaStyleLB->get_active_text();
+ }
+ else
+ {
+ m_aStyleArr[0] = OUString();
+ }
+ break;
+ case TOX_OBJECTS:
+ {
+ SwTOOElements nOLEData = SwTOOElements::NONE;
+ for (int i = 0, nCount = m_xFromObjCLB->n_children(); i < nCount; ++i)
+ {
+ if (m_xFromObjCLB->get_toggle(i) == TRISTATE_TRUE)
+ {
+ SwTOOElements nData = static_cast<SwTOOElements>(m_xFromObjCLB->get_id(i).toInt32());
+ nOLEData |= nData;
+ }
+ }
+ rDesc.SetOLEOptions(nOLEData);
+ if (m_xParaStyleCB->get_active())
+ {
+ m_aStyleArr[0] = m_xParaStyleLB->get_active_text();
+ }
+ else
+ {
+ m_aStyleArr[0] = OUString();
+ }
+ }
+ break;
+ case TOX_AUTHORITIES:
+ case TOX_BIBLIOGRAPHY :
+ {
+ if (m_xBracketLB->get_active())
+ rDesc.SetAuthBrackets(m_xBracketLB->get_active_text());
+ else
+ rDesc.SetAuthBrackets(OUString());
+ rDesc.SetAuthSequence(m_xSequenceCB->get_active());
+ }
+ break;
+ case TOX_CITATION :
+ break;
+ }
+
+ rDesc.SetLevelFromChapter( m_xLevelFromChapterCB->get_visible() &&
+ m_xLevelFromChapterCB->get_active());
+ if (m_xTOXMarksCB->get_active() && m_xTOXMarksCB->get_visible())
+ nContentOptions |= SwTOXElement::Mark;
+ if (m_xFromHeadingsCB->get_active() && m_xFromHeadingsCB->get_visible())
+ nContentOptions |= SwTOXElement::OutlineLevel;
+ if ((m_xAddStylesCB->get_active() && m_xAddStylesCB->get_visible())
+ || (m_xParaStyleCB->get_active() && m_xParaStyleCB->get_visible()))
+ {
+ nContentOptions |= SwTOXElement::Template;
+ }
+
+ rDesc.SetContentOptions(nContentOptions);
+ rDesc.SetIndexOptions(nIndexOptions);
+ rDesc.SetLevel(m_xLevelNF->get_value());
+
+ rDesc.SetReadonly(m_xReadOnlyCB->get_active());
+
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ rDesc.SetStyleNames(m_aStyleArr[i], i);
+
+ rDesc.SetLanguage(m_xLanguageLB->get_active_id());
+ const OUString& rEntryData = m_xSortAlgorithmLB->get_active_id();
+ rDesc.SetSortAlgorithm(rEntryData);
+}
+
+void SwTOXSelectTabPage::Reset( const SfxItemSet* )
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ SwWrtShell& rSh = pTOXDlg->GetWrtShell();
+ const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
+ sal_uInt32 nData = lcl_TOXTypesToUserData(aCurType);
+ m_xTypeLB->set_active_id(OUString::number(nData));
+
+ m_sAutoMarkURL = INetURLObject::decode( rSh.GetTOIAutoMarkURL(),
+ INetURLObject::DecodeMechanism::Unambiguous );
+ m_xFromFileCB->set_active(!m_sAutoMarkURL.isEmpty());
+
+ m_xCaptionSequenceLB->clear();
+ const size_t nCount = rSh.GetFieldTypeCount(SwFieldIds::SetExp);
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ SwFieldType *pType = rSh.GetFieldType( i, SwFieldIds::SetExp );
+ if( pType->Which() == SwFieldIds::SetExp &&
+ static_cast<SwSetExpFieldType *>( pType)->GetType() & nsSwGetSetExpType::GSE_SEQ )
+ m_xCaptionSequenceLB->append_text(pType->GetName());
+ }
+
+ if(pTOXDlg->IsTOXEditMode())
+ {
+ m_xTypeFT->set_sensitive(false);
+ m_xTypeLB->set_sensitive(false);
+ }
+
+ if(!m_bWaitingInitialSettings)
+ {
+ // save current values into the proper TOXDescription
+ FillTOXDescription();
+ }
+ m_bWaitingInitialSettings = false;
+
+ TOXTypeHdl(*m_xTypeLB);
+ CheckBoxHdl(*m_xAddStylesCB);
+}
+
+void SwTOXSelectTabPage::ActivatePage( const SfxItemSet& )
+{
+ //nothing to do
+}
+
+DeactivateRC SwTOXSelectTabPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if (_pSet)
+ _pSet->Put(SfxUInt16Item(FN_PARAM_TOX_TYPE, m_xTypeLB->get_active_id().toUInt32()));
+ FillTOXDescription();
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SwTOXSelectTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwTOXSelectTabPage>(pPage, pController, *rAttrSet);
+}
+
+IMPL_LINK(SwTOXSelectTabPage, TOXTypeHdl, weld::ComboBox&, rBox, void)
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ const sal_uInt16 nType = rBox.get_active_id().toUInt32();
+ CurTOXType eCurType = lcl_UserData2TOXTypes(nType);
+ pTOXDlg->SetCurrentTOXType(eCurType);
+
+ m_xAreaLB->set_visible( 0 != (nType & (TO_CONTENT|TO_ILLUSTRATION|TO_USER|TO_INDEX|TO_TABLE|TO_OBJECT)) );
+ m_xLevelFT->set_visible( 0 != (nType & (TO_CONTENT)) );
+ m_xLevelNF->set_visible( 0 != (nType & (TO_CONTENT)) );
+ m_xLevelFromChapterCB->set_visible( 0 != (nType & (TO_USER)) );
+ m_xAreaFrame->set_visible( 0 != (nType & (TO_CONTENT|TO_ILLUSTRATION|TO_USER|TO_INDEX|TO_TABLE|TO_OBJECT)) );
+
+ m_xFromHeadingsCB->set_visible( 0 != (nType & (TO_CONTENT)) );
+ m_xAddStylesCB->set_visible( 0 != (nType & (TO_CONTENT|TO_USER)) );
+ m_xAddStylesPB->set_visible( 0 != (nType & (TO_CONTENT|TO_USER)) );
+
+ m_xFromTablesCB->set_visible( 0 != (nType & (TO_USER)) );
+ m_xFromFramesCB->set_visible( 0 != (nType & (TO_USER)) );
+ m_xFromGraphicsCB->set_visible( 0 != (nType & (TO_USER)) );
+ m_xFromOLECB->set_visible( 0 != (nType & (TO_USER)) );
+
+ m_xFromCaptionsRB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
+ m_xFromObjectNamesRB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
+
+ m_xTOXMarksCB->set_visible( 0 != (nType & (TO_CONTENT|TO_USER)) );
+
+ m_xCreateFrame->set_visible( 0 != (nType & (TO_CONTENT|TO_ILLUSTRATION|TO_USER|TO_TABLE)) );
+ m_xCaptionSequenceFT->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
+ m_xCaptionSequenceLB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
+ m_xDisplayTypeFT->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
+ m_xDisplayTypeLB->set_visible( 0 != (nType & (TO_ILLUSTRATION|TO_TABLE)) );
+ m_xParaStyleCB->set_visible(0 != (nType & (TO_ILLUSTRATION|TO_TABLE|TO_OBJECT)));
+ m_xParaStyleLB->set_visible(0 != (nType & (TO_ILLUSTRATION|TO_TABLE|TO_OBJECT)));
+
+ m_xAuthorityFrame->set_visible( 0 != (nType & TO_AUTHORITIES) );
+
+ bool bEnableSortLanguage = 0 != (nType & (TO_INDEX|TO_AUTHORITIES));
+ m_xSortFrame->set_visible(bEnableSortLanguage);
+
+ if( nType & TO_ILLUSTRATION )
+ {
+ OUString sName(SwStyleNameMapper::GetUIName(RES_POOLCOLL_LABEL_FIGURE, OUString()));
+ m_xCaptionSequenceLB->set_active_text(sName);
+ }
+ else if( nType & TO_TABLE )
+ {
+ OUString sName(SwStyleNameMapper::GetUIName(RES_POOLCOLL_LABEL_TABLE, OUString()));
+ m_xCaptionSequenceLB->set_active_text(sName);
+ }
+ else if( nType & TO_USER )
+ {
+ m_xAddStylesCB->set_label(m_sAddStyleUser);
+ }
+
+ m_xIdxOptionsFrame->set_visible( 0 != (nType & TO_INDEX) );
+
+ //object index
+ m_xFromObjFrame->set_visible( 0 != (nType & TO_OBJECT) );
+
+ //set control values from the proper TOXDescription
+ {
+ ApplyTOXDescription();
+ }
+ ModifyHdl();
+}
+
+void SwTOXSelectTabPage::ModifyHdl()
+{
+ if(!m_bWaitingInitialSettings)
+ {
+ FillTOXDescription();
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ pTOXDlg->CreateOrUpdateExample(pTOXDlg->GetCurrentTOXType().eType, TOX_PAGE_SELECT);
+ }
+}
+
+IMPL_LINK_NOARG(SwTOXSelectTabPage, ModifyListBoxHdl, weld::ComboBox&, void)
+{
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwTOXSelectTabPage, ModifyEntryHdl, weld::Entry&, void)
+{
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwTOXSelectTabPage, ModifySpinHdl, weld::SpinButton&, void)
+{
+ ModifyHdl();
+}
+
+IMPL_LINK(SwTOXSelectTabPage, CheckBoxHdl, weld::Toggleable&, rButton, void)
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
+ if(TOX_CONTENT == aCurType.eType)
+ {
+ //at least one of the three CheckBoxes must be checked
+ if (!m_xAddStylesCB->get_active() && !m_xFromHeadingsCB->get_active() && !m_xTOXMarksCB->get_active())
+ {
+ //TODO: InfoBox?
+ rButton.set_active(true);
+ }
+ m_xAddStylesPB->set_sensitive(m_xAddStylesCB->get_active());
+ }
+ if (TOX_USER == aCurType.eType)
+ {
+ m_xAddStylesPB->set_sensitive(m_xAddStylesCB->get_active());
+ }
+ else if (TOX_INDEX == aCurType.eType)
+ {
+ m_xAutoMarkPB->set_sensitive(m_xFromFileCB->get_active());
+ m_xUseFFCB->set_sensitive(m_xCollectSameCB->get_active() && !m_xUseDashCB->get_active());
+ m_xUseDashCB->set_sensitive(m_xCollectSameCB->get_active() && !m_xUseFFCB->get_active());
+ m_xCaseSensitiveCB->set_sensitive(m_xCollectSameCB->get_active());
+ }
+ else if (TOX_ILLUSTRATIONS == aCurType.eType
+ || TOX_TABLES == aCurType.eType
+ || TOX_OBJECTS == aCurType.eType)
+ {
+ bool const bEnable(m_xParaStyleCB->get_active());
+ m_xParaStyleLB->set_sensitive(bEnable);
+ }
+ ModifyHdl();
+};
+
+IMPL_LINK_NOARG(SwTOXSelectTabPage, RadioButtonHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xFromCaptionsRB->get_active();
+ m_xCaptionSequenceFT->set_sensitive(bEnable);
+ m_xCaptionSequenceLB->set_sensitive(bEnable);
+ m_xDisplayTypeFT->set_sensitive(bEnable);
+ m_xDisplayTypeLB->set_sensitive(bEnable);
+ ModifyHdl();
+}
+
+IMPL_LINK(SwTOXSelectTabPage, LanguageListBoxHdl, weld::ComboBox&, rBox, void)
+{
+ LanguageHdl(&rBox);
+}
+
+void SwTOXSelectTabPage::LanguageHdl(const weld::ComboBox* pBox)
+{
+ lang::Locale aLcl( LanguageTag( m_xLanguageLB->get_active_id() ).getLocale() );
+ Sequence< OUString > aSeq = m_pIndexEntryWrapper->GetAlgorithmList( aLcl );
+
+ if( !m_pIndexRes )
+ m_pIndexRes.reset(new IndexEntryResource());
+
+ OUString sOldString = m_xSortAlgorithmLB->get_active_id();
+ m_xSortAlgorithmLB->clear();
+
+ sal_Int32 nEnd = aSeq.getLength();
+ for( sal_Int32 nCnt = 0; nCnt < nEnd; ++nCnt )
+ {
+ const OUString sAlg(aSeq[ nCnt ]);
+ const OUString sUINm = m_pIndexRes->GetTranslation( sAlg );
+ m_xSortAlgorithmLB->append(sAlg, sUINm);
+ if( sAlg == sOldString )
+ m_xSortAlgorithmLB->set_active(nCnt);
+ }
+
+ if (m_xSortAlgorithmLB->get_active() == -1)
+ m_xSortAlgorithmLB->set_active(0);
+
+ if (pBox)
+ ModifyHdl();
+};
+
+IMPL_LINK_NOARG(SwTOXSelectTabPage, AddStylesHdl, weld::Button&, void)
+{
+ SwAddStylesDlg_Impl aDlg(GetFrameWeld(), static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell(),
+ m_aStyleArr);
+ aDlg.run();
+ ModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwTOXSelectTabPage, MenuEnableHdl, weld::Toggleable&, void)
+{
+ m_xAutoMarkPB->set_item_sensitive("edit", !m_sAutoMarkURL.isEmpty());
+}
+
+IMPL_LINK(SwTOXSelectTabPage, MenuExecuteHdl, const OUString&, rIdent, void)
+{
+ const OUString sSaveAutoMarkURL = m_sAutoMarkURL;
+
+ if (rIdent == "open")
+ {
+ m_sAutoMarkURL = lcl_CreateAutoMarkFileDlg(GetFrameWeld(),
+ m_sAutoMarkURL, m_sAutoMarkType, true);
+ }
+ else if (rIdent == "new" || rIdent == "edit")
+ {
+ bool bNew = (rIdent == "new");
+ if (bNew)
+ {
+ m_sAutoMarkURL = lcl_CreateAutoMarkFileDlg(GetFrameWeld(),
+ m_sAutoMarkURL, m_sAutoMarkType, false);
+ if (m_sAutoMarkURL.isEmpty())
+ return;
+ }
+
+ SwAutoMarkDlg_Impl aAutoMarkDlg(GetFrameWeld(), m_sAutoMarkURL, bNew);
+ if (RET_OK != aAutoMarkDlg.run() && bNew)
+ m_sAutoMarkURL = sSaveAutoMarkURL;
+ }
+}
+
+class SwTOXWidget
+{
+protected:
+ Link<SwTOXWidget&,void> m_aGetFocusLink;
+public:
+ virtual WindowType GetType() const = 0;
+ virtual void GrabFocus() = 0;
+ virtual void Hide() = 0;
+ virtual void set_grid_left_attach(int nPos) = 0;
+ virtual void get_extents_relative_to(weld::Widget& rRelative, int& x, int& y, int& width, int& height) = 0;
+ void SetGetFocusHdl(const Link<SwTOXWidget&,void>& rLink) { m_aGetFocusLink = rLink; }
+ virtual ~SwTOXWidget() {}
+};
+
+class SwTOXEdit : public SwTOXWidget
+{
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ SwFormToken m_aFormToken;
+ Link<SwTOXEdit&,void> m_aModifiedLink;
+ Link<SwTOXEdit&,void> m_aPrevNextControlLink;
+ bool m_bNextControl;
+ SwTokenWindow* m_pParent;
+ std::unique_ptr<weld::Entry> m_xEntry;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+public:
+ SwTOXEdit(SwTokenWindow* pTokenWin, const SwFormToken& rToken)
+ : m_xBuilder(Application::CreateBuilder(pTokenWin->get_child_container(), "modules/swriter/ui/toxentrywidget.ui"))
+ , m_aFormToken(rToken)
+ , m_bNextControl(false)
+ , m_pParent(pTokenWin)
+ , m_xEntry(m_xBuilder->weld_entry("entry"))
+ {
+ m_xEntry->connect_changed(LINK(this, SwTOXEdit, ModifyHdl));
+ m_xEntry->connect_key_press(LINK(this, SwTOXEdit, KeyInputHdl));
+ m_xEntry->connect_focus_in(LINK(this, SwTOXEdit, FocusInHdl));
+ m_xEntry->set_tooltip_text(m_pParent->CreateQuickHelp(rToken));
+ }
+
+ virtual ~SwTOXEdit() override
+ {
+ m_pParent->get_child_container()->move(m_xEntry.get(), nullptr);
+ }
+
+ virtual WindowType GetType() const override
+ {
+ return WindowType::EDIT;
+ }
+
+ virtual void GrabFocus() override
+ {
+ m_xEntry->grab_focus();
+ }
+
+ virtual void Hide() override
+ {
+ m_xEntry->hide();
+ }
+
+ void Show()
+ {
+ m_xEntry->show();
+ }
+
+ void SetAccessibleName(const OUString& rName)
+ {
+ m_xEntry->set_accessible_name(rName);
+ }
+
+ virtual void set_grid_left_attach(int nPos) override
+ {
+ m_xEntry->set_grid_left_attach(nPos);
+ }
+
+ virtual void get_extents_relative_to(weld::Widget& rRelative, int& x, int& y, int& width, int& height) override
+ {
+ m_xEntry->get_extents_relative_to(rRelative, x, y, width, height);
+ }
+
+ OUString GetText() const
+ {
+ return m_xEntry->get_text();
+ }
+
+ void SetText(const OUString& rText)
+ {
+ m_xEntry->set_text(rText);
+ }
+
+ void get_selection_bounds(int& rStartPos, int& rEndPos)
+ {
+ m_xEntry->get_selection_bounds(rStartPos, rEndPos);
+ }
+
+ void select_region(int nStartPos, int nEndPos)
+ {
+ m_xEntry->select_region(nStartPos, nEndPos);
+ }
+
+ void SetModifyHdl(const Link<SwTOXEdit&,void>& rLink)
+ {
+ m_aModifiedLink = rLink;
+ }
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(FocusInHdl, weld::Widget&, void);
+
+ bool IsNextControl() const { return m_bNextControl; }
+ void SetPrevNextLink(const Link<SwTOXEdit&,void>& rLink) { m_aPrevNextControlLink = rLink; }
+
+ const SwFormToken& GetFormToken()
+ {
+ m_aFormToken.sText = m_xEntry->get_text();
+ return m_aFormToken;
+ }
+
+ void SetCharStyleName(const OUString& rSet, sal_uInt16 nPoolId)
+ {
+ m_aFormToken.sCharStyleName = rSet;
+ m_aFormToken.nPoolId = nPoolId;
+ }
+
+ void AdjustSize();
+};
+
+IMPL_LINK_NOARG(SwTOXEdit, ModifyHdl, weld::Entry&, void)
+{
+ m_aModifiedLink.Call(*this);
+}
+
+IMPL_LINK(SwTOXEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ bool bCall = false;
+ int nStartPos, nEndPos;
+ bool bStartIsEnd = !m_xEntry->get_selection_bounds(nStartPos, nEndPos);
+ int nMin = std::min(nStartPos, nEndPos);
+ const sal_Int32 nTextLen = GetText().getLength();
+ if ((bStartIsEnd && !nMin) || nMin == nTextLen)
+ {
+ vcl::KeyCode aCode = rKEvt.GetKeyCode();
+ if (aCode.GetCode() == KEY_RIGHT && nMin == nTextLen)
+ {
+ m_bNextControl = true;
+ bCall = true;
+ }
+ else if (aCode.GetCode() == KEY_LEFT && !nMin)
+ {
+ m_bNextControl = false;
+ bCall = true;
+ }
+ else if ( (aCode.GetCode() == KEY_F3) && aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ if (m_pParent)
+ {
+ m_pParent->SetFocus2theAllBtn();
+ }
+ }
+ if (bCall && m_aPrevNextControlLink.IsSet())
+ m_aPrevNextControlLink.Call(*this);
+ else
+ bCall = false;
+
+ }
+ return bCall;
+}
+
+IMPL_LINK_NOARG(SwTOXEdit, FocusInHdl, weld::Widget&, void)
+{
+ m_aGetFocusLink.Call(*this);
+}
+
+void SwTOXEdit::AdjustSize()
+{
+ auto nWidth = m_xEntry->get_pixel_size(GetText()).Width();
+ float fChars = nWidth / m_xEntry->get_approximate_digit_width();
+ m_xEntry->set_width_chars(std::max(1.0f, std::ceil(fChars)));
+}
+
+class SwTOXButton : public SwTOXWidget
+{
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ SwFormToken m_aFormToken;
+ Link<SwTOXButton&,void> m_aPrevNextControlLink;
+ bool m_bNextControl;
+ SwTokenWindow* m_pParent;
+ std::unique_ptr<weld::ToggleButton> m_xButton;
+public:
+ SwTOXButton(SwTokenWindow* pTokenWin, const SwFormToken& rToken)
+ : m_xBuilder(Application::CreateBuilder(pTokenWin->get_child_container(), "modules/swriter/ui/toxbuttonwidget.ui"))
+ , m_aFormToken(rToken)
+ , m_bNextControl(false)
+ , m_pParent(pTokenWin)
+ , m_xButton(m_xBuilder->weld_toggle_button("button"))
+ {
+ m_xButton->connect_key_press(LINK(this, SwTOXButton, KeyInputHdl));
+ m_xButton->connect_focus_in(LINK(this, SwTOXButton, FocusInHdl));
+ m_xButton->set_tooltip_text(m_pParent->CreateQuickHelp(rToken));
+ }
+
+ virtual ~SwTOXButton() override
+ {
+ m_pParent->get_child_container()->move(m_xButton.get(), nullptr);
+ }
+
+ virtual WindowType GetType() const override
+ {
+ return WindowType::PUSHBUTTON;
+ }
+
+ virtual void GrabFocus() override
+ {
+ m_xButton->grab_focus();
+ }
+
+ virtual void Hide() override
+ {
+ m_xButton->hide();
+ }
+
+ void Show()
+ {
+ m_xButton->show();
+ }
+
+ void SetAccessibleName(const OUString& rName)
+ {
+ m_xButton->set_accessible_name(rName);
+ }
+
+ virtual void set_grid_left_attach(int nPos) override
+ {
+ m_xButton->set_grid_left_attach(nPos);
+ }
+
+ void get_extents_relative_to(weld::Widget& rRelative, int& x, int& y, int& width, int& height) override
+ {
+ m_xButton->get_extents_relative_to(rRelative, x, y, width, height);
+ }
+
+ void Check(bool bCheck = true)
+ {
+ m_xButton->set_active(bCheck);
+ }
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(FocusInHdl, weld::Widget&, void);
+
+ bool IsNextControl() const {return m_bNextControl;}
+ void SetPrevNextLink(const Link<SwTOXButton&,void>& rLink) {m_aPrevNextControlLink = rLink;}
+ const SwFormToken& GetFormToken() const {return m_aFormToken;}
+
+ void SetCharStyleName(const OUString& rSet, sal_uInt16 nPoolId)
+ {
+ m_aFormToken.sCharStyleName = rSet;
+ m_aFormToken.nPoolId = nPoolId;
+ }
+
+ void SetTabPosition(SwTwips nSet)
+ { m_aFormToken.nTabStopPosition = nSet; }
+
+ void SetFillChar( sal_Unicode cSet )
+ { m_aFormToken.cTabFillChar = cSet; }
+
+ void SetTabAlign(SvxTabAdjust eAlign)
+ { m_aFormToken.eTabAlign = eAlign;}
+
+//---> i89791
+ //used for entry number format, in TOC only
+ //needed for different UI dialog position
+ void SetEntryNumberFormat(sal_uInt16 nSet) {
+ switch(nSet)
+ {
+ default:
+ case 0:
+ m_aFormToken.nChapterFormat = CF_NUMBER;
+ break;
+ case 1:
+ m_aFormToken.nChapterFormat = CF_NUM_NOPREPST_TITLE;
+ break;
+ }
+ }
+
+ void SetChapterInfo(sal_uInt16 nSet) {
+ switch(nSet)
+ {
+ default:
+ case 0:
+ m_aFormToken.nChapterFormat = CF_NUM_NOPREPST_TITLE;
+ break;
+ case 1:
+ m_aFormToken.nChapterFormat = CF_TITLE;
+ break;
+ case 2:
+ m_aFormToken.nChapterFormat = CF_NUMBER_NOPREPST;
+ break;
+ }
+ }
+
+ void SetOutlineLevel( sal_uInt16 nSet ) { m_aFormToken.nOutlineLevel = nSet;}//i53420
+
+ void SetText(const OUString& rText)
+ {
+ m_xButton->set_label(rText);
+ }
+
+ void SetLinkEnd()
+ {
+ OSL_ENSURE(TOKEN_LINK_START == m_aFormToken.eTokenType,
+ "call SetLinkEnd for link start only!");
+ m_aFormToken.eTokenType = TOKEN_LINK_END;
+ m_aFormToken.sText = SwForm::GetFormLinkEnd();
+ SetText(m_aFormToken.sText);
+ }
+
+ void SetLinkStart()
+ {
+ OSL_ENSURE(TOKEN_LINK_END == m_aFormToken.eTokenType,
+ "call SetLinkStart for link start only!");
+ m_aFormToken.eTokenType = TOKEN_LINK_START;
+ m_aFormToken.sText = SwForm::GetFormLinkStt();
+ SetText(m_aFormToken.sText);
+ }
+};
+
+IMPL_LINK(SwTOXButton, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ bool bCall = false;
+ vcl::KeyCode aCode = rKEvt.GetKeyCode();
+ if (aCode.GetCode() == KEY_RIGHT)
+ {
+ m_bNextControl = true;
+ bCall = true;
+ }
+ else if (aCode.GetCode() == KEY_LEFT)
+ {
+ m_bNextControl = false;
+ bCall = true;
+ }
+ else if (aCode.GetCode() == KEY_DELETE)
+ {
+ m_pParent->RemoveControl(this, true);
+ //this is invalid here
+ return true;
+ }
+ else if ( (aCode.GetCode() == KEY_F3) && aCode.IsShift() && !aCode.IsMod1() && !aCode.IsMod2() )
+ {
+ if (m_pParent)
+ {
+ m_pParent->SetFocus2theAllBtn();
+ }
+ }
+ if (bCall && m_aPrevNextControlLink.IsSet())
+ m_aPrevNextControlLink.Call(*this);
+ else
+ bCall = false;
+ return bCall;
+}
+
+IMPL_LINK_NOARG(SwTOXButton, FocusInHdl, weld::Widget&, void)
+{
+ m_aGetFocusLink.Call(*this);
+}
+
+namespace
+{
+ const TranslateId STR_AUTH_FIELD_ARY[] =
+ {
+ STR_AUTH_FIELD_IDENTIFIER,
+ STR_AUTH_FIELD_AUTHORITY_TYPE,
+ STR_AUTH_FIELD_ADDRESS,
+ STR_AUTH_FIELD_ANNOTE,
+ STR_AUTH_FIELD_AUTHOR,
+ STR_AUTH_FIELD_BOOKTITLE,
+ STR_AUTH_FIELD_CHAPTER,
+ STR_AUTH_FIELD_EDITION,
+ STR_AUTH_FIELD_EDITOR,
+ STR_AUTH_FIELD_HOWPUBLISHED,
+ STR_AUTH_FIELD_INSTITUTION,
+ STR_AUTH_FIELD_JOURNAL,
+ STR_AUTH_FIELD_MONTH,
+ STR_AUTH_FIELD_NOTE,
+ STR_AUTH_FIELD_NUMBER,
+ STR_AUTH_FIELD_ORGANIZATIONS,
+ STR_AUTH_FIELD_PAGES,
+ STR_AUTH_FIELD_PUBLISHER,
+ STR_AUTH_FIELD_SCHOOL,
+ STR_AUTH_FIELD_SERIES,
+ STR_AUTH_FIELD_TITLE,
+ STR_AUTH_FIELD_TYPE,
+ STR_AUTH_FIELD_VOLUME,
+ STR_AUTH_FIELD_YEAR,
+ STR_AUTH_FIELD_URL,
+ STR_AUTH_FIELD_CUSTOM1,
+ STR_AUTH_FIELD_CUSTOM2,
+ STR_AUTH_FIELD_CUSTOM3,
+ STR_AUTH_FIELD_CUSTOM4,
+ STR_AUTH_FIELD_CUSTOM5,
+ STR_AUTH_FIELD_ISBN,
+ STR_AUTH_FIELD_LOCAL_URL,
+ STR_AUTH_FIELD_TARGET_TYPE,
+ STR_AUTH_FIELD_TARGET_URL,
+ };
+}
+
+SwTOXEntryTabPage::SwTOXEntryTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/tocentriespage.ui", "TocEntriesPage", &rAttrSet)
+ , m_sDelimStr(SwResId(STR_DELIM))
+ , m_sNoCharStyle(SwResId(STR_NO_CHAR_STYLE))
+ , m_pCurrentForm(nullptr)
+ , m_bInLevelHdl(false)
+ , m_xTypeFT(m_xBuilder->weld_label("typeft"))
+ , m_xLevelFT(m_xBuilder->weld_label("levelft"))
+ , m_xLevelLB(m_xBuilder->weld_tree_view("level"))
+ , m_xAllLevelsPB(m_xBuilder->weld_button("all"))
+ , m_xEntryNoPB(m_xBuilder->weld_button("chapterno"))
+ , m_xEntryPB(m_xBuilder->weld_button("entrytext"))
+ , m_xTabPB(m_xBuilder->weld_button("tabstop"))
+ , m_xChapterInfoPB(m_xBuilder->weld_button("chapterinfo"))
+ , m_xPageNoPB(m_xBuilder->weld_button("pageno"))
+ , m_xHyperLinkPB(m_xBuilder->weld_button("hyperlink"))
+ , m_xFieldBox(m_xBuilder->weld_widget("fieldbox"))
+ , m_xAuthFieldsLB(m_xBuilder->weld_combo_box("authfield"))
+ , m_xAuthInsertPB(m_xBuilder->weld_button("insert"))
+ , m_xAuthRemovePB(m_xBuilder->weld_button("remove"))
+ , m_xCharStyleLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xEditStylePB(m_xBuilder->weld_button("edit"))
+ , m_xChapterEntryFT(m_xBuilder->weld_label("chapterentryft"))
+ , m_xChapterEntryLB(m_xBuilder->weld_combo_box("chapterentry"))
+ , m_xNumberFormatFT(m_xBuilder->weld_label("numberformatft"))
+ , m_xNumberFormatLB(m_xBuilder->weld_combo_box("numberformat"))
+ , m_xEntryOutlineLevelFT(m_xBuilder->weld_label("entryoutlinelevelft"))
+ , m_xEntryOutlineLevelNF(m_xBuilder->weld_spin_button("entryoutlinelevel"))
+ , m_xFillCharFT(m_xBuilder->weld_label("fillcharft"))
+ , m_xFillCharCB(m_xBuilder->weld_combo_box("fillchar"))
+ , m_xTabPosFT(m_xBuilder->weld_label("tabstopposft"))
+ , m_xTabPosMF(m_xBuilder->weld_metric_spin_button("tabstoppos", FieldUnit::CM))
+ , m_xAutoRightCB(m_xBuilder->weld_check_button("alignright"))
+ , m_xFormatFrame(m_xBuilder->weld_widget("formatframe"))
+ , m_xMainEntryStyleFT(m_xBuilder->weld_label("mainstyleft"))
+ , m_xMainEntryStyleLB(m_xBuilder->weld_combo_box("mainstyle"))
+ , m_xAlphaDelimCB(m_xBuilder->weld_check_button("alphadelim"))
+ , m_xCommaSeparatedCB(m_xBuilder->weld_check_button("commasep"))
+ , m_xRelToStyleCB(m_xBuilder->weld_check_button("reltostyle"))
+ , m_xSortingFrame(m_xBuilder->weld_widget("sortingframe"))
+ , m_xSortDocPosRB(m_xBuilder->weld_radio_button("sortpos"))
+ , m_xSortContentRB(m_xBuilder->weld_radio_button("sortcontents"))
+ , m_xSortKeyFrame(m_xBuilder->weld_widget("sortkeyframe"))
+ , m_xFirstKeyLB(m_xBuilder->weld_combo_box("key1lb"))
+ , m_xFirstSortUpRB(m_xBuilder->weld_toggle_button("up1cb"))
+ , m_xFirstSortDownRB(m_xBuilder->weld_toggle_button("down1cb"))
+ , m_xSecondKeyLB(m_xBuilder->weld_combo_box("key2lb"))
+ , m_xSecondSortUpRB(m_xBuilder->weld_toggle_button("up2cb"))
+ , m_xSecondSortDownRB(m_xBuilder->weld_toggle_button("down2cb"))
+ , m_xThirdKeyLB(m_xBuilder->weld_combo_box("key3lb"))
+ , m_xThirdSortUpRB(m_xBuilder->weld_toggle_button("up3cb"))
+ , m_xThirdSortDownRB(m_xBuilder->weld_toggle_button("down3cb"))
+ , m_xTokenWIN(new SwTokenWindow(m_xBuilder->weld_container("token")))
+{
+ const OUString sNoCharSortKey(SwResId(STR_NOSORTKEY));
+
+ m_sAuthTypeStr = m_xTypeFT->get_label();
+ m_sLevelStr = m_xLevelFT->get_label();
+ m_xAuthFieldsLB->make_sorted();
+ m_xTokenWIN->SetTabPage(this);
+
+ m_aLastTOXType.eType = TOXTypes(USHRT_MAX);
+ m_aLastTOXType.nIndex = 0;
+
+ SetExchangeSupport();
+ m_xEntryNoPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
+ m_xEntryPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
+ m_xChapterInfoPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
+ m_xPageNoPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
+ m_xTabPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
+ m_xHyperLinkPB->connect_clicked(LINK(this, SwTOXEntryTabPage, InsertTokenHdl));
+ m_xEditStylePB->connect_clicked(LINK(this, SwTOXEntryTabPage, EditStyleHdl));
+ m_xLevelLB->connect_changed(LINK(this, SwTOXEntryTabPage, LevelHdl));
+ m_xTokenWIN->SetButtonSelectedHdl(LINK(this, SwTOXEntryTabPage, TokenSelectedHdl));
+ m_xTokenWIN->SetModifyHdl(LINK(this, SwTOXEntryTabPage, ModifyHdl));
+ m_xCharStyleLB->connect_changed(LINK(this, SwTOXEntryTabPage, StyleSelectHdl));
+ m_xCharStyleLB->append_text(m_sNoCharStyle);
+ m_xChapterEntryLB->connect_changed(LINK(this, SwTOXEntryTabPage, ChapterInfoHdl));
+ m_xEntryOutlineLevelNF->connect_value_changed(LINK(this, SwTOXEntryTabPage, ChapterInfoOutlineHdl));
+ m_xNumberFormatLB->connect_changed(LINK(this, SwTOXEntryTabPage, NumberFormatHdl));
+
+ m_xTabPosMF->connect_value_changed(LINK(this, SwTOXEntryTabPage, TabPosHdl));
+ m_xFillCharCB->connect_changed(LINK(this, SwTOXEntryTabPage, FillCharHdl));
+ m_xAutoRightCB->connect_toggled(LINK(this, SwTOXEntryTabPage, AutoRightHdl));
+ m_xAuthInsertPB->connect_clicked(LINK(this, SwTOXEntryTabPage, RemoveInsertAuthHdl));
+ m_xAuthRemovePB->connect_clicked(LINK(this, SwTOXEntryTabPage, RemoveInsertAuthHdl));
+ m_xSortDocPosRB->connect_toggled(LINK(this, SwTOXEntryTabPage, SortKeyHdl));
+ m_xSortContentRB->connect_toggled(LINK(this, SwTOXEntryTabPage, SortKeyHdl));
+ m_xAllLevelsPB->connect_clicked(LINK(this, SwTOXEntryTabPage, AllLevelsHdl));
+
+ m_xAlphaDelimCB->connect_toggled(LINK(this, SwTOXEntryTabPage, ModifyClickHdl));
+ m_xCommaSeparatedCB->connect_toggled(LINK(this, SwTOXEntryTabPage, ModifyClickHdl));
+ m_xRelToStyleCB->connect_toggled(LINK(this, SwTOXEntryTabPage, ModifyClickHdl));
+
+ m_xFirstSortUpRB->set_active(true);
+ m_xSecondSortUpRB->set_active(true);
+ m_xThirdSortUpRB->set_active(true);
+
+ m_xFirstSortUpRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
+ m_xFirstSortDownRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
+ m_xSecondSortUpRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
+ m_xSecondSortDownRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
+ m_xThirdSortUpRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
+ m_xThirdSortDownRB->connect_toggled(LINK(this, SwTOXEntryTabPage, ToggleHdl));
+
+ FieldUnit aMetric = ::GetDfltMetric(false);
+ ::SetFieldUnit(*m_xTabPosMF, aMetric);
+
+ m_xSortDocPosRB->set_active(true);
+
+ m_xFillCharCB->set_entry_max_length(1);
+ m_xFillCharCB->append_text(OUString(' '));
+ m_xFillCharCB->append_text(OUString('.'));
+ m_xFillCharCB->append_text(OUString('-'));
+ m_xFillCharCB->append_text(OUString('_'));
+ m_xFillCharCB->append_text(OUString(u'\x2024')); // ONE DOT LEADER
+ m_xFillCharCB->append_text(OUString(u'\x2025')); // TWO DOT LEADER
+ m_xFillCharCB->append_text(OUString(u'\x2026')); // HORIZONTAL ELLIPSIS
+
+ m_xEditStylePB->set_sensitive(false);
+
+ //fill the types in
+ for (sal_uInt16 i = 0; i < AUTH_FIELD_END; ++i)
+ {
+ OUString sId(OUString::number(i));
+ m_xAuthFieldsLB->append(sId, SwResId(STR_AUTH_FIELD_ARY[i]));
+ }
+
+ m_xFirstKeyLB->append(OUString::number(USHRT_MAX), sNoCharSortKey);
+ m_xSecondKeyLB->append(OUString::number(USHRT_MAX), sNoCharSortKey);
+ m_xThirdKeyLB->append(OUString::number(USHRT_MAX), sNoCharSortKey);
+
+ for (sal_uInt16 i = 0; i < AUTH_FIELD_END; ++i)
+ {
+ const OUString sTmp(m_xAuthFieldsLB->get_text(i));
+ const OUString sEntryData(m_xAuthFieldsLB->get_id(i));
+ m_xFirstKeyLB->append(sEntryData, sTmp);
+ m_xSecondKeyLB->append(sEntryData, sTmp);
+ m_xThirdKeyLB->append(sEntryData, sTmp);
+ }
+ m_xFirstKeyLB->set_active(0);
+ m_xSecondKeyLB->set_active(0);
+ m_xThirdKeyLB->set_active(0);
+
+ // lock size of dialog. Determine the field box's widest possible
+ // configuration (tdf#149186) before doing so.
+ int nFieldBoxWidth = 0;
+ for (int eType = TOX_CITATION; eType >= TOX_INDEX; --eType)
+ {
+ ShowHideControls(eType);
+ nFieldBoxWidth = std::max<int>(m_xFieldBox->get_preferred_size().Width(), nFieldBoxWidth);
+ }
+ m_xFieldBox->set_size_request(nFieldBoxWidth, -1);
+ Size aPrefSize(m_xContainer->get_preferred_size());
+ m_xFieldBox->set_size_request(-1, -1);
+ m_xContainer->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+}
+
+SwTOXEntryTabPage::~SwTOXEntryTabPage()
+{
+ m_xTokenWIN.reset();
+
+ // tdf#135266 - remember last used entry level depending on the index type
+ if (const auto aSelectedIndex = m_xLevelLB->get_selected_index(); aSelectedIndex != -1)
+ {
+ auto& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
+ SwViewOption* pVOpt = const_cast<SwViewOption*>(rSh.GetViewOptions());
+ if (m_aLastTOXType == TOX_INDEX)
+ pVOpt->SetIdxEntryLvl(aSelectedIndex);
+ else
+ pVOpt->SetTocEntryLvl(aSelectedIndex);
+ }
+}
+
+IMPL_LINK_NOARG(SwTOXEntryTabPage, ModifyClickHdl, weld::Toggleable&, void)
+{
+ OnModify(true);
+}
+
+IMPL_LINK_NOARG(SwTOXEntryTabPage, ModifyHdl, LinkParamNone*, void)
+{
+ OnModify(false);
+}
+
+IMPL_LINK(SwTOXEntryTabPage, ToggleHdl, weld::Toggleable&, rToggle, void)
+{
+ if (&rToggle == m_xFirstSortUpRB.get())
+ m_xFirstSortDownRB->set_active(!m_xFirstSortUpRB->get_active());
+ else if (&rToggle == m_xFirstSortDownRB.get())
+ m_xFirstSortUpRB->set_active(!m_xFirstSortDownRB->get_active());
+ else if (&rToggle == m_xSecondSortUpRB.get())
+ m_xSecondSortDownRB->set_active(!m_xSecondSortUpRB->get_active());
+ else if (&rToggle == m_xSecondSortDownRB.get())
+ m_xSecondSortUpRB->set_active(!m_xSecondSortDownRB->get_active());
+ else if (&rToggle == m_xThirdSortUpRB.get())
+ m_xThirdSortDownRB->set_active(!m_xThirdSortUpRB->get_active());
+ else if (&rToggle == m_xThirdSortDownRB.get())
+ m_xThirdSortUpRB->set_active(!m_xThirdSortDownRB->get_active());
+}
+
+// bAllLevels is used as signal to change all levels of the example
+void SwTOXEntryTabPage::OnModify(bool bAllLevels)
+{
+ UpdateDescriptor();
+
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ if (pTOXDlg)
+ {
+ sal_uInt16 nCurLevel = m_xLevelLB->get_selected_index() + 1;
+ if (m_aLastTOXType.eType == TOX_CONTENT && bAllLevels)
+ nCurLevel = USHRT_MAX;
+ pTOXDlg->CreateOrUpdateExample(
+ pTOXDlg->GetCurrentTOXType().eType, TOX_PAGE_ENTRY, nCurLevel);
+ }
+}
+
+bool SwTOXEntryTabPage::FillItemSet( SfxItemSet* )
+{
+ // nothing to do
+ return true;
+}
+
+void SwTOXEntryTabPage::Reset( const SfxItemSet* )
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
+ m_pCurrentForm = pTOXDlg->GetForm(aCurType);
+ if(TOX_INDEX == aCurType.eType)
+ {
+ SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(aCurType);
+ const OUString& sMainEntryCharStyle = rDesc.GetMainEntryCharStyle();
+ if(!sMainEntryCharStyle.isEmpty())
+ {
+ if (m_xMainEntryStyleLB->find_text(sMainEntryCharStyle) == -1)
+ m_xMainEntryStyleLB->append_text(sMainEntryCharStyle);
+ m_xMainEntryStyleLB->set_active_text(sMainEntryCharStyle);
+ }
+ else
+ m_xMainEntryStyleLB->set_active_text(m_sNoCharStyle);
+ m_xAlphaDelimCB->set_active( bool(rDesc.GetIndexOptions() & SwTOIOptions::AlphaDelimiter) );
+ }
+ m_xRelToStyleCB->set_active(m_pCurrentForm->IsRelTabPos());
+ m_xCommaSeparatedCB->set_active(m_pCurrentForm->IsCommaSeparated());
+}
+
+void SwTOXEntryTabPage::ShowHideControls(int eType)
+{
+ bool bToxIsAuthorities = TOX_AUTHORITIES == eType;
+ bool bToxIsIndex = TOX_INDEX == eType;
+ bool bToxIsContent = TOX_CONTENT == eType;
+ bool bToxSupportsLinks = TOX_CONTENT == eType ||
+ TOX_ILLUSTRATIONS == eType ||
+ TOX_TABLES == eType ||
+ TOX_OBJECTS == eType ||
+ TOX_USER == eType;
+
+ //show or hide controls
+ m_xEntryNoPB->set_visible(bToxIsContent);
+ m_xHyperLinkPB->set_visible(bToxSupportsLinks);
+ m_xRelToStyleCB->set_visible(!bToxIsAuthorities);
+ m_xChapterInfoPB->set_visible(!bToxIsContent && !bToxIsAuthorities);
+ m_xEntryPB->set_visible(!bToxIsAuthorities);
+ m_xPageNoPB->set_visible(!bToxIsAuthorities);
+ m_xAuthFieldsLB->set_visible(bToxIsAuthorities);
+ m_xAuthInsertPB->set_visible(bToxIsAuthorities);
+ m_xAuthRemovePB->set_visible(bToxIsAuthorities);
+
+ m_xFormatFrame->set_visible(!bToxIsAuthorities);
+
+ m_xSortingFrame->set_visible(bToxIsAuthorities);
+ m_xSortKeyFrame->set_visible(bToxIsAuthorities);
+
+ m_xMainEntryStyleFT->set_visible(bToxIsIndex);
+ m_xMainEntryStyleLB->set_visible(bToxIsIndex);
+ m_xAlphaDelimCB->set_visible(bToxIsIndex);
+ m_xCommaSeparatedCB->set_visible(bToxIsIndex);
+}
+
+void SwTOXEntryTabPage::ActivatePage( const SfxItemSet& /*rSet*/)
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ const CurTOXType aCurType = pTOXDlg->GetCurrentTOXType();
+
+ m_pCurrentForm = pTOXDlg->GetForm(aCurType);
+ if( !( m_aLastTOXType == aCurType ))
+ {
+ bool bToxIsAuthorities = TOX_AUTHORITIES == aCurType.eType;
+ bool bToxIsIndex = TOX_INDEX == aCurType.eType;
+
+ m_xLevelLB->clear();
+ for(sal_uInt16 i = 1; i < m_pCurrentForm->GetFormMax(); i++)
+ {
+ if(bToxIsAuthorities)
+ m_xLevelLB->append_text( SwAuthorityFieldType::GetAuthTypeName(
+ static_cast<ToxAuthorityType>(i - 1)) );
+ else if( bToxIsIndex )
+ {
+ if(i == 1)
+ m_xLevelLB->append_text( m_sDelimStr );
+ else
+ m_xLevelLB->append_text( OUString::number(i - 1) );
+ }
+ else
+ m_xLevelLB->append_text(OUString::number(i));
+ }
+ if(bToxIsAuthorities)
+ {
+ SwWrtShell& rSh = pTOXDlg->GetWrtShell();
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ rSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ if(pFType)
+ {
+ if(pFType->IsSortByDocument())
+ m_xSortDocPosRB->set_active(true);
+ else
+ {
+ m_xSortContentRB->set_active(true);
+ const sal_uInt16 nKeyCount = pFType->GetSortKeyCount();
+ if(0 < nKeyCount)
+ {
+ const SwTOXSortKey* pKey = pFType->GetSortKey(0);
+ m_xFirstKeyLB->set_active_id(OUString::number(pKey->eField));
+ m_xFirstSortUpRB->set_active(pKey->bSortAscending);
+ m_xFirstSortDownRB->set_active(!pKey->bSortAscending);
+ }
+ if(1 < nKeyCount)
+ {
+ const SwTOXSortKey* pKey = pFType->GetSortKey(1);
+ m_xSecondKeyLB->set_active_id(OUString::number(pKey->eField));
+ m_xSecondSortUpRB->set_active(pKey->bSortAscending);
+ m_xSecondSortDownRB->set_active(!pKey->bSortAscending);
+ }
+ if(2 < nKeyCount)
+ {
+ const SwTOXSortKey* pKey = pFType->GetSortKey(2);
+ m_xThirdKeyLB->set_active_id(OUString::number(pKey->eField));
+ m_xThirdSortUpRB->set_active(pKey->bSortAscending);
+ m_xThirdSortDownRB->set_active(!pKey->bSortAscending);
+ }
+ }
+ }
+ SortKeyHdl(m_xSortDocPosRB->get_active() ? *m_xSortDocPosRB : *m_xSortContentRB);
+ m_xLevelFT->set_label(m_sAuthTypeStr);
+ }
+ else
+ m_xLevelFT->set_label(m_sLevelStr);
+
+ // tdf#135266 - remember last used entry level depending on the index type
+ m_xLevelLB->select(bToxIsIndex ? pTOXDlg->GetWrtShell().GetViewOptions()->GetIdxEntryLvl()
+ : pTOXDlg->GetWrtShell().GetViewOptions()->GetTocEntryLvl());
+
+
+ //show or hide controls
+ ShowHideControls(aCurType.eType);
+ }
+ m_aLastTOXType = aCurType;
+
+ //invalidate PatternWindow
+ m_xTokenWIN->SetInvalid();
+ LevelHdl(*m_xLevelLB);
+}
+
+void SwTOXEntryTabPage::UpdateDescriptor()
+{
+ WriteBackLevel();
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ SwTOXDescription& rDesc = pTOXDlg->GetTOXDescription(m_aLastTOXType);
+ if(TOX_INDEX == m_aLastTOXType.eType)
+ {
+ const OUString sTemp(m_xMainEntryStyleLB->get_active_text());
+ rDesc.SetMainEntryCharStyle(m_sNoCharStyle == sTemp ? OUString(): sTemp);
+ SwTOIOptions nIdxOptions = rDesc.GetIndexOptions() & ~SwTOIOptions::AlphaDelimiter;
+ if (m_xAlphaDelimCB->get_active())
+ nIdxOptions |= SwTOIOptions::AlphaDelimiter;
+ rDesc.SetIndexOptions(nIdxOptions);
+ }
+ else if (TOX_AUTHORITIES == m_aLastTOXType.eType)
+ {
+ rDesc.SetSortByDocument(m_xSortDocPosRB->get_active());
+ SwTOXSortKey aKey1, aKey2, aKey3;
+ aKey1.eField = static_cast<ToxAuthorityField>(m_xFirstKeyLB->get_active_id().toInt32());
+ aKey1.bSortAscending = m_xFirstSortUpRB->get_active();
+ aKey2.eField = static_cast<ToxAuthorityField>(m_xSecondKeyLB->get_active_id().toInt32());
+ aKey2.bSortAscending = m_xSecondSortUpRB->get_active();
+ aKey3.eField = static_cast<ToxAuthorityField>(m_xThirdKeyLB->get_active_id().toInt32());
+ aKey3.bSortAscending = m_xThirdSortUpRB->get_active();
+
+ rDesc.SetSortKeys(aKey1, aKey2, aKey3);
+ }
+ SwForm* pCurrentForm = pTOXDlg->GetForm(m_aLastTOXType);
+ if (m_xRelToStyleCB->get_visible())
+ pCurrentForm->SetRelTabPos(m_xRelToStyleCB->get_active());
+ if (m_xCommaSeparatedCB->get_visible())
+ pCurrentForm->SetCommaSeparated(m_xCommaSeparatedCB->get_active());
+}
+
+DeactivateRC SwTOXEntryTabPage::DeactivatePage( SfxItemSet* /*pSet*/)
+{
+ UpdateDescriptor();
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SwTOXEntryTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwTOXEntryTabPage>(pPage, pController, *rAttrSet);
+}
+
+IMPL_LINK_NOARG(SwTOXEntryTabPage, EditStyleHdl, weld::Button&, void)
+{
+ if (m_xCharStyleLB->get_active() != -1)
+ {
+ SfxStringItem aStyle(SID_STYLE_EDIT, m_xCharStyleLB->get_active_text());
+ SfxUInt16Item aFamily(SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Char));
+ static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell().
+ GetView().GetViewFrame().GetDispatcher()->ExecuteList(SID_STYLE_EDIT,
+ SfxCallMode::SYNCHRON,
+ { &aStyle, &aFamily });
+ }
+}
+
+IMPL_LINK(SwTOXEntryTabPage, RemoveInsertAuthHdl, weld::Button&, rButton, void)
+{
+ bool bInsert = &rButton == m_xAuthInsertPB.get();
+ if(bInsert)
+ {
+ sal_Int32 nSelPos = m_xAuthFieldsLB->get_active();
+ const OUString sToInsert(m_xAuthFieldsLB->get_active_text());
+ SwFormToken aInsert(TOKEN_AUTHORITY);
+ aInsert.nAuthorityField = m_xAuthFieldsLB->get_id(nSelPos).toUInt32();
+ m_xTokenWIN->InsertAtSelection(aInsert);
+ m_xAuthFieldsLB->remove_text(sToInsert);
+ m_xAuthFieldsLB->set_active(nSelPos ? nSelPos - 1 : 0);
+ }
+ else
+ {
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(WindowType::EDIT != pCtrl->GetType(), "Remove should be disabled");
+ if (WindowType::EDIT != pCtrl->GetType())
+ {
+ //fill it into the ListBox
+ const SwFormToken& rToken = static_cast<SwTOXButton*>(pCtrl)->GetFormToken();
+ PreTokenButtonRemoved(rToken);
+ m_xTokenWIN->RemoveControl(static_cast<SwTOXButton*>(pCtrl));
+ }
+ }
+ ModifyHdl(nullptr);
+}
+
+void SwTOXEntryTabPage::PreTokenButtonRemoved(const SwFormToken& rToken)
+{
+ //fill it into the ListBox
+ sal_uInt32 nData = rToken.nAuthorityField;
+ m_xAuthFieldsLB->append(OUString::number(nData), SwResId(STR_AUTH_FIELD_ARY[nData]));
+}
+
+void SwTOXEntryTabPage::SetFocus2theAllBtn()
+{
+ m_xAllLevelsPB->grab_focus();
+}
+
+// This function initializes the default value in the Token
+// put here the UI dependent initializations
+IMPL_LINK(SwTOXEntryTabPage, InsertTokenHdl, weld::Button&, rBtn, void)
+{
+ FormTokenType eTokenType = TOKEN_ENTRY_NO;
+ OUString sCharStyle;
+ sal_uInt16 nChapterFormat = CF_NUMBER; // i89791
+ if (&rBtn == m_xEntryNoPB.get())
+ {
+ eTokenType = TOKEN_ENTRY_NO;
+ }
+ else if (&rBtn == m_xEntryPB.get())
+ {
+ if( TOX_CONTENT == m_pCurrentForm->GetTOXType() )
+ {
+ eTokenType = TOKEN_ENTRY_TEXT;
+ }
+ else
+ {
+ eTokenType = TOKEN_ENTRY;
+ }
+ }
+ else if (&rBtn == m_xChapterInfoPB.get())
+ {
+ eTokenType = TOKEN_CHAPTER_INFO;
+ nChapterFormat = CF_NUM_NOPREPST_TITLE; // i89791
+ }
+ else if (&rBtn == m_xPageNoPB.get())
+ {
+ eTokenType = TOKEN_PAGE_NUMS;
+ }
+ else if (&rBtn == m_xHyperLinkPB.get())
+ {
+ eTokenType = TOKEN_LINK_START;
+ sCharStyle = SwResId(STR_POOLCHR_TOXJUMP);
+ }
+ else if (&rBtn == m_xTabPB.get())
+ {
+ eTokenType = TOKEN_TAB_STOP;
+ }
+ SwFormToken aInsert(eTokenType);
+ aInsert.sCharStyleName = sCharStyle;
+ aInsert.nTabStopPosition = 0;
+ aInsert.nChapterFormat = nChapterFormat; // i89791
+ m_xTokenWIN->InsertAtSelection(aInsert);
+ ModifyHdl(nullptr);
+}
+
+IMPL_LINK_NOARG(SwTOXEntryTabPage, AllLevelsHdl, weld::Button&, void)
+{
+ //get current level
+ //write it into all levels
+ if(m_xTokenWIN->IsValid())
+ {
+ const OUString sNewToken = m_xTokenWIN->GetPattern();
+ for(sal_uInt16 i = 1; i < m_pCurrentForm->GetFormMax(); i++)
+ m_pCurrentForm->SetPattern(i, sNewToken);
+
+ OnModify(true);
+ }
+}
+
+void SwTOXEntryTabPage::WriteBackLevel()
+{
+ if(m_xTokenWIN->IsValid())
+ {
+ const OUString sNewToken = m_xTokenWIN->GetPattern();
+ const sal_uInt16 nLastLevel = m_xTokenWIN->GetLastLevel();
+ if(nLastLevel != USHRT_MAX)
+ m_pCurrentForm->SetPattern(nLastLevel + 1, sNewToken);
+ }
+}
+
+IMPL_LINK(SwTOXEntryTabPage, LevelHdl, weld::TreeView&, rBox, void)
+{
+ if(m_bInLevelHdl)
+ return;
+ m_bInLevelHdl = true;
+ WriteBackLevel();
+
+ const sal_uInt16 nLevel = rBox.get_selected_index();
+ m_xTokenWIN->SetForm(*m_pCurrentForm, nLevel);
+ if(TOX_AUTHORITIES == m_pCurrentForm->GetTOXType())
+ {
+ //fill the types in
+ m_xAuthFieldsLB->clear();
+ for( sal_uInt32 i = 0; i < AUTH_FIELD_END; i++)
+ {
+ m_xAuthFieldsLB->append(OUString::number(i), SwResId(STR_AUTH_FIELD_ARY[i]));
+ }
+
+ // #i21237#
+ SwFormTokens aPattern = m_pCurrentForm->GetPattern(nLevel + 1);
+
+ for(const auto& aToken : aPattern)
+ {
+ if(TOKEN_AUTHORITY == aToken.eTokenType)
+ {
+ sal_uInt32 nSearch = aToken.nAuthorityField;
+ int nLstBoxPos = m_xAuthFieldsLB->find_id(OUString::number(nSearch));
+ OSL_ENSURE(nLstBoxPos != -1, "Entry not found?");
+ m_xAuthFieldsLB->remove(nLstBoxPos);
+ }
+ }
+ m_xAuthFieldsLB->set_active(0);
+ }
+ m_bInLevelHdl = false;
+ rBox.grab_focus();
+}
+
+IMPL_LINK_NOARG(SwTOXEntryTabPage, SortKeyHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xSortContentRB->get_active();
+ m_xSortKeyFrame->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SwTOXEntryTabPage, TokenSelectedHdl, SwFormToken&, rToken, void)
+{
+ if (!rToken.sCharStyleName.isEmpty())
+ m_xCharStyleLB->set_active_text(rToken.sCharStyleName);
+ else
+ m_xCharStyleLB->set_active_text(m_sNoCharStyle);
+
+ const OUString sEntry = m_xCharStyleLB->get_active_text();
+ m_xEditStylePB->set_sensitive(sEntry != m_sNoCharStyle);
+
+ if(rToken.eTokenType == TOKEN_CHAPTER_INFO)
+ {
+//---> i89791
+ switch(rToken.nChapterFormat)
+ {
+ default:
+ m_xChapterEntryLB->set_active(-1);//to alert the user
+ break;
+ case CF_NUM_NOPREPST_TITLE:
+ m_xChapterEntryLB->set_active(0);
+ break;
+ case CF_TITLE:
+ m_xChapterEntryLB->set_active(1);
+ break;
+ case CF_NUMBER_NOPREPST:
+ m_xChapterEntryLB->set_active(2);
+ break;
+ }
+//i53420
+
+ m_xEntryOutlineLevelNF->set_value(rToken.nOutlineLevel);
+ }
+
+//i53420
+ if(rToken.eTokenType == TOKEN_ENTRY_NO)
+ {
+ m_xEntryOutlineLevelNF->set_value(rToken.nOutlineLevel);
+ const sal_uInt16 nFormat =
+ rToken.nChapterFormat == CF_NUM_NOPREPST_TITLE ? 1 : 0;
+ m_xNumberFormatLB->set_active(nFormat);
+ }
+
+ bool bTabStop = TOKEN_TAB_STOP == rToken.eTokenType;
+ m_xFillCharFT->set_visible(bTabStop);
+ m_xFillCharCB->set_visible(bTabStop);
+ m_xTabPosFT->set_visible(bTabStop);
+ m_xTabPosMF->set_visible(bTabStop);
+ m_xAutoRightCB->set_visible(bTabStop);
+ m_xAutoRightCB->set_sensitive(bTabStop);
+ if(bTabStop)
+ {
+ m_xTabPosMF->set_value(m_xTabPosMF->normalize(rToken.nTabStopPosition), FieldUnit::TWIP);
+ m_xAutoRightCB->set_active(SvxTabAdjust::End == rToken.eTabAlign);
+ m_xFillCharCB->set_entry_text(OUString(rToken.cTabFillChar));
+ m_xTabPosFT->set_sensitive(!m_xAutoRightCB->get_active());
+ m_xTabPosMF->set_sensitive(!m_xAutoRightCB->get_active());
+ }
+ else
+ {
+ m_xTabPosMF->set_sensitive(false);
+ }
+
+ bool bIsChapterInfo = rToken.eTokenType == TOKEN_CHAPTER_INFO;
+ bool bIsEntryNumber = rToken.eTokenType == TOKEN_ENTRY_NO;
+ m_xChapterEntryFT->set_visible( bIsChapterInfo );
+ m_xChapterEntryLB->set_visible( bIsChapterInfo );
+ m_xEntryOutlineLevelFT->set_visible( bIsChapterInfo || bIsEntryNumber );
+ m_xEntryOutlineLevelNF->set_visible( bIsChapterInfo || bIsEntryNumber );
+ m_xNumberFormatFT->set_visible( bIsEntryNumber );
+ m_xNumberFormatLB->set_visible( bIsEntryNumber );
+
+ //now enable the visible buttons
+ //- inserting the same type of control is not allowed
+ //- some types of controls can only appear once (EntryText EntryNumber)
+
+ if (m_xEntryNoPB->get_visible())
+ {
+ m_xEntryNoPB->set_sensitive(TOKEN_ENTRY_NO != rToken.eTokenType );
+ }
+ if (m_xEntryPB->get_visible())
+ {
+ m_xEntryPB->set_sensitive(TOKEN_ENTRY_TEXT != rToken.eTokenType &&
+ !m_xTokenWIN->Contains(TOKEN_ENTRY_TEXT)
+ && !m_xTokenWIN->Contains(TOKEN_ENTRY));
+ }
+
+ if (m_xChapterInfoPB->get_visible())
+ {
+ m_xChapterInfoPB->set_sensitive(TOKEN_CHAPTER_INFO != rToken.eTokenType);
+ }
+ if (m_xPageNoPB->get_visible())
+ {
+ m_xPageNoPB->set_sensitive(TOKEN_PAGE_NUMS != rToken.eTokenType &&
+ !m_xTokenWIN->Contains(TOKEN_PAGE_NUMS));
+ }
+ if (m_xTabPB->get_visible())
+ {
+ m_xTabPB->set_sensitive(!bTabStop);
+ }
+ if (m_xHyperLinkPB->get_visible())
+ {
+ m_xHyperLinkPB->set_sensitive(TOKEN_LINK_START != rToken.eTokenType &&
+ TOKEN_LINK_END != rToken.eTokenType);
+ }
+ //table of authorities
+ if (m_xAuthInsertPB->get_visible())
+ {
+ bool bText = TOKEN_TEXT == rToken.eTokenType;
+ m_xAuthInsertPB->set_sensitive(bText && !m_xAuthFieldsLB->get_active_text().isEmpty());
+ m_xAuthRemovePB->set_sensitive(!bText);
+ }
+}
+
+IMPL_LINK(SwTOXEntryTabPage, StyleSelectHdl, weld::ComboBox&, rBox, void)
+{
+ OUString sEntry = rBox.get_active_text();
+ const sal_uInt16 nId = rBox.get_active_id().toUInt32();
+ const bool bEqualsNoCharStyle = sEntry == m_sNoCharStyle;
+ m_xEditStylePB->set_sensitive(!bEqualsNoCharStyle);
+ if (bEqualsNoCharStyle)
+ sEntry.clear();
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(pCtrl, "no active control?");
+ if(pCtrl)
+ {
+ if(WindowType::EDIT == pCtrl->GetType())
+ static_cast<SwTOXEdit*>(pCtrl)->SetCharStyleName(sEntry, nId);
+ else
+ static_cast<SwTOXButton*>(pCtrl)->SetCharStyleName(sEntry, nId);
+
+ }
+ ModifyHdl(nullptr);
+}
+
+IMPL_LINK(SwTOXEntryTabPage, ChapterInfoHdl, weld::ComboBox&, rBox, void)
+{
+ int nPos = rBox.get_active();
+ if (nPos != -1)
+ {
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(pCtrl, "no active control?");
+ if(pCtrl && WindowType::EDIT != pCtrl->GetType())
+ static_cast<SwTOXButton*>(pCtrl)->SetChapterInfo(nPos);
+ ModifyHdl(nullptr);
+ }
+}
+
+IMPL_LINK(SwTOXEntryTabPage, ChapterInfoOutlineHdl, weld::SpinButton&, rEdit, void)
+{
+ const sal_uInt16 nLevel = rEdit.get_value();
+
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(pCtrl, "no active control?");
+ if(pCtrl && WindowType::EDIT != pCtrl->GetType())
+ static_cast<SwTOXButton*>(pCtrl)->SetOutlineLevel(nLevel);
+
+ ModifyHdl(nullptr);
+}
+
+IMPL_LINK(SwTOXEntryTabPage, NumberFormatHdl, weld::ComboBox&, rBox, void)
+{
+ const sal_Int32 nPos = rBox.get_active();
+ if (nPos != -1)
+ {
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(pCtrl, "no active control?");
+ if(pCtrl && WindowType::EDIT != pCtrl->GetType())
+ {
+ static_cast<SwTOXButton*>(pCtrl)->SetEntryNumberFormat(nPos);//i89791
+ }
+ ModifyHdl(nullptr);
+ }
+}
+
+IMPL_LINK(SwTOXEntryTabPage, TabPosHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(pCtrl && WindowType::EDIT != pCtrl->GetType() &&
+ TOKEN_TAB_STOP == static_cast<SwTOXButton*>(pCtrl)->GetFormToken().eTokenType,
+ "no active style::TabStop control?");
+ if( pCtrl && WindowType::EDIT != pCtrl->GetType() )
+ {
+ static_cast<SwTOXButton*>(pCtrl)->SetTabPosition( static_cast< SwTwips >(
+ rEdit.denormalize(rEdit.get_value(FieldUnit::TWIP))));
+ }
+ ModifyHdl(nullptr);
+}
+
+IMPL_LINK(SwTOXEntryTabPage, FillCharHdl, weld::ComboBox&, rBox, void)
+{
+ SwTOXWidget* pCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(pCtrl && WindowType::EDIT != pCtrl->GetType() &&
+ TOKEN_TAB_STOP == static_cast<SwTOXButton*>(pCtrl)->GetFormToken().eTokenType,
+ "no active style::TabStop control?");
+ if (pCtrl && WindowType::EDIT != pCtrl->GetType())
+ {
+ sal_Unicode cSet;
+ if (!rBox.get_active_text().isEmpty())
+ cSet = rBox.get_active_text()[0];
+ else
+ cSet = ' ';
+ static_cast<SwTOXButton*>(pCtrl)->SetFillChar( cSet );
+ }
+ ModifyHdl(nullptr);
+}
+
+IMPL_LINK(SwTOXEntryTabPage, AutoRightHdl, weld::Toggleable&, rBox, void)
+{
+ //the most right style::TabStop is usually right aligned
+ SwTOXWidget* pCurCtrl = m_xTokenWIN->GetActiveControl();
+ OSL_ENSURE(WindowType::EDIT != pCurCtrl->GetType() &&
+ static_cast<SwTOXButton*>(pCurCtrl)->GetFormToken().eTokenType == TOKEN_TAB_STOP,
+ "no style::TabStop selected!");
+
+ const SwFormToken& rToken = static_cast<SwTOXButton*>(pCurCtrl)->GetFormToken();
+ bool bChecked = rBox.get_active();
+ if(rToken.eTokenType == TOKEN_TAB_STOP)
+ static_cast<SwTOXButton*>(pCurCtrl)->SetTabAlign(
+ bChecked ? SvxTabAdjust::End : SvxTabAdjust::Left);
+ m_xTabPosFT->set_sensitive(!bChecked);
+ m_xTabPosMF->set_sensitive(!bChecked);
+ ModifyHdl(nullptr);
+}
+
+void SwTOXEntryTabPage::SetWrtShell(SwWrtShell& rSh)
+{
+ SwDocShell* pDocSh = rSh.GetView().GetDocShell();
+ ::FillCharStyleListBox(*m_xCharStyleLB, pDocSh, true, true);
+ const OUString sDefault(SwResId(STR_POOLCHR_STANDARD));
+ for (int i = 0, nCount = m_xCharStyleLB->get_count(); i < nCount; ++i)
+ {
+ const OUString sEntry = m_xCharStyleLB->get_text(i);
+ if(sDefault != sEntry)
+ {
+ m_xMainEntryStyleLB->append(m_xCharStyleLB->get_id(i), sEntry);
+ }
+ }
+ m_xMainEntryStyleLB->set_active_text(SwStyleNameMapper::GetUIName(
+ RES_POOLCHR_IDX_MAIN_ENTRY, OUString()));
+}
+
+ const TranslateId STR_TOKEN_ARY[] =
+{
+ STR_TOKEN_ENTRY_NO,
+ STR_TOKEN_ENTRY, //mapped from original STR_TOKEN_ENTRY_TEXT,
+ STR_TOKEN_ENTRY,
+ STR_TOKEN_TAB_STOP,
+ {},
+ STR_TOKEN_PAGE_NUMS,
+ STR_TOKEN_CHAPTER_INFO,
+ STR_TOKEN_LINK_START,
+ STR_TOKEN_LINK_END,
+ STR_TOKEN_AUTHORITY
+};
+
+ const TranslateId STR_TOKEN_HELP_ARY[] =
+{
+ STR_TOKEN_HELP_ENTRY_NO,
+ STR_TOKEN_HELP_ENTRY, // mapped from original STR_TOKEN_HELP_ENTRY_TEXT,
+ STR_TOKEN_HELP_ENTRY,
+ STR_TOKEN_HELP_TAB_STOP,
+ STR_TOKEN_HELP_TEXT,
+ STR_TOKEN_HELP_PAGE_NUMS,
+ STR_TOKEN_HELP_CHAPTER_INFO,
+ STR_TOKEN_HELP_LINK_START,
+ STR_TOKEN_HELP_LINK_END,
+ STR_TOKEN_HELP_AUTHORITY
+};
+
+SwTokenWindow::SwTokenWindow(std::unique_ptr<weld::Container> xParent)
+ : m_pForm(nullptr)
+ , m_nLevel(0)
+ , m_bValid(false)
+ , m_sCharStyle(SwResId(STR_CHARSTYLE))
+ , m_pActiveCtrl(nullptr)
+ , m_aAdjustPositionsIdle("SwTokenWindow m_aAdjustPositionsIdle")
+ , m_pParent(nullptr)
+ , m_xParentWidget(std::move(xParent))
+ , m_xBuilder(Application::CreateBuilder(m_xParentWidget.get(), "modules/swriter/ui/tokenwidget.ui"))
+ , m_xContainer(m_xBuilder->weld_container("TokenWidget"))
+ , m_xLeftScrollWin(m_xBuilder->weld_button("left"))
+ , m_xCtrlParentWin(m_xBuilder->weld_container("ctrl"))
+ , m_xScrollWin(m_xBuilder->weld_scrolled_window("scrollwin"))
+ , m_xRightScrollWin(m_xBuilder->weld_button("right"))
+{
+ m_xScrollWin->connect_hadjustment_changed(LINK(this, SwTokenWindow, ScrollHdl));
+ m_xCtrlParentWin->connect_size_allocate(LINK(this, SwTokenWindow, AdjustPositionsHdl));
+
+ for (sal_uInt32 i = 0; i < TOKEN_END; ++i)
+ {
+ TranslateId pTextId = STR_TOKEN_ARY[i];
+ if (pTextId)
+ m_aButtonTexts[i] = SwResId(pTextId);
+
+ TranslateId pHelpId = STR_TOKEN_HELP_ARY[i];
+ m_aButtonHelpTexts[i] = SwResId(pHelpId);
+ }
+
+ m_sAccessibleName = SwResId(STR_STRUCTURE);
+ m_sAdditionalAccnameString1 = SwResId(STR_ADDITIONAL_ACCNAME_STRING1);
+ m_sAdditionalAccnameString2 = SwResId(STR_ADDITIONAL_ACCNAME_STRING2);
+ m_sAdditionalAccnameString3 = SwResId(STR_ADDITIONAL_ACCNAME_STRING3);
+
+ Link<weld::Button&,void> aLink(LINK(this, SwTokenWindow, ScrollBtnHdl));
+ m_xLeftScrollWin->connect_clicked(aLink);
+ m_xRightScrollWin->connect_clicked(aLink);
+}
+
+SwTokenWindow::~SwTokenWindow()
+{
+}
+
+void SwTokenWindow::SetForm(SwForm& rForm, sal_uInt16 nL)
+{
+ SetActiveControl(nullptr);
+ m_bValid = true;
+
+ if (m_pForm)
+ {
+ //apply current level settings to the form
+ m_aControlList.clear();
+ }
+
+ m_nLevel = nL;
+ m_pForm = &rForm;
+ //now the display
+ if(m_nLevel < MAXLEVEL || rForm.GetTOXType() == TOX_AUTHORITIES)
+ {
+ // #i21237#
+ SwFormTokens aPattern = m_pForm->GetPattern(m_nLevel + 1);
+ bool bLastWasText = false; //assure alternating text - code - text
+
+ SwTOXWidget* pSetActiveControl = nullptr;
+ for (const auto& aToken : aPattern) // #i21237#
+ {
+ if(TOKEN_TEXT == aToken.eTokenType)
+ {
+ SAL_WARN_IF(bLastWasText, "sw", "text following text is invalid");
+ SwTOXWidget* pCtrl = InsertItem(aToken.sText, aToken);
+ bLastWasText = true;
+ if (!GetActiveControl())
+ SetActiveControl(pCtrl);
+ }
+ else
+ {
+ if( !bLastWasText )
+ {
+ SwFormToken aTemp(TOKEN_TEXT);
+ SwTOXWidget* pCtrl = InsertItem(OUString(), aTemp);
+ if(!pSetActiveControl)
+ pSetActiveControl = pCtrl;
+ }
+
+ OUString sForm;
+ switch( aToken.eTokenType )
+ {
+ case TOKEN_ENTRY_NO: sForm = SwForm::GetFormEntryNum(); break;
+ case TOKEN_ENTRY_TEXT: sForm = SwForm::GetFormEntryText(); break;
+ case TOKEN_ENTRY: sForm = SwForm::GetFormEntry(); break;
+ case TOKEN_TAB_STOP: sForm = SwForm::GetFormTab(); break;
+ case TOKEN_PAGE_NUMS: sForm = SwForm::GetFormPageNums(); break;
+ case TOKEN_CHAPTER_INFO: sForm = SwForm::GetFormChapterMark(); break;
+ case TOKEN_LINK_START: sForm = SwForm::GetFormLinkStt(); break;
+ case TOKEN_LINK_END: sForm = SwForm::GetFormLinkEnd(); break;
+ case TOKEN_AUTHORITY: sForm = SwForm::GetFormAuth(); break;
+ default:; //prevent warning
+ }
+
+ InsertItem( sForm, aToken );
+ bLastWasText = false;
+ }
+ }
+ if(!bLastWasText)
+ {
+ SwFormToken aTemp(TOKEN_TEXT);
+ SwTOXWidget* pCtrl = InsertItem(OUString(), aTemp);
+ if(!pSetActiveControl)
+ pSetActiveControl = pCtrl;
+ }
+ SetActiveControl(pSetActiveControl);
+ }
+ AdjustScrolling();
+}
+
+void SwTokenWindow::SetActiveControl(SwTOXWidget* pSet)
+{
+ if (pSet == m_pActiveCtrl)
+ return;
+
+ m_pActiveCtrl = pSet;
+ if( !m_pActiveCtrl )
+ return;
+
+ m_pActiveCtrl->GrabFocus();
+ //it must be a SwTOXEdit
+ const SwFormToken* pFToken;
+ if( WindowType::EDIT == m_pActiveCtrl->GetType() )
+ pFToken = &static_cast<SwTOXEdit*>(m_pActiveCtrl)->GetFormToken();
+ else
+ pFToken = &static_cast<SwTOXButton*>(m_pActiveCtrl)->GetFormToken();
+
+ SwFormToken aTemp( *pFToken );
+ m_aButtonSelectedHdl.Call( aTemp );
+}
+
+SwTOXWidget* SwTokenWindow::InsertItem(const OUString& rText, const SwFormToken& rToken)
+{
+ SwTOXWidget* pRet = nullptr;
+
+ if (TOKEN_TEXT == rToken.eTokenType)
+ {
+ SwTOXEdit* pEdit = new SwTOXEdit(this, rToken);
+ pEdit->set_grid_left_attach(m_aControlList.size());
+
+ m_aControlList.emplace_back(pEdit);
+
+ pEdit->SetText(rText);
+ sal_uInt32 nIndex = GetControlIndex( TOKEN_TEXT );
+ OUString strName(m_sAccessibleName + OUString::number(nIndex));
+ if ( nIndex == 1 )
+ {
+ /*Press left or right arrow to choose the structure controls*/
+ strName += " (" + m_sAdditionalAccnameString2 + ", "
+ /*Press Ctrl+Alt+A to move focus for more operations*/
+ + m_sAdditionalAccnameString1 + ", "
+ /*Press Ctrl+Alt+B to move focus back to the current structure control*/
+ + m_sAdditionalAccnameString3 + ")";
+ }
+ pEdit->SetAccessibleName(strName);
+ pEdit->AdjustSize();
+ pEdit->SetModifyHdl(LINK(this, SwTokenWindow, EditResize ));
+ pEdit->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemHdl));
+ pEdit->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusHdl));
+ pEdit->Show();
+ pRet = pEdit;
+ }
+ else
+ {
+ SwTOXButton* pButton = new SwTOXButton(this, rToken);
+ pButton->set_grid_left_attach(m_aControlList.size());
+
+ m_aControlList.emplace_back(pButton);
+
+ pButton->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemBtnHdl));
+ pButton->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusBtnHdl));
+
+ if(TOKEN_AUTHORITY != rToken.eTokenType)
+ pButton->SetText(m_aButtonTexts[rToken.eTokenType]);
+ else
+ {
+ //use the first two chars as symbol
+ OUString sTmp(SwAuthorityFieldType::GetAuthFieldName(
+ static_cast<ToxAuthorityField>(rToken.nAuthorityField)));
+ pButton->SetText(sTmp.copy(0, 2));
+ }
+
+ sal_uInt32 nIndex = GetControlIndex( rToken.eTokenType );
+ OUString sAccName = m_aButtonHelpTexts[rToken.eTokenType];
+ if ( nIndex )
+ {
+ sAccName += " " + OUString::number(nIndex);
+ }
+ pButton->SetAccessibleName( sAccName );
+
+ pButton->Show();
+ pRet = pButton;
+ }
+
+ return pRet;
+}
+
+void SwTokenWindow::InsertAtSelection(const SwFormToken& rToken)
+{
+ OSL_ENSURE(m_pActiveCtrl, "no active control!");
+
+ if(!m_pActiveCtrl)
+ return;
+
+ SwFormToken aToInsertToken(rToken);
+
+ if(TOKEN_LINK_START == aToInsertToken.eTokenType)
+ {
+ //determine if start or end of hyperlink is appropriate
+ //eventually change a following link start into a link end
+ // groups of LS LE should be ignored
+ // <insert>
+ //LS <insert>
+ //LE <insert>
+ //<insert> LS
+ //<insert> LE
+ //<insert>
+ bool bPreStartLinkFound = false;
+ bool bPreEndLinkFound = false;
+
+ const SwTOXWidget* pControl = nullptr;
+ const SwTOXWidget* pExchange = nullptr;
+
+ auto it = m_aControlList.cbegin();
+ for( ; it != m_aControlList.cend() && m_pActiveCtrl != it->get(); ++it )
+ {
+ pControl = it->get();
+
+ if( WindowType::EDIT != pControl->GetType())
+ {
+ const SwFormToken& rNewToken =
+ static_cast<const SwTOXButton*>(pControl)->GetFormToken();
+
+ if( TOKEN_LINK_START == rNewToken.eTokenType )
+ {
+ bPreStartLinkFound = true;
+ pExchange = nullptr;
+ }
+ else if(TOKEN_LINK_END == rNewToken.eTokenType)
+ {
+ if( bPreStartLinkFound )
+ bPreStartLinkFound = false;
+ else
+ {
+ bPreEndLinkFound = false;
+ pExchange = pControl;
+ }
+ }
+ }
+ }
+
+ bool bPostLinkStartFound = false;
+
+ if(!bPreStartLinkFound && !bPreEndLinkFound)
+ {
+ for( ; it != m_aControlList.cend(); ++it )
+ {
+ pControl = it->get();
+
+ if( pControl != m_pActiveCtrl &&
+ WindowType::EDIT != pControl->GetType())
+ {
+ const SwFormToken& rNewToken =
+ static_cast<const SwTOXButton*>(pControl)->GetFormToken();
+
+ if( TOKEN_LINK_START == rNewToken.eTokenType )
+ {
+ if(bPostLinkStartFound)
+ break;
+ bPostLinkStartFound = true;
+ pExchange = pControl;
+ }
+ else if(TOKEN_LINK_END == rNewToken.eTokenType )
+ {
+ if(bPostLinkStartFound)
+ {
+ bPostLinkStartFound = false;
+ pExchange = nullptr;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if(bPreStartLinkFound)
+ {
+ aToInsertToken.eTokenType = TOKEN_LINK_END;
+ aToInsertToken.sText = m_aButtonTexts[TOKEN_LINK_END];
+ }
+
+ if(bPostLinkStartFound)
+ {
+ OSL_ENSURE(pExchange, "no control to exchange?");
+ if(pExchange)
+ {
+ const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetLinkEnd();
+ const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetText(m_aButtonTexts[TOKEN_LINK_END]);
+ }
+ }
+
+ if(bPreEndLinkFound)
+ {
+ OSL_ENSURE(pExchange, "no control to exchange?");
+
+ if(pExchange)
+ {
+ const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetLinkStart();
+ const_cast<SwTOXButton*>(static_cast<const SwTOXButton*>(pExchange))->SetText(m_aButtonTexts[TOKEN_LINK_START]);
+ }
+ }
+ }
+
+ //if the active control is text then insert a new button at the selection
+ //else replace the button
+ auto iterActive = std::find_if(m_aControlList.begin(), m_aControlList.end(),
+ [this](const auto& rControl)
+ {
+ SwTOXWidget* pCtrl = rControl.get();
+ return pCtrl == m_pActiveCtrl;
+ });
+
+ assert(iterActive != m_aControlList.end());
+ if (iterActive == m_aControlList.end())
+ return;
+
+ if (WindowType::EDIT == m_pActiveCtrl->GetType())
+ {
+ ++iterActive;
+
+ int nStartPos, nEndPos;
+ static_cast<SwTOXEdit*>(m_pActiveCtrl)->get_selection_bounds(nStartPos, nEndPos);
+
+ const OUString sEditText = static_cast<SwTOXEdit*>(m_pActiveCtrl)->GetText();
+ const OUString sLeft = sEditText.copy( 0, std::min(nStartPos, nEndPos) );
+ const OUString sRight = sEditText.copy( std::max(nStartPos, nEndPos) );
+
+ static_cast<SwTOXEdit*>(m_pActiveCtrl)->SetText(sLeft);
+ static_cast<SwTOXEdit*>(m_pActiveCtrl)->AdjustSize();
+
+ SwFormToken aTmpToken(TOKEN_TEXT);
+ SwTOXEdit* pEdit = new SwTOXEdit(this, aTmpToken);
+ iterActive = m_aControlList.emplace(iterActive, pEdit);
+
+ pEdit->SetText(sRight);
+ sal_uInt32 nIndex = GetControlIndex( TOKEN_TEXT );
+ OUString strName(m_sAccessibleName + OUString::number(nIndex));
+ if ( nIndex == 1)
+ {
+ /*Press left or right arrow to choose the structure controls*/
+ strName += " (" + m_sAdditionalAccnameString2 + ", "
+ /*Press Ctrl+Alt+A to move focus for more operations*/
+ + m_sAdditionalAccnameString1 + ", "
+ /*Press Ctrl+Alt+B to move focus back to the current structure control*/
+ + m_sAdditionalAccnameString3 + ")";
+ }
+ pEdit->SetAccessibleName(strName);
+ pEdit->AdjustSize();
+ pEdit->SetModifyHdl(LINK(this, SwTokenWindow, EditResize ));
+ pEdit->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemHdl));
+ pEdit->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusHdl));
+ pEdit->Show();
+ }
+ else
+ {
+ m_pActiveCtrl->Hide();
+ m_pActiveCtrl = nullptr;
+ iterActive = m_aControlList.erase(iterActive);
+ }
+
+ //now the new button
+ SwTOXButton* pButton = new SwTOXButton(this, aToInsertToken);
+ m_aControlList.emplace(iterActive, pButton);
+
+ pButton->SetPrevNextLink(LINK(this, SwTokenWindow, NextItemBtnHdl));
+ pButton->SetGetFocusHdl(LINK(this, SwTokenWindow, TbxFocusBtnHdl));
+
+ if (TOKEN_AUTHORITY != aToInsertToken.eTokenType)
+ {
+ pButton->SetText(m_aButtonTexts[aToInsertToken.eTokenType]);
+ }
+ else
+ {
+ //use the first two chars as symbol
+ OUString sTmp(SwAuthorityFieldType::GetAuthFieldName(
+ static_cast<ToxAuthorityField>(aToInsertToken.nAuthorityField)));
+ pButton->SetText(sTmp.copy(0, 2));
+ }
+
+ pButton->Check();
+ pButton->Show();
+ SetActiveControl(pButton);
+
+ AdjustPositions();
+}
+
+void SwTokenWindow::RemoveControl(const SwTOXButton* pDel, bool bInternalCall)
+{
+ if (bInternalCall && TOX_AUTHORITIES == m_pForm->GetTOXType())
+ m_pParent->PreTokenButtonRemoved(pDel->GetFormToken());
+
+ auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
+ [pDel](const auto& rControl)
+ {
+ SwTOXWidget* pCtrl = rControl.get();
+ return pCtrl == pDel;
+ });
+ assert(it != m_aControlList.end()); //Control does not exist!
+ if (it == m_aControlList.end())
+ return;
+
+ // the two neighbours of the box must be merged
+ // the properties of the right one will be lost
+ assert(it != m_aControlList.begin() && it != m_aControlList.end() - 1); //Button at first or last position?
+ if (it == m_aControlList.begin() || it == m_aControlList.end() - 1)
+ return;
+
+ auto itLeft = it, itRight = it;
+ --itLeft;
+ ++itRight;
+ SwTOXWidget* pLeftEdit = itLeft->get();
+ SwTOXWidget* pRightEdit = itRight->get();
+
+ static_cast<SwTOXEdit*>(pLeftEdit)->SetText(static_cast<SwTOXEdit*>(pLeftEdit)->GetText() +
+ static_cast<SwTOXEdit*>(pRightEdit)->GetText());
+ static_cast<SwTOXEdit*>(pLeftEdit)->AdjustSize();
+
+ m_pActiveCtrl->Hide();
+ m_pActiveCtrl = nullptr;
+
+ m_aControlList.erase(itRight);
+ m_aControlList.erase(it);
+
+ SetActiveControl(pLeftEdit);
+ AdjustPositions();
+ m_aModifyHdl.Call(nullptr);
+}
+
+IMPL_LINK_NOARG(SwTokenWindow, AdjustPositionsHdl, const Size&, void)
+{
+ AdjustScrolling();
+}
+
+void SwTokenWindow::AdjustPositions()
+{
+ for (size_t i = 0; i < m_aControlList.size(); ++i)
+ m_aControlList[i]->set_grid_left_attach(i);
+ AdjustScrolling();
+}
+
+void SwTokenWindow::MoveControls(tools::Long nOffset)
+{
+ m_xScrollWin->hadjustment_set_value(nOffset);
+}
+
+IMPL_LINK_NOARG(SwTokenWindow, ScrollHdl, weld::ScrolledWindow&, void)
+{
+ AdjustScrolling();
+}
+
+void SwTokenWindow::AdjustScrolling()
+{
+ if (m_aControlList.size() <= 1)
+ return;
+
+ //validate scroll buttons
+
+ auto nLeft = m_xScrollWin->hadjustment_get_value();
+ auto nSpace = m_xScrollWin->hadjustment_get_page_size();
+ auto nWidth = m_xScrollWin->hadjustment_get_upper();
+
+ bool bEnable = nWidth > nSpace;
+
+ //the active control must be visible
+ if (bEnable && m_pActiveCtrl)
+ {
+ int x, y, width, height;
+ m_pActiveCtrl->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
+
+ if (x < nLeft || x + width > nLeft + nSpace)
+ {
+ MoveControls(x);
+ nLeft = x;
+ }
+
+ m_xLeftScrollWin->set_sensitive(nLeft > 0);
+ m_xRightScrollWin->set_sensitive(nLeft + nSpace < nWidth);
+ }
+ else
+ {
+ //if the control fits into the space then the first control must be at position 0
+ m_xRightScrollWin->set_sensitive(false);
+ m_xLeftScrollWin->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SwTokenWindow, ScrollBtnHdl, weld::Button&, rBtn, void)
+{
+ if (m_aControlList.empty())
+ return;
+
+ const auto nSpace = m_xScrollWin->hadjustment_get_page_size();
+ const auto nWidth = m_xScrollWin->hadjustment_get_upper();
+ const auto nLeft = m_xScrollWin->hadjustment_get_value();
+
+ tools::Long nMove = nLeft;
+ if (&rBtn == m_xLeftScrollWin.get())
+ {
+ //find the first completely visible control (left edge visible)
+ auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
+ [this, nLeft](const auto& rControl)
+ {
+ SwTOXWidget* pCtrl = rControl.get();
+
+ int x, y, width, height;
+ pCtrl->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
+
+ return x >= nLeft;
+ });
+ if (it != m_aControlList.end())
+ {
+ if (it == m_aControlList.begin())
+ {
+ nMove = 0;
+ }
+ else
+ {
+ //move the left neighbor to the start position
+ auto itLeft = it;
+ --itLeft;
+ SwTOXWidget* pLeft = itLeft->get();
+
+ int x, y, width, height;
+ pLeft->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
+
+ nMove = x;
+ }
+ }
+ }
+ else
+ {
+ //find the first completely visible control (right edge visible)
+ auto it = std::find_if(m_aControlList.rbegin(), m_aControlList.rend(),
+ [this, nLeft, nSpace](const auto& rControl) {
+ SwTOXWidget* pCtrl = rControl.get();
+
+ int x, y, width, height;
+ pCtrl->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
+
+ auto nXPos = x + width;
+ return nXPos <= nLeft + nSpace;
+ });
+ if (it != m_aControlList.rend() && it != m_aControlList.rbegin())
+ {
+ //move the right neighbor to the right edge right aligned
+ auto itRight = it;
+ --itRight;
+ SwTOXWidget* pRight = itRight->get();
+
+ int x, y, width, height;
+ pRight->get_extents_relative_to(*m_xCtrlParentWin, x, y, width, height);
+
+ nMove = x + width - nSpace;
+ }
+
+ //move it left until it's completely visible
+ }
+
+ if (nMove != nLeft)
+ {
+ // move the complete list
+ MoveControls(nMove);
+ m_xLeftScrollWin->set_sensitive(nMove > 0);
+ m_xRightScrollWin->set_sensitive(nMove + nSpace < nWidth);
+ }
+}
+
+OUString SwTokenWindow::GetPattern() const
+{
+ OUStringBuffer sRet;
+
+ for (const auto& elem : m_aControlList)
+ {
+ const SwTOXWidget* pCtrl = elem.get();
+
+ const SwFormToken &rNewToken = pCtrl->GetType() == WindowType::EDIT
+ ? const_cast<SwTOXEdit*>(static_cast<const SwTOXEdit*>(pCtrl))->GetFormToken()
+ : static_cast<const SwTOXButton*>(pCtrl)->GetFormToken();
+
+ //TODO: prevent input of TOX_STYLE_DELIMITER in KeyInput
+ sRet.append(rNewToken.GetString());
+ }
+
+ return sRet.makeStringAndClear();
+}
+
+// Check if a control of the specified TokenType is already contained in the list
+bool SwTokenWindow::Contains(FormTokenType eSearchFor) const
+{
+ bool bRet = false;
+
+ for (const auto& elem : m_aControlList)
+ {
+ const SwTOXWidget* pCtrl = elem.get();
+ const SwFormToken &rNewToken = pCtrl->GetType() == WindowType::EDIT
+ ? const_cast<SwTOXEdit*>(static_cast<const SwTOXEdit*>(pCtrl))->GetFormToken()
+ : static_cast<const SwTOXButton*>(pCtrl)->GetFormToken();
+
+ if (eSearchFor == rNewToken.eTokenType)
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+OUString SwTokenWindow::CreateQuickHelp(const SwFormToken& rToken)
+{
+ OUString sEntry;
+ if (rToken.eTokenType != TOKEN_AUTHORITY)
+ sEntry = m_aButtonHelpTexts[rToken.eTokenType];
+ else
+ {
+ sEntry += SwAuthorityFieldType::GetAuthFieldName(
+ static_cast<ToxAuthorityField>(rToken.nAuthorityField));
+ }
+
+ if (rToken.eTokenType != TOKEN_TAB_STOP)
+ {
+ if (!rToken.sCharStyleName.isEmpty())
+ {
+ sEntry += " " + m_sCharStyle + rToken.sCharStyleName;
+ }
+ }
+
+ return sEntry;
+}
+
+IMPL_LINK(SwTokenWindow, EditResize, SwTOXEdit&, rEdit, void)
+{
+ rEdit.AdjustSize();
+ AdjustPositions();
+ m_aModifyHdl.Call(nullptr);
+}
+
+IMPL_LINK(SwTokenWindow, NextItemHdl, SwTOXEdit&, rEdit, void)
+{
+ auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
+ [&rEdit](const auto& rControl)
+ {
+ SwTOXWidget* pCtrl = rControl.get();
+ return pCtrl == &rEdit;
+ });
+
+ if (it == m_aControlList.end())
+ return;
+
+ auto itTest = it;
+ ++itTest;
+
+ if ((it != m_aControlList.begin() && !rEdit.IsNextControl()) ||
+ (itTest != m_aControlList.end() && rEdit.IsNextControl()))
+ {
+ auto iterFocus = it;
+ rEdit.IsNextControl() ? ++iterFocus : --iterFocus;
+
+ SwTOXWidget *pCtrlFocus = iterFocus->get();
+ pCtrlFocus->GrabFocus();
+ static_cast<SwTOXButton*>(pCtrlFocus)->Check();
+
+ AdjustScrolling();
+ }
+}
+
+IMPL_LINK(SwTokenWindow, TbxFocusHdl, SwTOXWidget&, rControl, void)
+{
+ SwTOXEdit* pEdit = static_cast<SwTOXEdit*>(&rControl);
+ for (const auto& aControl : m_aControlList)
+ {
+ SwTOXWidget* pCtrl = aControl.get();
+ if (pCtrl && pCtrl->GetType() != WindowType::EDIT)
+ static_cast<SwTOXButton*>(pCtrl)->Check(false);
+ }
+
+ SetActiveControl(pEdit);
+}
+
+IMPL_LINK(SwTokenWindow, NextItemBtnHdl, SwTOXButton&, rBtn, void )
+{
+ auto it = std::find_if(m_aControlList.begin(), m_aControlList.end(),
+ [&rBtn](const auto& rControl)
+ {
+ SwTOXWidget* pCtrl = rControl.get();
+ return pCtrl == &rBtn;
+ });
+
+ if (it == m_aControlList.end())
+ return;
+
+ auto itTest = it;
+ ++itTest;
+
+ if (rBtn.IsNextControl() && (itTest == m_aControlList.end() || !rBtn.IsNextControl()))
+ return;
+
+ bool isNext = rBtn.IsNextControl();
+
+ auto iterFocus = it;
+ isNext ? ++iterFocus : --iterFocus;
+
+ SwTOXWidget* pCtrlFocus = iterFocus->get();
+ pCtrlFocus->GrabFocus();
+ int nStartPos(0), nEndPos(0);
+
+ if (!isNext)
+ {
+ const sal_Int32 nLen = static_cast<SwTOXEdit*>(pCtrlFocus)->GetText().getLength();
+
+ nStartPos = nLen;
+ nEndPos = nLen;
+ }
+
+ static_cast<SwTOXEdit*>(pCtrlFocus)->select_region(nStartPos, nEndPos);
+
+ rBtn.Check(false);
+
+ AdjustScrolling();
+}
+
+IMPL_LINK(SwTokenWindow, TbxFocusBtnHdl, SwTOXWidget&, rControl, void)
+{
+ SwTOXButton* pBtn = static_cast<SwTOXButton*>(&rControl);
+ for (const auto& aControl : m_aControlList)
+ {
+ SwTOXWidget* pControl = aControl.get();
+
+ if (pControl && WindowType::EDIT != pControl->GetType())
+ static_cast<SwTOXButton*>(pControl)->Check(pBtn == pControl);
+ }
+
+ SetActiveControl(pBtn);
+}
+
+void SwTokenWindow::SetFocus2theAllBtn()
+{
+ if (m_pParent)
+ {
+ m_pParent->SetFocus2theAllBtn();
+ }
+}
+
+sal_uInt32 SwTokenWindow::GetControlIndex(FormTokenType eType) const
+{
+ //there are only one entry-text button and only one page-number button,
+ //so we need not add index for these two buttons.
+ if ( eType == TOKEN_ENTRY_TEXT || eType == TOKEN_PAGE_NUMS )
+ {
+ return 0;
+ }
+
+ sal_uInt32 nIndex = 0;
+ for (const auto& elem : m_aControlList)
+ {
+ const SwTOXWidget* pControl = elem.get();
+
+ const SwFormToken& rNewToken = WindowType::EDIT == pControl->GetType()
+ ? const_cast<SwTOXEdit*>(static_cast<const SwTOXEdit*>(pControl))->GetFormToken()
+ : static_cast<const SwTOXButton*>(pControl)->GetFormToken();
+
+ if(eType == rNewToken.eTokenType)
+ {
+ ++nIndex;
+ }
+ }
+
+ return nIndex;
+}
+
+SwTOXStylesTabPage::SwTOXStylesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/tocstylespage.ui", "TocStylesPage", &rAttrSet)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levels"))
+ , m_xAssignBT(m_xBuilder->weld_button("assign"))
+ , m_xParaLayLB(m_xBuilder->weld_tree_view("styles"))
+ , m_xStdBT(m_xBuilder->weld_button("default"))
+ , m_xEditStyleBT(m_xBuilder->weld_button("edit"))
+{
+ m_xParaLayLB->make_sorted();
+ auto nHeight = m_xLevelLB->get_height_rows(16);
+ m_xLevelLB->set_size_request(-1, nHeight);
+ m_xParaLayLB->set_size_request(-1, nHeight);
+
+ SetExchangeSupport();
+
+ m_xEditStyleBT->connect_clicked(LINK(this, SwTOXStylesTabPage, EditStyleHdl));
+ m_xAssignBT->connect_clicked(LINK(this, SwTOXStylesTabPage, AssignHdl));
+ m_xStdBT->connect_clicked(LINK(this, SwTOXStylesTabPage, StdHdl));
+ m_xParaLayLB->connect_changed(LINK(this, SwTOXStylesTabPage, EnableSelectHdl));
+ m_xLevelLB->connect_changed(LINK(this, SwTOXStylesTabPage, EnableSelectHdl));
+ m_xParaLayLB->connect_row_activated(LINK(this, SwTOXStylesTabPage, DoubleClickHdl));
+}
+
+SwTOXStylesTabPage::~SwTOXStylesTabPage()
+{
+}
+
+bool SwTOXStylesTabPage::FillItemSet( SfxItemSet* )
+{
+ return true;
+}
+
+void SwTOXStylesTabPage::Reset( const SfxItemSet* rSet )
+{
+ ActivatePage(*rSet);
+}
+
+void SwTOXStylesTabPage::ActivatePage( const SfxItemSet& )
+{
+ m_pCurrentForm.reset(new SwForm(GetForm()));
+
+ // not hyperlink for user directories
+ const sal_uInt16 nSize = m_pCurrentForm->GetFormMax();
+
+ // display form pattern without title
+
+ m_xLevelLB->freeze();
+ m_xLevelLB->clear();
+ // display 1st TemplateEntry
+ OUString aStr( SwResId( STR_TITLE ));
+ if( !m_pCurrentForm->GetTemplate( 0 ).isEmpty() )
+ {
+ aStr += " " + OUStringChar(aDeliStart)
+ + m_pCurrentForm->GetTemplate( 0 )
+ + OUStringChar(aDeliEnd);
+ }
+ m_xLevelLB->append_text(aStr);
+
+ for( sal_uInt16 i=1; i < nSize; ++i )
+ {
+ if( TOX_INDEX == m_pCurrentForm->GetTOXType() &&
+ FORM_ALPHA_DELIMITER == i )
+ {
+ aStr = SwResId(STR_ALPHA);
+ }
+ else
+ {
+ aStr = SwResId(STR_LEVEL) + OUString::number(
+ TOX_INDEX == m_pCurrentForm->GetTOXType() ? i - 1 : i );
+ }
+ if( !m_pCurrentForm->GetTemplate( i ).isEmpty() )
+ {
+ aStr += " " + OUStringChar(aDeliStart)
+ + m_pCurrentForm->GetTemplate( i )
+ + OUStringChar(aDeliEnd);
+ }
+ m_xLevelLB->append_text(aStr);
+ }
+ m_xLevelLB->thaw();
+
+ // initialise templates
+ SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
+ const sal_uInt16 nSz = rSh.GetTextFormatCollCount();
+
+ m_xParaLayLB->freeze();
+ m_xParaLayLB->clear();
+ for( sal_uInt16 i = 0; i < nSz; ++i )
+ {
+ const SwTextFormatColl *pColl = &rSh.GetTextFormatColl( i );
+ if( !pColl->IsDefault() )
+ m_xParaLayLB->append_text( pColl->GetName() );
+ }
+
+ // query pool collections and set them for the directory
+ for( sal_uInt16 i = 0; i < m_pCurrentForm->GetFormMax(); ++i )
+ {
+ aStr = m_pCurrentForm->GetTemplate( i );
+ if (!aStr.isEmpty() && m_xParaLayLB->find_text(aStr) == -1)
+ m_xParaLayLB->append_text(aStr);
+ }
+ m_xParaLayLB->thaw();
+
+ EnableSelectHdl(*m_xParaLayLB);
+}
+
+DeactivateRC SwTOXStylesTabPage::DeactivatePage( SfxItemSet* /*pSet*/ )
+{
+ GetForm() = *m_pCurrentForm;
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SwTOXStylesTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwTOXStylesTabPage>(pPage, pController, *rAttrSet);
+}
+
+IMPL_LINK_NOARG(SwTOXStylesTabPage, EditStyleHdl, weld::Button&, void)
+{
+ if (m_xParaLayLB->get_selected_index() != -1)
+ {
+ SfxStringItem aStyle(SID_STYLE_EDIT, m_xParaLayLB->get_selected_text());
+ SfxUInt16Item aFamily(SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Para));
+ SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
+ rSh.GetView().GetViewFrame().GetDispatcher()->ExecuteList(SID_STYLE_EDIT,
+ SfxCallMode::SYNCHRON,
+ { &aStyle, &aFamily });
+ }
+}
+
+// allocate templates
+IMPL_LINK_NOARG(SwTOXStylesTabPage, AssignHdl, weld::Button&, void)
+{
+ auto nLevPos = m_xLevelLB->get_selected_index();
+ auto nTemplPos = m_xParaLayLB->get_selected_index();
+ if (nLevPos == -1 || nTemplPos == -1)
+ return;
+
+ const OUString aStr(o3tl::getToken(m_xLevelLB->get_text(nLevPos), 0, aDeliStart)
+ + OUStringChar(aDeliStart)
+ + m_xParaLayLB->get_selected_text()
+ + OUStringChar(aDeliEnd));
+
+ m_pCurrentForm->SetTemplate(nLevPos, m_xParaLayLB->get_selected_text());
+
+ m_xLevelLB->remove(nLevPos);
+ m_xLevelLB->insert_text(nLevPos, aStr);
+ m_xLevelLB->select_text(aStr);
+ Modify();
+}
+
+IMPL_LINK_NOARG(SwTOXStylesTabPage, StdHdl, weld::Button&, void)
+{
+ const auto nPos = m_xLevelLB->get_selected_index();
+ if (nPos != -1)
+ {
+ const OUString aStr(m_xLevelLB->get_text(nPos).getToken(0, aDeliStart));
+ m_xLevelLB->remove(nPos);
+ m_xLevelLB->insert_text(nPos, aStr);
+ m_xLevelLB->select_text(aStr);
+ m_pCurrentForm->SetTemplate(nPos, OUString());
+ Modify();
+ }
+}
+
+IMPL_LINK_NOARG(SwTOXStylesTabPage, DoubleClickHdl, weld::TreeView&, bool)
+{
+ const OUString aTmpName(m_xParaLayLB->get_selected_text());
+ SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
+
+ if(m_xParaLayLB->get_selected_index() != -1 &&
+ (m_xLevelLB->get_selected_index() == 0 || SwMultiTOXTabDialog::IsNoNum(rSh, aTmpName)))
+ AssignHdl(*m_xAssignBT);
+
+ return true;
+}
+
+// enable only when selected
+IMPL_LINK_NOARG(SwTOXStylesTabPage, EnableSelectHdl, weld::TreeView&, void)
+{
+ m_xStdBT->set_sensitive(m_xLevelLB->get_selected_index() != -1);
+
+ SwWrtShell& rSh = static_cast<SwMultiTOXTabDialog*>(GetDialogController())->GetWrtShell();
+ const OUString aTmpName(m_xParaLayLB->get_selected_text());
+ m_xAssignBT->set_sensitive(m_xParaLayLB->get_selected_index() != -1 &&
+ m_xLevelLB->get_selected_index() != -1 &&
+ (m_xLevelLB->get_selected_index() == 0 || SwMultiTOXTabDialog::IsNoNum(rSh, aTmpName)));
+ m_xEditStyleBT->set_sensitive(m_xParaLayLB->get_selected_index() != -1);
+}
+
+void SwTOXStylesTabPage::Modify()
+{
+ SwMultiTOXTabDialog* pTOXDlg = static_cast<SwMultiTOXTabDialog*>(GetDialogController());
+ if (pTOXDlg)
+ {
+ GetForm() = *m_pCurrentForm;
+ pTOXDlg->CreateOrUpdateExample(pTOXDlg->GetCurrentTOXType().eType, TOX_PAGE_STYLES);
+ }
+}
+
+#define ITEM_SEARCH 1
+#define ITEM_ALTERNATIVE 2
+#define ITEM_PRIM_KEY 3
+#define ITEM_SEC_KEY 4
+#define ITEM_COMMENT 5
+#define ITEM_CASE 6
+#define ITEM_WORDONLY 7
+
+SwEntryBrowseBox::SwEntryBrowseBox(const css::uno::Reference<css::awt::XWindow> &rParent)
+ : SwEntryBrowseBox_Base(VCLUnoHelper::GetWindow(rParent), EditBrowseBoxFlags::NONE, WB_TABSTOP | WB_BORDER,
+ BrowserMode::KEEPHIGHLIGHT |
+ BrowserMode::COLUMNSELECTION |
+ BrowserMode::MULTISELECTION |
+ BrowserMode::TRACKING_TIPS |
+ BrowserMode::HLINES |
+ BrowserMode::VLINES |
+ BrowserMode::AUTO_VSCROLL|
+ BrowserMode::HIDECURSOR )
+ , m_aCellEdit(VclPtr<svt::EditControl>::Create(&GetDataWindow()))
+ , m_aCellCheckBox(VclPtr<svt::CheckBoxControl>::Create(&GetDataWindow()))
+ , m_nCurrentRow(0)
+ , m_bModified(false)
+{
+ OUString sSearch = SwResId(STR_AUTOMARK_SEARCHTERM);
+ OUString sAlternative = SwResId(STR_AUTOMARK_ALTERNATIVE);
+ OUString sPrimKey = SwResId(STR_AUTOMARK_KEY1);
+ OUString sSecKey = SwResId(STR_AUTOMARK_KEY2);
+ OUString sComment = SwResId(STR_AUTOMARK_COMMENT);
+ OUString sCaseSensitive = SwResId(STR_AUTOMARK_CASESENSITIVE);
+ OUString sWordOnly = SwResId(STR_AUTOMARK_WORDONLY);
+ m_sYes = SwResId(STR_AUTOMARK_YES);
+ m_sNo = SwResId(STR_AUTOMARK_NO);
+
+ m_aCellCheckBox->EnableTriState(false);
+ m_xController = new ::svt::EditCellController(m_aCellEdit.get());
+ m_xCheckController = new ::svt::CheckBoxCellController(m_aCellCheckBox.get());
+
+ // HACK: BrowseBox doesn't invalidate its children, how it should be.
+ // That's why WB_CLIPCHILDREN is reset in order to enforce the
+ // children' invalidation
+ WinBits aStyle = GetStyle();
+ if( aStyle & WB_CLIPCHILDREN )
+ {
+ aStyle &= ~WB_CLIPCHILDREN;
+ SetStyle( aStyle );
+ }
+
+ const OUString* aTitles[7] =
+ {
+ &sSearch,
+ &sAlternative,
+ &sPrimKey,
+ &sSecKey,
+ &sComment,
+ &sCaseSensitive,
+ &sWordOnly
+ };
+
+ tools::Long nWidth = GetSizePixel().Width();
+ nWidth /=7;
+ --nWidth;
+ for(sal_uInt16 i = 1; i < 8; i++)
+ InsertDataColumn( i, *aTitles[i - 1], nWidth );
+}
+
+SwEntryBrowseBox::~SwEntryBrowseBox()
+{
+ disposeOnce();
+}
+
+void SwEntryBrowseBox::dispose()
+{
+ m_aCellEdit.disposeAndClear();
+ m_aCellCheckBox.disposeAndClear();
+ SwEntryBrowseBox_Base::dispose();
+}
+
+void SwEntryBrowseBox::Resize()
+{
+ SwEntryBrowseBox_Base::Resize();
+
+ tools::Long nWidth = GetSizePixel().Width();
+ std::vector<tools::Long> aWidths = GetOptimalColWidths();
+ tools::Long nNaturalWidth(std::accumulate(aWidths.begin(), aWidths.end(), 0));
+ tools::Long nExcess = ((nWidth - nNaturalWidth) / aWidths.size()) - 1;
+
+ for (size_t i = 0; i < aWidths.size(); ++i)
+ SetColumnWidth(i+1, aWidths[i] + nExcess);
+}
+
+std::vector<tools::Long> SwEntryBrowseBox::GetOptimalColWidths() const
+{
+ std::vector<tools::Long> aWidths;
+
+ tools::Long nStandardColMinWidth = approximate_digit_width() * 15;
+ tools::Long nYesNoWidth = approximate_digit_width() * 5;
+ nYesNoWidth = std::max(nYesNoWidth, GetTextWidth(m_sYes));
+ nYesNoWidth = std::max(nYesNoWidth, GetTextWidth(m_sNo));
+ for (sal_uInt16 i = 1; i < 6; i++)
+ {
+ tools::Long nColWidth = std::max(nStandardColMinWidth,
+ GetTextWidth(GetColumnTitle(i)));
+ nColWidth += 12;
+ aWidths.push_back(nColWidth);
+ }
+
+ for (sal_uInt16 i = 6; i < 8; i++)
+ {
+ tools::Long nColWidth = std::max(nYesNoWidth,
+ GetTextWidth(GetColumnTitle(i)));
+ nColWidth += 12;
+ aWidths.push_back(nColWidth);
+ }
+
+ return aWidths;
+}
+
+Size SwEntryBrowseBox::GetOptimalSize() const
+{
+ Size aSize = LogicToPixel(Size(276 , 175), MapMode(MapUnit::MapAppFont));
+
+ std::vector<tools::Long> aWidths = GetOptimalColWidths();
+
+ tools::Long nWidth(std::accumulate(aWidths.begin(), aWidths.end(), 0));
+
+ aSize.setWidth( std::max(aSize.Width(), nWidth) );
+
+ return aSize;
+}
+
+bool SwEntryBrowseBox::SeekRow( sal_Int32 nRow )
+{
+ m_nCurrentRow = nRow;
+ return true;
+}
+
+OUString SwEntryBrowseBox::GetCellText(sal_Int32 nRow, sal_uInt16 nColumn) const
+{
+ OUString pRet;
+ if (o3tl::make_unsigned(nRow) < m_Entries.size())
+ {
+ const AutoMarkEntry* pEntry = m_Entries[ nRow ].get();
+ switch(nColumn)
+ {
+ case ITEM_SEARCH : pRet = pEntry->sSearch; break;
+ case ITEM_ALTERNATIVE : pRet = pEntry->sAlternative; break;
+ case ITEM_PRIM_KEY : pRet = pEntry->sPrimKey; break;
+ case ITEM_SEC_KEY : pRet = pEntry->sSecKey; break;
+ case ITEM_COMMENT : pRet = pEntry->sComment; break;
+ case ITEM_CASE : pRet = pEntry->bCase ? m_sYes : m_sNo; break;
+ case ITEM_WORDONLY : pRet = pEntry->bWord ? m_sYes : m_sNo; break;
+ }
+ }
+ return pRet;
+}
+
+void SwEntryBrowseBox::PaintCell(OutputDevice& rDev,
+ const tools::Rectangle& rRect, sal_uInt16 nColumnId) const
+{
+ const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
+ rDev.DrawText( rRect, GetCellText( m_nCurrentRow, nColumnId ), nStyle );
+}
+
+::svt::CellController* SwEntryBrowseBox::GetController(sal_Int32 /*nRow*/, sal_uInt16 nCol)
+{
+ return nCol < ITEM_CASE ? m_xController.get() : m_xCheckController.get();
+}
+
+bool SwEntryBrowseBox::SaveModified()
+{
+ m_bModified = true;
+ const size_t nRow = GetCurRow();
+ const sal_uInt16 nCol = GetCurColumnId();
+
+ OUString sNew;
+ bool bVal = false;
+ ::svt::CellController* pController = nullptr;
+ if(nCol < ITEM_CASE)
+ {
+ pController = m_xController.get();
+ sNew = static_cast< ::svt::EditCellController*>(pController)->GetEditImplementation()->GetText( LINEEND_LF );
+ }
+ else
+ {
+ pController = m_xCheckController.get();
+ bVal = static_cast< ::svt::CheckBoxCellController*>(pController)->GetCheckBox().get_active();
+ }
+ const bool bAddEntry = nRow >= m_Entries.size();
+ std::unique_ptr<AutoMarkEntry> xNewEntry(bAddEntry ? new AutoMarkEntry : nullptr);
+ AutoMarkEntry* pEntry = bAddEntry ? xNewEntry.get() : m_Entries[nRow].get();
+ switch(nCol)
+ {
+ case ITEM_SEARCH : pEntry->sSearch = sNew; break;
+ case ITEM_ALTERNATIVE : pEntry->sAlternative = sNew; break;
+ case ITEM_PRIM_KEY : pEntry->sPrimKey = sNew; break;
+ case ITEM_SEC_KEY : pEntry->sSecKey = sNew; break;
+ case ITEM_COMMENT : pEntry->sComment = sNew; break;
+ case ITEM_CASE : pEntry->bCase = bVal; break;
+ case ITEM_WORDONLY : pEntry->bWord = bVal; break;
+ }
+ if (bAddEntry)
+ {
+ m_Entries.push_back(std::move(xNewEntry));
+ RowInserted(nRow, 1, true, true);
+ if(nCol < ITEM_WORDONLY)
+ {
+ pController->SaveValue();
+ GoToRow( nRow );
+ }
+ }
+ return true;
+}
+
+void SwEntryBrowseBox::InitController(
+ ::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol)
+{
+ const OUString rText = GetCellText( nRow, nCol );
+ if(nCol < ITEM_CASE)
+ {
+ rController = m_xController;
+ ::svt::CellController* pController = m_xController.get();
+ static_cast< ::svt::EditCellController*>(pController)->GetEditImplementation()->SetText( rText );
+ }
+ else
+ {
+ rController = m_xCheckController;
+ ::svt::CellController* pController = m_xCheckController.get();
+ static_cast< ::svt::CheckBoxCellController*>(pController)->GetCheckBox().set_active(
+ rText == m_sYes );
+ }
+}
+
+void SwEntryBrowseBox::ReadEntries(SvStream& rInStr)
+{
+ AutoMarkEntry* pToInsert = nullptr;
+ // tdf#108910, tdf#125496 - read index entries using the appropriate character set
+ rtl_TextEncoding eTEnc = SwIoSystem::GetTextEncoding(rInStr);
+ if (eTEnc == RTL_TEXTENCODING_DONTKNOW)
+ eTEnc = osl_getThreadTextEncoding();
+ while (rInStr.good())
+ {
+ OUString sLine;
+ rInStr.ReadByteStringLine( sLine, eTEnc );
+
+ // # -> comment
+ // ; -> delimiter between entries ->
+ // Format: TextToSearchFor;AlternativeString;PrimaryKey;SecondaryKey
+ // Leading and trailing blanks are ignored
+ if( !sLine.isEmpty() )
+ {
+ //comments are contained in separate lines but are put into the struct of the following data
+ //line (if available)
+ if( '#' != sLine[0] )
+ {
+ if( !pToInsert )
+ pToInsert = new AutoMarkEntry;
+
+ sal_Int32 nSttPos = 0;
+ pToInsert->sSearch = sLine.getToken(0, ';', nSttPos );
+ pToInsert->sAlternative = sLine.getToken(0, ';', nSttPos );
+ pToInsert->sPrimKey = sLine.getToken(0, ';', nSttPos );
+ pToInsert->sSecKey = sLine.getToken(0, ';', nSttPos );
+
+ std::u16string_view sStr = o3tl::getToken(sLine, 0, ';', nSttPos );
+ pToInsert->bCase = !sStr.empty() && sStr != u"0";
+
+ sStr = o3tl::getToken(sLine, 0, ';', nSttPos );
+ pToInsert->bWord = !sStr.empty() && sStr != u"0";
+
+ m_Entries.push_back(std::unique_ptr<AutoMarkEntry>(pToInsert));
+ pToInsert = nullptr;
+ }
+ else
+ {
+ if(pToInsert)
+ m_Entries.push_back(std::unique_ptr<AutoMarkEntry>(pToInsert));
+ pToInsert = new AutoMarkEntry;
+ pToInsert->sComment = sLine.copy(1);
+ }
+ }
+ }
+ if( pToInsert )
+ m_Entries.push_back(std::unique_ptr<AutoMarkEntry>(pToInsert));
+ RowInserted(0, m_Entries.size() + 1);
+}
+
+void SwEntryBrowseBox::WriteEntries(SvStream& rOutStr)
+{
+ //check if the current controller is modified
+ const sal_uInt16 nCol = GetCurColumnId();
+ ::svt::CellController* pController;
+ if(nCol < ITEM_CASE)
+ pController = m_xController.get();
+ else
+ pController = m_xCheckController.get();
+ if (pController->IsValueChangedFromSaved())
+ GoToColumnId(nCol + (nCol < ITEM_CASE ? 1 : -1 ));
+
+ for(const std::unique_ptr<AutoMarkEntry> & rpEntry : m_Entries)
+ {
+ AutoMarkEntry* pEntry = rpEntry.get();
+ if(!pEntry->sComment.isEmpty())
+ {
+ // tdf#108910, tdf#125496 - write index entries using the utf8 text encoding
+ rOutStr.WriteByteStringLine( Concat2View("#" + pEntry->sComment), RTL_TEXTENCODING_UTF8 );
+ }
+
+ OUString sWrite( pEntry->sSearch + ";" +
+ pEntry->sAlternative + ";" +
+ pEntry->sPrimKey + ";" +
+ pEntry->sSecKey + ";" +
+ (pEntry->bCase ? std::u16string_view(u"1") : std::u16string_view(u"0")) +
+ ";" +
+ (pEntry->bWord ? std::u16string_view(u"1") : std::u16string_view(u"0")) );
+
+ if( sWrite.getLength() > 5 )
+ // tdf#108910, tdf#125496 - write index entries using the utf8 text encoding
+ rOutStr.WriteByteStringLine( sWrite, RTL_TEXTENCODING_UTF8 );
+ }
+}
+
+bool SwEntryBrowseBox::IsModified()const
+{
+ if(m_bModified)
+ return true;
+
+ //check if the current controller is modified
+ const sal_uInt16 nCol = GetCurColumnId();
+ ::svt::CellController* pController;
+ if(nCol < ITEM_CASE)
+ pController = m_xController.get();
+ else
+ pController = m_xCheckController.get();
+ return pController->IsValueChangedFromSaved();
+}
+
+SwAutoMarkDlg_Impl::SwAutoMarkDlg_Impl(weld::Window* pParent, OUString aAutoMarkURL,
+ bool bCreate)
+ : GenericDialogController(pParent, "modules/swriter/ui/createautomarkdialog.ui", "CreateAutomarkDialog")
+ , m_sAutoMarkURL(std::move(aAutoMarkURL))
+ , m_bCreateMode(bCreate)
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+ , m_xTable(m_xBuilder->weld_container("area"))
+ , m_xTableCtrlParent(m_xTable->CreateChildFrame())
+ , m_xEntriesBB(VclPtr<SwEntryBrowseBox>::Create(m_xTableCtrlParent))
+{
+ m_xEntriesBB->Show();
+ m_xOKPB->connect_clicked(LINK(this, SwAutoMarkDlg_Impl, OkHdl));
+
+ m_xDialog->set_title(m_xDialog->get_title() + ": " + m_sAutoMarkURL);
+ bool bError = false;
+ if( m_bCreateMode )
+ m_xEntriesBB->RowInserted(0);
+ else
+ {
+ SfxMedium aMed( m_sAutoMarkURL, StreamMode::STD_READ );
+ if( aMed.GetInStream() && !aMed.GetInStream()->GetError() )
+ m_xEntriesBB->ReadEntries( *aMed.GetInStream() );
+ else
+ bError = true;
+ }
+
+ Size aPrefSize = m_xEntriesBB->GetOptimalSize();
+ m_xTable->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+
+ if (bError)
+ m_xDialog->response(RET_CANCEL);
+}
+
+SwAutoMarkDlg_Impl::~SwAutoMarkDlg_Impl()
+{
+ m_xEntriesBB.disposeAndClear();
+ m_xTableCtrlParent->dispose();
+ m_xTableCtrlParent.clear();
+}
+
+IMPL_LINK_NOARG(SwAutoMarkDlg_Impl, OkHdl, weld::Button&, void)
+{
+ bool bError = false;
+ if (m_xEntriesBB->IsModified() || m_bCreateMode)
+ {
+ SfxMedium aMed( m_sAutoMarkURL,
+ m_bCreateMode ? StreamMode::WRITE
+ : StreamMode::WRITE| StreamMode::TRUNC );
+ SvStream* pStrm = aMed.GetOutStream();
+ // tdf#108910, tdf#125496 - write index entries using the utf8 text encoding
+ pStrm->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
+ if( !pStrm->GetError() )
+ {
+ m_xEntriesBB->WriteEntries( *pStrm );
+ aMed.Commit();
+ }
+ else
+ bError = true;
+ }
+ if (!bError)
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/index/multmrk.cxx b/sw/source/ui/index/multmrk.cxx
new file mode 100644
index 0000000000..e944bf24a5
--- /dev/null
+++ b/sw/source/ui/index/multmrk.cxx
@@ -0,0 +1,65 @@
+/* -*- 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 <multmrk.hxx>
+#include <toxmgr.hxx>
+#include <wrtsh.hxx>
+
+SwMultiTOXMarkDlg::SwMultiTOXMarkDlg(weld::Window* pParent, SwTOXMgr& rTOXMgr)
+ : GenericDialogController(pParent, "modules/swriter/ui/selectindexdialog.ui",
+ "SelectIndexDialog")
+ , m_rMgr(rTOXMgr)
+ , m_nPos(0)
+ , m_xTextFT(m_xBuilder->weld_label("type"))
+ , m_xTOXLB(m_xBuilder->weld_tree_view("treeview"))
+{
+ m_xTOXLB->set_size_request(m_xTOXLB->get_approximate_digit_width() * 32,
+ m_xTOXLB->get_height_rows(8));
+
+ m_xTOXLB->connect_changed(LINK(this, SwMultiTOXMarkDlg, SelectHdl));
+
+ sal_uInt16 nSize = m_rMgr.GetTOXMarkCount();
+ for (sal_uInt16 i = 0; i < nSize; ++i)
+ m_xTOXLB->append_text(m_rMgr.GetTOXMark(i)->GetText(m_rMgr.GetShell()->GetLayout()));
+
+ m_xTOXLB->select(0);
+ m_xTextFT->set_label(m_rMgr.GetTOXMark(0)->GetTOXType()->GetTypeName());
+}
+
+IMPL_LINK(SwMultiTOXMarkDlg, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (rBox.get_selected_index() != -1)
+ {
+ SwTOXMark* pMark = m_rMgr.GetTOXMark(rBox.get_selected_index());
+ m_xTextFT->set_label(pMark->GetTOXType()->GetTypeName());
+ m_nPos = rBox.get_selected_index();
+ }
+}
+
+short SwMultiTOXMarkDlg::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ m_rMgr.SetCurTOXMark(m_nPos);
+ return nRet;
+}
+
+SwMultiTOXMarkDlg::~SwMultiTOXMarkDlg() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/index/swuiidxmrk.cxx b/sw/source/ui/index/swuiidxmrk.cxx
new file mode 100644
index 0000000000..39443f7e7b
--- /dev/null
+++ b/sw/source/ui/index/swuiidxmrk.cxx
@@ -0,0 +1,1965 @@
+/* -*- 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 <swuiidxmrk.hxx>
+#include <hintids.hxx>
+#include <helpids.h>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/Bibliography.hpp>
+#include <com/sun/star/i18n/IndexEntrySupplier.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <i18nutil/searchopt.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/langitem.hxx>
+#include <osl/diagnose.h>
+#include <o3tl/string_view.hxx>
+#include <swtypes.hxx>
+#include <toxmgr.hxx>
+#include <txttxmrk.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <swundo.hxx>
+#include <cmdid.h>
+#include <swmodule.hxx>
+#include <fldmgr.hxx>
+#include <fldbas.hxx>
+#include <strings.hrc>
+#include <svl/cjkoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <ndtxt.hxx>
+#include <SwRewriter.hxx>
+#include <doc.hxx>
+#include <docsh.hxx>
+
+#define POS_CONTENT 0
+#define POS_INDEX 1
+
+static sal_Int32 nTypePos = 1; // TOX_INDEX as standard
+static sal_uInt16 nKey1Pos = USHRT_MAX;
+
+static sal_uInt16 nKey2Pos = USHRT_MAX;
+
+using namespace com::sun::star;
+using namespace com::sun::star::i18n;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::util;
+using namespace ::comphelper;
+
+namespace
+{
+bool SplitUrlAndPage(const OUString& rText, OUString& rUrl, int& nPageNumber)
+{
+ uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
+ = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
+ uno::Reference<uri::XUriReference> xUriRef;
+ try
+ {
+ xUriRef = xUriReferenceFactory->parse(rText);
+ }
+ catch (const uno::Exception& rException)
+ {
+ SAL_WARN("sw.ui", "SplitUrlAndPage: failed to parse url: " << rException.Message);
+ return false;
+ }
+
+ OUString aPagePrefix("page=");
+ if (!xUriRef->getFragment().startsWith(aPagePrefix))
+ {
+ return false;
+ }
+
+ nPageNumber = o3tl::toInt32(xUriRef->getFragment().subView(aPagePrefix.getLength()));
+ xUriRef->clearFragment();
+ rUrl = xUriRef->getUriReference();
+ return true;
+}
+
+OUString MergeUrlAndPage(const OUString& rUrl, const std::unique_ptr<weld::SpinButton>& xPageSB)
+{
+ if (!xPageSB->get_sensitive())
+ {
+ return rUrl;
+ }
+
+ uno::Reference<uri::XUriReferenceFactory> xUriReferenceFactory
+ = uri::UriReferenceFactory::create(comphelper::getProcessComponentContext());
+ uno::Reference<uri::XUriReference> xUriRef;
+ try
+ {
+ xUriRef = xUriReferenceFactory->parse(rUrl);
+ }
+ catch (const uno::Exception& rException)
+ {
+ SAL_WARN("sw.ui", "MergeUrlAndPage: failed to parse url: " << rException.Message);
+ return rUrl;
+ }
+
+ OUString aFragment("page=" + OUString::number(xPageSB->get_value()));
+ xUriRef->setFragment(aFragment);
+ return xUriRef->getUriReference();
+}
+}
+
+// dialog to insert a directory selection
+SwIndexMarkPane::SwIndexMarkPane(std::shared_ptr<weld::Dialog> xDialog, weld::Builder& rBuilder, bool bNewDlg,
+ SwWrtShell* pWrtShell)
+ : m_xDialog(std::move(xDialog))
+ , m_bDel(false)
+ , m_bNewMark(bNewDlg)
+ , m_bSelected(false)
+ , m_bPhoneticED0_ChangedByUser(false)
+ , m_bPhoneticED1_ChangedByUser(false)
+ , m_bPhoneticED2_ChangedByUser(false)
+ , m_nLangForPhoneticReading(LANGUAGE_CHINESE_SIMPLIFIED)
+ , m_bIsPhoneticReadingEnabled(false)
+ , m_pSh(pWrtShell)
+ , m_xTypeFT(rBuilder.weld_label("typeft"))
+ , m_xTypeDCB(rBuilder.weld_combo_box("typecb"))
+ , m_xNewBT(rBuilder.weld_button("new"))
+ , m_xEntryED(rBuilder.weld_entry("entryed"))
+ , m_xSyncED(rBuilder.weld_button("sync"))
+ , m_xPhoneticFT0(rBuilder.weld_label("phonetic0ft"))
+ , m_xPhoneticED0(rBuilder.weld_entry("phonetic0ed"))
+ , m_xKey1FT(rBuilder.weld_label("key1ft"))
+ , m_xKey1DCB(rBuilder.weld_combo_box("key1cb"))
+ , m_xPhoneticFT1(rBuilder.weld_label("phonetic1ft"))
+ , m_xPhoneticED1(rBuilder.weld_entry("phonetic1ed"))
+ , m_xKey2FT(rBuilder.weld_label("key2ft"))
+ , m_xKey2DCB(rBuilder.weld_combo_box("key2cb"))
+ , m_xPhoneticFT2(rBuilder.weld_label("phonetic2ft"))
+ , m_xPhoneticED2(rBuilder.weld_entry("phonetic2ed"))
+ , m_xLevelFT(rBuilder.weld_label("levelft"))
+ , m_xLevelNF(rBuilder.weld_spin_button("levelnf"))
+ , m_xMainEntryCB(rBuilder.weld_check_button("mainentrycb"))
+ , m_xApplyToAllCB(rBuilder.weld_check_button("applytoallcb"))
+ , m_xSearchCaseSensitiveCB(rBuilder.weld_check_button("searchcasesensitivecb"))
+ , m_xSearchCaseWordOnlyCB(rBuilder.weld_check_button("searchcasewordonlycb"))
+ , m_xOKBT(bNewDlg ? rBuilder.weld_button("insert") : rBuilder.weld_button("ok"))
+ , m_xCloseBT(rBuilder.weld_button("close"))
+ , m_xDelBT(rBuilder.weld_button("delete"))
+ , m_xPrevSameBT(rBuilder.weld_button("first"))
+ , m_xNextSameBT(rBuilder.weld_button("last"))
+ , m_xPrevBT(rBuilder.weld_button("previous"))
+ , m_xNextBT(rBuilder.weld_button("next"))
+ , m_xForSelectedEntry(rBuilder.weld_label("selectedentrytitle"))
+{
+ m_xSyncED->show();
+
+ if (SvtCJKOptions::IsCJKFontEnabled())
+ {
+ uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext();
+
+ m_xExtendedIndexEntrySupplier = i18n::IndexEntrySupplier::create(xContext);
+
+ m_xPhoneticFT0->show();
+ m_xPhoneticED0->show();
+ m_xPhoneticFT1->show();
+ m_xPhoneticED1->show();
+ m_xPhoneticFT2->show();
+ m_xPhoneticED2->show();
+ }
+
+ // tdf#129726 there are two help pages for this dialog, one for each mode,
+ // where a widget/dialog appears in both, use -insert/-edit to disambiguate
+ if (m_bNewMark)
+ {
+ m_xDialog->set_title(SwResId(STR_IDXMRK_INSERT));
+ m_xDialog->set_help_id(m_xDialog->get_help_id() + "-insert");
+ m_xTypeDCB->set_help_id(m_xTypeDCB->get_help_id() + "-insert");
+ }
+ else
+ {
+ m_xDialog->set_title(SwResId(STR_IDXMRK_EDIT));
+ m_xDialog->set_help_id(m_xDialog->get_help_id() + "-edit");
+ m_xTypeDCB->set_help_id(m_xTypeDCB->get_help_id() + "-edit");
+ }
+
+ m_xDelBT->connect_clicked(LINK(this,SwIndexMarkPane, DelHdl));
+ m_xPrevBT->connect_clicked(LINK(this,SwIndexMarkPane, PrevHdl));
+ m_xPrevSameBT->connect_clicked(LINK(this,SwIndexMarkPane, PrevSameHdl));
+ m_xNextBT->connect_clicked(LINK(this,SwIndexMarkPane, NextHdl));
+ m_xNextSameBT->connect_clicked(LINK(this,SwIndexMarkPane, NextSameHdl));
+ m_xTypeDCB->connect_changed(LINK(this,SwIndexMarkPane, ModifyListBoxHdl));
+ m_xKey1DCB->connect_changed(LINK(this,SwIndexMarkPane, KeyDCBModifyHdl));
+ m_xKey2DCB->connect_changed(LINK(this,SwIndexMarkPane, KeyDCBModifyHdl));
+ m_xCloseBT->connect_clicked(LINK(this,SwIndexMarkPane, CloseHdl));
+ m_xEntryED->connect_changed(LINK(this,SwIndexMarkPane, ModifyEditHdl));
+ m_xNewBT->connect_clicked(LINK(this, SwIndexMarkPane, NewUserIdxHdl));
+ m_xApplyToAllCB->connect_toggled(LINK(this, SwIndexMarkPane, SearchTypeHdl));
+ m_xPhoneticED0->connect_changed(LINK(this,SwIndexMarkPane, PhoneticEDModifyHdl));
+ m_xPhoneticED1->connect_changed(LINK(this,SwIndexMarkPane, PhoneticEDModifyHdl));
+ m_xPhoneticED2->connect_changed(LINK(this,SwIndexMarkPane, PhoneticEDModifyHdl));
+ m_xSyncED->connect_clicked(LINK(this, SwIndexMarkPane, SyncSelectionHdl));
+
+ if (m_bNewMark)
+ m_xDelBT->hide();
+ else
+ m_xNewBT->hide();
+ m_xOKBT->show();
+ m_xOKBT->connect_clicked(LINK(this, SwIndexMarkPane, InsertHdl));
+
+ m_xEntryED->grab_focus();
+}
+
+// Newly initialise controls with the new selection
+void SwIndexMarkPane::InitControls()
+{
+ assert(m_pSh && m_pTOXMgr && "no shell?");
+ // contents index
+ const SwTOXType* pType = m_pTOXMgr->GetTOXType(TOX_CONTENT);
+ assert(pType && "No directory type !!");
+ OUString sTmpTypeSelection;
+ if (m_xTypeDCB->get_active() != -1)
+ sTmpTypeSelection = m_xTypeDCB->get_active_text();
+ m_xTypeDCB->clear();
+ m_xTypeDCB->append_text(pType->GetTypeName());
+
+ // keyword index
+ pType = m_pTOXMgr->GetTOXType(TOX_INDEX);
+ assert(pType && "No directory type !!");
+ m_xTypeDCB->append_text(pType->GetTypeName());
+
+ // user index
+ sal_uInt16 nCount = m_pSh->GetTOXTypeCount(TOX_USER);
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ m_xTypeDCB->append_text(m_pSh->GetTOXType(TOX_USER, i)->GetTypeName());
+
+ // read keywords primary
+ {
+ std::vector<OUString> aArr;
+ m_pSh->GetTOIKeys(TOI_PRIMARY, aArr);
+ std::sort(aArr.begin(), aArr.end());
+ auto last = std::unique(aArr.begin(), aArr.end());
+ for (auto it = aArr.begin(); it != last; ++it)
+ m_xKey1DCB->append_text(*it);
+ }
+
+ // read keywords secondary
+ {
+ std::vector<OUString> aArr;
+ m_pSh->GetTOIKeys( TOI_SECONDARY, aArr );
+ std::sort(aArr.begin(), aArr.end());
+ auto last = std::unique(aArr.begin(), aArr.end());
+ for (auto it = aArr.begin(); it != last; ++it)
+ m_xKey2DCB->append_text(*it);
+ }
+
+ UpdateLanguageDependenciesForPhoneticReading();
+
+ // current entry
+ const SwTOXMark* pMark = m_pTOXMgr->GetCurTOXMark();
+ if( pMark && !m_bNewMark)
+ {
+ // Controls-Handling
+
+ // only if there are more than one
+ // if equal it lands at the same entry
+ m_pSh->SttCursorMove();
+
+ const SwTOXMark* pMoveMark;
+ bool bShow = false;
+
+ pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ {
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT );
+ bShow = true;
+ }
+ m_xPrevBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ {
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV );
+ bShow = true;
+ }
+ m_xNextBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ if( bShow )
+ {
+ m_xPrevBT->show();
+ m_xNextBT->show();
+ bShow = false;
+ }
+
+ pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ {
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT );
+ bShow = true;
+ }
+ m_xPrevSameBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ {
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV );
+ bShow = true;
+ }
+ m_xNextSameBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark));
+ if( bShow )
+ {
+ m_xNextSameBT->show();
+ m_xPrevSameBT->show();
+ }
+ m_pSh->EndCursorMove();
+
+ m_xTypeFT->show();
+
+ m_xTypeDCB->set_sensitive(false);
+ m_xTypeFT->set_sensitive(false);
+
+ UpdateDialog();
+ }
+ else
+ { // display current selection (first element) ????
+ if (m_pSh->GetCursorCnt() < 2)
+ {
+ m_bSelected = !m_pSh->HasSelection();
+ m_aOrgStr = m_pSh->GetView().GetSelectionTextParam(true, false);
+ m_xEntryED->set_text(m_aOrgStr);
+
+ //to include all equal entries may only be allowed in the body and even there
+ //only when a simple selection exists
+ const FrameTypeFlags nFrameType = m_pSh->GetFrameType(nullptr,true);
+ m_xForSelectedEntry->show();
+ m_xApplyToAllCB->show();
+ m_xSearchCaseSensitiveCB->show();
+ m_xSearchCaseWordOnlyCB->show();
+ m_xApplyToAllCB->set_sensitive(!m_aOrgStr.isEmpty() &&
+ !(nFrameType & ( FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FLY_ANY )));
+ SearchTypeHdl(*m_xApplyToAllCB);
+ }
+
+ // index type is default
+ if (!sTmpTypeSelection.isEmpty() && m_xTypeDCB->find_text(sTmpTypeSelection) != -1)
+ m_xTypeDCB->set_active_text(sTmpTypeSelection);
+ else
+ m_xTypeDCB->set_active_text(m_xTypeDCB->get_text(nTypePos));
+ ModifyHdl(*m_xTypeDCB);
+ }
+}
+
+void SwIndexMarkPane::UpdateLanguageDependenciesForPhoneticReading()
+{
+ //no phonetic reading if no global cjk support
+ if( !m_xExtendedIndexEntrySupplier.is() )
+ {
+ m_bIsPhoneticReadingEnabled = false;
+ return;
+ }
+ m_bIsPhoneticReadingEnabled = true;
+
+ //get the current language
+ if(!m_bNewMark) //if dialog is opened to iterate existing marks
+ {
+ OSL_ENSURE(m_pTOXMgr, "need TOXMgr");
+ if(!m_pTOXMgr)
+ return;
+ SwTOXMark* pMark = m_pTOXMgr->GetCurTOXMark();
+ OSL_ENSURE(pMark, "need current SwTOXMark");
+ if(!pMark)
+ return;
+ SwTextTOXMark* pTextTOXMark = pMark->GetTextTOXMark();
+ OSL_ENSURE(pTextTOXMark, "need current SwTextTOXMark");
+ if(!pTextTOXMark)
+ return;
+ const SwTextNode* pTextNode = pTextTOXMark->GetpTextNd();
+ OSL_ENSURE(pTextNode, "need current SwTextNode");
+ if(!pTextNode)
+ return;
+ sal_Int32 nTextIndex = pTextTOXMark->GetStart();
+ m_nLangForPhoneticReading = pTextNode->GetLang( nTextIndex );
+ }
+ else //if dialog is opened to create a new mark
+ {
+ sal_uInt16 nWhich;
+ switch(m_pSh->GetScriptType())
+ {
+ case SvtScriptType::ASIAN: nWhich = RES_CHRATR_CJK_LANGUAGE; break;
+ case SvtScriptType::COMPLEX:nWhich = RES_CHRATR_CTL_LANGUAGE; break;
+ default:nWhich = RES_CHRATR_LANGUAGE; break;
+ }
+ SfxItemSet aLangSet(m_pSh->GetAttrPool(), nWhich, nWhich);
+ m_pSh->GetCurAttr(aLangSet);
+ m_nLangForPhoneticReading = static_cast<const SvxLanguageItem&>(aLangSet.Get(nWhich)).GetLanguage();
+ }
+
+}
+
+OUString SwIndexMarkPane::GetDefaultPhoneticReading( const OUString& rText )
+{
+ if( !m_bIsPhoneticReadingEnabled )
+ return OUString();
+
+ return m_xExtendedIndexEntrySupplier->getPhoneticCandidate(rText, LanguageTag::convertToLocale( m_nLangForPhoneticReading ));
+}
+
+void SwIndexMarkPane::Activate()
+{
+ // display current selection (first element) ????
+ if (m_bNewMark)
+ {
+ m_xSyncED->set_sensitive(m_pSh->GetCursorCnt() < 2);
+ }
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, SyncSelectionHdl, weld::Button&, void)
+{
+ m_bSelected = !m_pSh->HasSelection();
+ m_aOrgStr = m_pSh->GetView().GetSelectionTextParam(true, false);
+ m_xEntryED->set_text(m_aOrgStr);
+
+ //to include all equal entries may only be allowed in the body and even there
+ //only when a simple selection exists
+ const FrameTypeFlags nFrameType = m_pSh->GetFrameType(nullptr,true);
+ m_xApplyToAllCB->show();
+ m_xSearchCaseSensitiveCB->show();
+ m_xSearchCaseWordOnlyCB->show();
+ m_xApplyToAllCB->set_sensitive(!m_aOrgStr.isEmpty() &&
+ !(nFrameType & ( FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FLY_ANY )));
+ SearchTypeHdl(*m_xApplyToAllCB);
+ ModifyHdl(*m_xEntryED);
+}
+
+// evaluate Ok-Button
+void SwIndexMarkPane::Apply()
+{
+ InsertUpdate();
+ if(m_bSelected)
+ m_pSh->ResetSelect(nullptr, false);
+}
+
+// apply changes
+void SwIndexMarkPane::InsertUpdate()
+{
+ m_pSh->StartUndo(m_bDel ? SwUndoId::INDEX_ENTRY_DELETE : SwUndoId::INDEX_ENTRY_INSERT);
+ m_pSh->StartAllAction();
+ SwRewriter aRewriter;
+
+ if( m_bNewMark )
+ {
+ InsertMark();
+
+ if ( m_pTOXMgr->GetCurTOXMark())
+ aRewriter.AddRule(UndoArg1,
+ m_pTOXMgr->GetCurTOXMark()->GetText(m_pSh->GetLayout()));
+ }
+ else if( !m_pSh->HasReadonlySel() )
+ {
+ if ( m_pTOXMgr->GetCurTOXMark())
+ aRewriter.AddRule(UndoArg1,
+ m_pTOXMgr->GetCurTOXMark()->GetText(m_pSh->GetLayout()));
+
+ if( m_bDel )
+ m_pTOXMgr->DeleteTOXMark();
+ else if( m_pTOXMgr->GetCurTOXMark() )
+ UpdateMark();
+ }
+
+ m_pSh->EndAllAction();
+ m_pSh->EndUndo(m_bDel ? SwUndoId::INDEX_ENTRY_DELETE : SwUndoId::INDEX_ENTRY_INSERT);
+
+ nTypePos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
+ if(nTypePos == -1)
+ nTypePos = 0;
+
+ nKey1Pos = m_xKey1DCB->find_text(m_xKey1DCB->get_active_text());
+ nKey2Pos = m_xKey2DCB->find_text(m_xKey2DCB->get_active_text());
+}
+
+// insert mark
+static void lcl_SelectSameStrings(SwWrtShell& rSh, bool bWordOnly, bool bCaseSensitive)
+{
+ rSh.Push();
+
+ i18nutil::SearchOptions2 aSearchOpt(
+ ( bWordOnly ? SearchFlags::NORM_WORD_ONLY : 0 ),
+ rSh.GetSelText(), OUString(),
+ GetAppLanguageTag().getLocale(),
+ 0, 0, 0,
+ (bCaseSensitive
+ ? TransliterationFlags::NONE
+ : TransliterationFlags::IGNORE_CASE),
+ SearchAlgorithms2::ABSOLUTE,
+ '\\' );
+
+ rSh.ClearMark();
+ bool bCancel;
+
+ //todo/mba: assuming that notes should not be searched
+ rSh.Find_Text(aSearchOpt, false/*bSearchInNotes*/, SwDocPositions::Start, SwDocPositions::End, bCancel,
+ FindRanges::InSelAll | FindRanges::InBodyOnly );
+}
+
+void SwIndexMarkPane::InsertMark()
+{
+ auto nPos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
+ TOXTypes eType = nPos == POS_CONTENT ? TOX_CONTENT :
+ nPos == POS_INDEX ? TOX_INDEX : TOX_USER;
+
+ SwTOXMarkDescription aDesc(eType);
+
+ const int nLevel = m_xLevelNF->denormalize(m_xLevelNF->get_value());
+ switch( nPos)
+ {
+ case POS_CONTENT : break;
+ case POS_INDEX: // keyword index mark
+ {
+ UpdateKeyBoxes();
+ aDesc.SetPrimKey(m_xKey1DCB->get_active_text());
+ aDesc.SetSecKey(m_xKey2DCB->get_active_text());
+ aDesc.SetMainEntry(m_xMainEntryCB->get_active());
+ aDesc.SetPhoneticReadingOfAltStr(m_xPhoneticED0->get_text());
+ aDesc.SetPhoneticReadingOfPrimKey(m_xPhoneticED1->get_text());
+ aDesc.SetPhoneticReadingOfSecKey(m_xPhoneticED2->get_text());
+ }
+ break;
+ default: // Userdefined index mark
+ {
+ aDesc.SetTOUName(m_xTypeDCB->get_active_text());
+ }
+ }
+ if (m_aOrgStr != m_xEntryED->get_text())
+ aDesc.SetAltStr(m_xEntryED->get_text());
+ bool bApplyAll = m_xApplyToAllCB->get_active();
+ bool bWordOnly = m_xSearchCaseWordOnlyCB->get_active();
+ bool bCaseSensitive = m_xSearchCaseSensitiveCB->get_active();
+
+ m_pSh->StartAllAction();
+ // all equal strings have to be selected here so that the
+ // entry is applied to all equal strings
+ if(bApplyAll)
+ {
+ lcl_SelectSameStrings(*m_pSh, bWordOnly, bCaseSensitive);
+ }
+ aDesc.SetLevel(nLevel);
+ SwTOXMgr aMgr(m_pSh);
+ aMgr.InsertTOXMark(aDesc);
+ if(bApplyAll)
+ m_pSh->Pop(SwCursorShell::PopMode::DeleteCurrent);
+
+ m_pSh->EndAllAction();
+}
+
+// update mark
+void SwIndexMarkPane::UpdateMark()
+{
+ OUString aAltText(m_xEntryED->get_text());
+ OUString* pAltText = m_aOrgStr != m_xEntryED->get_text() ? &aAltText : nullptr;
+ //empty alternative texts are not allowed
+ if(pAltText && pAltText->isEmpty())
+ return;
+
+ UpdateKeyBoxes();
+
+ auto nPos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
+ TOXTypes eType = TOX_USER;
+ if(POS_CONTENT == nPos)
+ eType = TOX_CONTENT;
+ else if(POS_INDEX == nPos)
+ eType = TOX_INDEX;
+
+ SwTOXMarkDescription aDesc(eType);
+ aDesc.SetLevel(m_xLevelNF->get_value());
+ if(pAltText)
+ aDesc.SetAltStr(*pAltText);
+
+ OUString aPrim(m_xKey1DCB->get_active_text());
+ if(!aPrim.isEmpty())
+ aDesc.SetPrimKey(aPrim);
+ OUString aSec(m_xKey2DCB->get_active_text());
+ if(!aSec.isEmpty())
+ aDesc.SetSecKey(aSec);
+
+ if(eType == TOX_INDEX)
+ {
+ aDesc.SetPhoneticReadingOfAltStr(m_xPhoneticED0->get_text());
+ aDesc.SetPhoneticReadingOfPrimKey(m_xPhoneticED1->get_text());
+ aDesc.SetPhoneticReadingOfSecKey(m_xPhoneticED2->get_text());
+ }
+ aDesc.SetMainEntry(m_xMainEntryCB->get_visible() && m_xMainEntryCB->get_active());
+ m_pTOXMgr->UpdateTOXMark(aDesc);
+}
+
+// insert new keys
+void SwIndexMarkPane::UpdateKeyBoxes()
+{
+ OUString aKey(m_xKey1DCB->get_active_text());
+ auto nPos = m_xKey1DCB->find_text(aKey);
+ if(nPos == -1 && !aKey.isEmpty())
+ { // create new key
+ m_xKey1DCB->append_text(aKey);
+ }
+
+ aKey = m_xKey2DCB->get_active_text();
+ nPos = m_xKey2DCB->find_text(aKey);
+
+ if(nPos == -1 && !aKey.isEmpty())
+ { // create new key
+ m_xKey2DCB->append_text(aKey);
+ }
+}
+
+namespace {
+
+class SwNewUserIdxDlg : public weld::GenericDialogController
+{
+ SwIndexMarkPane* m_pDlg;
+
+ std::unique_ptr<weld::Button> m_xOKPB;
+ std::unique_ptr<weld::Entry> m_xNameED;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ explicit SwNewUserIdxDlg(SwIndexMarkPane* pPane, weld::Window* pParent)
+ : GenericDialogController(pParent, "modules/swriter/ui/newuserindexdialog.ui", "NewUserIndexDialog")
+ , m_pDlg(pPane)
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+ , m_xNameED(m_xBuilder->weld_entry("entry"))
+ {
+ m_xNameED->connect_changed(LINK(this, SwNewUserIdxDlg, ModifyHdl));
+ m_xOKPB->set_sensitive(false);
+ m_xNameED->grab_focus();
+ }
+ OUString GetName() const { return m_xNameED->get_text(); }
+};
+
+}
+
+IMPL_LINK( SwNewUserIdxDlg, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ m_xOKPB->set_sensitive(!rEdit.get_text().isEmpty() && !m_pDlg->IsTOXType(rEdit.get_text()));
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, NewUserIdxHdl, weld::Button&, void)
+{
+ SwNewUserIdxDlg aDlg(this, m_xDialog.get());
+ if (aDlg.run() == RET_OK)
+ {
+ OUString sNewName(aDlg.GetName());
+ m_xTypeDCB->append_text(sNewName);
+ m_xTypeDCB->set_active_text(sNewName);
+ }
+}
+
+IMPL_LINK( SwIndexMarkPane, SearchTypeHdl, weld::Toggleable&, rBox, void)
+{
+ const bool bEnable = rBox.get_active() && rBox.get_sensitive();
+ m_xSearchCaseWordOnlyCB->set_sensitive(bEnable);
+ m_xSearchCaseSensitiveCB->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SwIndexMarkPane, InsertHdl, weld::Button&, rButton, void)
+{
+ Apply();
+ //close the dialog if only one entry is available
+ if(!m_bNewMark && !m_xPrevBT->get_visible() && !m_xNextBT->get_visible())
+ CloseHdl(rButton);
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, CloseHdl, weld::Button&, void)
+{
+ if (m_bNewMark)
+ {
+ if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
+ {
+ pViewFrm->GetDispatcher()->Execute(FN_INSERT_IDX_ENTRY_DLG,
+ SfxCallMode::ASYNCHRON|SfxCallMode::RECORD);
+ }
+ }
+ else
+ {
+ m_xDialog->response(RET_CLOSE);
+ }
+}
+
+// select index type only when inserting
+IMPL_LINK(SwIndexMarkPane, ModifyListBoxHdl, weld::ComboBox&, rBox, void)
+{
+ ModifyHdl(rBox);
+}
+
+IMPL_LINK(SwIndexMarkPane, ModifyEditHdl, weld::Entry&, rEdit, void)
+{
+ ModifyHdl(rEdit);
+}
+
+void SwIndexMarkPane::ModifyHdl(const weld::Widget& rBox)
+{
+ if (m_xTypeDCB.get() == &rBox)
+ {
+ // set index type
+ auto nPos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
+ bool bLevelEnable = false,
+ bKeyEnable = false,
+ bSetKey2 = false,
+ bKey2Enable = false,
+ bEntryHasText = false,
+ bKey1HasText = false,
+ bKey2HasText = false;
+ if(nPos == POS_INDEX)
+ {
+ if (!m_xEntryED->get_text().isEmpty())
+ bEntryHasText = true;
+ m_xPhoneticED0->set_text(GetDefaultPhoneticReading(m_xEntryED->get_text()));
+
+ bKeyEnable = true;
+ m_xKey1DCB->set_active_text(m_xKey1DCB->get_text(nKey1Pos));
+ m_xPhoneticED1->set_text(GetDefaultPhoneticReading(m_xKey1DCB->get_active_text()));
+ if (!m_xKey1DCB->get_active_text().isEmpty())
+ {
+ bKey1HasText = bSetKey2 = bKey2Enable = true;
+ m_xKey2DCB->set_active_text(m_xKey2DCB->get_text(nKey2Pos));
+ m_xPhoneticED2->set_text(GetDefaultPhoneticReading(m_xKey2DCB->get_active_text()));
+ if(!m_xKey2DCB->get_active_text().isEmpty())
+ bKey2HasText = true;
+ }
+ }
+ else
+ {
+ bLevelEnable = true;
+ m_xLevelNF->set_max(MAXLEVEL);
+ m_xLevelNF->set_value(m_xLevelNF->normalize(0));
+ bSetKey2 = true;
+ }
+ m_xLevelFT->set_visible(bLevelEnable);
+ m_xLevelNF->set_visible(bLevelEnable);
+ m_xMainEntryCB->set_visible(nPos == POS_INDEX);
+
+ m_xKey1FT->set_sensitive(bKeyEnable);
+ m_xKey1DCB->set_sensitive(bKeyEnable);
+ if ( bSetKey2 )
+ {
+ m_xKey2DCB->set_sensitive(bKey2Enable);
+ m_xKey2FT->set_sensitive(bKey2Enable);
+ }
+ m_xPhoneticFT0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticFT1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticFT2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
+ }
+ else //m_xEntryED !!m_xEntryED is not a ListBox but an Edit
+ {
+ bool bHasText = !m_xEntryED->get_text().isEmpty();
+ if(!bHasText)
+ {
+ m_xPhoneticED0->set_text(OUString());
+ m_bPhoneticED0_ChangedByUser = false;
+ }
+ else if(!m_bPhoneticED0_ChangedByUser)
+ m_xPhoneticED0->set_text(GetDefaultPhoneticReading(m_xEntryED->get_text()));
+
+ m_xPhoneticFT0->set_sensitive(bHasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED0->set_sensitive(bHasText&&m_bIsPhoneticReadingEnabled);
+ }
+ m_xOKBT->set_sensitive(!m_pSh->HasReadonlySel() &&
+ (!m_xEntryED->get_text().isEmpty() || m_pSh->GetCursorCnt(false)));
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, NextHdl, weld::Button&, void)
+{
+ InsertUpdate();
+ m_pTOXMgr->NextTOXMark();
+ UpdateDialog();
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, NextSameHdl, weld::Button&, void)
+{
+ InsertUpdate();
+ m_pTOXMgr->NextTOXMark(true);
+ UpdateDialog();
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, PrevHdl, weld::Button&, void)
+{
+ InsertUpdate();
+ m_pTOXMgr->PrevTOXMark();
+ UpdateDialog();
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, PrevSameHdl, weld::Button&, void)
+{
+ InsertUpdate();
+ m_pTOXMgr->PrevTOXMark(true);
+ UpdateDialog();
+}
+
+IMPL_LINK_NOARG(SwIndexMarkPane, DelHdl, weld::Button&, void)
+{
+ m_bDel = true;
+ InsertUpdate();
+ m_bDel = false;
+
+ if(m_pTOXMgr->GetCurTOXMark())
+ UpdateDialog();
+ else
+ {
+ CloseHdl(*m_xCloseBT);
+ if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
+ pViewFrm->GetBindings().Invalidate(FN_EDIT_IDX_ENTRY_DLG);
+ }
+}
+
+// renew dialog view
+void SwIndexMarkPane::UpdateDialog()
+{
+ OSL_ENSURE(m_pSh && m_pTOXMgr, "no shell?");
+ SwTOXMark* pMark = m_pTOXMgr->GetCurTOXMark();
+ OSL_ENSURE(pMark, "no current marker");
+ if(!pMark)
+ return;
+
+ SwViewShell::SetCareDialog(m_xDialog);
+
+ m_aOrgStr = pMark->GetText(m_pSh->GetLayout());
+ m_xEntryED->set_text(m_aOrgStr);
+
+ // set index type
+ bool bLevelEnable = true,
+ bKeyEnable = false,
+ bKey2Enable = false,
+ bEntryHasText = false,
+ bKey1HasText = false,
+ bKey2HasText = false;
+
+ TOXTypes eCurType = pMark->GetTOXType()->GetType();
+ if(TOX_INDEX == eCurType)
+ {
+ bLevelEnable = false;
+ bKeyEnable = true;
+ bKey1HasText = bKey2Enable = !pMark->GetPrimaryKey().isEmpty();
+ bKey2HasText = !pMark->GetSecondaryKey().isEmpty();
+ bEntryHasText = !pMark->GetText(m_pSh->GetLayout()).isEmpty();
+ m_xKey1DCB->set_entry_text( pMark->GetPrimaryKey() );
+ m_xKey2DCB->set_entry_text( pMark->GetSecondaryKey() );
+ m_xPhoneticED0->set_text( pMark->GetTextReading() );
+ m_xPhoneticED1->set_text( pMark->GetPrimaryKeyReading() );
+ m_xPhoneticED2->set_text( pMark->GetSecondaryKeyReading() );
+ m_xMainEntryCB->set_active(pMark->IsMainEntry());
+ }
+ else if(TOX_CONTENT == eCurType || TOX_USER == eCurType)
+ {
+ m_xLevelNF->set_value(m_xLevelNF->normalize(pMark->GetLevel()));
+ }
+ m_xKey1FT->set_sensitive(bKeyEnable);
+ m_xKey1DCB->set_sensitive(bKeyEnable);
+ m_xLevelNF->set_max(MAXLEVEL);
+ m_xLevelFT->set_visible(bLevelEnable);
+ m_xLevelNF->set_visible(bLevelEnable);
+ m_xMainEntryCB->set_visible(!bLevelEnable);
+ m_xKey2FT->set_sensitive(bKey2Enable);
+ m_xKey2DCB->set_sensitive(bKey2Enable);
+
+ UpdateLanguageDependenciesForPhoneticReading();
+ m_xPhoneticFT0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticFT1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticFT2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
+
+ // set index type
+ m_xTypeDCB->set_active_text(pMark->GetTOXType()->GetTypeName());
+
+ // set Next - Prev - Buttons
+ m_pSh->SttCursorMove();
+ if( m_xPrevBT->get_visible() )
+ {
+ const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT );
+ m_xPrevBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV );
+ m_xNextBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ }
+
+ if (m_xPrevSameBT->get_visible())
+ {
+ const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT );
+ m_xPrevSameBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT );
+ if (!SfxPoolItem::areSame( pMoveMark, pMark ))
+ m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV );
+ m_xNextSameBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) );
+ }
+
+ const bool bEnable = !m_pSh->HasReadonlySel();
+ m_xOKBT->set_sensitive(bEnable);
+ m_xDelBT->set_sensitive(bEnable);
+ m_xEntryED->set_sensitive(bEnable);
+ m_xLevelNF->set_sensitive(bEnable);
+ m_xKey1DCB->set_sensitive(bEnable);
+ m_xKey2DCB->set_sensitive(bEnable);
+
+ m_pSh->SelectTextAttr( RES_TXTATR_TOXMARK, pMark->GetTextTOXMark() );
+ // we need the point at the start of the attribute
+ m_pSh->SwapPam();
+
+ m_pSh->EndCursorMove();
+}
+
+// Remind whether the edit boxes for Phonetic reading are changed manually
+IMPL_LINK(SwIndexMarkPane, PhoneticEDModifyHdl, weld::Entry&, rEdit, void)
+{
+ if (m_xPhoneticED0.get() == &rEdit)
+ {
+ m_bPhoneticED0_ChangedByUser = !rEdit.get_text().isEmpty();
+ }
+ else if (m_xPhoneticED1.get() == &rEdit)
+ {
+ m_bPhoneticED1_ChangedByUser = !rEdit.get_text().isEmpty();
+ }
+ else if (m_xPhoneticED2.get() == &rEdit)
+ {
+ m_bPhoneticED2_ChangedByUser = !rEdit.get_text().isEmpty();
+ }
+}
+
+// Enable Disable of the 2nd key
+IMPL_LINK( SwIndexMarkPane, KeyDCBModifyHdl, weld::ComboBox&, rBox, void )
+{
+ if (m_xKey1DCB.get() == &rBox)
+ {
+ bool bEnable = !rBox.get_active_text().isEmpty();
+ if(!bEnable)
+ {
+ m_xKey2DCB->set_entry_text(OUString());
+ m_xPhoneticED1->set_text(OUString());
+ m_xPhoneticED2->set_text(OUString());
+ m_bPhoneticED1_ChangedByUser = false;
+ m_bPhoneticED2_ChangedByUser = false;
+ }
+ else
+ {
+ if (rBox.get_popup_shown())
+ {
+ //reset bPhoneticED1_ChangedByUser if a completely new string is selected
+ m_bPhoneticED1_ChangedByUser = false;
+ }
+ if (!m_bPhoneticED1_ChangedByUser)
+ m_xPhoneticED1->set_text(GetDefaultPhoneticReading(rBox.get_active_text()));
+ }
+ m_xKey2DCB->set_sensitive(bEnable);
+ m_xKey2FT->set_sensitive(bEnable);
+ }
+ else if (m_xKey2DCB.get() == &rBox)
+ {
+ if (rBox.get_active_text().isEmpty())
+ {
+ m_xPhoneticED2->set_text(OUString());
+ m_bPhoneticED2_ChangedByUser = false;
+ }
+ else
+ {
+ if (rBox.get_popup_shown())
+ {
+ //reset bPhoneticED1_ChangedByUser if a completely new string is selected
+ m_bPhoneticED2_ChangedByUser = false;
+ }
+ if(!m_bPhoneticED2_ChangedByUser)
+ m_xPhoneticED2->set_text(GetDefaultPhoneticReading(rBox.get_active_text()));
+ }
+ }
+
+ bool bKey1HasText = !m_xKey1DCB->get_active_text().isEmpty();
+ bool bKey2HasText = !m_xKey2DCB->get_active_text().isEmpty();
+
+ m_xPhoneticFT1->set_sensitive(bKey1HasText && m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED1->set_sensitive(bKey1HasText && m_bIsPhoneticReadingEnabled);
+ m_xPhoneticFT2->set_sensitive(bKey2HasText && m_bIsPhoneticReadingEnabled);
+ m_xPhoneticED2->set_sensitive(bKey2HasText && m_bIsPhoneticReadingEnabled);
+}
+
+SwIndexMarkPane::~SwIndexMarkPane()
+{
+}
+
+void SwIndexMarkPane::ReInitDlg(SwWrtShell& rWrtShell, SwTOXMark const * pCurTOXMark)
+{
+ m_pSh = &rWrtShell;
+ m_pTOXMgr.reset( new SwTOXMgr(m_pSh) );
+ if(pCurTOXMark)
+ {
+ for(sal_uInt16 i = 0; i < m_pTOXMgr->GetTOXMarkCount(); i++)
+ if (SfxPoolItem::areSame(m_pTOXMgr->GetTOXMark(i), pCurTOXMark))
+ {
+ m_pTOXMgr->SetCurTOXMark(i);
+ break;
+ }
+ }
+ InitControls();
+}
+
+SwIndexMarkFloatDlg::SwIndexMarkFloatDlg(SfxBindings* _pBindings,
+ SfxChildWindow* pChild, weld::Window *pParent,
+ SfxChildWinInfo const * pInfo, bool bNew)
+ : SfxModelessDialogController(_pBindings, pChild, pParent,
+ "modules/swriter/ui/indexentry.ui", "IndexEntryDialog")
+ , m_aContent(m_xDialog, *m_xBuilder, bNew, ::GetActiveWrtShell())
+{
+ if (SwWrtShell* pWrtShell = ::GetActiveWrtShell())
+ m_aContent.ReInitDlg(*pWrtShell);
+ Initialize(pInfo);
+}
+
+void SwIndexMarkFloatDlg::Activate()
+{
+ SfxModelessDialogController::Activate();
+ m_aContent.Activate();
+}
+
+void SwIndexMarkFloatDlg::ReInitDlg(SwWrtShell& rWrtShell)
+{
+ m_aContent.ReInitDlg( rWrtShell );
+}
+
+SwIndexMarkModalDlg::SwIndexMarkModalDlg(weld::Window *pParent, SwWrtShell& rSh, SwTOXMark const * pCurTOXMark)
+ : SfxDialogController(pParent, "modules/swriter/ui/indexentry.ui",
+ "IndexEntryDialog")
+ , m_aContent(m_xDialog, *m_xBuilder, false, &rSh)
+{
+ m_aContent.ReInitDlg(rSh, pCurTOXMark);
+}
+
+SwIndexMarkModalDlg::~SwIndexMarkModalDlg()
+{
+ SwViewShell::SetCareDialog(nullptr);
+}
+
+short SwIndexMarkModalDlg::run()
+{
+ short nRet = SfxDialogController::run();
+ if (RET_OK == nRet)
+ m_aContent.Apply();
+ return nRet;
+}
+
+namespace {
+
+class SwCreateAuthEntryDlg_Impl : public weld::GenericDialogController
+{
+ std::vector<std::unique_ptr<weld::Builder>> m_aBuilders;
+
+ Link<weld::Entry&,bool> m_aShortNameCheckLink;
+
+ SwWrtShell& m_rWrtSh;
+
+ bool m_bNewEntryMode;
+ bool m_bNameAllowed;
+
+ std::vector<std::unique_ptr<weld::Container>> m_aOrigContainers;
+ std::vector<std::unique_ptr<weld::Label>> m_aFixedTexts;
+ std::unique_ptr<weld::Box> m_pBoxes[AUTH_FIELD_END];
+ std::unique_ptr<weld::Entry> m_pEdits[AUTH_FIELD_END];
+ std::unique_ptr<weld::Button> m_xOKBT;
+ std::unique_ptr<weld::Container> m_xBox;
+ std::unique_ptr<weld::Container> m_xLeft;
+ std::unique_ptr<weld::Container> m_xRight;
+ std::unique_ptr<weld::ComboBox> m_xTypeListBox;
+ std::unique_ptr<weld::ComboBox> m_xIdentifierBox;
+ std::unique_ptr<weld::Button> m_xLocalBrowseButton;
+ std::unique_ptr<weld::CheckButton> m_xLocalPageCB;
+ std::unique_ptr<weld::SpinButton> m_xLocalPageSB;
+ std::unique_ptr<weld::ComboBox> m_xTargetTypeListBox;
+ weld::Entry* m_pTargetURLField;
+
+ DECL_LINK(IdentifierHdl, weld::ComboBox&, void);
+ DECL_LINK(ShortNameHdl, weld::Entry&, void);
+ DECL_LINK(EnableHdl, weld::ComboBox&, void);
+ DECL_LINK(BrowseHdl, weld::Button&, void);
+ DECL_LINK(PageNumHdl, weld::Toggleable&, void);
+ DECL_LINK(TargetTypeHdl, weld::ComboBox&, void);
+
+public:
+ SwCreateAuthEntryDlg_Impl(weld::Window* pParent,
+ const OUString pFields[],
+ SwWrtShell& rSh,
+ bool bNewEntry,
+ bool bCreate);
+
+ OUString GetEntryText(ToxAuthorityField eField) const;
+
+ void SetCheckNameHdl(const Link<weld::Entry&,bool>& rLink) {m_aShortNameCheckLink = rLink;}
+
+};
+
+struct TextInfo
+{
+ ToxAuthorityField nToxField;
+ const OUString pHelpId;
+};
+
+}
+
+const TextInfo aTextInfoArr[] =
+{
+ {AUTH_FIELD_IDENTIFIER, HID_AUTH_FIELD_IDENTIFIER },
+ {AUTH_FIELD_AUTHORITY_TYPE, HID_AUTH_FIELD_AUTHORITY_TYPE },
+ {AUTH_FIELD_AUTHOR, HID_AUTH_FIELD_AUTHOR },
+ {AUTH_FIELD_TITLE, HID_AUTH_FIELD_TITLE },
+ {AUTH_FIELD_YEAR, HID_AUTH_FIELD_YEAR },
+ {AUTH_FIELD_PUBLISHER, HID_AUTH_FIELD_PUBLISHER },
+ {AUTH_FIELD_ADDRESS, HID_AUTH_FIELD_ADDRESS },
+ {AUTH_FIELD_ISBN, HID_AUTH_FIELD_ISBN },
+ {AUTH_FIELD_CHAPTER, HID_AUTH_FIELD_CHAPTER },
+ {AUTH_FIELD_PAGES, HID_AUTH_FIELD_PAGES },
+ {AUTH_FIELD_EDITOR, HID_AUTH_FIELD_EDITOR },
+ {AUTH_FIELD_EDITION, HID_AUTH_FIELD_EDITION },
+ {AUTH_FIELD_BOOKTITLE, HID_AUTH_FIELD_BOOKTITLE },
+ {AUTH_FIELD_VOLUME, HID_AUTH_FIELD_VOLUME },
+ {AUTH_FIELD_HOWPUBLISHED, HID_AUTH_FIELD_HOWPUBLISHED },
+ {AUTH_FIELD_ORGANIZATIONS, HID_AUTH_FIELD_ORGANIZATIONS },
+ {AUTH_FIELD_INSTITUTION, HID_AUTH_FIELD_INSTITUTION },
+ {AUTH_FIELD_SCHOOL, HID_AUTH_FIELD_SCHOOL },
+ {AUTH_FIELD_REPORT_TYPE, HID_AUTH_FIELD_REPORT_TYPE },
+ {AUTH_FIELD_MONTH, HID_AUTH_FIELD_MONTH },
+ {AUTH_FIELD_JOURNAL, HID_AUTH_FIELD_JOURNAL },
+ {AUTH_FIELD_NUMBER, HID_AUTH_FIELD_NUMBER },
+ {AUTH_FIELD_SERIES, HID_AUTH_FIELD_SERIES },
+ {AUTH_FIELD_ANNOTE, HID_AUTH_FIELD_ANNOTE },
+ {AUTH_FIELD_NOTE, HID_AUTH_FIELD_NOTE },
+ {AUTH_FIELD_URL, HID_AUTH_FIELD_URL },
+ {AUTH_FIELD_TARGET_TYPE, HID_AUTH_FIELD_TARGET_TYPE },
+ {AUTH_FIELD_TARGET_URL, HID_AUTH_FIELD_TARGET_URL },
+ {AUTH_FIELD_LOCAL_URL, HID_AUTH_FIELD_LOCAL_URL },
+ {AUTH_FIELD_CUSTOM1, HID_AUTH_FIELD_CUSTOM1 },
+ {AUTH_FIELD_CUSTOM2, HID_AUTH_FIELD_CUSTOM2 },
+ {AUTH_FIELD_CUSTOM3, HID_AUTH_FIELD_CUSTOM3 },
+ {AUTH_FIELD_CUSTOM4, HID_AUTH_FIELD_CUSTOM4 },
+ {AUTH_FIELD_CUSTOM5, HID_AUTH_FIELD_CUSTOM5 }
+};
+
+static OUString lcl_FindColumnEntry(const uno::Sequence<beans::PropertyValue>& rFields, std::u16string_view rColumnTitle)
+{
+ for(const auto& rField : rFields)
+ {
+ OUString sRet;
+ if(rField.Name == rColumnTitle &&
+ (rField.Value >>= sRet))
+ {
+ return sRet;
+ }
+ }
+ return OUString();
+}
+
+bool SwAuthorMarkPane::s_bIsFromComponent = true;
+
+SwAuthorMarkPane::SwAuthorMarkPane(weld::DialogController &rDialog, weld::Builder& rBuilder, bool bNewDlg)
+ : m_rDialog(rDialog)
+ , m_bNewEntry(bNewDlg)
+ , m_bBibAccessInitialized(false)
+ , m_pSh(nullptr)
+ , m_xFromComponentRB(rBuilder.weld_radio_button("frombibliography"))
+ , m_xFromDocContentRB(rBuilder.weld_radio_button("fromdocument"))
+ , m_xAuthorFI(rBuilder.weld_label("author"))
+ , m_xTitleFI(rBuilder.weld_label("title"))
+ , m_xEntryED(rBuilder.weld_entry("entryed"))
+ , m_xEntryLB(rBuilder.weld_combo_box("entrylb"))
+ , m_xActionBT(rBuilder.weld_button(m_bNewEntry ? OUString("insert") : OUString("modify")))
+ , m_xCloseBT(rBuilder.weld_button("close"))
+ , m_xCreateEntryPB(rBuilder.weld_button("new"))
+ , m_xEditEntryPB(rBuilder.weld_button("edit"))
+{
+ m_xActionBT->show();
+ m_xFromComponentRB->set_visible(m_bNewEntry);
+ m_xFromDocContentRB->set_visible(m_bNewEntry);
+ m_xFromComponentRB->set_active(s_bIsFromComponent);
+ m_xFromDocContentRB->set_active(!s_bIsFromComponent);
+
+ m_xActionBT->connect_clicked(LINK(this,SwAuthorMarkPane, InsertHdl));
+ m_xCloseBT->connect_clicked(LINK(this,SwAuthorMarkPane, CloseHdl));
+ m_xCreateEntryPB->connect_clicked(LINK(this,SwAuthorMarkPane, CreateEntryHdl));
+ m_xEditEntryPB->connect_clicked(LINK(this,SwAuthorMarkPane, CreateEntryHdl));
+ m_xFromComponentRB->connect_toggled(LINK(this,SwAuthorMarkPane, ChangeSourceHdl));
+ m_xFromDocContentRB->connect_toggled(LINK(this,SwAuthorMarkPane, ChangeSourceHdl));
+ m_xEntryED->connect_changed(LINK(this,SwAuthorMarkPane, EditModifyHdl));
+
+ m_rDialog.set_title(SwResId(
+ m_bNewEntry ? STR_AUTHMRK_INSERT : STR_AUTHMRK_EDIT));
+
+ m_xEntryED->set_visible(!m_bNewEntry);
+ m_xEntryLB->set_visible(m_bNewEntry);
+ // tdf#90641 - sort bibliography entries by identifier
+ m_xEntryLB->make_sorted();
+ if (m_bNewEntry)
+ {
+ m_xEntryLB->connect_changed(LINK(this, SwAuthorMarkPane, CompEntryHdl));
+ }
+}
+
+void SwAuthorMarkPane::ReInitDlg(SwWrtShell& rWrtShell)
+{
+ m_pSh = &rWrtShell;
+ InitControls();
+}
+
+IMPL_LINK_NOARG(SwAuthorMarkPane, CloseHdl, weld::Button&, void)
+{
+ if(m_bNewEntry)
+ {
+ if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
+ {
+ pViewFrm->GetDispatcher()->Execute(FN_INSERT_AUTH_ENTRY_DLG,
+ SfxCallMode::ASYNCHRON|SfxCallMode::RECORD);
+ }
+ }
+ else
+ {
+ m_rDialog.response(RET_CANCEL);
+ }
+}
+
+IMPL_LINK( SwAuthorMarkPane, CompEntryHdl, weld::ComboBox&, rBox, void)
+{
+ const OUString sEntry(rBox.get_active_text());
+ if(s_bIsFromComponent)
+ {
+ if(m_xBibAccess.is() && !sEntry.isEmpty())
+ {
+ if(m_xBibAccess->hasByName(sEntry))
+ {
+ uno::Any aEntry(m_xBibAccess->getByName(sEntry));
+ uno::Sequence<beans::PropertyValue> aFieldProps;
+ if(aEntry >>= aFieldProps)
+ {
+ auto nSize = std::min(static_cast<sal_Int32>(AUTH_FIELD_END), aFieldProps.getLength());
+ for(sal_Int32 i = 0; i < nSize; i++)
+ {
+ m_sFields[i] = lcl_FindColumnEntry(aFieldProps, m_sColumnTitles[i]);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if(!sEntry.isEmpty())
+ {
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ const SwAuthEntry* pEntry = pFType ? pFType->GetEntryByIdentifier(sEntry) : nullptr;
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ m_sFields[i] = pEntry ?
+ pEntry->GetAuthorField(static_cast<ToxAuthorityField>(i)) : OUString();
+ }
+ }
+ if (rBox.get_active_text().isEmpty())
+ {
+ for(OUString & s : m_sFields)
+ s.clear();
+ }
+ m_xAuthorFI->set_label(m_sFields[AUTH_FIELD_AUTHOR]);
+ m_xTitleFI->set_label(m_sFields[AUTH_FIELD_TITLE]);
+}
+
+IMPL_LINK_NOARG(SwAuthorMarkPane, InsertHdl, weld::Button&, void)
+{
+ //insert or update the SwAuthorityField...
+ if(m_pSh)
+ {
+ bool bDifferent = false;
+ OSL_ENSURE(!m_sFields[AUTH_FIELD_IDENTIFIER].isEmpty() , "No Id is set!");
+ OSL_ENSURE(!m_sFields[AUTH_FIELD_AUTHORITY_TYPE].isEmpty() , "No authority type is set!");
+ //check if the entry already exists with different content
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ const SwAuthEntry* pEntry = pFType ?
+ pFType->GetEntryByIdentifier( m_sFields[AUTH_FIELD_IDENTIFIER])
+ : nullptr;
+ if(pEntry)
+ {
+ for(int i = 0; i < AUTH_FIELD_END && !bDifferent; i++)
+ bDifferent |= m_sFields[i] != pEntry->GetAuthorField(static_cast<ToxAuthorityField>(i));
+ if(bDifferent)
+ {
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(m_rDialog.getDialog(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ SwResId(STR_QUERY_CHANGE_AUTH_ENTRY)));
+ if (RET_YES != xQuery->run())
+ return;
+ }
+ }
+
+ SwFieldMgr aMgr(m_pSh);
+ OUStringBuffer sFields;
+ for(OUString & s : m_sFields)
+ {
+ sFields.append(s + OUStringChar(TOX_STYLE_DELIMITER));
+ }
+ if(m_bNewEntry)
+ {
+ if(bDifferent)
+ {
+ rtl::Reference<SwAuthEntry> xNewData(new SwAuthEntry);
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ xNewData->SetAuthorField(static_cast<ToxAuthorityField>(i), m_sFields[i]);
+ m_pSh->ChangeAuthorityData(xNewData.get());
+ }
+ SwInsertField_Data aData(SwFieldTypesEnum::Authority, 0, sFields.makeStringAndClear(), OUString(), 0 );
+ aMgr.InsertField( aData );
+ }
+ else if(aMgr.GetCurField())
+ {
+ aMgr.UpdateCurField(0, sFields.makeStringAndClear(), OUString());
+ }
+ }
+ if(!m_bNewEntry)
+ CloseHdl(*m_xCloseBT);
+}
+
+IMPL_LINK(SwAuthorMarkPane, CreateEntryHdl, weld::Button&, rButton, void)
+{
+ bool bCreate = &rButton == m_xCreateEntryPB.get();
+ OUString sOldId = m_sCreatedEntry[0];
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ m_sCreatedEntry[i] = bCreate ? OUString() : m_sFields[i];
+ SwCreateAuthEntryDlg_Impl aDlg(m_rDialog.getDialog(),
+ bCreate ? m_sCreatedEntry : m_sFields,
+ *m_pSh, m_bNewEntry, bCreate);
+ if(m_bNewEntry)
+ {
+ aDlg.SetCheckNameHdl(LINK(this, SwAuthorMarkPane, IsEntryAllowedHdl));
+ }
+ if(RET_OK != aDlg.run())
+ return;
+
+ if(bCreate && !sOldId.isEmpty())
+ {
+ m_xEntryLB->remove_text(sOldId);
+ }
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ {
+ m_sFields[i] = aDlg.GetEntryText(static_cast<ToxAuthorityField>(i));
+ m_sCreatedEntry[i] = m_sFields[i];
+ }
+ if(m_bNewEntry && !m_xFromDocContentRB->get_active())
+ {
+ m_xFromDocContentRB->set_active(true);
+ ChangeSourceHdl(*m_xFromDocContentRB);
+ }
+ if(bCreate)
+ {
+ OSL_ENSURE(m_xEntryLB->find_text(m_sFields[AUTH_FIELD_IDENTIFIER]) == -1,
+ "entry exists!");
+ m_xEntryLB->append_text(m_sFields[AUTH_FIELD_IDENTIFIER]);
+ m_xEntryLB->set_active_text(m_sFields[AUTH_FIELD_IDENTIFIER]);
+ }
+ m_xEntryED->set_text(m_sFields[AUTH_FIELD_IDENTIFIER]);
+ m_xAuthorFI->set_label(m_sFields[AUTH_FIELD_AUTHOR]);
+ m_xTitleFI->set_label(m_sFields[AUTH_FIELD_TITLE]);
+ m_xActionBT->set_sensitive(true);
+
+ if (!m_bNewEntry)
+ {
+ // When in edit mode, automatically apply the changed entry to update the field in the doc
+ // model.
+ InsertHdl(*m_xActionBT);
+ }
+}
+
+IMPL_LINK_NOARG(SwAuthorMarkPane, ChangeSourceHdl, weld::Toggleable&, void)
+{
+ bool bFromComp = m_xFromComponentRB->get_active();
+ s_bIsFromComponent = bFromComp;
+ m_xCreateEntryPB->set_sensitive(!s_bIsFromComponent);
+ m_xEntryLB->clear();
+ if(s_bIsFromComponent)
+ {
+ if(!m_bBibAccessInitialized)
+ {
+ uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext();
+ m_xBibAccess = frame::Bibliography::create( xContext );
+ uno::Reference< beans::XPropertySet > xPropSet(m_xBibAccess, uno::UNO_QUERY);
+ OUString uPropName("BibliographyDataFieldNames");
+ if(xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName(uPropName))
+ {
+ uno::Any aNames = xPropSet->getPropertyValue(uPropName);
+ uno::Sequence<beans::PropertyValue> aSeq;
+ if( aNames >>= aSeq)
+ {
+ for(const beans::PropertyValue& rProp : std::as_const(aSeq))
+ {
+ sal_Int16 nField = 0;
+ rProp.Value >>= nField;
+ if(nField >= 0 && nField < AUTH_FIELD_END)
+ m_sColumnTitles[nField] = rProp.Name;
+ }
+ }
+ }
+ m_bBibAccessInitialized = true;
+ }
+ if(m_xBibAccess.is())
+ {
+ const uno::Sequence<OUString> aIdentifiers = m_xBibAccess->getElementNames();
+ for(const OUString& rName : aIdentifiers)
+ m_xEntryLB->append_text(rName);
+ }
+ }
+ else
+ {
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ if(pFType)
+ {
+ std::vector<OUString> aIds;
+ pFType->GetAllEntryIdentifiers( aIds );
+ for(const OUString & i : aIds)
+ m_xEntryLB->append_text(i);
+ }
+ if(!m_sCreatedEntry[AUTH_FIELD_IDENTIFIER].isEmpty())
+ m_xEntryLB->append_text(m_sCreatedEntry[AUTH_FIELD_IDENTIFIER]);
+ }
+ m_xEntryLB->set_active(0);
+ CompEntryHdl(*m_xEntryLB);
+}
+
+IMPL_LINK(SwAuthorMarkPane, EditModifyHdl, weld::Entry&, rEdit, void)
+{
+ Link<weld::Entry&,bool> aAllowed = LINK(this, SwAuthorMarkPane, IsEditAllowedHdl);
+ bool bResult = aAllowed.Call(rEdit);
+ m_xActionBT->set_sensitive(bResult);
+ if(bResult)
+ {
+ OUString sEntry(rEdit.get_text());
+ m_sFields[AUTH_FIELD_IDENTIFIER] = sEntry;
+ m_sCreatedEntry[AUTH_FIELD_IDENTIFIER] = sEntry;
+ }
+};
+
+IMPL_LINK(SwAuthorMarkPane, IsEntryAllowedHdl, weld::Entry&, rEdit, bool)
+{
+ OUString sEntry = rEdit.get_text();
+ bool bAllowed = false;
+ if(!sEntry.isEmpty())
+ {
+ if (m_xEntryLB->find_text(sEntry) != -1)
+ return false;
+ else if(s_bIsFromComponent)
+ {
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ bAllowed = !pFType || !pFType->GetEntryByIdentifier(sEntry);
+ }
+ else
+ {
+ bAllowed = !m_xBibAccess.is() || !m_xBibAccess->hasByName(sEntry);
+ }
+ }
+ return bAllowed;
+}
+
+IMPL_LINK(SwAuthorMarkPane, IsEditAllowedHdl, weld::Entry&, rEdit, bool)
+{
+ OUString sEntry = rEdit.get_text();
+ bool bAllowed = false;
+ if(!sEntry.isEmpty())
+ {
+ if (m_xEntryLB->find_text(sEntry) != -1)
+ return false;
+ else if(s_bIsFromComponent)
+ {
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ bAllowed = !pFType || !pFType->GetEntryByIdentifier(sEntry);
+ }
+ else
+ {
+ bAllowed = !m_xBibAccess.is() || !m_xBibAccess->hasByName(sEntry);
+ }
+ }
+ return bAllowed;
+}
+
+void SwAuthorMarkPane::InitControls()
+{
+ OSL_ENSURE(m_pSh, "no shell?");
+ SwField* pField = m_pSh->GetCurField();
+ OSL_ENSURE(m_bNewEntry || pField, "no current marker");
+ if(m_bNewEntry)
+ {
+ ChangeSourceHdl(m_xFromComponentRB->get_active() ? *m_xFromComponentRB : *m_xFromDocContentRB);
+ m_xCreateEntryPB->set_sensitive(!m_xFromComponentRB->get_active());
+ if(!m_xFromComponentRB->get_active() && !m_sCreatedEntry[0].isEmpty())
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ m_sFields[i] = m_sCreatedEntry[i];
+ }
+ if(m_bNewEntry || !pField || pField->GetTyp()->Which() != SwFieldIds::TableOfAuthorities)
+ return;
+
+ const SwAuthEntry* pEntry = static_cast<SwAuthorityField*>(pField)->GetAuthEntry();
+
+ OSL_ENSURE(pEntry, "No authority entry found");
+ if(!pEntry)
+ return;
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ m_sFields[i] = pEntry->GetAuthorField(static_cast<ToxAuthorityField>(i));
+
+ m_xEntryED->set_text(pEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER));
+ m_xAuthorFI->set_label(pEntry->GetAuthorField(AUTH_FIELD_AUTHOR));
+ m_xTitleFI->set_label(pEntry->GetAuthorField(AUTH_FIELD_TITLE));
+}
+
+void SwAuthorMarkPane::Activate()
+{
+ m_xActionBT->set_sensitive(!m_pSh->HasReadonlySel());
+}
+
+namespace
+{
+ const TranslateId STR_AUTH_FIELD_ARY[] =
+ {
+ STR_AUTH_FIELD_IDENTIFIER,
+ STR_AUTH_FIELD_AUTHORITY_TYPE,
+ STR_AUTH_FIELD_ADDRESS,
+ STR_AUTH_FIELD_ANNOTE,
+ STR_AUTH_FIELD_AUTHOR,
+ STR_AUTH_FIELD_BOOKTITLE,
+ STR_AUTH_FIELD_CHAPTER,
+ STR_AUTH_FIELD_EDITION,
+ STR_AUTH_FIELD_EDITOR,
+ STR_AUTH_FIELD_HOWPUBLISHED,
+ STR_AUTH_FIELD_INSTITUTION,
+ STR_AUTH_FIELD_JOURNAL,
+ STR_AUTH_FIELD_MONTH,
+ STR_AUTH_FIELD_NOTE,
+ STR_AUTH_FIELD_NUMBER,
+ STR_AUTH_FIELD_ORGANIZATIONS,
+ STR_AUTH_FIELD_PAGES,
+ STR_AUTH_FIELD_PUBLISHER,
+ STR_AUTH_FIELD_SCHOOL,
+ STR_AUTH_FIELD_SERIES,
+ STR_AUTH_FIELD_TITLE,
+ STR_AUTH_FIELD_TYPE,
+ STR_AUTH_FIELD_VOLUME,
+ STR_AUTH_FIELD_YEAR,
+ STR_AUTH_FIELD_URL,
+ STR_AUTH_FIELD_CUSTOM1,
+ STR_AUTH_FIELD_CUSTOM2,
+ STR_AUTH_FIELD_CUSTOM3,
+ STR_AUTH_FIELD_CUSTOM4,
+ STR_AUTH_FIELD_CUSTOM5,
+ STR_AUTH_FIELD_ISBN,
+ STR_AUTH_FIELD_LOCAL_URL,
+ STR_AUTH_FIELD_TARGET_TYPE,
+ STR_AUTH_FIELD_TARGET_URL,
+ };
+}
+
+SwCreateAuthEntryDlg_Impl::SwCreateAuthEntryDlg_Impl(weld::Window* pParent,
+ const OUString pFields[],
+ SwWrtShell& rSh,
+ bool bNewEntry,
+ bool bCreate)
+ : GenericDialogController(pParent, "modules/swriter/ui/createauthorentry.ui", "CreateAuthorEntryDialog")
+ , m_rWrtSh(rSh)
+ , m_bNewEntryMode(bNewEntry)
+ , m_bNameAllowed(true)
+ , m_xOKBT(m_xBuilder->weld_button("ok"))
+ , m_xBox(m_xBuilder->weld_container("box"))
+ , m_xLeft(m_xBuilder->weld_container("leftgrid"))
+ , m_xRight(m_xBuilder->weld_container("rightgrid"))
+ , m_pTargetURLField(nullptr)
+{
+ bool bLeft = true;
+ sal_Int32 nLeftRow(0), nRightRow(0);
+ for(int nIndex = 0; nIndex < AUTH_FIELD_END; nIndex++)
+ {
+ //m_xBox parent just to have some parent during setup, added contents are not directly visible under m_xBox
+ m_aBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "modules/swriter/ui/bibliofragment.ui"));
+ const TextInfo aCurInfo = aTextInfoArr[nIndex];
+
+ m_aOrigContainers.emplace_back(m_aBuilders.back()->weld_container("biblioentry"));
+ m_aFixedTexts.emplace_back(m_aBuilders.back()->weld_label("label"));
+ if (bLeft)
+ m_aOrigContainers.back()->move(m_aFixedTexts.back().get(), m_xLeft.get());
+ else
+ m_aOrigContainers.back()->move(m_aFixedTexts.back().get(), m_xRight.get());
+ m_aFixedTexts.back()->set_grid_left_attach(0);
+ m_aFixedTexts.back()->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
+ m_aFixedTexts.back()->set_label(SwResId(STR_AUTH_FIELD_ARY[aCurInfo.nToxField]));
+ m_aFixedTexts.back()->show();
+ if( AUTH_FIELD_AUTHORITY_TYPE == aCurInfo.nToxField )
+ {
+ m_xTypeListBox = m_aBuilders.back()->weld_combo_box("listbox");
+ if (bLeft)
+ m_aOrigContainers.back()->move(m_xTypeListBox.get(), m_xLeft.get());
+ else
+ m_aOrigContainers.back()->move(m_xTypeListBox.get(), m_xRight.get());
+
+ for (int j = 0; j < AUTH_TYPE_END; j++)
+ {
+ m_xTypeListBox->append_text(
+ SwAuthorityFieldType::GetAuthTypeName(static_cast<ToxAuthorityType>(j)));
+ }
+ if(!pFields[aCurInfo.nToxField].isEmpty())
+ {
+ m_xTypeListBox->set_active(pFields[aCurInfo.nToxField].toInt32());
+ }
+ m_xTypeListBox->set_grid_left_attach(1);
+ m_xTypeListBox->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
+ m_xTypeListBox->set_hexpand(true);
+ m_xTypeListBox->show();
+ m_xTypeListBox->connect_changed(LINK(this, SwCreateAuthEntryDlg_Impl, EnableHdl));
+ m_xTypeListBox->set_help_id(aCurInfo.pHelpId);
+ m_aFixedTexts.back()->set_mnemonic_widget(m_xTypeListBox.get());
+ }
+ else if(AUTH_FIELD_IDENTIFIER == aCurInfo.nToxField && !m_bNewEntryMode)
+ {
+ m_xIdentifierBox = m_aBuilders.back()->weld_combo_box("combobox");
+ if (bLeft)
+ m_aOrigContainers.back()->move(m_xIdentifierBox.get(), m_xLeft.get());
+ else
+ m_aOrigContainers.back()->move(m_xIdentifierBox.get(), m_xRight.get());
+
+ m_xIdentifierBox->connect_changed(LINK(this,
+ SwCreateAuthEntryDlg_Impl, IdentifierHdl));
+
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ rSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ if(pFType)
+ {
+ std::vector<OUString> aIds;
+ pFType->GetAllEntryIdentifiers( aIds );
+ for (const OUString& a : aIds)
+ m_xIdentifierBox->append_text(a);
+ }
+ m_xIdentifierBox->set_entry_text(pFields[aCurInfo.nToxField]);
+ m_xIdentifierBox->set_grid_left_attach(1);
+ m_xIdentifierBox->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
+ m_xIdentifierBox->set_hexpand(true);
+ m_xIdentifierBox->show();
+ m_xIdentifierBox->set_help_id(aCurInfo.pHelpId);
+ m_aFixedTexts.back()->set_mnemonic_widget(m_xIdentifierBox.get());
+ }
+ else if (AUTH_FIELD_TARGET_TYPE == aCurInfo.nToxField)
+ {
+ m_xTargetTypeListBox = m_aBuilders.back()->weld_combo_box("listbox-target-type");
+ if (bLeft)
+ m_aOrigContainers.back()->move(m_xTargetTypeListBox.get(), m_xLeft.get());
+ else
+ m_aOrigContainers.back()->move(m_xTargetTypeListBox.get(), m_xRight.get());
+
+ if(!pFields[aCurInfo.nToxField].isEmpty())
+ {
+ m_xTargetTypeListBox->set_active(pFields[aCurInfo.nToxField].toInt32());
+ }
+ else if(m_bNewEntryMode)
+ {
+ // For new documents, set value to "BibliographyTableRow"
+ m_xTargetTypeListBox->set_active(SwAuthorityField::TargetType::BibliographyTableRow);
+ }
+ m_xTargetTypeListBox->set_grid_left_attach(1);
+ m_xTargetTypeListBox->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
+ m_xTargetTypeListBox->set_hexpand(true);
+ m_xTargetTypeListBox->show();
+ m_xTargetTypeListBox->connect_changed(LINK(this, SwCreateAuthEntryDlg_Impl, TargetTypeHdl));
+ m_xTargetTypeListBox->set_help_id(aCurInfo.pHelpId);
+ m_aFixedTexts.back()->set_mnemonic_widget(m_xTargetTypeListBox.get());
+ }
+ else
+ {
+ m_pBoxes[nIndex] = m_aBuilders.back()->weld_box("vbox");
+ m_pEdits[nIndex] = m_aBuilders.back()->weld_entry("entry");
+
+ if (AUTH_FIELD_TARGET_URL == aCurInfo.nToxField)
+ {
+ m_pTargetURLField = m_pEdits[nIndex].get();
+ assert(m_xTargetTypeListBox);
+ m_pTargetURLField->set_sensitive(
+ m_xTargetTypeListBox->get_active() == SwAuthorityField::TargetType::UseTargetURL);
+ }
+
+ if (bLeft)
+ m_aOrigContainers.back()->move(m_pBoxes[nIndex].get(), m_xLeft.get());
+ else
+ m_aOrigContainers.back()->move(m_pBoxes[nIndex].get(), m_xRight.get());
+
+ m_pBoxes[nIndex]->set_grid_left_attach(1);
+ m_pBoxes[nIndex]->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
+ m_pBoxes[nIndex]->set_hexpand(true);
+ if (aCurInfo.nToxField == AUTH_FIELD_LOCAL_URL)
+ {
+ m_xLocalBrowseButton = m_aBuilders.back()->weld_button("browse");
+ m_xLocalBrowseButton->connect_clicked(
+ LINK(this, SwCreateAuthEntryDlg_Impl, BrowseHdl));
+ m_xLocalPageCB = m_aBuilders.back()->weld_check_button("pagecb");
+ // Distinguish different instances of this for ui-testing.
+ m_xLocalPageCB->set_buildable_name(m_xLocalPageCB->get_buildable_name()
+ + "-local-visible");
+ m_xLocalPageSB = m_aBuilders.back()->weld_spin_button("pagesb");
+ }
+
+ // Now that both pEdits[nIndex] and m_xPageSB is initialized, set their values.
+ OUString aText = pFields[aCurInfo.nToxField];
+ if (aCurInfo.nToxField == AUTH_FIELD_LOCAL_URL)
+ {
+ OUString aUrl;
+ int nPageNumber;
+ if (SplitUrlAndPage(aText, aUrl, nPageNumber))
+ {
+ m_pEdits[nIndex]->set_text(aUrl);
+ m_xLocalPageCB->set_active(true);
+ m_xLocalPageSB->set_sensitive(true);
+ m_xLocalPageSB->set_value(nPageNumber);
+ }
+ else
+ {
+ m_pEdits[nIndex]->set_text(aText);
+ }
+ }
+ else
+ {
+ m_pEdits[nIndex]->set_text(aText);
+ }
+ m_pEdits[nIndex]->show();
+ m_pEdits[nIndex]->set_help_id(aCurInfo.pHelpId);
+
+ if(AUTH_FIELD_IDENTIFIER == aCurInfo.nToxField)
+ {
+ m_pEdits[nIndex]->connect_changed(LINK(this, SwCreateAuthEntryDlg_Impl, ShortNameHdl));
+ m_bNameAllowed = !pFields[nIndex].isEmpty();
+ if(!bCreate)
+ {
+ m_aFixedTexts.back()->set_sensitive(false);
+ m_pEdits[nIndex]->set_sensitive(false);
+ }
+ }
+ else if (aCurInfo.nToxField == AUTH_FIELD_LOCAL_URL)
+ {
+ m_xLocalPageCB->show();
+ m_xLocalPageCB->connect_toggled(LINK(this, SwCreateAuthEntryDlg_Impl, PageNumHdl));
+ m_xLocalPageSB->show();
+ }
+
+ m_aFixedTexts.back()->set_mnemonic_widget(m_pEdits[nIndex].get());
+ }
+ if(bLeft)
+ ++nLeftRow;
+ else
+ ++nRightRow;
+ bLeft = !bLeft;
+ }
+ assert(m_xTypeListBox && "this will exist after the loop");
+ EnableHdl(*m_xTypeListBox);
+}
+
+OUString SwCreateAuthEntryDlg_Impl::GetEntryText(ToxAuthorityField eField) const
+{
+ if( AUTH_FIELD_AUTHORITY_TYPE == eField )
+ {
+ assert(m_xTypeListBox && "No ListBox");
+ return OUString::number(m_xTypeListBox->get_active());
+ }
+
+ if( AUTH_FIELD_IDENTIFIER == eField && !m_bNewEntryMode)
+ {
+ assert(m_xIdentifierBox && "No ComboBox");
+ return m_xIdentifierBox->get_active_text();
+ }
+
+ if (AUTH_FIELD_TARGET_TYPE == eField)
+ {
+ assert(m_xTargetTypeListBox && "No TargetType ListBox");
+ return OUString::number(m_xTargetTypeListBox->get_active());
+ }
+
+ for(int nIndex = 0; nIndex < AUTH_FIELD_END; nIndex++)
+ {
+ const TextInfo aCurInfo = aTextInfoArr[nIndex];
+ if(aCurInfo.nToxField == eField)
+ {
+ if (aCurInfo.nToxField == AUTH_FIELD_LOCAL_URL)
+ {
+ return MergeUrlAndPage(m_pEdits[nIndex]->get_text(), m_xLocalPageSB);
+ }
+ else
+ {
+ return m_pEdits[nIndex]->get_text();
+ }
+ }
+ }
+
+ return OUString();
+}
+
+IMPL_LINK(SwCreateAuthEntryDlg_Impl, IdentifierHdl, weld::ComboBox&, rBox, void)
+{
+ const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
+ m_rWrtSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
+ if(!pFType)
+ return;
+
+ const SwAuthEntry* pEntry = pFType->GetEntryByIdentifier(
+ rBox.get_active_text());
+ if(!pEntry)
+ return;
+
+ for(int i = 0; i < AUTH_FIELD_END; i++)
+ {
+ const TextInfo aCurInfo = aTextInfoArr[i];
+ if(AUTH_FIELD_IDENTIFIER == aCurInfo.nToxField)
+ continue;
+ if(AUTH_FIELD_AUTHORITY_TYPE == aCurInfo.nToxField)
+ m_xTypeListBox->set_active_text(
+ pEntry->GetAuthorField(aCurInfo.nToxField));
+ else
+ m_pEdits[i]->set_text(
+ pEntry->GetAuthorField(aCurInfo.nToxField));
+ }
+}
+
+IMPL_LINK(SwCreateAuthEntryDlg_Impl, ShortNameHdl, weld::Entry&, rEdit, void)
+{
+ if (m_aShortNameCheckLink.IsSet())
+ {
+ bool bEnable = m_aShortNameCheckLink.Call(rEdit);
+ m_bNameAllowed |= bEnable;
+ m_xOKBT->set_sensitive(m_xTypeListBox->get_active() != -1 && bEnable);
+ }
+}
+
+IMPL_LINK(SwCreateAuthEntryDlg_Impl, EnableHdl, weld::ComboBox&, rBox, void)
+{
+ m_xOKBT->set_sensitive(m_bNameAllowed && rBox.get_active() != -1);
+ m_xLocalBrowseButton->show();
+};
+
+IMPL_LINK(SwCreateAuthEntryDlg_Impl, TargetTypeHdl, weld::ComboBox&, rBox, void)
+{
+ assert(m_pTargetURLField);
+ m_pTargetURLField->set_sensitive(rBox.get_active() == SwAuthorityField::TargetType::UseTargetURL);
+}
+
+IMPL_LINK(SwCreateAuthEntryDlg_Impl, BrowseHdl, weld::Button&, rButton, void)
+{
+ sfx2::FileDialogHelper aFileDlg(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, getDialog());
+ OUString aPath;
+ if (&rButton == m_xLocalBrowseButton.get())
+ {
+ aPath = GetEntryText(AUTH_FIELD_LOCAL_URL);
+ }
+ if (!aPath.isEmpty())
+ {
+ aFileDlg.SetDisplayDirectory(aPath);
+ }
+ else
+ {
+ OUString aBaseURL = m_rWrtSh.GetDoc()->GetDocShell()->getDocumentBaseURL();
+ if (!aBaseURL.isEmpty())
+ {
+ aFileDlg.SetDisplayDirectory(aBaseURL);
+ }
+ }
+
+ if (aFileDlg.Execute() != ERRCODE_NONE)
+ {
+ return;
+ }
+
+ aPath = aFileDlg.GetPath();
+
+ for (int nIndex = 0; nIndex < AUTH_FIELD_END; nIndex++)
+ {
+ const TextInfo& rCurInfo = aTextInfoArr[nIndex];
+ if (rCurInfo.nToxField == AUTH_FIELD_LOCAL_URL && &rButton == m_xLocalBrowseButton.get())
+ {
+ m_pEdits[nIndex]->set_text(aPath);
+ break;
+ }
+ }
+};
+
+IMPL_LINK(SwCreateAuthEntryDlg_Impl, PageNumHdl, weld::Toggleable&, rPageCB, void)
+{
+ if (rPageCB.get_active())
+ {
+ m_xLocalPageSB->set_sensitive(true);
+ m_xLocalPageSB->set_value(1);
+ }
+ else
+ {
+ m_xLocalPageSB->set_sensitive(false);
+ }
+}
+
+SwAuthMarkFloatDlg::SwAuthMarkFloatDlg(SfxBindings* _pBindings,
+ SfxChildWindow* pChild,
+ weld::Window *pParent,
+ SfxChildWinInfo const * pInfo,
+ bool bNew)
+ : SfxModelessDialogController(_pBindings, pChild, pParent,
+ "modules/swriter/ui/bibliographyentry.ui", "BibliographyEntryDialog")
+ , m_aContent(*this, *m_xBuilder, bNew)
+{
+ Initialize(pInfo);
+ if (SwWrtShell* pWrtShell = ::GetActiveWrtShell())
+ m_aContent.ReInitDlg(*pWrtShell);
+}
+
+void SwAuthMarkFloatDlg::Activate()
+{
+ SfxModelessDialogController::Activate();
+ m_aContent.Activate();
+}
+
+void SwAuthMarkFloatDlg::ReInitDlg(SwWrtShell& rWrtShell)
+{
+ m_aContent.ReInitDlg( rWrtShell );
+}
+
+SwAuthMarkModalDlg::SwAuthMarkModalDlg(weld::Window *pParent, SwWrtShell& rSh)
+ : SfxDialogController(pParent, "modules/swriter/ui/bibliographyentry.ui",
+ "BibliographyEntryDialog")
+ , m_aContent(*this, *m_xBuilder, false)
+{
+ m_aContent.ReInitDlg(rSh);
+}
+
+short SwAuthMarkModalDlg::run()
+{
+ short ret = SfxDialogController::run();
+ if (ret == RET_OK)
+ Apply();
+ return ret;
+}
+
+void SwAuthMarkModalDlg::Apply()
+{
+ m_aContent.InsertHdl(*m_aContent.m_xActionBT);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/bookmark.cxx b/sw/source/ui/misc/bookmark.cxx
new file mode 100644
index 0000000000..6431809c95
--- /dev/null
+++ b/sw/source/ui/misc/bookmark.cxx
@@ -0,0 +1,590 @@
+/* -*- 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 <rtl/ustrbuf.hxx>
+#include <sfx2/request.hxx>
+#include <svl/stritem.hxx>
+#include <unotools/viewoptions.hxx>
+#include <vcl/weld.hxx>
+#include <o3tl/string_view.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XBookmarksSupplier.hpp>
+#include <officecfg/Office/Common.hxx>
+
+#include <swabstdlg.hxx>
+#include <swuiexp.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+#include <bookmark.hxx>
+#include <docsh.hxx>
+#include <ndtxt.hxx>
+#include <strings.hrc>
+#include <IDocumentSettingAccess.hxx>
+
+using namespace ::com::sun::star;
+
+const char BookmarkTable::s_cSeparator(';');
+
+// callback to modify EditBox
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, ModifyHdl, weld::Entry&, void)
+{
+ ValidateBookmarks();
+ m_xBookmarksBox->unselect_all();
+ // if a string has been pasted from the clipboard then
+ // there may be illegal characters in the box
+ // sanitization
+ OUString sTmp = m_xEditBox->get_text();
+ OUString sMsg;
+ const sal_Int32 nLen = sTmp.getLength();
+ for (sal_Int32 i = 0; i < BookmarkTable::aForbiddenChars.getLength(); i++)
+ {
+ const sal_Int32 nTmpLen = sTmp.getLength();
+ sTmp = sTmp.replaceAll(OUStringChar(BookmarkTable::aForbiddenChars.getStr()[i]), "");
+ if (sTmp.getLength() != nTmpLen)
+ sMsg += OUStringChar(BookmarkTable::aForbiddenChars.getStr()[i]);
+ }
+ const bool bHasForbiddenChars = sTmp.getLength() != nLen;
+ m_xForbiddenChars->set_visible(bHasForbiddenChars);
+ if (bHasForbiddenChars)
+ m_xEditBox->set_message_type(weld::EntryMessageType::Error);
+ else
+ m_xEditBox->set_message_type(weld::EntryMessageType::Normal);
+
+ sal_Int32 nSelectedEntries = 0;
+ sal_Int32 nEntries = 0;
+ sal_Int32 nTokenIndex = 0;
+ while (!sTmp.isEmpty() && nTokenIndex >= 0)
+ {
+ OUString aToken = sTmp.getToken(0, BookmarkTable::s_cSeparator, nTokenIndex);
+ if (m_xBookmarksBox->GetBookmarkByName(aToken))
+ {
+ m_xBookmarksBox->SelectByName(aToken);
+ nSelectedEntries++;
+ }
+ nEntries++;
+ }
+
+ // allow to add new bookmark only if one name provided and it's not taken
+ m_xInsertBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 0 && !bHasForbiddenChars
+ && !m_bAreProtected);
+
+ // allow to delete only if all bookmarks are recognized
+ m_xDeleteBtn->set_sensitive(nEntries > 0 && nSelectedEntries == nEntries && !m_bAreProtected);
+ m_xGotoBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1);
+ m_xEditTextBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1);
+ m_xRenameBtn->set_sensitive(nEntries == 1 && nSelectedEntries == 1 && !m_bAreProtected);
+}
+
+// callback to delete a text mark
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, DeleteHdl, weld::Button&, void)
+{
+ if (!ValidateBookmarks())
+ return;
+
+ int nSelectedRows(0);
+
+ m_xBookmarksBox->selected_foreach([this, &nSelectedRows](weld::TreeIter& rEntry) {
+ // remove from model
+ sw::mark::IMark* pBookmark
+ = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rEntry));
+ OUString sRemoved = pBookmark->GetName();
+ IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
+ pMarkAccess->deleteMark(pMarkAccess->findMark(sRemoved), false);
+ SfxRequest aReq(m_rSh.GetView().GetViewFrame(), FN_DELETE_BOOKMARK);
+ aReq.AppendItem(SfxStringItem(FN_DELETE_BOOKMARK, sRemoved));
+ aReq.Done();
+ std::erase(m_aTableBookmarks, std::make_pair(pBookmark, sRemoved));
+
+ ++nSelectedRows;
+
+ return false;
+ });
+
+ if (!nSelectedRows)
+ return;
+
+ // remove from BookmarkTable
+ m_xBookmarksBox->remove_selection();
+
+ ValidateBookmarks();
+
+ m_xDeleteBtn->set_sensitive(false);
+ m_xGotoBtn->set_sensitive(false);
+ m_xEditTextBtn->set_sensitive(false);
+ m_xRenameBtn->set_sensitive(false);
+ m_xInsertBtn->set_sensitive(false);
+}
+
+// callback to a goto button
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, GotoHdl, weld::Button&, void) { GotoSelectedBookmark(); }
+
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, DoubleClickHdl, weld::TreeView&, bool)
+{
+ GotoSelectedBookmark();
+ return true;
+}
+
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, SelectionChangedHdl, weld::TreeView&, void)
+{
+ if (!ValidateBookmarks())
+ return;
+ // this event should fired only if we change selection by clicking on BookmarkTable entry
+ if (!m_xBookmarksBox->has_focus())
+ return;
+
+ SelectionChanged();
+}
+
+void SwInsertBookmarkDlg::SelectionChanged()
+{
+ OUStringBuffer sEditBoxText;
+ int nSelectedRows = 0;
+ m_xBookmarksBox->selected_foreach(
+ [this, &sEditBoxText, &nSelectedRows](weld::TreeIter& rEntry) {
+ sw::mark::IMark* pBookmark
+ = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rEntry));
+ const OUString& sEntryName = pBookmark->GetName();
+ if (!sEditBoxText.isEmpty())
+ sEditBoxText.append(";");
+ sEditBoxText.append(sEntryName);
+ ++nSelectedRows;
+ return false;
+ });
+ if (nSelectedRows)
+ {
+ m_xInsertBtn->set_sensitive(false);
+ m_xGotoBtn->set_sensitive(nSelectedRows == 1);
+ m_xEditTextBtn->set_sensitive(nSelectedRows == 1);
+ m_xRenameBtn->set_sensitive(nSelectedRows == 1 && !m_bAreProtected);
+ m_xDeleteBtn->set_sensitive(!m_bAreProtected);
+ m_xEditBox->set_text(sEditBoxText.makeStringAndClear());
+ }
+ else
+ {
+ m_xInsertBtn->set_sensitive(!m_bAreProtected);
+ m_xGotoBtn->set_sensitive(false);
+ m_xEditTextBtn->set_sensitive(false);
+ m_xRenameBtn->set_sensitive(false);
+ m_xDeleteBtn->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, EditTextHdl, weld::Button&, void)
+{
+ if (!ValidateBookmarks())
+ return;
+ auto pSelected = m_xBookmarksBox->get_selected();
+ if (!pSelected)
+ return;
+
+ m_xBookmarksBox->start_editing(*pSelected);
+}
+
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, RenameHdl, weld::Button&, void)
+{
+ if (!ValidateBookmarks())
+ return;
+ auto xSelected = m_xBookmarksBox->get_selected();
+ if (!xSelected)
+ return;
+
+ sw::mark::IMark* pBookmark
+ = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(*xSelected));
+ uno::Reference<frame::XModel> xModel = m_rSh.GetView().GetDocShell()->GetBaseModel();
+ uno::Reference<text::XBookmarksSupplier> xBkms(xModel, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xNameAccess = xBkms->getBookmarks();
+ uno::Any aObj = xNameAccess->getByName(pBookmark->GetName());
+ uno::Reference<uno::XInterface> xTmp;
+ aObj >>= xTmp;
+ uno::Reference<container::XNamed> xNamed(xTmp, uno::UNO_QUERY);
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+ ScopedVclPtr<AbstractSwRenameXNamedDlg> pDlg(
+ rFact.CreateSwRenameXNamedDlg(m_xDialog.get(), xNamed, xNameAccess));
+ pDlg->SetForbiddenChars(BookmarkTable::aForbiddenChars
+ + OUStringChar(BookmarkTable::s_cSeparator));
+
+ if (pDlg->Execute())
+ {
+ ValidateBookmarks();
+ m_xDeleteBtn->set_sensitive(false);
+ m_xGotoBtn->set_sensitive(false);
+ m_xEditTextBtn->set_sensitive(false);
+ m_xRenameBtn->set_sensitive(false);
+ m_xInsertBtn->set_sensitive(false);
+ }
+}
+
+// callback to an insert button. Inserts a new text mark to the current position.
+IMPL_LINK_NOARG(SwInsertBookmarkDlg, InsertHdl, weld::Button&, void)
+{
+ OUString sBookmark = m_xEditBox->get_text();
+ m_rSh.SetBookmark2(vcl::KeyCode(), sBookmark, m_xHideCB->get_active(),
+ m_xConditionED->get_text());
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwInsertBookmarkDlg, ChangeHideHdl, weld::Toggleable&, rBox, void)
+{
+ bool bHide = rBox.get_active();
+ m_xConditionED->set_sensitive(bHide);
+ m_xConditionFT->set_sensitive(bHide);
+}
+
+IMPL_LINK(SwInsertBookmarkDlg, EditingHdl, weld::TreeIter const&, rIter, bool)
+{
+ sw::mark::IMark const* const pBookmark(
+ weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rIter)));
+ assert(pBookmark);
+ return pBookmark->IsExpanded()
+ && pBookmark->GetMarkPos().GetNode() == pBookmark->GetOtherMarkPos().GetNode()
+ && !m_xBookmarksBox->get_text(rIter).endsWith(u"…");
+}
+
+IMPL_LINK(SwInsertBookmarkDlg, EditedHdl, weld::TreeView::iter_string const&, rIterString, bool)
+{
+ sw::mark::IMark const* const pBookmark(
+ weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(rIterString.first)));
+ assert(pBookmark);
+ bool bRet(false);
+ if (pBookmark->GetMarkPos() != pBookmark->GetOtherMarkPos())
+ {
+ if (pBookmark->GetMarkPos().GetNode() != pBookmark->GetOtherMarkPos().GetNode())
+ {
+ return false; // don't allow editing if it spans multiple nodes
+ }
+ m_rSh.Push();
+ m_rSh.GotoMark(pBookmark);
+ // GetSelText only works for 1 paragraph, but it's checked above
+ if (m_rSh.GetSelText() != rIterString.second)
+ {
+ bRet = m_rSh.Replace(rIterString.second, false);
+ }
+ m_rSh.Pop(SwEditShell::PopMode::DeleteCurrent);
+ }
+ else if (pBookmark->IsExpanded() && !rIterString.second.isEmpty())
+ { // SwEditShell::Replace does nothing for empty selection
+ m_rSh.Insert(rIterString.second);
+ bRet = true;
+ }
+ return bRet;
+}
+
+void SwInsertBookmarkDlg::GotoSelectedBookmark()
+{
+ if (!ValidateBookmarks())
+ return;
+ // if no entries selected we can't jump anywhere
+ // shouldn't be needed as we disable GoTo button when jump is not possible
+ auto xSelected = m_xBookmarksBox->get_selected();
+ if (!xSelected)
+ return;
+
+ sw::mark::IMark* pBookmark
+ = weld::fromId<sw::mark::IMark*>(m_xBookmarksBox->get_id(*xSelected));
+
+ m_rSh.EnterStdMode();
+ m_rSh.GotoMark(pBookmark);
+}
+
+bool SwInsertBookmarkDlg::ValidateBookmarks()
+{
+ if (HaveBookmarksChanged())
+ {
+ PopulateTable();
+ m_xEditBox->set_text("");
+ return false;
+ }
+ return true;
+}
+
+bool SwInsertBookmarkDlg::HaveBookmarksChanged()
+{
+ IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
+ if (pMarkAccess->getBookmarksCount() != m_nLastBookmarksCount)
+ return true;
+
+ std::vector<std::pair<sw::mark::IMark*, OUString>>::const_iterator aListIter
+ = m_aTableBookmarks.begin();
+ for (IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
+ ppBookmark != pMarkAccess->getBookmarksEnd(); ++ppBookmark)
+ {
+ if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
+ {
+ // more bookmarks then expected
+ if (aListIter == m_aTableBookmarks.end())
+ return true;
+ if (aListIter->first != *ppBookmark || aListIter->second != (*ppBookmark)->GetName())
+ return true;
+ ++aListIter;
+ }
+ }
+ // less bookmarks then expected
+ return aListIter != m_aTableBookmarks.end();
+}
+
+void SwInsertBookmarkDlg::PopulateTable()
+{
+ m_aTableBookmarks.clear();
+ m_xBookmarksBox->clear();
+
+ IDocumentMarkAccess* const pMarkAccess = m_rSh.getIDocumentMarkAccess();
+ for (IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
+ ppBookmark != pMarkAccess->getBookmarksEnd(); ++ppBookmark)
+ {
+ if (IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
+ {
+ m_xBookmarksBox->InsertBookmark(m_rSh, *ppBookmark);
+ m_aTableBookmarks.emplace_back(*ppBookmark, (*ppBookmark)->GetName());
+ }
+ }
+ m_nLastBookmarksCount = pMarkAccess->getBookmarksCount();
+}
+
+SwInsertBookmarkDlg::SwInsertBookmarkDlg(weld::Window* pParent, SwWrtShell& rS,
+ OUString const* const pSelected)
+ : SfxDialogController(pParent, "modules/swriter/ui/insertbookmark.ui", "InsertBookmarkDialog")
+ , m_rSh(rS)
+ , m_nLastBookmarksCount(0)
+ , m_bSorted(false)
+ , m_xEditBox(m_xBuilder->weld_entry("name"))
+ , m_xInsertBtn(m_xBuilder->weld_button("insert"))
+ , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
+ , m_xGotoBtn(m_xBuilder->weld_button("goto"))
+ , m_xEditTextBtn(m_xBuilder->weld_button("edittext"))
+ , m_xRenameBtn(m_xBuilder->weld_button("rename"))
+ , m_xHideCB(m_xBuilder->weld_check_button("hide"))
+ , m_xConditionFT(m_xBuilder->weld_label("condlabel"))
+ , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry("withcond")))
+ , m_xBookmarksBox(new BookmarkTable(m_xBuilder->weld_tree_view("bookmarks")))
+ , m_xForbiddenChars(m_xBuilder->weld_label("lbForbiddenChars"))
+{
+ m_xBookmarksBox->connect_changed(LINK(this, SwInsertBookmarkDlg, SelectionChangedHdl));
+ m_xBookmarksBox->connect_row_activated(LINK(this, SwInsertBookmarkDlg, DoubleClickHdl));
+ m_xBookmarksBox->connect_column_clicked(LINK(this, SwInsertBookmarkDlg, HeaderBarClick));
+ m_xBookmarksBox->connect_editing(LINK(this, SwInsertBookmarkDlg, EditingHdl),
+ LINK(this, SwInsertBookmarkDlg, EditedHdl));
+ m_xEditBox->connect_changed(LINK(this, SwInsertBookmarkDlg, ModifyHdl));
+ m_xInsertBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, InsertHdl));
+ m_xDeleteBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, DeleteHdl));
+ m_xGotoBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, GotoHdl));
+ m_xEditTextBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, EditTextHdl));
+ m_xRenameBtn->connect_clicked(LINK(this, SwInsertBookmarkDlg, RenameHdl));
+ m_xHideCB->connect_toggled(LINK(this, SwInsertBookmarkDlg, ChangeHideHdl));
+
+ m_xDeleteBtn->set_sensitive(false);
+ m_xGotoBtn->set_sensitive(false);
+ m_xEditTextBtn->set_sensitive(false);
+ m_xRenameBtn->set_sensitive(false);
+
+ // select 3rd column, otherwise it'll pick 1st one
+ m_xBookmarksBox->set_column_editables({ false, false, true, false, false });
+
+ PopulateTable();
+
+ m_xEditBox->set_text(m_xBookmarksBox->GetNameProposal());
+ m_xEditBox->set_position(-1);
+
+ m_xForbiddenChars->set_label(SwResId(STR_BOOKMARK_FORBIDDENCHARS) + " "
+ + BookmarkTable::aForbiddenChars);
+ m_xForbiddenChars->set_visible(false);
+
+ if (!officecfg::Office::Common::Misc::ExperimentalMode::get())
+ {
+ m_xHideCB->set_visible(false);
+ m_xConditionFT->set_visible(false);
+ m_xConditionED->set_visible(false);
+ }
+
+ m_bAreProtected = m_rSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS);
+
+ // disabled until "Hide" flag is not checked
+ m_xConditionED->set_sensitive(false);
+ m_xConditionFT->set_sensitive(false);
+
+ // restore dialog size
+ SvtViewOptions aDlgOpt(EViewType::Dialog, "BookmarkDialog");
+ if (aDlgOpt.Exists())
+ m_xDialog->set_window_state(aDlgOpt.GetWindowState());
+
+ if (pSelected)
+ {
+ if (m_xBookmarksBox->SelectByName(*pSelected))
+ {
+ SelectionChanged();
+ // which is better, focus on a button or focus on the table row?
+ // as long as editing doesn't work via the TreeView with VCL
+ // widgets, better on button.
+ m_xEditTextBtn->grab_focus();
+ }
+ }
+}
+
+SwInsertBookmarkDlg::~SwInsertBookmarkDlg()
+{
+ // tdf#146261 - Remember size of bookmark dialog
+ SvtViewOptions aDlgOpt(EViewType::Dialog, "BookmarkDialog");
+ OUString sWindowState = m_xDialog->get_window_state(vcl::WindowDataMask::PosSize);
+ aDlgOpt.SetWindowState(sWindowState);
+}
+
+IMPL_LINK(SwInsertBookmarkDlg, HeaderBarClick, int, nColumn, void)
+{
+ if (!m_bSorted)
+ {
+ m_xBookmarksBox->make_sorted();
+ m_bSorted = true;
+ }
+
+ bool bSortAtoZ = m_xBookmarksBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xBookmarksBox->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xBookmarksBox->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ int nOldSortColumn = m_xBookmarksBox->get_sort_column();
+ if (nOldSortColumn != -1)
+ m_xBookmarksBox->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
+ m_xBookmarksBox->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xBookmarksBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+BookmarkTable::BookmarkTable(std::unique_ptr<weld::TreeView> xControl)
+ : m_xControl(std::move(xControl))
+{
+ m_xControl->set_size_request(-1, m_xControl->get_height_rows(8));
+ m_xControl->set_column_fixed_widths({ 40, 110, 150, 160 });
+ m_xControl->set_selection_mode(SelectionMode::Multiple);
+}
+
+std::unique_ptr<weld::TreeIter> BookmarkTable::get_selected() const
+{
+ std::unique_ptr<weld::TreeIter> xIter(m_xControl->make_iterator());
+ if (!m_xControl->get_selected(xIter.get()))
+ xIter.reset();
+ return xIter;
+}
+
+void BookmarkTable::InsertBookmark(SwWrtShell& rSh, sw::mark::IMark* const pMark)
+{
+ sw::mark::IBookmark* pBookmark = dynamic_cast<sw::mark::IBookmark*>(pMark);
+ assert(pBookmark);
+
+ OUString sBookmarkNodeText;
+ static const sal_Int32 nMaxTextLen = 50;
+
+ if (pBookmark->IsExpanded())
+ {
+ rSh.Push();
+ rSh.GotoMark(pBookmark);
+ rSh.GetSelectedText(sBookmarkNodeText, ParaBreakType::ToBlank);
+ rSh.Pop(SwEditShell::PopMode::DeleteCurrent);
+ }
+ if (nMaxTextLen < sBookmarkNodeText.getLength())
+ {
+ sBookmarkNodeText = sBookmarkNodeText.subView(0, nMaxTextLen);
+ ;
+ sBookmarkNodeText += u"…";
+ }
+
+ const OUString& sHideCondition = pBookmark->GetHideCondition();
+ const OUString& sName = pBookmark->GetName();
+ OUString sHidden
+ = (pBookmark->IsHidden() || !sHideCondition.isEmpty() ||
+ // tdf#150955 add "hidden" status to the imported OOXML _Toc and _Ref bookmarks
+ // to allow separating custom bookmarks by sorting based on their Hidden status.
+ // Note: this "hidden" means here only that these bookmarks haven't got
+ // visible bookmark formatting aids (gray I-shape or brackets), otherwise
+ // their anchor are still visible.
+ sName.startsWith("_Toc") || sName.startsWith("_Ref"))
+ ? SwResId(STR_BOOKMARK_YES)
+ : SwResId(STR_BOOKMARK_NO);
+
+ OUString sPageNum = OUString::number(SwPaM(pMark->GetMarkStart()).GetPageNum());
+ int nRow = m_xControl->n_children();
+ m_xControl->append(weld::toId(pMark), sPageNum);
+ m_xControl->set_text(nRow, sName, 1);
+ m_xControl->set_text(nRow, sBookmarkNodeText, 2);
+ m_xControl->set_text(nRow, sHidden, 3);
+ m_xControl->set_text(nRow, sHideCondition, 4);
+}
+
+std::unique_ptr<weld::TreeIter> BookmarkTable::GetRowByBookmarkName(const OUString& sName)
+{
+ std::unique_ptr<weld::TreeIter> xRet;
+ m_xControl->all_foreach([this, &sName, &xRet](weld::TreeIter& rEntry) {
+ sw::mark::IMark* pBookmark = weld::fromId<sw::mark::IMark*>(m_xControl->get_id(rEntry));
+ if (pBookmark->GetName() == sName)
+ {
+ xRet = m_xControl->make_iterator(&rEntry);
+ return true;
+ }
+ return false;
+ });
+ return xRet;
+}
+
+sw::mark::IMark* BookmarkTable::GetBookmarkByName(const OUString& sName)
+{
+ auto xEntry = GetRowByBookmarkName(sName);
+ if (!xEntry)
+ return nullptr;
+
+ return weld::fromId<sw::mark::IMark*>(m_xControl->get_id(*xEntry));
+}
+
+bool BookmarkTable::SelectByName(const OUString& sName)
+{
+ auto xEntry = GetRowByBookmarkName(sName);
+ if (!xEntry)
+ return false;
+ select(*xEntry);
+ return true;
+}
+
+OUString BookmarkTable::GetNameProposal() const
+{
+ OUString sDefaultBookmarkName = SwResId(STR_BOOKMARK_DEF_NAME);
+ sal_Int32 nHighestBookmarkId = 0;
+ for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i)
+ {
+ sw::mark::IMark* pBookmark = weld::fromId<sw::mark::IMark*>(m_xControl->get_id(i));
+ const OUString& sName = pBookmark->GetName();
+ sal_Int32 nIndex = 0;
+ if (o3tl::getToken(sName, 0, ' ', nIndex) == sDefaultBookmarkName)
+ {
+ sal_Int32 nCurrBookmarkId = o3tl::toInt32(o3tl::getToken(sName, 0, ' ', nIndex));
+ nHighestBookmarkId = std::max<sal_Int32>(nHighestBookmarkId, nCurrBookmarkId);
+ }
+ }
+ return sDefaultBookmarkName + " " + OUString::number(nHighestBookmarkId + 1);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/contentcontroldlg.cxx b/sw/source/ui/misc/contentcontroldlg.cxx
new file mode 100644
index 0000000000..f318fa6a69
--- /dev/null
+++ b/sw/source/ui/misc/contentcontroldlg.cxx
@@ -0,0 +1,477 @@
+/* -*- 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 <contentcontroldlg.hxx>
+
+#include <vcl/weld.hxx>
+#include <cui/cuicharmap.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
+
+#include <wrtsh.hxx>
+#include <ndtxt.hxx>
+#include <textcontentcontrol.hxx>
+#include <IDocumentState.hxx>
+#include <swuiexp.hxx>
+#include <numfmtlb.hxx>
+
+using namespace com::sun::star;
+
+SwContentControlDlg::SwContentControlDlg(weld::Window* pParent, SwWrtShell& rWrtShell)
+ : SfxDialogController(pParent, "modules/swriter/ui/contentcontroldlg.ui",
+ "ContentControlDialog")
+ , m_rWrtShell(rWrtShell)
+ , m_xShowingPlaceHolderCB(m_xBuilder->weld_check_button("showing_place_holder"))
+ , m_xAlias(m_xBuilder->weld_entry("aliasentry"))
+ , m_xTag(m_xBuilder->weld_entry("tagentry"))
+ , m_xId(m_xBuilder->weld_spin_button("idspinbutton"))
+ , m_xTabIndex(m_xBuilder->weld_spin_button("tabindexspinbutton"))
+ , m_xCheckboxFrame(m_xBuilder->weld_frame("checkboxframe"))
+ , m_xCheckedState(m_xBuilder->weld_entry("checkboxcheckedentry"))
+ , m_xCheckedStateBtn(m_xBuilder->weld_button("btncheckboxchecked"))
+ , m_xUncheckedState(m_xBuilder->weld_entry("checkboxuncheckedentry"))
+ , m_xUncheckedStateBtn(m_xBuilder->weld_button("btncheckboxunchecked"))
+ , m_xListItemsFrame(m_xBuilder->weld_frame("listitemsframe"))
+ , m_xListItems(m_xBuilder->weld_tree_view("listitems"))
+ , m_xListItemButtons(m_xBuilder->weld_box("listitembuttons"))
+ , m_xInsertBtn(m_xBuilder->weld_button("add"))
+ , m_xRenameBtn(m_xBuilder->weld_button("modify"))
+ , m_xDeleteBtn(m_xBuilder->weld_button("remove"))
+ , m_xMoveUpBtn(m_xBuilder->weld_button("moveup"))
+ , m_xMoveDownBtn(m_xBuilder->weld_button("movedown"))
+ , m_xDateFrame(m_xBuilder->weld_frame("dateframe"))
+ , m_xDateFormat(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("date_formats_treeview")))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+{
+ m_xCheckedStateBtn->connect_clicked(LINK(this, SwContentControlDlg, SelectCharHdl));
+ m_xUncheckedStateBtn->connect_clicked(LINK(this, SwContentControlDlg, SelectCharHdl));
+ m_xListItems->connect_changed(LINK(this, SwContentControlDlg, SelectionChangedHdl));
+ m_xOk->connect_clicked(LINK(this, SwContentControlDlg, OkHdl));
+
+ // Only 2 items would be visible by default.
+ m_xListItems->set_size_request(-1, m_xListItems->get_height_rows(8));
+ // Only the first column would have a non-zero size by default in the SvHeaderTabListBox case.
+ m_xListItems->set_column_fixed_widths({ 100, 100 });
+
+ m_xInsertBtn->connect_clicked(LINK(this, SwContentControlDlg, InsertHdl));
+ m_xRenameBtn->connect_clicked(LINK(this, SwContentControlDlg, RenameHdl));
+ m_xDeleteBtn->connect_clicked(LINK(this, SwContentControlDlg, DeleteHdl));
+ m_xMoveUpBtn->connect_clicked(LINK(this, SwContentControlDlg, MoveUpHdl));
+ m_xMoveDownBtn->connect_clicked(LINK(this, SwContentControlDlg, MoveDownHdl));
+
+ const SwPosition* pStart = rWrtShell.GetCursor()->Start();
+ SwTextNode* pTextNode = pStart->GetNode().GetTextNode();
+ if (!pTextNode)
+ {
+ return;
+ }
+
+ SwTextAttr* pAttr = pTextNode->GetTextAttrAt(
+ pStart->GetContentIndex(), RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent);
+ if (!pAttr)
+ {
+ return;
+ }
+
+ SwTextContentControl* pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr);
+ const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
+ m_pContentControl = rFormatContentControl.GetContentControl();
+
+ bool bShowingPlaceHolder = m_pContentControl->GetShowingPlaceHolder();
+ TriState eShowingPlaceHolder = bShowingPlaceHolder ? TRISTATE_TRUE : TRISTATE_FALSE;
+ m_xShowingPlaceHolderCB->set_state(eShowingPlaceHolder);
+ m_xShowingPlaceHolderCB->save_state();
+
+ if (!m_pContentControl->GetAlias().isEmpty())
+ {
+ m_xAlias->set_text(m_pContentControl->GetAlias());
+ m_xAlias->save_value();
+ }
+
+ if (!m_pContentControl->GetTag().isEmpty())
+ {
+ m_xTag->set_text(m_pContentControl->GetTag());
+ m_xTag->save_value();
+ }
+
+ // The ID is supposed to be a unique ID, but it isn't really used for much
+ // and in MS Word it (supposedly) is automatically made unique if it is a duplicate.
+ // The main purpose for having it here is lookup, not modification,
+ // since AFAIK the only use of the ID is for VBA macro name lookup.
+ // Since it is used as unsigned in VBA, make the UI display the unsigned values too.
+ m_xId->set_range(0, SAL_MAX_UINT32);
+ m_xId->set_increments(1, 10);
+ const sal_uInt32 nId = static_cast<sal_uInt32>(m_pContentControl->GetId());
+ m_xId->set_value(nId);
+ // a one-time chance to set the ID - only allow setting it when it is undefined.
+ if (nId)
+ m_xId->set_editable(false); // still available for copy/paste
+ m_xId->save_value();
+
+ // And on the contrary, the tabIndex is stored as unsigned,
+ // even though humanly speaking it is much nicer to use -1 to indicate a no tab stop. Oh well.
+ m_xTabIndex->set_range(SAL_MIN_INT32, SAL_MAX_INT32);
+ m_xTabIndex->set_increments(1, 10);
+ const sal_Int32 nTabIndex = static_cast<sal_Int32>(m_pContentControl->GetTabIndex());
+ m_xTabIndex->set_value(nTabIndex);
+ m_xTabIndex->save_value();
+
+ if (m_pContentControl->GetCheckbox())
+ {
+ m_xCheckedState->set_text(m_pContentControl->GetCheckedState());
+ m_xCheckedState->save_value();
+ m_xUncheckedState->set_text(m_pContentControl->GetUncheckedState());
+ m_xUncheckedState->save_value();
+ }
+ else
+ {
+ m_xCheckboxFrame->set_visible(false);
+ }
+
+ if (m_pContentControl->GetComboBox() || m_pContentControl->GetDropDown())
+ {
+ for (const auto& rListItem : m_pContentControl->GetListItems())
+ {
+ int nRow = m_xListItems->n_children();
+ m_xListItems->append_text(rListItem.m_aDisplayText);
+ m_xListItems->set_text(nRow, rListItem.m_aValue, 1);
+ }
+ m_aSavedListItems = m_pContentControl->GetListItems();
+ }
+ else
+ {
+ m_xListItemsFrame->set_visible(false);
+ m_xListItemButtons->set_visible(false);
+ }
+
+ if (m_pContentControl->GetDate())
+ {
+ m_xDateFormat->SetFormatType(SvNumFormatType::DATE);
+ m_xDateFormat->SetShowLanguageControl(true);
+
+ // Set height to double of the default.
+ weld::TreeView& rTreeView = dynamic_cast<weld::TreeView&>(m_xDateFormat->get_widget());
+ rTreeView.set_size_request(rTreeView.get_preferred_size().Width(),
+ rTreeView.get_height_rows(10));
+
+ OUString sFormatString = m_pContentControl->GetDateFormat();
+ OUString sLang = m_pContentControl->GetDateLanguage();
+ if (!sFormatString.isEmpty() && !sLang.isEmpty())
+ {
+ SvNumberFormatter* pNumberFormatter = m_rWrtShell.GetNumberFormatter();
+ LanguageType aLangType = LanguageTag(sLang).getLanguageType();
+ sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(sFormatString, aLangType);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ pNumberFormatter->PutEntry(sFormatString, nCheckPos, nType, nFormat,
+ LanguageTag(sLang).getLanguageType());
+ }
+
+ if (aLangType != LANGUAGE_DONTKNOW && nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ m_xDateFormat->SetDefFormat(nFormat);
+ }
+ }
+ }
+ else
+ {
+ m_xDateFrame->set_visible(false);
+ }
+}
+
+SwContentControlDlg::~SwContentControlDlg()
+{
+ if (m_xListItemDialog)
+ m_xListItemDialog.disposeAndClear();
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, OkHdl, weld::Button&, void)
+{
+ if (!m_pContentControl)
+ {
+ return;
+ }
+
+ bool bChanged = false;
+ if (m_xShowingPlaceHolderCB->get_state_changed_from_saved())
+ {
+ bool bShowingPlaceHolder = m_xShowingPlaceHolderCB->get_state() == TRISTATE_TRUE;
+ m_pContentControl->SetShowingPlaceHolder(bShowingPlaceHolder);
+ bChanged = true;
+ }
+
+ if (m_xAlias->get_value_changed_from_saved())
+ {
+ m_pContentControl->SetAlias(m_xAlias->get_text());
+ bChanged = true;
+ }
+
+ if (m_xTag->get_value_changed_from_saved())
+ {
+ m_pContentControl->SetTag(m_xTag->get_text());
+ bChanged = true;
+ }
+
+ if (m_xId->get_value_changed_from_saved())
+ {
+ m_pContentControl->SetId(o3tl::narrowing<sal_Int32>(m_xId->get_value()));
+ bChanged = true;
+ }
+
+ if (m_xTabIndex->get_value_changed_from_saved())
+ {
+ m_pContentControl->SetTabIndex(o3tl::narrowing<sal_uInt32>(m_xTabIndex->get_value()));
+ bChanged = true;
+ }
+
+ if (m_xCheckedState->get_value_changed_from_saved())
+ {
+ m_pContentControl->SetCheckedState(m_xCheckedState->get_text());
+ }
+
+ if (m_xUncheckedState->get_value_changed_from_saved())
+ {
+ m_pContentControl->SetUncheckedState(m_xUncheckedState->get_text());
+ }
+
+ std::vector<SwContentControlListItem> aItems;
+ for (int i = 0; i < m_xListItems->n_children(); ++i)
+ {
+ SwContentControlListItem aItem;
+ aItem.m_aDisplayText = m_xListItems->get_text(i, 0);
+ aItem.m_aValue = m_xListItems->get_text(i, 1);
+ aItems.push_back(aItem);
+ }
+ if (aItems != m_aSavedListItems)
+ {
+ m_pContentControl->SetListItems(aItems);
+ bChanged = true;
+ }
+
+ if (m_pContentControl->GetDate())
+ {
+ SvNumberFormatter* pNumberFormatter = m_rWrtShell.GetNumberFormatter();
+ const SvNumberformat* pFormat = pNumberFormatter->GetEntry(m_xDateFormat->GetFormat());
+ if (pFormat)
+ {
+ if (pFormat->GetFormatstring() != m_pContentControl->GetDateFormat())
+ {
+ m_pContentControl->SetDateFormat(pFormat->GetFormatstring());
+ bChanged = true;
+ }
+
+ OUString aLanguage = LanguageTag(pFormat->GetLanguage()).getBcp47();
+ if (aLanguage != m_pContentControl->GetDateLanguage())
+ {
+ m_pContentControl->SetDateLanguage(aLanguage);
+ bChanged = true;
+ }
+ }
+ }
+
+ if (bChanged)
+ {
+ m_rWrtShell.GetDoc()->getIDocumentState().SetModified();
+
+ // Make sure that the cursor gets updated with the new list items.
+ m_rWrtShell.HideCursor();
+ m_rWrtShell.ShowCursor();
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwContentControlDlg, SelectCharHdl, weld::Button&, rButton, void)
+{
+ SvxCharacterMap aMap(m_xDialog.get(), nullptr, nullptr);
+ sal_UCS4 cBullet = 0;
+ sal_Int32 nIndex = 0;
+ if (&rButton == m_xCheckedStateBtn.get())
+ {
+ cBullet = m_pContentControl->GetCheckedState().iterateCodePoints(&nIndex);
+ }
+ else if (&rButton == m_xUncheckedStateBtn.get())
+ {
+ cBullet = m_pContentControl->GetUncheckedState().iterateCodePoints(&nIndex);
+ }
+ aMap.SetChar(cBullet);
+ if (aMap.run() != RET_OK)
+ {
+ return;
+ }
+
+ cBullet = aMap.GetChar();
+ if (&rButton == m_xCheckedStateBtn.get())
+ {
+ m_xCheckedState->set_text(OUString(&cBullet, 1));
+ }
+ else if (&rButton == m_xUncheckedStateBtn.get())
+ {
+ m_xUncheckedState->set_text(OUString(&cBullet, 1));
+ }
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, InsertHdl, weld::Button&, void)
+{
+ std::shared_ptr<SwContentControlListItem> aItem = std::make_shared<SwContentControlListItem>();
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+ m_xListItemDialog = rFact.CreateSwContentControlListItemDlg(m_xDialog.get(), *aItem);
+ m_xListItemDialog->StartExecuteAsync([this, aItem](sal_Int32 nResult) {
+ if (nResult == RET_OK)
+ {
+ if (aItem->m_aDisplayText.isEmpty() && aItem->m_aValue.isEmpty())
+ {
+ // Maintain the invariant that value can't be empty.
+ return;
+ }
+
+ if (aItem->m_aValue.isEmpty())
+ {
+ aItem->m_aValue = aItem->m_aDisplayText;
+ }
+
+ int nRow = m_xListItems->n_children();
+ m_xListItems->append_text(aItem->m_aDisplayText);
+ m_xListItems->set_text(nRow, aItem->m_aValue, 1);
+ }
+
+ m_xListItemDialog.disposeAndClear();
+ });
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, RenameHdl, weld::Button&, void)
+{
+ int nRow = m_xListItems->get_selected_index();
+ if (nRow < 0)
+ {
+ return;
+ }
+
+ std::shared_ptr<SwContentControlListItem> aItem = std::make_shared<SwContentControlListItem>();
+ aItem->m_aDisplayText = m_xListItems->get_text(nRow, 0);
+ aItem->m_aValue = m_xListItems->get_text(nRow, 1);
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+ m_xListItemDialog = rFact.CreateSwContentControlListItemDlg(m_xDialog.get(), *aItem);
+ m_xListItemDialog->StartExecuteAsync([this, aItem, nRow](sal_Int32 nResult) {
+ if (nResult == RET_OK)
+ {
+ if (aItem->m_aDisplayText.isEmpty() && aItem->m_aValue.isEmpty())
+ {
+ // Maintain the invariant that value can't be empty.
+ return;
+ }
+
+ if (aItem->m_aValue.isEmpty())
+ {
+ aItem->m_aValue = aItem->m_aDisplayText;
+ }
+
+ m_xListItems->set_text(nRow, aItem->m_aDisplayText, 0);
+ m_xListItems->set_text(nRow, aItem->m_aValue, 1);
+ }
+
+ m_xListItemDialog.disposeAndClear();
+ });
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, DeleteHdl, weld::Button&, void)
+{
+ int nRow = m_xListItems->get_selected_index();
+ if (nRow < 0)
+ {
+ return;
+ }
+
+ m_xListItems->remove(nRow);
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, MoveUpHdl, weld::Button&, void)
+{
+ int nRow = m_xListItems->get_selected_index();
+ if (nRow <= 0)
+ {
+ return;
+ }
+
+ SwContentControlListItem aItem;
+ aItem.m_aDisplayText = m_xListItems->get_text(nRow, 0);
+ aItem.m_aValue = m_xListItems->get_text(nRow, 1);
+ m_xListItems->remove(nRow);
+ --nRow;
+ m_xListItems->insert_text(nRow, aItem.m_aDisplayText);
+ m_xListItems->set_text(nRow, aItem.m_aValue, 1);
+ m_xListItems->select(nRow);
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, MoveDownHdl, weld::Button&, void)
+{
+ int nRow = m_xListItems->get_selected_index();
+ int nEndPos = m_xListItems->n_children() - 1;
+ if (nRow < 0 || nRow >= nEndPos)
+ {
+ return;
+ }
+
+ SwContentControlListItem aItem;
+ aItem.m_aDisplayText = m_xListItems->get_text(nRow, 0);
+ aItem.m_aValue = m_xListItems->get_text(nRow, 1);
+ m_xListItems->remove(nRow);
+ ++nRow;
+ m_xListItems->insert_text(nRow, aItem.m_aDisplayText);
+ m_xListItems->set_text(nRow, aItem.m_aValue, 1);
+ m_xListItems->select(nRow);
+}
+
+IMPL_LINK_NOARG(SwContentControlDlg, SelectionChangedHdl, weld::TreeView&, void)
+{
+ int nRow = m_xListItems->get_selected_index();
+ if (nRow < 0)
+ {
+ m_xRenameBtn->set_sensitive(false);
+ m_xDeleteBtn->set_sensitive(false);
+ }
+ else
+ {
+ m_xRenameBtn->set_sensitive(true);
+ m_xDeleteBtn->set_sensitive(true);
+ }
+
+ if (nRow <= 0)
+ {
+ m_xMoveUpBtn->set_sensitive(false);
+ }
+ else
+ {
+ m_xMoveUpBtn->set_sensitive(true);
+ }
+
+ int nEndPos = m_xListItems->n_children() - 1;
+ if (nRow < 0 || nRow >= nEndPos)
+ {
+ m_xMoveDownBtn->set_sensitive(false);
+ }
+ else
+ {
+ m_xMoveDownBtn->set_sensitive(true);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/contentcontrollistitemdlg.cxx b/sw/source/ui/misc/contentcontrollistitemdlg.cxx
new file mode 100644
index 0000000000..6ac160aebb
--- /dev/null
+++ b/sw/source/ui/misc/contentcontrollistitemdlg.cxx
@@ -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 .
+ */
+
+#include <contentcontrollistitemdlg.hxx>
+
+#include <formatcontentcontrol.hxx>
+
+using namespace com::sun::star;
+
+SwContentControlListItemDlg::SwContentControlListItemDlg(weld::Widget* pParent,
+ SwContentControlListItem& rItem)
+ : GenericDialogController(pParent, "modules/swriter/ui/contentcontrollistitemdlg.ui",
+ "ContentControlListItemDialog")
+ , m_rItem(rItem)
+ , m_xDisplayNameED(m_xBuilder->weld_entry("displayname"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+{
+ m_xOk->connect_clicked(LINK(this, SwContentControlListItemDlg, OkHdl));
+ m_xDisplayNameED->set_text(rItem.m_aDisplayText);
+ m_xValueED->set_text(rItem.m_aValue);
+}
+
+IMPL_LINK_NOARG(SwContentControlListItemDlg, OkHdl, weld::Button&, void)
+{
+ m_rItem.m_aDisplayText = m_xDisplayNameED->get_text();
+ m_rItem.m_aValue = m_xValueED->get_text();
+
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/docfnote.cxx b/sw/source/ui/misc/docfnote.cxx
new file mode 100644
index 0000000000..0fbe3b7c6f
--- /dev/null
+++ b/sw/source/ui/misc/docfnote.cxx
@@ -0,0 +1,393 @@
+/* -*- 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 <svl/style.hxx>
+#include <osl/diagnose.h>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <docfnote.hxx>
+#include "impfnote.hxx"
+#include <ftninfo.hxx>
+#include <fmtcol.hxx>
+#include <pagedesc.hxx>
+#include <charfmt.hxx>
+#include <docstyle.hxx>
+#include <wdocsh.hxx>
+#include <uitool.hxx>
+#include <poolfmt.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <memory>
+
+SwFootNoteOptionDlg::SwFootNoteOptionDlg(weld::Window *pParent, SwWrtShell &rS)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/footendnotedialog.ui", "FootEndnoteDialog")
+ , m_rSh( rS )
+{
+ RemoveResetButton();
+
+ GetOKButton().connect_clicked(LINK(this, SwFootNoteOptionDlg, OkHdl));
+
+ AddTabPage("footnotes", SwFootNoteOptionPage::Create, nullptr);
+ AddTabPage("endnotes", SwEndNoteOptionPage::Create, nullptr);
+}
+
+void SwFootNoteOptionDlg::PageCreated(const OUString& /*rId*/, SfxTabPage &rPage)
+{
+ static_cast<SwEndNoteOptionPage&>(rPage).SetShell(m_rSh);
+}
+
+IMPL_LINK(SwFootNoteOptionDlg, OkHdl, weld::Button&, rBtn, void)
+{
+ SfxItemSetFixed<1, 1> aDummySet(m_rSh.GetAttrPool());
+ SfxTabPage *pPage = GetTabPage(u"footnotes");
+ if ( pPage )
+ pPage->FillItemSet( &aDummySet );
+ pPage = GetTabPage(u"endnotes");
+ if ( pPage )
+ pPage->FillItemSet( &aDummySet );
+ SfxTabDialogController::OkHdl(rBtn);
+}
+
+SwEndNoteOptionPage::SwEndNoteOptionPage(weld::Container* pPage, weld::DialogController* pController, bool bEN,
+ const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController,
+ bEN ? OUString("modules/swriter/ui/endnotepage.ui") : OUString("modules/swriter/ui/footnotepage.ui"),
+ bEN ? OUString("EndnotePage") : OUString("FootnotePage"),
+ &rSet)
+ , m_pSh(nullptr)
+ , m_bPosDoc(false)
+ , m_bEndNote(bEN)
+ , m_xNumViewBox(new SwNumberingTypeListBox(m_xBuilder->weld_combo_box("numberinglb")))
+ , m_xOffsetLbl(m_xBuilder->weld_label("offset"))
+ , m_xOffsetField(m_xBuilder->weld_spin_button("offsetnf"))
+ , m_xNumCountBox(m_xBuilder->weld_combo_box("countinglb"))
+ , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
+ , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
+ , m_xPosPageBox(m_xBuilder->weld_radio_button("pospagecb"))
+ , m_xPosChapterBox(m_xBuilder->weld_radio_button("posdoccb"))
+ , m_xStylesContainer(m_xBuilder->weld_widget("allstyles"))
+ , m_xParaTemplBox(m_xBuilder->weld_combo_box("parastylelb"))
+ , m_xPageTemplLbl(m_xBuilder->weld_label("pagestyleft"))
+ , m_xPageTemplBox(m_xBuilder->weld_combo_box("pagestylelb"))
+ , m_xFootnoteCharAnchorTemplBox(m_xBuilder->weld_combo_box("charanchorstylelb"))
+ , m_xFootnoteCharTextTemplBox(m_xBuilder->weld_combo_box("charstylelb"))
+ , m_xContEdit(m_xBuilder->weld_entry("conted"))
+ , m_xContFromEdit(m_xBuilder->weld_entry("contfromed"))
+{
+ m_xNumViewBox->Reload(SwInsertNumTypes::Extended);
+ if (!m_bEndNote)
+ {
+ m_xNumCountBox->connect_changed(LINK(this, SwEndNoteOptionPage, NumCountHdl));
+ m_aNumDoc = m_xNumCountBox->get_text(FTNNUM_DOC);
+ m_aNumPage = m_xNumCountBox->get_text(FTNNUM_PAGE);
+ m_aNumChapter = m_xNumCountBox->get_text(FTNNUM_CHAPTER);
+ m_xPosPageBox->connect_toggled(LINK(this, SwEndNoteOptionPage, ToggleHdl));
+ m_xPosChapterBox->connect_toggled(LINK(this, SwEndNoteOptionPage, ToggleHdl));
+ }
+ m_xParaTemplBox->make_sorted();
+}
+
+SwEndNoteOptionPage::~SwEndNoteOptionPage()
+{
+}
+
+void SwEndNoteOptionPage::Reset( const SfxItemSet* )
+{
+ std::unique_ptr<SwEndNoteInfo> pInf(m_bEndNote ? new SwEndNoteInfo( m_pSh->GetEndNoteInfo() )
+ : new SwFootnoteInfo( m_pSh->GetFootnoteInfo() ));
+ SfxObjectShell * pDocSh = SfxObjectShell::Current();
+
+ if (dynamic_cast<SwWebDocShell*>( pDocSh) )
+ m_xStylesContainer->hide();
+
+ if ( m_bEndNote )
+ {
+ m_bPosDoc = true;
+ }
+ else
+ {
+ const SwFootnoteInfo &rInf = m_pSh->GetFootnoteInfo();
+ // set position (page, chapter)
+ if ( rInf.m_ePos == FTNPOS_PAGE )
+ {
+ m_xPosPageBox->set_active(true);
+ m_xPageTemplLbl->set_sensitive(false);
+ m_xPageTemplBox->set_sensitive(false);
+ }
+ else
+ {
+ m_xPosChapterBox->set_active(true);
+ m_xNumCountBox->remove_text(m_aNumPage);
+ m_xNumCountBox->remove_text(m_aNumChapter);
+ m_bPosDoc = true;
+ }
+ // reference tests
+ m_xContEdit->set_text(rInf.m_aQuoVadis);
+ m_xContFromEdit->set_text(rInf.m_aErgoSum);
+
+ // collected
+ SelectNumbering(rInf.m_eNum);
+ }
+
+ // numbering
+ // art
+ m_xNumViewBox->SelectNumberingType( pInf->m_aFormat.GetNumberingType());
+ m_xOffsetField->set_value(pInf->m_nFootnoteOffset + 1);
+ m_xPrefixED->set_text(pInf->GetPrefix().replaceAll("\t", "\\t")); // fdo#65666
+ m_xSuffixED->set_text(pInf->GetSuffix().replaceAll("\t", "\\t"));
+
+ const SwCharFormat* pCharFormat = pInf->GetCharFormat(
+ *m_pSh->GetView().GetDocShell()->GetDoc());
+ m_xFootnoteCharTextTemplBox->set_active_text(pCharFormat->GetName());
+ m_xFootnoteCharTextTemplBox->save_value();
+
+ pCharFormat = pInf->GetAnchorCharFormat( *m_pSh->GetDoc() );
+ m_xFootnoteCharAnchorTemplBox->set_active_text( pCharFormat->GetName() );
+ m_xFootnoteCharAnchorTemplBox->save_value();
+
+ // styles special regions
+ // paragraph
+ SfxStyleSheetBasePool* pStyleSheetPool = m_pSh->GetView().GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase *pStyle = pStyleSheetPool->First(SfxStyleFamily::Para, SfxStyleSearchBits::SwExtra);
+ while(pStyle)
+ {
+ m_xParaTemplBox->append_text(pStyle->GetName());
+ pStyle = pStyleSheetPool->Next();
+ }
+
+ OUString sStr;
+ SwStyleNameMapper::FillUIName( static_cast< sal_uInt16 >(m_bEndNote ? RES_POOLCOLL_ENDNOTE
+ : RES_POOLCOLL_FOOTNOTE), sStr );
+ if (m_xParaTemplBox->find_text(sStr) == -1)
+ m_xParaTemplBox->append_text(sStr);
+
+ SwTextFormatColl* pColl = pInf->GetFootnoteTextColl();
+ if( !pColl )
+ m_xParaTemplBox->set_active_text(sStr); // Default
+ else
+ {
+ OSL_ENSURE(!pColl->IsDefault(), "default style for footnotes is wrong");
+ const int nPos = m_xParaTemplBox->find_text(pColl->GetName());
+ if (nPos != -1)
+ m_xParaTemplBox->set_active( nPos );
+ else
+ {
+ m_xParaTemplBox->append_text(pColl->GetName());
+ m_xParaTemplBox->set_active_text(pColl->GetName());
+ }
+ }
+
+ // page
+ for (sal_uInt16 i = RES_POOLPAGE_BEGIN; i < RES_POOLPAGE_END; ++i)
+ m_xPageTemplBox->append_text(SwStyleNameMapper::GetUIName(i, OUString()));
+
+ const size_t nCount = m_pSh->GetPageDescCnt();
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ const SwPageDesc &rPageDesc = m_pSh->GetPageDesc(i);
+ if (m_xPageTemplBox->find_text(rPageDesc.GetName()) == -1)
+ m_xPageTemplBox->append_text(rPageDesc.GetName());
+ }
+ m_xPageTemplBox->make_sorted();
+
+ m_xPageTemplBox->set_active_text(pInf->GetPageDesc(*m_pSh->GetDoc())->GetName());
+}
+
+std::unique_ptr<SfxTabPage> SwEndNoteOptionPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet )
+{
+ return std::make_unique<SwEndNoteOptionPage>(pPage, pController, true, *rSet);
+}
+
+// Different kinds of numbering; because the Listbox has varying numbers of
+// entries, here are functions to set and query the intended kind of numbering.
+void SwEndNoteOptionPage::SelectNumbering(SwFootnoteNum const eNum)
+{
+ OUString sSelect;
+ switch(eNum)
+ {
+ case FTNNUM_DOC:
+ sSelect = m_aNumDoc;
+ break;
+ case FTNNUM_PAGE:
+ sSelect = m_aNumPage;
+ break;
+ case FTNNUM_CHAPTER:
+ sSelect = m_aNumChapter;
+ break;
+ default:
+ assert(false);
+ }
+ m_xNumCountBox->set_active_text(sSelect);
+ NumCountHdl(*m_xNumCountBox);
+}
+
+SwFootnoteNum SwEndNoteOptionPage::GetNumbering() const
+{
+ const int nPos = m_xNumCountBox->get_active();
+ return static_cast<SwFootnoteNum>(m_bPosDoc ? nPos + 2 : nPos);
+}
+
+void SwEndNoteOptionPage::SetShell( SwWrtShell &rShell )
+{
+ m_pSh = &rShell;
+ // collect character templates
+ m_xFootnoteCharTextTemplBox->clear();
+ m_xFootnoteCharAnchorTemplBox->clear();
+ ::FillCharStyleListBox(*m_xFootnoteCharTextTemplBox,
+ m_pSh->GetView().GetDocShell(), true);
+
+ ::FillCharStyleListBox(*m_xFootnoteCharAnchorTemplBox,
+ m_pSh->GetView().GetDocShell(), true);
+}
+
+IMPL_LINK(SwEndNoteOptionPage, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ if (m_xPosPageBox->get_active())
+ {
+ // Handler behind the button to collect the footnote at the page. In this case
+ // all kinds of numbering can be used.
+
+ const SwFootnoteNum eNum = GetNumbering();
+ m_bPosDoc = false;
+ if (m_xNumCountBox->find_text(m_aNumPage) == -1)
+ {
+ m_xNumCountBox->insert_text(FTNNUM_PAGE, m_aNumPage);
+ m_xNumCountBox->insert_text(FTNNUM_CHAPTER, m_aNumChapter);
+ SelectNumbering(eNum);
+ }
+ m_xPageTemplLbl->set_sensitive(false);
+ m_xPageTemplBox->set_sensitive(false);
+ }
+ else if (m_xPosChapterBox->get_active())
+ {
+ // Handler behind the button to collect the footnote at the chapter or end of
+ // the document. In this case no pagewise numbering can be used.
+
+ if ( !m_bPosDoc )
+ SelectNumbering(FTNNUM_DOC);
+
+ m_bPosDoc = true;
+ m_xNumCountBox->remove_text(m_aNumPage);
+ m_xNumCountBox->remove_text(m_aNumChapter);
+ m_xPageTemplLbl->set_sensitive(true);
+ m_xPageTemplBox->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SwEndNoteOptionPage, NumCountHdl, weld::ComboBox&, void)
+{
+ bool bEnable = true;
+ if (m_xNumCountBox->get_count() - 1 != m_xNumCountBox->get_active())
+ {
+ bEnable = false;
+ m_xOffsetField->set_value(1);
+ }
+ m_xOffsetLbl->set_sensitive(bEnable);
+ m_xOffsetField->set_sensitive(bEnable);
+}
+
+static SwCharFormat* lcl_GetCharFormat( SwWrtShell* pSh, const OUString& rCharFormatName )
+{
+ SwCharFormat* pFormat = nullptr;
+ const sal_uInt16 nChCount = pSh->GetCharFormatCount();
+ for(sal_uInt16 i = 0; i< nChCount; i++)
+ {
+ SwCharFormat& rChFormat = pSh->GetCharFormat(i);
+ if(rChFormat.GetName() == rCharFormatName )
+ {
+ pFormat = &rChFormat;
+ break;
+ }
+ }
+ if(!pFormat)
+ {
+ SfxStyleSheetBasePool* pPool = pSh->GetView().GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase* pBase;
+ pBase = pPool->Find(rCharFormatName, SfxStyleFamily::Char);
+ if(!pBase)
+ pBase = &pPool->Make(rCharFormatName, SfxStyleFamily::Char);
+ pFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
+ }
+ return pFormat;
+}
+
+bool SwEndNoteOptionPage::FillItemSet( SfxItemSet * )
+{
+ std::unique_ptr<SwEndNoteInfo> pInf(m_bEndNote ? new SwEndNoteInfo() : new SwFootnoteInfo());
+
+ pInf->m_nFootnoteOffset = m_xOffsetField->get_value() - 1;
+ pInf->m_aFormat.SetNumberingType(m_xNumViewBox->GetSelectedNumberingType() );
+ pInf->SetPrefix(m_xPrefixED->get_text().replaceAll("\\t", "\t"));
+ pInf->SetSuffix(m_xSuffixED->get_text().replaceAll("\\t", "\t"));
+
+ pInf->SetCharFormat( lcl_GetCharFormat( m_pSh,
+ m_xFootnoteCharTextTemplBox->get_active_text() ) );
+ pInf->SetAnchorCharFormat( lcl_GetCharFormat( m_pSh,
+ m_xFootnoteCharAnchorTemplBox->get_active_text() ) );
+
+ // paragraph template
+ int nPos = m_xParaTemplBox->get_active();
+ if (nPos != -1)
+ {
+ const OUString aFormatName( m_xParaTemplBox->get_active_text() );
+ SwTextFormatColl *pColl = m_pSh->GetParaStyle(aFormatName, SwWrtShell::GETSTYLE_CREATEANY);
+ OSL_ENSURE(pColl, "paragraph style not found");
+ pInf->SetFootnoteTextColl(*pColl);
+ }
+
+ // page template
+ pInf->ChgPageDesc( m_pSh->FindPageDescByName(
+ m_xPageTemplBox->get_active_text(), true ) );
+
+ if ( m_bEndNote )
+ {
+ if ( !(*pInf == m_pSh->GetEndNoteInfo()) )
+ m_pSh->SetEndNoteInfo( *pInf );
+ }
+ else
+ {
+ SwFootnoteInfo *pI = static_cast<SwFootnoteInfo*>(pInf.get());
+ pI->m_ePos = m_xPosPageBox->get_active() ? FTNPOS_PAGE : FTNPOS_CHAPTER;
+ pI->m_eNum = GetNumbering();
+ pI->m_aQuoVadis = m_xContEdit->get_text();
+ pI->m_aErgoSum = m_xContFromEdit->get_text();
+ if ( !(*pI == m_pSh->GetFootnoteInfo()) )
+ m_pSh->SetFootnoteInfo( *pI );
+ }
+ return true;
+}
+
+SwFootNoteOptionPage::SwFootNoteOptionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SwEndNoteOptionPage(pPage, pController, false, rSet)
+{
+}
+
+SwFootNoteOptionPage::~SwFootNoteOptionPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwFootNoteOptionPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet )
+{
+ return std::make_unique<SwFootNoteOptionPage>(pPage, pController, *rSet);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/glosbib.cxx b/sw/source/ui/misc/glosbib.cxx
new file mode 100644
index 0000000000..ed74973a1b
--- /dev/null
+++ b/sw/source/ui/misc/glosbib.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 <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/pathoptions.hxx>
+#include <osl/diagnose.h>
+#include <o3tl/string_view.hxx>
+
+#include <swtypes.hxx>
+#include <glosbib.hxx>
+#include <gloshdl.hxx>
+#include <glossary.hxx>
+#include <glosdoc.hxx>
+#include <swunohelper.hxx>
+
+#include <strings.hrc>
+
+#define PATH_CASE_SENSITIVE 0x01
+#define PATH_READONLY 0x02
+
+#define RENAME_TOKEN_DELIM u'\x0001'
+
+SwGlossaryGroupDlg::SwGlossaryGroupDlg(weld::Window * pParent,
+ std::vector<OUString> const& rPathArr, SwGlossaryHdl *pHdl)
+ : SfxDialogController(pParent, "modules/swriter/ui/editcategories.ui",
+ "EditCategoriesDialog")
+ , m_pParent(pParent)
+ , m_pGlosHdl(pHdl)
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xPathLB(m_xBuilder->weld_combo_box("pathlb"))
+ , m_xGroupTLB(m_xBuilder->weld_tree_view("group"))
+ , m_xNewPB(m_xBuilder->weld_button("new"))
+ , m_xDelPB(m_xBuilder->weld_button("delete"))
+ , m_xRenamePB(m_xBuilder->weld_button("rename"))
+{
+ int nWidth = m_xGroupTLB->get_approximate_digit_width() * 34;
+ m_xPathLB->set_size_request(nWidth, -1);
+ //just has to be something small, real size will be available space
+ m_xGroupTLB->set_size_request(nWidth, m_xGroupTLB->get_height_rows(10));
+
+ m_xGroupTLB->set_column_fixed_widths( { nWidth } );
+ m_xGroupTLB->connect_changed(LINK(this, SwGlossaryGroupDlg, SelectHdl));
+
+ m_xNewPB->connect_clicked(LINK(this, SwGlossaryGroupDlg, NewHdl));
+ m_xDelPB->connect_clicked(LINK(this, SwGlossaryGroupDlg, DeleteHdl));
+ m_xNameED->connect_changed(LINK(this, SwGlossaryGroupDlg, ModifyHdl));
+ m_xNameED->connect_insert_text(LINK(this, SwGlossaryGroupDlg, EditInsertTextHdl));
+ m_xPathLB->connect_changed(LINK(this, SwGlossaryGroupDlg, ModifyListBoxHdl));
+ m_xRenamePB->connect_clicked(LINK(this, SwGlossaryGroupDlg, RenameHdl));
+
+ m_xNameED->connect_size_allocate(LINK(this, SwGlossaryGroupDlg, EntrySizeAllocHdl));
+ m_xPathLB->connect_size_allocate(LINK(this, SwGlossaryGroupDlg, EntrySizeAllocHdl));
+
+ for (size_t i = 0; i < rPathArr.size(); ++i)
+ {
+ INetURLObject aTempURL(rPathArr[i]);
+ const OUString sPath = aTempURL.GetMainURL(INetURLObject::DecodeMechanism::WithCharset );
+ sal_uInt32 nCaseReadonly = 0;
+ utl::TempFileNamed aTempFile(&sPath);
+ aTempFile.EnableKillingFile();
+ if(!aTempFile.IsValid())
+ nCaseReadonly |= PATH_READONLY;
+ else if( SWUnoHelper::UCB_IsCaseSensitiveFileName( aTempFile.GetURL()))
+ nCaseReadonly |= PATH_CASE_SENSITIVE;
+ m_xPathLB->append(OUString::number(nCaseReadonly), sPath);
+ }
+ m_xPathLB->set_active(0);
+ m_xPathLB->set_sensitive(true);
+
+ const size_t nCount = pHdl->GetGroupCnt();
+ /* tdf#111870 "My AutoText" comes from mytexts.bau but should be translated
+ here as well, see also SwGlossaryDlg::Init */
+ static constexpr OUStringLiteral sMyAutoTextEnglish(u"My AutoText");
+ for( size_t i = 0; i < nCount; ++i)
+ {
+ OUString sTitle;
+ OUString sGroup = pHdl->GetGroupName(i, &sTitle);
+ if(sGroup.isEmpty())
+ continue;
+ GlosBibUserData* pData = new GlosBibUserData;
+ pData->sGroupName = sGroup;
+ if ( sTitle == sMyAutoTextEnglish )
+ pData->sGroupTitle = SwResId(STR_MY_AUTOTEXT);
+ else
+ pData->sGroupTitle = sTitle;
+ pData->sPath = m_xPathLB->get_text(o3tl::toInt32(o3tl::getToken(sGroup, 1, GLOS_DELIM)));
+ const OUString sId(weld::toId(pData));
+ m_xGroupTLB->append(sId, pData->sGroupTitle);
+ int nEntry = m_xGroupTLB->find_id(sId);
+ m_xGroupTLB->set_text(nEntry, pData->sPath, 1);
+
+ }
+ m_xGroupTLB->make_sorted();
+}
+
+SwGlossaryGroupDlg::~SwGlossaryGroupDlg()
+{
+ int nCount = m_xGroupTLB->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ GlosBibUserData* pUserData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(i));
+ delete pUserData;
+ }
+}
+
+short SwGlossaryGroupDlg::run()
+{
+ short nRet = SfxDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+void SwGlossaryGroupDlg::Apply()
+{
+ if (m_xNewPB->get_sensitive())
+ NewHdl(*m_xNewPB);
+
+ const OUString aActGroup = SwGlossaryDlg::GetCurrGroup();
+
+ for (const auto& removedStr : m_RemovedArr)
+ {
+ sal_Int32 nIdx{ 0 };
+ const OUString sDelGroup = removedStr.getToken(0, '\t', nIdx);
+ if( sDelGroup == aActGroup )
+ {
+ //when the current group is deleted, the current group has to be relocated
+ if (m_xGroupTLB->n_children())
+ {
+ GlosBibUserData* pUserData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(0));
+ m_pGlosHdl->SetCurGroup(pUserData->sGroupName);
+ }
+ }
+ const OUString sMsg(SwResId(STR_QUERY_DELETE_GROUP1)
+ + o3tl::getToken(removedStr, 0, '\t', nIdx)
+ + SwResId(STR_QUERY_DELETE_GROUP2));
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_pParent,
+ VclMessageType::Question, VclButtonsType::YesNo, sMsg));
+ xQueryBox->set_default_response(RET_NO);
+ if (RET_YES == xQueryBox->run())
+ m_pGlosHdl->DelGroup( sDelGroup );
+ }
+
+ //don't rename before there was one
+ for (auto it(m_RenamedArr.cbegin()); it != m_RenamedArr.cend(); ++it)
+ {
+ sal_Int32 nIdx{ 0 };
+ OUString const sOld(it->getToken(0, RENAME_TOKEN_DELIM, nIdx));
+ OUString sNew(it->getToken(0, RENAME_TOKEN_DELIM, nIdx));
+ OUString const sTitle(it->getToken(0, RENAME_TOKEN_DELIM, nIdx));
+ m_pGlosHdl->RenameGroup(sOld, sNew, sTitle);
+ if (it == m_RenamedArr.begin())
+ {
+ m_sCreatedGroup = sNew;
+ }
+ }
+ for (auto& sNewGroup : m_InsertedArr)
+ {
+ OUString sNewTitle = sNewGroup.getToken(0, GLOS_DELIM);
+ if( sNewGroup != aActGroup )
+ {
+ m_pGlosHdl->NewGroup(sNewGroup, sNewTitle);
+ if(m_sCreatedGroup.isEmpty())
+ m_sCreatedGroup = sNewGroup;
+ }
+ }
+}
+
+IMPL_LINK_NOARG( SwGlossaryGroupDlg, SelectHdl, weld::TreeView&, void )
+{
+ m_xNewPB->set_sensitive(false);
+ int nFirstEntry = m_xGroupTLB->get_selected_index();
+ if (nFirstEntry == -1)
+ return;
+
+ GlosBibUserData* pUserData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(nFirstEntry));
+ const OUString sEntry(pUserData->sGroupName);
+ const OUString sName(m_xNameED->get_text());
+ bool bExists = false;
+ int nPos = m_xGroupTLB->find_text(sName);
+ if (nPos != -1)
+ {
+ GlosBibUserData* pFoundData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(nPos));
+ bExists = pFoundData->sGroupName == sEntry;
+ }
+
+ m_xRenamePB->set_sensitive(!bExists && !sName.isEmpty());
+ m_xDelPB->set_sensitive(IsDeleteAllowed(sEntry));
+}
+
+IMPL_LINK_NOARG(SwGlossaryGroupDlg, NewHdl, weld::Button&, void)
+{
+ OUString sGroup = m_xNameED->get_text()
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(m_xPathLB->get_active());
+ OSL_ENSURE(!m_pGlosHdl->FindGroupName(sGroup), "group already available!");
+ m_InsertedArr.push_back(sGroup);
+ GlosBibUserData* pData = new GlosBibUserData;
+ pData->sPath = m_xPathLB->get_active_text();
+ pData->sGroupName = sGroup;
+ pData->sGroupTitle = m_xNameED->get_text();
+ OUString sId(weld::toId(pData));
+ m_xGroupTLB->append(sId, m_xNameED->get_text());
+ int nEntry = m_xGroupTLB->find_id(sId);
+ m_xGroupTLB->set_text(nEntry, pData->sPath, 1);
+ m_xGroupTLB->select(nEntry);
+ SelectHdl(*m_xGroupTLB);
+ m_xGroupTLB->scroll_to_row(nEntry);
+}
+
+IMPL_LINK_NOARG(SwGlossaryGroupDlg, EntrySizeAllocHdl, const Size&, void)
+{
+ std::vector<int> aWidths;
+ int x, y, width, height;
+ if (m_xPathLB->get_extents_relative_to(*m_xGroupTLB, x, y, width, height))
+ {
+ aWidths.push_back(x);
+ m_xGroupTLB->set_column_fixed_widths(aWidths);
+ }
+}
+
+IMPL_LINK( SwGlossaryGroupDlg, DeleteHdl, weld::Button&, rButton, void )
+{
+ int nEntry = m_xGroupTLB->get_selected_index();
+ if (nEntry == -1)
+ {
+ rButton.set_sensitive(false);
+ return;
+ }
+ GlosBibUserData* pUserData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(nEntry));
+ OUString const sEntry(pUserData->sGroupName);
+ // if the name to be deleted is among the new ones - get rid of it
+ bool bDelete = true;
+ auto it = std::find(m_InsertedArr.begin(), m_InsertedArr.end(), sEntry);
+ if (it != m_InsertedArr.end())
+ {
+ m_InsertedArr.erase(it);
+ bDelete = false;
+ }
+ // it should probably be renamed?
+ if(bDelete)
+ {
+ it = std::find_if(m_RenamedArr.begin(), m_RenamedArr.end(),
+ [&sEntry](OUString& s) { return o3tl::getToken(s, 0, RENAME_TOKEN_DELIM) == sEntry; });
+ if (it != m_RenamedArr.end())
+ {
+ m_RenamedArr.erase(it);
+ bDelete = false;
+ }
+ }
+ if(bDelete)
+ {
+ m_RemovedArr.emplace_back(pUserData->sGroupName + "\t" + pUserData->sGroupTitle);
+ }
+ delete pUserData;
+ m_xGroupTLB->remove(nEntry);
+ if (!m_xGroupTLB->n_children())
+ rButton.set_sensitive(false);
+ //the content must be deleted - otherwise the new handler would be called in Apply()
+ m_xNameED->set_text(OUString());
+ ModifyHdl(*m_xNameED);
+}
+
+IMPL_LINK_NOARG(SwGlossaryGroupDlg, RenameHdl, weld::Button&, void)
+{
+ int nEntry = m_xGroupTLB->get_selected_index();
+ GlosBibUserData* pUserData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(nEntry));
+ OUString sEntry(pUserData->sGroupName);
+
+ const OUString sNewTitle(m_xNameED->get_text());
+ OUString sNewName = sNewTitle
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(m_xPathLB->get_active());
+ OSL_ENSURE(!m_pGlosHdl->FindGroupName(sNewName), "group already available!");
+
+ // if the name to be renamed is among the new ones - replace
+ bool bDone = false;
+ auto it = std::find(m_InsertedArr.begin(), m_InsertedArr.end(), sEntry);
+ if (it != m_InsertedArr.end())
+ {
+ m_InsertedArr.erase(it);
+ m_InsertedArr.push_back(sNewName);
+ bDone = true;
+ }
+ if(!bDone)
+ {
+ sEntry += OUStringChar(RENAME_TOKEN_DELIM) + sNewName
+ + OUStringChar(RENAME_TOKEN_DELIM) + sNewTitle;
+ m_RenamedArr.push_back(sEntry);
+ }
+ delete pUserData;
+ m_xGroupTLB->remove(nEntry);
+
+ GlosBibUserData* pData = new GlosBibUserData;
+ pData->sPath = m_xPathLB->get_active_text();
+ pData->sGroupName = sNewName;
+ pData->sGroupTitle = sNewTitle;
+
+ OUString sId(weld::toId(pData));
+ m_xGroupTLB->append(sId, m_xNameED->get_text());
+ nEntry = m_xGroupTLB->find_id(sId);
+ m_xGroupTLB->set_text(nEntry, m_xPathLB->get_active_text(), 1);
+ m_xGroupTLB->select(nEntry);
+ SelectHdl(*m_xGroupTLB);
+ m_xGroupTLB->scroll_to_row(nEntry);
+}
+
+IMPL_LINK_NOARG(SwGlossaryGroupDlg, ModifyListBoxHdl, weld::ComboBox&, void)
+{
+ ModifyHdl(*m_xNameED);
+}
+
+IMPL_LINK_NOARG(SwGlossaryGroupDlg, ModifyHdl, weld::Entry&, void)
+{
+ const OUString sEntry(m_xNameED->get_text());
+ bool bEnableNew = true;
+ bool bEnableDel = false;
+ sal_uInt32 nCaseReadonly = m_xPathLB->get_active_id().toUInt32();
+ bool bDirReadonly = 0 != (nCaseReadonly&PATH_READONLY);
+
+ if (sEntry.isEmpty() || bDirReadonly)
+ bEnableNew = false;
+ else if(!sEntry.isEmpty())
+ {
+ int nPos = m_xGroupTLB->find_text(sEntry);
+ //if it's not case sensitive you have to search for yourself
+ if (nPos == -1)
+ {
+ const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
+ for (int i = 0, nEntryCount = m_xGroupTLB->n_children(); i < nEntryCount; ++i)
+ {
+ const OUString sTemp = m_xGroupTLB->get_text(i, 0);
+ nCaseReadonly = m_xPathLB->get_id(m_xPathLB->find_text(m_xGroupTLB->get_text(i,1))).toUInt32();
+ bool bCase = 0 != (nCaseReadonly & PATH_CASE_SENSITIVE);
+
+ if( !bCase && rSCmp.isEqual( sTemp, sEntry ))
+ {
+ nPos = i;
+ break;
+ }
+ }
+ }
+ if (nPos != -1)
+ {
+ bEnableNew = false;
+ m_xGroupTLB->select(nPos);
+ m_xGroupTLB->scroll_to_row(nPos);
+ SelectHdl(*m_xGroupTLB);
+ }
+ }
+ int nEntry = m_xGroupTLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ GlosBibUserData* pUserData = weld::fromId<GlosBibUserData*>(m_xGroupTLB->get_id(nEntry));
+ bEnableDel = IsDeleteAllowed(pUserData->sGroupName);
+ }
+
+ m_xDelPB->set_sensitive(bEnableDel);
+ m_xNewPB->set_sensitive(bEnableNew);
+ m_xRenamePB->set_sensitive(bEnableNew && nEntry != -1);
+}
+
+bool SwGlossaryGroupDlg::IsDeleteAllowed(const OUString &rGroup)
+{
+ bool bDel = !m_pGlosHdl->IsReadOnly(&rGroup);
+
+ // OM: if the name is among the new region name, it is deletable
+ // as well! Because for non existing region names ReadOnly issues
+ // true.
+
+ auto it = std::find(m_InsertedArr.cbegin(), m_InsertedArr.cend(), rGroup);
+ if (it != m_InsertedArr.cend())
+ bDel = true;
+
+ return bDel;
+}
+
+IMPL_STATIC_LINK(SwGlossaryGroupDlg, EditInsertTextHdl, OUString&, rText, bool)
+{
+ rText = rText.replaceAll(OUStringChar(SVT_SEARCHPATH_DELIMITER), "");
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/glossary.cxx b/sw/source/ui/misc/glossary.cxx
new file mode 100644
index 0000000000..8b2860c20c
--- /dev/null
+++ b/sw/source/ui/misc/glossary.cxx
@@ -0,0 +1,1100 @@
+/* -*- 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 <hintids.hxx>
+
+#include <o3tl/any.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/transfer.hxx>
+#include <vcl/weld.hxx>
+#include <svl/stritem.hxx>
+#include <svl/macitem.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/docfilt.hxx>
+#include <osl/diagnose.h>
+
+#include <svx/svxdlg.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <unotools.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/text/AutoTextContainer.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <svl/urihelper.hxx>
+#include <unotools/charclass.hxx>
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <glossary.hxx>
+#include <gloshdl.hxx>
+#include <glosbib.hxx>
+#include <initui.hxx>
+#include <glosdoc.hxx>
+#include <macassgn.hxx>
+#include <docsh.hxx>
+#include <shellio.hxx>
+#include <unotextcursor.hxx>
+
+#include <cmdid.h>
+#include <sfx2/filedlghelper.hxx>
+
+#include <memory>
+
+#include <strings.hrc>
+#include <iodetect.hxx>
+
+#include <officecfg/Office/Writer.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::ucbhelper;
+using namespace ::sfx2;
+
+static OUString lcl_GetValidShortCut( const OUString& rName )
+{
+ const sal_Int32 nSz = rName.getLength();
+
+ if ( 0 == nSz )
+ return rName;
+
+ sal_Int32 nStart = 1;
+ while( rName[nStart-1]==' ' && nStart < nSz )
+ nStart++;
+
+ OUStringBuffer aBuf(OUString::number(rName[nStart-1]));
+
+ for( ; nStart < nSz; ++nStart )
+ {
+ if( rName[nStart-1]==' ' && rName[nStart]!=' ')
+ aBuf.append(rName[nStart]);
+ }
+ return aBuf.makeStringAndClear();
+}
+
+struct GroupUserData
+{
+ OUString sGroupName;
+ sal_uInt16 nPathIdx;
+ bool bReadonly;
+
+ GroupUserData()
+ : nPathIdx(0),
+ bReadonly(false) {}
+};
+
+// dialog for new block name
+class SwNewGlosNameDlg : public weld::GenericDialogController
+{
+ TextFilter m_aNoSpaceFilter;
+ SwGlossaryDlg* m_pParent;
+
+ std::unique_ptr<weld::Entry> m_xNewName;
+ std::unique_ptr<weld::Entry> m_xNewShort;
+ std::unique_ptr<weld::Button> m_xOk;
+ std::unique_ptr<weld::Entry> m_xOldName;
+ std::unique_ptr<weld::Entry> m_xOldShort;
+
+protected:
+ DECL_LINK(Modify, weld::Entry&, void);
+ DECL_LINK(Rename, weld::Button&, void);
+ DECL_LINK(TextFilterHdl, OUString&, bool);
+
+public:
+ SwNewGlosNameDlg(SwGlossaryDlg* pParent,
+ const OUString& rOldName,
+ const OUString& rOldShort);
+
+ OUString GetNewName() const { return m_xNewName->get_text(); }
+ OUString GetNewShort() const { return m_xNewShort->get_text(); }
+};
+
+IMPL_LINK(SwNewGlosNameDlg, TextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = m_aNoSpaceFilter.filter(rTest);
+ return true;
+}
+
+SwNewGlosNameDlg::SwNewGlosNameDlg(SwGlossaryDlg* pParent, const OUString& rOldName, const OUString& rOldShort)
+ : GenericDialogController(pParent->getDialog(), "modules/swriter/ui/renameautotextdialog.ui", "RenameAutoTextDialog")
+ , m_pParent(pParent)
+ , m_xNewName(m_xBuilder->weld_entry("newname"))
+ , m_xNewShort(m_xBuilder->weld_entry("newsc"))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+ , m_xOldName(m_xBuilder->weld_entry("oldname"))
+ , m_xOldShort(m_xBuilder->weld_entry("oldsc"))
+{
+ m_xNewShort->connect_insert_text(LINK(this, SwNewGlosNameDlg, TextFilterHdl));
+
+ m_xOldName->set_text(rOldName);
+ m_xOldShort->set_text(rOldShort);
+ m_xNewName->connect_changed(LINK(this, SwNewGlosNameDlg, Modify ));
+ m_xNewShort->connect_changed(LINK(this, SwNewGlosNameDlg, Modify ));
+ m_xOk->connect_clicked(LINK(this, SwNewGlosNameDlg, Rename ));
+ m_xNewName->grab_focus();
+}
+
+// query / set currently set group
+OUString SwGlossaryDlg::GetCurrGroup()
+{
+ if( !::GetCurrGlosGroup().isEmpty() )
+ return ::GetCurrGlosGroup();
+ return SwGlossaries::GetDefName();
+}
+
+void SwGlossaryDlg::SetActGroup(const OUString &rGrp)
+{
+ ::SetCurrGlosGroup(rGrp);
+}
+
+IMPL_LINK(SwGlossaryDlg, TextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = m_aNoSpaceFilter.filter(rTest);
+ return true;
+}
+
+class SwGlossaryDropTarget : public DropTargetHelper
+{
+private:
+ weld::TreeView& m_rTreeView;
+ SwGlossaryHdl* m_pGlosHdl;
+
+ virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override
+ {
+ weld::TreeView* pSource = m_rTreeView.get_drag_source();
+ if (!pSource || pSource != &m_rTreeView)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSelected(pSource->make_iterator());
+ bool bSelected = pSource->get_selected(xSelected.get());
+ if (!bSelected)
+ return DND_ACTION_NONE;
+
+ while (pSource->get_iter_depth(*xSelected))
+ (void)pSource->iter_parent(*xSelected);
+
+ GroupUserData* pSrcRootData = weld::fromId<GroupUserData*>(pSource->get_id(*xSelected));
+ GroupUserData* pDestRootData = nullptr;
+
+ std::unique_ptr<weld::TreeIter> xDestEntry(m_rTreeView.make_iterator());
+ bool bEntry = m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xDestEntry.get(), true);
+ if (bEntry)
+ {
+ while (m_rTreeView.get_iter_depth(*xDestEntry))
+ (void)m_rTreeView.iter_parent(*xDestEntry);
+ pDestRootData = weld::fromId<GroupUserData*>(m_rTreeView.get_id(*xDestEntry));
+ }
+ if (pDestRootData == pSrcRootData)
+ return DND_ACTION_NONE;
+ sal_uInt8 nRet = DND_ACTION_COPY;
+ const bool bCheckForMove = rEvt.mnAction & DND_ACTION_MOVE;
+ if (bCheckForMove && !pSrcRootData->bReadonly)
+ nRet |= DND_ACTION_MOVE;
+ return nRet;
+ }
+
+ virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override
+ {
+ weld::TreeView* pSource = m_rTreeView.get_drag_source();
+ if (!pSource)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xDestEntry(m_rTreeView.make_iterator());
+ bool bEntry = m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xDestEntry.get(), true);
+ if (!bEntry)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSelected(pSource->make_iterator());
+ bool bSelected = pSource->get_selected(xSelected.get());
+ if (!bSelected)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSrcParent(pSource->make_iterator(xSelected.get()));
+ while (pSource->get_iter_depth(*xSrcParent))
+ (void)pSource->iter_parent(*xSrcParent);
+
+ std::unique_ptr<weld::TreeIter> xDestParent(pSource->make_iterator(xDestEntry.get()));
+ while (pSource->get_iter_depth(*xDestParent))
+ (void)pSource->iter_parent(*xDestParent);
+
+ GroupUserData* pSrcParent = weld::fromId<GroupUserData*>(pSource->get_id(*xSrcParent));
+ GroupUserData* pDestParent = weld::fromId<GroupUserData*>(m_rTreeView.get_id(*xDestParent));
+
+ if (pDestParent != pSrcParent)
+ {
+ weld::WaitObject aBusy(&m_rTreeView);
+
+ OUString sSourceGroup = pSrcParent->sGroupName
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(pSrcParent->nPathIdx);
+
+ m_pGlosHdl->SetCurGroup(sSourceGroup);
+ OUString sTitle(pSource->get_text(*xSelected));
+ OUString sShortName(pSource->get_id(*xSelected));
+
+ OUString sDestName = pDestParent->sGroupName
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(pDestParent->nPathIdx);
+
+ bool bIsMove = rEvt.mnAction & DND_ACTION_MOVE;
+
+ const bool bRet = m_pGlosHdl->CopyOrMove(sSourceGroup, sShortName,
+ sDestName, sTitle, bIsMove);
+
+ if(bRet)
+ {
+ m_rTreeView.insert(xDestParent.get(), -1, &sTitle, &sShortName,
+ nullptr, nullptr, false, nullptr);
+ if (bIsMove)
+ {
+ pSource->remove(*xSelected);
+ }
+ }
+ }
+
+ return DND_ACTION_NONE;
+ }
+
+public:
+ SwGlossaryDropTarget(weld::TreeView& rTreeView, SwGlossaryHdl* pGlosHdl)
+ : DropTargetHelper(rTreeView.get_drop_target())
+ , m_rTreeView(rTreeView)
+ , m_pGlosHdl(pGlosHdl)
+ {
+ }
+};
+
+SwGlossaryDlg::SwGlossaryDlg(const SfxViewFrame& rViewFrame,
+ SwGlossaryHdl * pGlosHdl, SwWrtShell *pWrtShell)
+ : SfxDialogController(rViewFrame.GetFrameWeld(), "modules/swriter/ui/autotext.ui", "AutoTextDialog")
+ , m_sReadonlyPath(SwResId(STR_READONLY_PATH))
+ , m_pGlossaryHdl(pGlosHdl)
+ , m_bResume(false)
+ , m_bSelection(pWrtShell->IsSelection())
+ , m_bReadOnly(false)
+ , m_bIsOld(false)
+ , m_bIsDocReadOnly(false)
+ , m_pShell(pWrtShell)
+ , m_xInsertTipCB(m_xBuilder->weld_check_button("inserttip"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xShortNameLbl(m_xBuilder->weld_label("shortnameft"))
+ , m_xShortNameEdit(m_xBuilder->weld_entry("shortname"))
+ , m_xCategoryBox(m_xBuilder->weld_tree_view("category"))
+ , m_xFileRelCB(m_xBuilder->weld_check_button("relfile"))
+ , m_xNetRelCB(m_xBuilder->weld_check_button("relnet"))
+ , m_xInsertBtn(m_xBuilder->weld_button("ok"))
+ , m_xEditBtn(m_xBuilder->weld_menu_button("autotext"))
+ , m_xBibBtn(m_xBuilder->weld_button("categories"))
+ , m_xPathBtn(m_xBuilder->weld_button("path"))
+{
+ m_xCategoryBox->set_size_request(m_xCategoryBox->get_approximate_digit_width() * 52,
+ m_xCategoryBox->get_height_rows(12));
+
+ Link<SwOneExampleFrame&,void> aLink(LINK(this, SwGlossaryDlg, PreviewLoadedHdl));
+ m_xExampleFrame.reset(new SwOneExampleFrame(EX_SHOW_ONLINE_LAYOUT, &aLink));
+ m_xExampleFrameWin.reset(new weld::CustomWeld(*m_xBuilder, "example", *m_xExampleFrame));
+ Size aSize = m_xExampleFrame->GetDrawingArea()->get_ref_device().LogicToPixel(
+ Size(82, 124), MapMode(MapUnit::MapAppFont));
+ m_xExampleFrame->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xShortNameEdit->connect_insert_text(LINK(this, SwGlossaryDlg, TextFilterHdl));
+
+ m_xEditBtn->connect_toggled(LINK(this, SwGlossaryDlg, EnableHdl));
+ m_xEditBtn->connect_selected(LINK(this, SwGlossaryDlg, MenuHdl));
+ m_xPathBtn->connect_clicked(LINK(this, SwGlossaryDlg, PathHdl));
+
+ m_xNameED->connect_changed(LINK(this,SwGlossaryDlg,NameModify));
+ m_xShortNameEdit->connect_changed(LINK(this,SwGlossaryDlg,NameModify));
+
+ m_xCategoryBox->connect_row_activated(LINK(this, SwGlossaryDlg, NameDoubleClick));
+ m_xCategoryBox->connect_changed(LINK(this, SwGlossaryDlg, GrpSelect));
+ m_xCategoryBox->connect_key_press(LINK(this, SwGlossaryDlg, KeyInputHdl));
+
+ m_xDropTarget.reset(new SwGlossaryDropTarget(*m_xCategoryBox, pGlosHdl));
+ rtl::Reference<TransferDataContainer> xHelper(new TransferDataContainer);
+ m_xCategoryBox->enable_drag_source(xHelper, DND_ACTION_COPYMOVE);
+
+ m_xBibBtn->connect_clicked(LINK(this,SwGlossaryDlg,BibHdl));
+
+ m_xInsertBtn->connect_clicked(LINK(this,SwGlossaryDlg,InsertHdl));
+
+ ShowPreview();
+
+ m_bIsDocReadOnly = m_pShell->GetView().GetDocShell()->IsReadOnly() ||
+ m_pShell->HasReadonlySel();
+ if( m_bIsDocReadOnly )
+ m_xInsertBtn->set_sensitive(false);
+ m_xNameED->grab_focus();
+ m_xCategoryBox->make_sorted();
+ m_xCategoryBox->set_sort_order(true);
+
+ Init();
+}
+
+SwGlossaryDlg::~SwGlossaryDlg()
+{
+}
+
+namespace
+{
+
+OUString getCurrentGlossary()
+{
+ const OUString sTemp{ ::GetCurrGlosGroup() };
+
+ // the zeroth path is not being recorded!
+ if (o3tl::starts_with(o3tl::getToken(sTemp, 1, GLOS_DELIM), u"0"))
+ return sTemp.getToken(0, GLOS_DELIM);
+
+ return sTemp;
+}
+
+}
+
+// select new group
+IMPL_LINK(SwGlossaryDlg, GrpSelect, weld::TreeView&, rBox, void)
+{
+ std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
+ if (!rBox.get_selected(xEntry.get()))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent = rBox.make_iterator(xEntry.get());
+ weld::TreeIter* pParent;
+ if (rBox.get_iter_depth(*xParent))
+ {
+ rBox.iter_parent(*xParent);
+ pParent = xParent.get();
+ }
+ else
+ pParent = xEntry.get();
+ GroupUserData* pGroupData = weld::fromId<GroupUserData*>(rBox.get_id(*pParent));
+ ::SetCurrGlosGroup(pGroupData->sGroupName
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(pGroupData->nPathIdx));
+ m_pGlossaryHdl->SetCurGroup(::GetCurrGlosGroup());
+ // set current text block
+ m_bReadOnly = m_pGlossaryHdl->IsReadOnly();
+ EnableShortName( !m_bReadOnly );
+ m_xEditBtn->set_sensitive(!m_bReadOnly);
+ m_bIsOld = m_pGlossaryHdl->IsOld();
+ if( pParent != xEntry.get())
+ {
+ OUString aName(rBox.get_text(*xEntry));
+ m_xNameED->set_text(aName);
+ m_xShortNameEdit->set_text(rBox.get_id(*xEntry));
+ m_xInsertBtn->set_sensitive( !m_bIsDocReadOnly);
+ ShowAutoText(::GetCurrGlosGroup(), m_xShortNameEdit->get_text());
+ }
+ else
+ ShowAutoText("", "");
+ // update controls
+ NameModify(*m_xShortNameEdit);
+ if (SfxRequest::HasMacroRecorder(m_pShell->GetView().GetViewFrame()))
+ {
+ SfxRequest aReq(m_pShell->GetView().GetViewFrame(), FN_SET_ACT_GLOSSARY);
+ aReq.AppendItem(SfxStringItem(FN_SET_ACT_GLOSSARY, getCurrentGlossary()));
+ aReq.Done();
+ }
+}
+
+short SwGlossaryDlg::run()
+{
+ short nRet = SfxDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+void SwGlossaryDlg::Apply()
+{
+ const OUString aGlosName(m_xShortNameEdit->get_text());
+ if (!aGlosName.isEmpty())
+ {
+ m_pGlossaryHdl->InsertGlossary(aGlosName);
+ }
+ if (SfxRequest::HasMacroRecorder(m_pShell->GetView().GetViewFrame()))
+ {
+ SfxRequest aReq(m_pShell->GetView().GetViewFrame(), FN_INSERT_GLOSSARY);
+ aReq.AppendItem(SfxStringItem(FN_INSERT_GLOSSARY, getCurrentGlossary()));
+ aReq.AppendItem(SfxStringItem(FN_PARAM_1, aGlosName));
+ aReq.Done();
+ }
+}
+
+void SwGlossaryDlg::EnableShortName(bool bOn)
+{
+ m_xShortNameLbl->set_sensitive(bOn);
+ m_xShortNameEdit->set_sensitive(bOn);
+}
+
+// does the title exist in the selected group?
+std::unique_ptr<weld::TreeIter> SwGlossaryDlg::DoesBlockExist(std::u16string_view rBlock,
+ std::u16string_view rShort)
+{
+ // look for possible entry in TreeListBox
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ if (m_xCategoryBox->get_selected(xEntry.get()))
+ {
+ if (m_xCategoryBox->get_iter_depth(*xEntry))
+ m_xCategoryBox->iter_parent(*xEntry);
+ if (!m_xCategoryBox->iter_children(*xEntry))
+ return nullptr;
+ do
+ {
+ if (rBlock == m_xCategoryBox->get_text(*xEntry) &&
+ (rShort.empty() ||
+ rShort == m_xCategoryBox->get_id(*xEntry))
+ )
+ {
+ return xEntry;
+ }
+ }
+ while (m_xCategoryBox->iter_next_sibling(*xEntry));
+ }
+ return nullptr;
+}
+
+IMPL_LINK(SwGlossaryDlg, NameModify, weld::Entry&, rEdit, void)
+{
+ const OUString aName(m_xNameED->get_text());
+ bool bNameED = &rEdit == m_xNameED.get();
+ if( aName.isEmpty() )
+ {
+ if(bNameED)
+ m_xShortNameEdit->set_text(aName);
+ m_xInsertBtn->set_sensitive(false);
+ return;
+ }
+ const bool bNotFound = !DoesBlockExist(aName, bNameED ? OUString() : rEdit.get_text());
+ if(bNameED)
+ {
+ // did the text get in to the Listbox in the Edit with a click?
+ if(bNotFound)
+ {
+ m_xShortNameEdit->set_text( lcl_GetValidShortCut( aName ) );
+ EnableShortName();
+ }
+ else
+ {
+ m_xShortNameEdit->set_text(m_pGlossaryHdl->GetGlossaryShortName(aName));
+ EnableShortName(!m_bReadOnly);
+ }
+ m_xInsertBtn->set_sensitive(!bNotFound && !m_bIsDocReadOnly);
+ }
+ else
+ {
+ //ShortNameEdit
+ if(!bNotFound)
+ {
+ m_xInsertBtn->set_sensitive(!m_bIsDocReadOnly);
+ }
+ }
+}
+
+IMPL_LINK( SwGlossaryDlg, NameDoubleClick, weld::TreeView&, rBox, bool )
+{
+ std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
+ if (rBox.get_selected(xEntry.get()) && rBox.get_iter_depth(*xEntry) && !m_bIsDocReadOnly)
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+IMPL_LINK_NOARG( SwGlossaryDlg, EnableHdl, weld::Toggleable&, void )
+{
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ bool bEntry = m_xCategoryBox->get_selected(xEntry.get());
+
+ const OUString aEditText(m_xNameED->get_text());
+ const bool bHasEntry = !aEditText.isEmpty() && !m_xShortNameEdit->get_text().isEmpty();
+ const bool bExists = nullptr != DoesBlockExist(aEditText, m_xShortNameEdit->get_text());
+ const bool bIsGroup = bEntry && !m_xCategoryBox->get_iter_depth(*xEntry);
+ m_xEditBtn->set_item_visible("new", m_bSelection && bHasEntry && !bExists);
+ m_xEditBtn->set_item_visible("newtext", m_bSelection && bHasEntry && !bExists);
+ m_xEditBtn->set_item_visible("copy", bExists && !bIsGroup);
+ m_xEditBtn->set_item_visible("replace", m_bSelection && bExists && !bIsGroup && !m_bIsOld );
+ m_xEditBtn->set_item_visible("replacetext", m_bSelection && bExists && !bIsGroup && !m_bIsOld );
+ m_xEditBtn->set_item_visible("edit", bExists && !bIsGroup );
+ m_xEditBtn->set_item_visible("rename", bExists && !bIsGroup );
+ m_xEditBtn->set_item_visible("delete", bExists && !bIsGroup );
+ m_xEditBtn->set_item_visible("macro", bExists && !bIsGroup && !m_bIsOld &&
+ !m_pGlossaryHdl->IsReadOnly() );
+ m_xEditBtn->set_item_visible("import", bIsGroup && !m_bIsOld && !m_pGlossaryHdl->IsReadOnly() );
+}
+
+IMPL_LINK(SwGlossaryDlg, MenuHdl, const OUString&, rItemIdent, void)
+{
+ if (rItemIdent == "edit")
+ {
+ std::unique_ptr<SwTextBlocks> pGroup = ::GetGlossaries()->GetGroupDoc ( GetCurrGrpName () );
+ pGroup.reset();
+ m_xDialog->response(RET_EDIT);
+ }
+ else if (rItemIdent == "replace")
+ {
+ m_pGlossaryHdl->NewGlossary(m_xNameED->get_text(),
+ m_xShortNameEdit->get_text());
+ }
+ else if (rItemIdent == "replacetext")
+ {
+ m_pGlossaryHdl->NewGlossary(m_xNameED->get_text(),
+ m_xShortNameEdit->get_text(),
+ false, true);
+ }
+ else if (rItemIdent == "new" || rItemIdent == "newtext")
+ {
+ bool bNoAttr = rItemIdent == "newtext";
+
+ const OUString aStr(m_xNameED->get_text());
+ const OUString aShortName(m_xShortNameEdit->get_text());
+ if(m_pGlossaryHdl->HasShortName(aShortName))
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_DOUBLE_SHORTNAME)));
+ xInfoBox->run();
+ m_xShortNameEdit->select_region(0, -1);
+ m_xShortNameEdit->grab_focus();
+ }
+ if(m_pGlossaryHdl->NewGlossary(aStr, aShortName, false, bNoAttr ))
+ {
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ if (!m_xCategoryBox->get_selected(xEntry.get()))
+ xEntry.reset();
+ else if (m_xCategoryBox->get_iter_depth(*xEntry))
+ m_xCategoryBox->iter_parent(*xEntry);
+ m_xCategoryBox->insert(xEntry.get(), -1, &aStr, &aShortName,
+ nullptr, nullptr, false, nullptr);
+
+ m_xNameED->set_text(aStr);
+ m_xShortNameEdit->set_text(aShortName);
+ NameModify(*m_xNameED); // for toggling the buttons
+
+ if (SfxRequest::HasMacroRecorder(m_pShell->GetView().GetViewFrame()))
+ {
+ SfxRequest aReq(m_pShell->GetView().GetViewFrame(), FN_NEW_GLOSSARY);
+ aReq.AppendItem(SfxStringItem(FN_NEW_GLOSSARY, getCurrentGlossary()));
+ aReq.AppendItem(SfxStringItem(FN_PARAM_1, aShortName));
+ aReq.AppendItem(SfxStringItem(FN_PARAM_2, aStr));
+ aReq.Done();
+ }
+ }
+ }
+ else if (rItemIdent == "copy")
+ {
+ m_pGlossaryHdl->CopyToClipboard(*m_pShell, m_xShortNameEdit->get_text());
+ }
+ else if (rItemIdent == "rename")
+ {
+ m_xShortNameEdit->set_text(m_pGlossaryHdl->GetGlossaryShortName(m_xNameED->get_text()));
+ SwNewGlosNameDlg aNewNameDlg(this, m_xNameED->get_text(), m_xShortNameEdit->get_text());
+ if (aNewNameDlg.run() == RET_OK && m_pGlossaryHdl->Rename(m_xShortNameEdit->get_text(),
+ aNewNameDlg.GetNewShort(),
+ aNewNameDlg.GetNewName()))
+ {
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ if (m_xCategoryBox->get_selected(xEntry.get()))
+ {
+ std::unique_ptr<weld::TreeIter> xOldEntry = m_xCategoryBox->make_iterator(xEntry.get());
+ if (m_xCategoryBox->get_iter_depth(*xEntry))
+ m_xCategoryBox->iter_parent(*xEntry);
+
+ std::unique_ptr<weld::TreeIter> xNewEntry = m_xCategoryBox->make_iterator();
+ OUString sId(aNewNameDlg.GetNewShort());
+ OUString sName(aNewNameDlg.GetNewName());
+
+ m_xCategoryBox->insert(xEntry.get(), -1, &sName, &sId,
+ nullptr, nullptr, false, xNewEntry.get());
+
+ m_xCategoryBox->remove(*xOldEntry);
+ m_xCategoryBox->select(*xNewEntry);
+ m_xCategoryBox->scroll_to_row(*xNewEntry);
+ }
+ }
+ GrpSelect(*m_xCategoryBox);
+ }
+ else if (rItemIdent == "delete")
+ {
+ DeleteEntry();
+ }
+ else if (rItemIdent == "macro")
+ {
+ SfxItemSetFixed<RES_FRMMACRO, RES_FRMMACRO, SID_EVENTCONFIG, SID_EVENTCONFIG> aSet( m_pShell->GetAttrPool() );
+
+ SvxMacro aStart(OUString(), OUString(), STARBASIC);
+ SvxMacro aEnd(OUString(), OUString(), STARBASIC);
+ m_pGlossaryHdl->GetMacros(m_xShortNameEdit->get_text(), aStart, aEnd );
+
+ SvxMacroItem aItem(RES_FRMMACRO);
+ if( aStart.HasMacro() )
+ aItem.SetMacro( SvMacroItemId::SwStartInsGlossary, aStart );
+ if( aEnd.HasMacro() )
+ aItem.SetMacro( SvMacroItemId::SwEndInsGlossary, aEnd );
+
+ aSet.Put( aItem );
+ aSet.Put( SwMacroAssignDlg::AddEvents( MACASSGN_AUTOTEXT ) );
+
+ const SvxMacroItem* pMacroItem;
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pMacroDlg(pFact->CreateEventConfigDialog(m_xDialog.get(), aSet,
+ m_pShell->GetView().GetViewFrame().GetFrame().GetFrameInterface() ));
+ if ( pMacroDlg && pMacroDlg->Execute() == RET_OK &&
+ (pMacroItem = pMacroDlg->GetOutputItemSet()->GetItemIfSet( RES_FRMMACRO, false )) )
+ {
+ const SvxMacroTableDtor& rTable = pMacroItem->GetMacroTable();
+ m_pGlossaryHdl->SetMacros( m_xShortNameEdit->get_text(),
+ rTable.Get( SvMacroItemId::SwStartInsGlossary ),
+ rTable.Get( SvMacroItemId::SwEndInsGlossary ) );
+ }
+ }
+ else if (rItemIdent == "import")
+ {
+ // call the FileOpenDialog do find WinWord - Files with templates
+ FileDialogHelper aDlgHelper(TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, m_xDialog.get());
+ aDlgHelper.SetContext(FileDialogHelper::WriterImportAutotext);
+ uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
+
+ SfxFilterMatcher aMatcher( SwDocShell::Factory().GetFactoryName() );
+ SfxFilterMatcherIter aIter( aMatcher );
+ std::shared_ptr<const SfxFilter> pFilter = aIter.First();
+ while ( pFilter )
+ {
+ if( pFilter->GetUserData() == FILTER_WW8 )
+ {
+ xFP->appendFilter( pFilter->GetUIName(),
+ pFilter->GetWildcard().getGlob() );
+ xFP->setCurrentFilter( pFilter->GetUIName() ) ;
+ }
+ else if( pFilter->GetUserData() == FILTER_DOCX )
+ {
+ xFP->appendFilter( pFilter->GetUIName(),
+ pFilter->GetWildcard().getGlob() );
+ xFP->setCurrentFilter( pFilter->GetUIName() ) ;
+ }
+
+ pFilter = aIter.Next();
+ }
+
+ if( aDlgHelper.Execute() == ERRCODE_NONE )
+ {
+ if( m_pGlossaryHdl->ImportGlossaries( xFP->getSelectedFiles().getConstArray()[0] ))
+ Init();
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_NO_GLOSSARIES)));
+ xInfoBox->run();
+ }
+ }
+ }
+}
+
+// dialog manage regions
+IMPL_LINK_NOARG(SwGlossaryDlg, BibHdl, weld::Button&, void)
+{
+ SwGlossaries* pGloss = ::GetGlossaries();
+ if( pGloss->IsGlosPathErr() )
+ pGloss->ShowError();
+ else
+ {
+ //check if at least one glossary path is write enabled
+ SvtPathOptions aPathOpt;
+ const OUString& sGlosPath( aPathOpt.GetAutoTextPath() );
+ bool bIsWritable = false;
+ sal_Int32 nIdx {sGlosPath.isEmpty() ? -1 : 0};
+ while (nIdx>=0)
+ {
+ const OUString sPath = URIHelper::SmartRel2Abs(
+ INetURLObject(), sGlosPath.getToken(0, ';', nIdx),
+ URIHelper::GetMaybeFileHdl());
+ try
+ {
+ Content aTestContent( sPath,
+ uno::Reference< XCommandEnvironment >(),
+ comphelper::getProcessComponentContext() );
+ Any aAny = aTestContent.getPropertyValue( "IsReadOnly" );
+ if(aAny.hasValue())
+ {
+ bIsWritable = !*o3tl::doAccess<bool>(aAny);
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ if(bIsWritable)
+ break;
+ }
+ if(bIsWritable)
+ {
+
+ SwGlossaryGroupDlg aDlg(m_xDialog.get(), pGloss->GetPathArray(), m_pGlossaryHdl);
+ if (aDlg.run() == RET_OK)
+ {
+ Init();
+ //if new groups were created - select one of them
+ const OUString sNewGroup = aDlg.GetCreatedGroupName();
+
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ bool bEntry = m_xCategoryBox->get_iter_first(*xEntry);
+
+ while (!sNewGroup.isEmpty() && bEntry)
+ {
+ if (!m_xCategoryBox->get_iter_depth(*xEntry))
+ {
+ GroupUserData* pGroupData = weld::fromId<GroupUserData*>(m_xCategoryBox->get_id(*xEntry));
+ const OUString sGroup = pGroupData->sGroupName
+ + OUStringChar(GLOS_DELIM)
+ + OUString::number(pGroupData->nPathIdx);
+ if(sGroup == sNewGroup)
+ {
+ m_xCategoryBox->select(*xEntry);
+ m_xCategoryBox->scroll_to_row(*xEntry);
+ GrpSelect(*m_xCategoryBox);
+ break;
+ }
+ }
+ bEntry = m_xCategoryBox->iter_next(*xEntry);
+ }
+
+ }
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_sReadonlyPath));
+ if (RET_YES == xBox->run())
+ PathHdl(*m_xPathBtn);
+ }
+ }
+}
+
+// initialisation; from Ctor and after editing regions
+void SwGlossaryDlg::Init()
+{
+ m_xCategoryBox->freeze();
+ m_xCategoryBox->clear();
+ m_xGroupData.clear();
+ m_xCategoryBox->make_unsorted();
+
+ // display text block regions
+ const size_t nCnt = m_pGlossaryHdl->GetGroupCnt();
+ std::unique_ptr<weld::TreeIter> xSelEntry;
+ const OUString sSelStr(::GetCurrGlosGroup().getToken(0, GLOS_DELIM));
+ const sal_Int32 nSelPath = o3tl::toInt32(o3tl::getToken(::GetCurrGlosGroup(), 1, GLOS_DELIM));
+ // #i66304# - "My AutoText" comes from mytexts.bau, but should be translated
+ static constexpr OUStringLiteral sMyAutoTextEnglish(u"My AutoText");
+ const OUString sMyAutoTextTranslated(SwResId(STR_MY_AUTOTEXT));
+ for(size_t nId = 0; nId < nCnt; ++nId )
+ {
+ OUString sTitle;
+ OUString sGroupName(m_pGlossaryHdl->GetGroupName(nId, &sTitle));
+ if(sGroupName.isEmpty())
+ continue;
+ sal_Int32 nIdx{ 0 };
+ const OUString sName{ sGroupName.getToken( 0, GLOS_DELIM, nIdx ) };
+ if(sTitle.isEmpty())
+ sTitle = sName;
+ if(sTitle == sMyAutoTextEnglish)
+ sTitle = sMyAutoTextTranslated;
+
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ m_xCategoryBox->append(xEntry.get());
+ m_xCategoryBox->set_text(*xEntry, sTitle, 0);
+ const sal_Int32 nPath = o3tl::toInt32(o3tl::getToken(sGroupName, 0, GLOS_DELIM, nIdx ));
+
+ GroupUserData* pData = new GroupUserData;
+ pData->sGroupName = sName;
+ pData->nPathIdx = static_cast< sal_uInt16 >(nPath);
+ pData->bReadonly = m_pGlossaryHdl->IsReadOnly(&sGroupName);
+ m_xGroupData.emplace_back(pData);
+
+ m_xCategoryBox->set_id(*xEntry, weld::toId(pData));
+ if (sSelStr == pData->sGroupName && nSelPath == nPath)
+ xSelEntry = m_xCategoryBox->make_iterator(xEntry.get());
+
+ // fill entries for the groups
+ {
+ m_pGlossaryHdl->SetCurGroup(sGroupName, false, true);
+ const sal_uInt16 nCount = m_pGlossaryHdl->GetGlossaryCnt();
+ for(sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ OUString sEntryName = m_pGlossaryHdl->GetGlossaryName(i);
+ OUString sId = m_pGlossaryHdl->GetGlossaryShortName(i);
+ m_xCategoryBox->insert(xEntry.get(), -1, &sEntryName, &sId,
+ nullptr, nullptr, false, nullptr);
+ }
+ }
+ }
+ // set current group and display text blocks
+ if (!xSelEntry)
+ {
+ //find a non-readonly group
+ std::unique_ptr<weld::TreeIter> xSearch = m_xCategoryBox->make_iterator();
+ if (m_xCategoryBox->get_iter_first(*xSearch))
+ {
+ do
+ {
+ if (!m_xCategoryBox->get_iter_depth(*xSearch))
+ {
+ GroupUserData* pData = weld::fromId<GroupUserData*>(m_xCategoryBox->get_id(*xSearch));
+ if (!pData->bReadonly)
+ {
+ xSelEntry = std::move(xSearch);
+ break;
+ }
+ }
+ }
+ while (m_xCategoryBox->iter_next(*xSearch));
+ }
+ if (!xSelEntry)
+ {
+ xSelEntry = std::move(xSearch);
+ if (!xSelEntry || !m_xCategoryBox->get_iter_first(*xSelEntry))
+ xSelEntry.reset();
+ }
+ }
+
+ m_xCategoryBox->thaw();
+ m_xCategoryBox->make_sorted();
+
+ if (xSelEntry)
+ {
+ m_xCategoryBox->expand_row(*xSelEntry);
+ m_xCategoryBox->select(*xSelEntry);
+ m_xCategoryBox->scroll_to_row(*xSelEntry);
+ GrpSelect(*m_xCategoryBox);
+ }
+
+ const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ m_xFileRelCB->set_active( rCfg.IsSaveRelFile() );
+ m_xFileRelCB->connect_toggled(LINK(this, SwGlossaryDlg, CheckBoxHdl));
+ m_xNetRelCB->set_active( rCfg.IsSaveRelNet() );
+ m_xNetRelCB->connect_toggled(LINK(this, SwGlossaryDlg, CheckBoxHdl));
+ m_xInsertTipCB->set_active( rCfg.IsAutoTextTip() );
+ m_xInsertTipCB->set_sensitive(!officecfg::Office::Writer::AutoFunction::Text::ShowToolTip::isReadOnly());
+ m_xInsertTipCB->connect_toggled(LINK(this, SwGlossaryDlg, CheckBoxHdl));
+
+ // tdf#124088 - propose autotext and shortcut name based on selected text
+ if (m_pShell->HasSelection())
+ {
+ OUString aSelText;
+ m_pShell->GetSelectedText(aSelText, ParaBreakType::ToBlank);
+
+ aSelText = aSelText.trim();
+ if (aSelText.getLength() > 25)
+ {
+ aSelText = aSelText.copy(0, 25);
+ if (const sal_Int32 nBlankIndex = aSelText.lastIndexOf(' '); nBlankIndex != -1)
+ aSelText = aSelText.copy(0, nBlankIndex);
+ }
+
+ m_xNameED->set_text(aSelText);
+ m_xNameED->select_region(0, -1);
+ m_xShortNameEdit->set_text(lcl_GetValidShortCut(aSelText));
+ }
+}
+
+// KeyInput for ShortName - Edits without Spaces
+IMPL_LINK( SwNewGlosNameDlg, Modify, weld::Entry&, rBox, void )
+{
+ OUString aName(m_xNewName->get_text());
+ SwGlossaryDlg* pDlg = m_pParent;
+ if (&rBox == m_xNewName.get())
+ m_xNewShort->set_text(lcl_GetValidShortCut(aName));
+
+ bool bEnable = !aName.isEmpty() && !m_xNewShort->get_text().isEmpty() &&
+ (!pDlg->DoesBlockExist(aName, m_xNewShort->get_text())
+ || aName == m_xOldName->get_text());
+ m_xOk->set_sensitive(bEnable);
+}
+
+IMPL_LINK_NOARG(SwNewGlosNameDlg, Rename, weld::Button&, void)
+{
+ SwGlossaryDlg* pDlg = m_pParent;
+ OUString sNew = GetAppCharClass().uppercase(m_xNewShort->get_text());
+ if (pDlg->m_pGlossaryHdl->HasShortName(m_xNewShort->get_text())
+ && sNew != m_xOldShort->get_text())
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_DOUBLE_SHORTNAME)));
+ xBox->run();
+ m_xNewShort->grab_focus();
+ }
+ else
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwGlossaryDlg, CheckBoxHdl, weld::Toggleable&, rBox, void)
+{
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ bool bCheck = rBox.get_active();
+ if (&rBox == m_xInsertTipCB.get())
+ rCfg.SetAutoTextTip(bCheck);
+ else if (&rBox == m_xFileRelCB.get())
+ rCfg.SetSaveRelFile(bCheck);
+ else
+ rCfg.SetSaveRelNet(bCheck);
+ rCfg.Commit();
+}
+
+IMPL_LINK(SwGlossaryDlg, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ if (rKEvt.GetKeyCode().GetCode() == KEY_DELETE)
+ {
+ DeleteEntry();
+ return true;
+ }
+ return false;
+}
+
+OUString SwGlossaryDlg::GetCurrGrpName() const
+{
+ std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
+ if (m_xCategoryBox->get_selected(xEntry.get()))
+ {
+ if (m_xCategoryBox->get_iter_depth(*xEntry))
+ m_xCategoryBox->iter_parent(*xEntry);
+ GroupUserData* pGroupData = weld::fromId<GroupUserData*>(m_xCategoryBox->get_id(*xEntry));
+ return pGroupData->sGroupName + OUStringChar(GLOS_DELIM) + OUString::number(pGroupData->nPathIdx);
+ }
+ return OUString();
+}
+
+IMPL_LINK_NOARG( SwGlossaryDlg, PathHdl, weld::Button&, void )
+{
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxMultiPathDialog> pDlg(pFact->CreateSvxPathSelectDialog(m_xDialog.get()));
+ SvtPathOptions aPathOpt;
+ const OUString sGlosPath( aPathOpt.GetAutoTextPath() );
+ pDlg->SetPath(sGlosPath);
+ if(RET_OK == pDlg->Execute())
+ {
+ const OUString sTmp(pDlg->GetPath());
+ if(sTmp != sGlosPath)
+ {
+ aPathOpt.SetAutoTextPath( sTmp );
+ ::GetGlossaries()->UpdateGlosPath( true );
+ Init();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SwGlossaryDlg, InsertHdl, weld::Button&, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+void SwGlossaryDlg::ShowPreview()
+{
+ ShowAutoText(::GetCurrGlosGroup(), m_xShortNameEdit->get_text());
+};
+
+IMPL_LINK_NOARG(SwGlossaryDlg, PreviewLoadedHdl, SwOneExampleFrame&, void)
+{
+ ResumeShowAutoText();
+}
+
+void SwGlossaryDlg::ShowAutoText(const OUString& rGroup, const OUString& rShortName)
+{
+ if (m_xExampleFrameWin->get_visible())
+ {
+ SetResumeData(rGroup, rShortName);
+ //try to make an Undo()
+ m_xExampleFrame->ClearDocument();
+ }
+}
+
+void SwGlossaryDlg::ResumeShowAutoText()
+{
+ OUString sGroup;
+ OUString sShortName;
+ if(GetResumeData(sGroup, sShortName) && m_xExampleFrameWin->get_visible())
+ {
+ if(!m_xAutoText.is())
+ {
+ //now the AutoText ListBoxes have to be filled
+ m_xAutoText = text::AutoTextContainer::create( comphelper::getProcessComponentContext() );
+ }
+
+ rtl::Reference< SwXTextCursor > & xCursor = m_xExampleFrame->GetTextCursor();
+ if(xCursor.is())
+ {
+ if (!sShortName.isEmpty())
+ {
+ uno::Any aGroup = m_xAutoText->getByName(sGroup);
+ uno::Reference< XAutoTextGroup > xGroup;
+ if((aGroup >>= xGroup) && xGroup->hasByName(sShortName))
+ {
+ uno::Any aEntry(xGroup->getByName(sShortName));
+ uno::Reference< XAutoTextEntry > xEntry;
+ aEntry >>= xEntry;
+ xEntry->applyTo(static_cast<XSentenceCursor*>(xCursor.get()));
+ }
+ }
+ }
+ }
+ m_bResume = false;
+}
+
+void SwGlossaryDlg::DeleteEntry()
+{
+ bool bEntry = m_xCategoryBox->get_selected(nullptr);
+
+ const OUString aTitle(m_xNameED->get_text());
+ const OUString aShortName(m_xShortNameEdit->get_text());
+
+ std::unique_ptr<weld::TreeIter> xParent;
+ std::unique_ptr<weld::TreeIter> xChild = DoesBlockExist(aTitle, aShortName);
+ if (xChild && m_xCategoryBox->get_iter_depth(*xChild))
+ {
+ xParent = m_xCategoryBox->make_iterator(xChild.get());
+ m_xCategoryBox->iter_parent(*xParent);
+ }
+
+ const bool bExists = nullptr != xChild;
+ const bool bIsGroup = bEntry && !xParent;
+
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ SwResId(STR_QUERY_DELETE)));
+ if (bExists && !bIsGroup && RET_YES == xQuery->run())
+ {
+ if (!aTitle.isEmpty() && m_pGlossaryHdl->DelGlossary(aShortName))
+ {
+ OSL_ENSURE(xChild, "entry not found!");
+ m_xCategoryBox->select(*xParent);
+ m_xCategoryBox->remove(*xChild);
+ m_xNameED->set_text(OUString());
+ NameModify(*m_xNameED);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/impfnote.hxx b/sw/source/ui/misc/impfnote.hxx
new file mode 100644
index 0000000000..eb5c491a45
--- /dev/null
+++ b/sw/source/ui/misc/impfnote.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_MISC_IMPFNOTE_HXX
+#define INCLUDED_SW_SOURCE_UI_MISC_IMPFNOTE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/weld.hxx>
+#include <numberingtypelistbox.hxx>
+
+enum SwFootnoteNum : unsigned;
+class SwWrtShell;
+
+class SwEndNoteOptionPage : public SfxTabPage
+{
+ OUString m_aNumDoc;
+ OUString m_aNumPage;
+ OUString m_aNumChapter;
+ SwWrtShell *m_pSh;
+ bool m_bPosDoc;
+ bool m_bEndNote;
+
+ std::unique_ptr<SwNumberingTypeListBox> m_xNumViewBox;
+ std::unique_ptr<weld::Label> m_xOffsetLbl;
+ std::unique_ptr<weld::SpinButton> m_xOffsetField;
+ std::unique_ptr<weld::ComboBox> m_xNumCountBox;
+ std::unique_ptr<weld::Entry> m_xPrefixED;
+ std::unique_ptr<weld::Entry> m_xSuffixED;
+ std::unique_ptr<weld::RadioButton> m_xPosPageBox;
+ std::unique_ptr<weld::RadioButton> m_xPosChapterBox;
+ std::unique_ptr<weld::Widget> m_xStylesContainer;
+ std::unique_ptr<weld::ComboBox> m_xParaTemplBox;
+ std::unique_ptr<weld::Label> m_xPageTemplLbl;
+ std::unique_ptr<weld::ComboBox> m_xPageTemplBox;
+ std::unique_ptr<weld::ComboBox> m_xFootnoteCharAnchorTemplBox;
+ std::unique_ptr<weld::ComboBox> m_xFootnoteCharTextTemplBox;
+ std::unique_ptr<weld::Entry> m_xContEdit;
+ std::unique_ptr<weld::Entry> m_xContFromEdit;
+
+ inline void SelectNumbering(SwFootnoteNum eNum);
+ SwFootnoteNum GetNumbering() const;
+
+ DECL_LINK(ToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(NumCountHdl, weld::ComboBox&, void);
+
+public:
+ SwEndNoteOptionPage(weld::Container* pPage, weld::DialogController* pController, bool bEndNote, const SfxItemSet &rSet);
+ virtual ~SwEndNoteOptionPage() 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* ) override;
+
+ void SetShell( SwWrtShell &rShell );
+};
+
+class SwFootNoteOptionPage : public SwEndNoteOptionPage
+{
+public:
+ SwFootNoteOptionPage(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 ~SwFootNoteOptionPage() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/insfnote.cxx b/sw/source/ui/misc/insfnote.cxx
new file mode 100644
index 0000000000..f468ae51c6
--- /dev/null
+++ b/sw/source/ui/misc/insfnote.cxx
@@ -0,0 +1,249 @@
+/* -*- 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 <hintids.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <fmtftn.hxx>
+#include <swundo.hxx>
+#include <cmdid.h>
+#include <wrtsh.hxx>
+#include <insfnote.hxx>
+#include <svx/svxdlg.hxx>
+
+#include <memory>
+
+static bool bFootnote = true;
+
+// inserting a footnote with OK
+void SwInsFootNoteDlg::Apply()
+{
+ OUString aStr;
+ if ( m_xNumberCharBtn->get_active() )
+ aStr = m_xNumberCharEdit->get_text();
+
+ if (m_bEdit)
+ {
+ m_rSh.StartAction();
+ m_rSh.Left(SwCursorSkipMode::Chars, false, 1, false );
+ m_rSh.StartUndo( SwUndoId::START );
+ SwFormatFootnote aNote( m_xEndNoteBtn->get_active() );
+ aNote.SetNumStr( aStr );
+
+ if (m_rSh.SetCurFootnote( aNote ) && m_bExtCharAvailable)
+ {
+ m_rSh.Right(SwCursorSkipMode::Chars, true, 1, false );
+ SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet(m_rSh.GetAttrPool());
+ m_rSh.GetCurAttr(aSet);
+ const SvxFontItem &rFont = aSet.Get( RES_CHRATR_FONT );
+ SvxFontItem aFont( rFont.GetFamily(), m_aFontName,
+ rFont.GetStyleName(), rFont.GetPitch(),
+ m_eCharSet, RES_CHRATR_FONT );
+ aSet.Put( aFont );
+ m_rSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
+ m_rSh.ResetSelect(nullptr, false);
+ m_rSh.Left(SwCursorSkipMode::Chars, false, 1, false );
+ }
+ m_rSh.EndUndo( SwUndoId::END );
+ m_rSh.EndAction();
+ }
+
+ bFootnote = m_xFootnoteBtn->get_active();
+}
+
+IMPL_LINK_NOARG(SwInsFootNoteDlg, NumberEditHdl, weld::Entry&, void)
+{
+ m_xNumberCharBtn->set_active(true);
+ m_xOkBtn->set_sensitive( !m_xNumberCharEdit->get_text().isEmpty() );
+}
+
+IMPL_LINK(SwInsFootNoteDlg, NumberToggleHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ if (m_xNumberAutoBtn->get_active())
+ m_xOkBtn->set_sensitive(true);
+ else if (m_xNumberCharBtn->get_active())
+ {
+ m_xNumberCharEdit->grab_focus();
+ m_xOkBtn->set_sensitive( !m_xNumberCharEdit->get_text().isEmpty() || m_bExtCharAvailable );
+ }
+}
+
+IMPL_LINK_NOARG(SwInsFootNoteDlg, NumberExtCharHdl, weld::Button&, void)
+{
+ m_xNumberCharBtn->set_active(true);
+
+ SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet(m_rSh.GetAttrPool());
+ m_rSh.GetCurAttr( aSet );
+ const SvxFontItem &rFont = aSet.Get( RES_CHRATR_FONT );
+
+ SfxAllItemSet aAllSet(m_rSh.GetAttrPool());
+ aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
+ aAllSet.Put( rFont );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(m_xDialog.get(), aAllSet, nullptr));
+ if (RET_OK != pDlg->Execute())
+ return;
+
+ const SfxStringItem* pItem = SfxItemSet::GetItem<SfxStringItem>(pDlg->GetOutputItemSet(), SID_CHARMAP, false);
+ const SvxFontItem* pFontItem = SfxItemSet::GetItem<SvxFontItem>(pDlg->GetOutputItemSet(), SID_ATTR_CHAR_FONT, false);
+ if ( !pItem )
+ return;
+
+ m_xNumberCharEdit->set_text(pItem->GetValue());
+
+ if ( pFontItem )
+ {
+ m_aFontName = pFontItem->GetFamilyName();
+ m_eCharSet = pFontItem->GetCharSet();
+ vcl::Font aFont(m_aFontName, pFontItem->GetStyleName(), m_xNumberCharEdit->get_font().GetFontSize());
+ aFont.SetCharSet( pFontItem->GetCharSet() );
+ aFont.SetPitch( pFontItem->GetPitch() );
+ m_xNumberCharEdit->set_font(aFont);
+ }
+
+ m_bExtCharAvailable = true;
+ m_xOkBtn->set_sensitive(!m_xNumberCharEdit->get_text().isEmpty());
+}
+
+IMPL_LINK( SwInsFootNoteDlg, NextPrevHdl, weld::Button&, rBtn, void )
+{
+ Apply();
+
+ // go to the next foot/endnote here
+ m_rSh.ResetSelect(nullptr, false);
+ if (&rBtn == m_xNextBT.get())
+ m_rSh.GotoNextFootnoteAnchor();
+ else
+ m_rSh.GotoPrevFootnoteAnchor();
+
+ Init();
+}
+
+SwInsFootNoteDlg::SwInsFootNoteDlg(weld::Window *pParent, SwWrtShell &rShell, bool bEd)
+ : GenericDialogController(pParent, "modules/swriter/ui/insertfootnote.ui", "InsertFootnoteDialog")
+ , m_rSh(rShell)
+ , m_eCharSet(RTL_TEXTENCODING_DONTKNOW)
+ , m_bExtCharAvailable(false)
+ , m_bEdit(bEd)
+ , m_xNumberFrame(m_xBuilder->weld_widget("numberingframe"))
+ , m_xNumberAutoBtn(m_xBuilder->weld_radio_button("automatic"))
+ , m_xNumberCharBtn(m_xBuilder->weld_radio_button("character"))
+ , m_xNumberCharEdit(m_xBuilder->weld_entry("characterentry"))
+ , m_xNumberExtChar(m_xBuilder->weld_button("choosecharacter"))
+ , m_xFootnoteBtn(m_xBuilder->weld_radio_button("footnote"))
+ , m_xEndNoteBtn(m_xBuilder->weld_radio_button("endnote"))
+ , m_xOkBtn(m_xBuilder->weld_button("ok"))
+ , m_xPrevBT(m_xBuilder->weld_button("prev"))
+ , m_xNextBT(m_xBuilder->weld_button("next"))
+{
+ m_xNumberAutoBtn->connect_toggled(LINK(this,SwInsFootNoteDlg,NumberToggleHdl));
+ m_xNumberCharBtn->connect_toggled(LINK(this,SwInsFootNoteDlg,NumberToggleHdl));
+ m_xNumberExtChar->connect_clicked(LINK(this,SwInsFootNoteDlg,NumberExtCharHdl));
+ m_xNumberCharEdit->connect_changed(LINK(this,SwInsFootNoteDlg,NumberEditHdl));
+
+ m_xPrevBT->connect_clicked(LINK(this, SwInsFootNoteDlg, NextPrevHdl));
+ m_xNextBT->connect_clicked(LINK(this, SwInsFootNoteDlg, NextPrevHdl));
+
+ SwViewShell::SetCareDialog(m_xDialog);
+
+ if (m_bEdit)
+ {
+ Init();
+
+ m_xPrevBT->show();
+ m_xNextBT->show();
+ }
+}
+
+SwInsFootNoteDlg::~SwInsFootNoteDlg() COVERITY_NOEXCEPT_FALSE
+{
+ SwViewShell::SetCareDialog(nullptr);
+
+ if (m_bEdit)
+ m_rSh.ResetSelect(nullptr, false);
+}
+
+void SwInsFootNoteDlg::Init()
+{
+ SwFormatFootnote aFootnoteNote;
+ OUString sNumStr;
+ vcl::Font aFont;
+ m_bExtCharAvailable = false;
+
+ m_rSh.StartAction();
+
+ if (m_rSh.GetCurFootnote(&aFootnoteNote))
+ {
+ if (!aFootnoteNote.GetNumStr().isEmpty())
+ {
+ sNumStr = aFootnoteNote.GetNumStr();
+
+ m_rSh.Right(SwCursorSkipMode::Chars, true, 1, false );
+ SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet(m_rSh.GetAttrPool());
+ m_rSh.GetCurAttr(aSet);
+ const SvxFontItem &rFont = aSet.Get( RES_CHRATR_FONT );
+ aFont = m_xNumberCharEdit->get_font();
+ m_aFontName = rFont.GetFamilyName();
+ m_eCharSet = rFont.GetCharSet();
+ aFont.SetFamilyName(m_aFontName);
+ aFont.SetCharSet(m_eCharSet);
+ m_bExtCharAvailable = true;
+ m_rSh.Left( SwCursorSkipMode::Chars, false, 1, false );
+ }
+ bFootnote = !aFootnoteNote.IsEndNote();
+ }
+ m_xNumberCharEdit->set_font(aFont);
+
+ const bool bNumChar = !sNumStr.isEmpty();
+
+ m_xNumberCharEdit->set_text(sNumStr);
+ m_xNumberCharBtn->set_active(bNumChar);
+ m_xNumberAutoBtn->set_active(!bNumChar);
+ if (bNumChar)
+ m_xNumberCharEdit->grab_focus();
+
+ if (bFootnote)
+ m_xFootnoteBtn->set_active(true);
+ else
+ m_xEndNoteBtn->set_active(true);
+
+ bool bNext = m_rSh.GotoNextFootnoteAnchor();
+
+ if (bNext)
+ m_rSh.GotoPrevFootnoteAnchor();
+
+ bool bPrev = m_rSh.GotoPrevFootnoteAnchor();
+
+ if (bPrev)
+ m_rSh.GotoNextFootnoteAnchor();
+
+ m_xPrevBT->set_sensitive(bPrev);
+ m_xNextBT->set_sensitive(bNext);
+
+ m_rSh.Right(SwCursorSkipMode::Chars, true, 1, false );
+
+ m_rSh.EndAction();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/linenum.cxx b/sw/source/ui/misc/linenum.cxx
new file mode 100644
index 0000000000..8e9ad04111
--- /dev/null
+++ b/sw/source/ui/misc/linenum.cxx
@@ -0,0 +1,260 @@
+/* -*- 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/viewfrm.hxx>
+#include <svl/style.hxx>
+#include <svtools/unitconv.hxx>
+#include <sal/log.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <charfmt.hxx>
+
+#include <docstyle.hxx>
+
+#include <lineinfo.hxx>
+#include <linenum.hxx>
+#include <swmodule.hxx>
+#include <uitool.hxx>
+#include <usrpref.hxx>
+#include <wdocsh.hxx>
+#include <fmtline.hxx>
+#include <strings.hrc>
+
+#include <IDocumentStylePoolAccess.hxx>
+
+static rtl::Reference<SwDocStyleSheet> lcl_getDocStyleSheet(const OUString& rName, SwWrtShell *pSh)
+{
+ SfxStyleSheetBasePool* pBase = pSh->GetView().GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyle = pBase->Find(rName, SfxStyleFamily::Para);
+ SAL_WARN_IF( !pStyle, "sw.ui", "Style not found" );
+ if(!pStyle)
+ return nullptr;
+ return new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pStyle));
+}
+
+static void lcl_setLineNumbering(const OUString& rName, SwWrtShell* pSh, bool bLineNumber)
+{
+ rtl::Reference<SwDocStyleSheet> xStyleSheet = lcl_getDocStyleSheet(rName, pSh);
+ if(!xStyleSheet.is())
+ return;
+ SfxItemSet& rSet = xStyleSheet->GetItemSet();
+ SwFormatLineNumber aFormat;
+ aFormat.SetCountLines(bLineNumber);
+ rSet.Put(aFormat);
+ xStyleSheet->MergeIndentAttrsOfListStyle( rSet );
+ xStyleSheet->SetItemSet(rSet);
+}
+
+SwLineNumberingDlg::SwLineNumberingDlg(const SwView& rVw)
+ : SfxDialogController(rVw.GetViewFrame().GetFrameWeld(),
+ "modules/swriter/ui/linenumbering.ui", "LineNumberingDialog")
+ , m_pSh(rVw.GetWrtShellPtr())
+ , m_xBodyContent(m_xBuilder->weld_widget("content"))
+ , m_xDivIntervalFT(m_xBuilder->weld_widget("every"))
+ , m_xDivIntervalNF(m_xBuilder->weld_spin_button("linesspin"))
+ , m_xDivRowsFT(m_xBuilder->weld_widget("lines"))
+ , m_xNumIntervalNF(m_xBuilder->weld_spin_button("intervalspin"))
+ , m_xCharStyleLB(m_xBuilder->weld_combo_box("styledropdown"))
+ , m_xFormatLB(new SwNumberingTypeListBox(m_xBuilder->weld_combo_box("formatdropdown")))
+ , m_xPosLB(m_xBuilder->weld_combo_box("positiondropdown"))
+ , m_xOffsetMF(m_xBuilder->weld_metric_spin_button("spacingspin", FieldUnit::CM))
+ , m_xDivisorED(m_xBuilder->weld_entry("textentry"))
+ , m_xCountEmptyLinesCB(m_xBuilder->weld_check_button("blanklines"))
+ , m_xCountFrameLinesCB(m_xBuilder->weld_check_button("linesintextframes"))
+ , m_xRestartEachPageCB(m_xBuilder->weld_check_button("restarteverynewpage"))
+ , m_xNumberingOnCB(m_xBuilder->weld_check_button("shownumbering"))
+ , m_xNumberingOnFooterHeader(m_xBuilder->weld_check_button("showfooterheadernumbering"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xNumIntervalFT(m_xBuilder->weld_widget("interval"))
+ , m_xNumRowsFT(m_xBuilder->weld_widget("intervallines"))
+{
+ m_xFormatLB->Reload(SwInsertNumTypes::Extended);
+
+ OUString sIntervalName = m_xDivIntervalFT->get_accessible_name()
+ + "("
+ + m_xDivRowsFT->get_accessible_name()
+ + ")";
+ m_xDivIntervalNF->set_accessible_name(sIntervalName);
+
+ sIntervalName = m_xNumIntervalFT->get_accessible_name()
+ + "("
+ + m_xNumRowsFT->get_accessible_name()
+ + ")";
+ m_xNumIntervalNF->set_accessible_name(sIntervalName);
+
+ // char styles
+ ::FillCharStyleListBox(*m_xCharStyleLB, m_pSh->GetView().GetDocShell());
+
+ const SwLineNumberInfo &rInf = m_pSh->GetLineNumberInfo();
+ IDocumentStylePoolAccess& rIDSPA = m_pSh->getIDocumentStylePoolAccess();
+
+ OUString sStyleName(rInf.GetCharFormat( rIDSPA )->GetName());
+ const int nPos = m_xCharStyleLB->find_text(sStyleName);
+
+ if (nPos != -1)
+ m_xCharStyleLB->set_active(nPos);
+ else
+ {
+ if (!sStyleName.isEmpty())
+ {
+ m_xCharStyleLB->append_text(sStyleName);
+ m_xCharStyleLB->set_active_text(sStyleName);
+ }
+ }
+
+ // format
+ SvxNumType nSelFormat = rInf.GetNumType().GetNumberingType();
+
+ m_xFormatLB->SelectNumberingType(nSelFormat);
+
+ // position
+ m_xPosLB->set_active(rInf.GetPos());
+
+ // offset
+ sal_uInt16 nOffset = rInf.GetPosFromLeft();
+ if (nOffset == USHRT_MAX)
+ nOffset = 0;
+
+ FieldUnit eFieldUnit = SW_MOD()->GetUsrPref(dynamic_cast< const SwWebDocShell*>(
+ rVw.GetDocShell()) != nullptr)->GetMetric();
+ ::SetFieldUnit(*m_xOffsetMF, eFieldUnit);
+ m_xOffsetMF->set_value(m_xOffsetMF->normalize(nOffset), FieldUnit::TWIP);
+
+ // numbering offset
+ m_xNumIntervalNF->set_value(rInf.GetCountBy());
+
+ // divider
+ m_xDivisorED->set_text(rInf.GetDivider());
+
+ // divider offset
+ m_xDivIntervalNF->set_value(rInf.GetDividerCountBy());
+
+ // count
+ m_xCountEmptyLinesCB->set_active(rInf.IsCountBlankLines());
+ m_xCountFrameLinesCB->set_active(rInf.IsCountInFlys());
+ m_xRestartEachPageCB->set_active(rInf.IsRestartEachPage());
+
+ m_xNumberingOnCB->set_active(rInf.IsPaintLineNumbers());
+
+ // Header/Footer Line Numbering
+ rtl::Reference< SwDocStyleSheet > xStyleSheet = lcl_getDocStyleSheet(SwResId(STR_POOLCOLL_FOOTER), m_pSh);
+ if(xStyleSheet.is())
+ {
+ SfxItemSet& rSet = xStyleSheet->GetItemSet();
+ const SwFormatLineNumber &aFormat = rSet.Get(RES_LINENUMBER);
+ if (aFormat.IsCount())
+ m_xNumberingOnFooterHeader->set_state(TRISTATE_TRUE);
+ else
+ m_xNumberingOnFooterHeader->set_state(TRISTATE_FALSE);
+ }
+
+ // Line Numbering
+ m_xNumberingOnCB->connect_toggled(LINK(this, SwLineNumberingDlg, LineOnOffHdl));
+ m_xDivisorED->connect_changed(LINK(this, SwLineNumberingDlg, ModifyHdl));
+ ModifyHdl(*m_xDivisorED);
+ LineOnOffHdl(*m_xNumberingOnCB);
+
+ m_xOKButton->connect_clicked(LINK(this, SwLineNumberingDlg, OKHdl));
+}
+
+SwLineNumberingDlg::~SwLineNumberingDlg()
+{
+}
+
+IMPL_LINK_NOARG(SwLineNumberingDlg, OKHdl, weld::Button&, void)
+{
+ SwLineNumberInfo aInf(m_pSh->GetLineNumberInfo());
+
+ // char styles
+ OUString sCharFormatName(m_xCharStyleLB->get_active_text());
+ SwCharFormat *pCharFormat = m_pSh->FindCharFormatByName(sCharFormatName);
+
+ if (!pCharFormat)
+ {
+ SfxStyleSheetBasePool* pPool = m_pSh->GetView().GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase* pBase;
+ pBase = pPool->Find(sCharFormatName, SfxStyleFamily::Char);
+ if(!pBase)
+ pBase = &pPool->Make(sCharFormatName, SfxStyleFamily::Char);
+ pCharFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
+ }
+
+ if (pCharFormat)
+ aInf.SetCharFormat(pCharFormat);
+
+ // format
+ SvxNumberType aType;
+ aType.SetNumberingType(m_xFormatLB->GetSelectedNumberingType());
+ aInf.SetNumType(aType);
+
+ // position
+ aInf.SetPos(static_cast<LineNumberPosition>(m_xPosLB->get_active()));
+
+ // offset
+ aInf.SetPosFromLeft(o3tl::narrowing<sal_uInt16>(m_xOffsetMF->denormalize(m_xOffsetMF->get_value(FieldUnit::TWIP))));
+
+ // numbering offset
+ aInf.SetCountBy(o3tl::narrowing<sal_uInt16>(m_xNumIntervalNF->get_value()));
+
+ // divider
+ aInf.SetDivider(m_xDivisorED->get_text());
+
+ // divider offset
+ aInf.SetDividerCountBy(o3tl::narrowing<sal_uInt16>(m_xDivIntervalNF->get_value()));
+
+ // count
+ aInf.SetCountBlankLines(m_xCountEmptyLinesCB->get_active());
+ aInf.SetCountInFlys(m_xCountFrameLinesCB->get_active());
+ aInf.SetRestartEachPage(m_xRestartEachPageCB->get_active());
+
+ aInf.SetPaintLineNumbers(m_xNumberingOnCB->get_active());
+
+ m_pSh->SetLineNumberInfo(aInf);
+
+ // Set LineNumber explicitly for Header and Footer
+ lcl_setLineNumbering(SwResId(STR_POOLCOLL_FOOTER), m_pSh, m_xNumberingOnFooterHeader->get_active());
+ lcl_setLineNumbering(SwResId(STR_POOLCOLL_HEADER), m_pSh, m_xNumberingOnFooterHeader->get_active());
+ if( m_xNumberingOnFooterHeader->get_active())
+ m_xNumberingOnFooterHeader->set_state(TRISTATE_TRUE);
+ else
+ m_xNumberingOnFooterHeader->set_state(TRISTATE_FALSE);
+
+ m_xDialog->response(RET_OK);
+}
+
+// modify
+IMPL_LINK_NOARG(SwLineNumberingDlg, ModifyHdl, weld::Entry&, void)
+{
+ bool bEnable = m_xNumberingOnCB->get_active() && !m_xDivisorED->get_text().isEmpty();
+
+ m_xDivIntervalFT->set_sensitive(bEnable);
+ m_xDivIntervalNF->set_sensitive(bEnable);
+ m_xDivRowsFT->set_sensitive(bEnable);
+}
+
+// On/Off
+IMPL_LINK_NOARG(SwLineNumberingDlg, LineOnOffHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xNumberingOnCB->get_active();
+ m_xBodyContent->set_sensitive(bEnable);
+ ModifyHdl(*m_xDivisorED);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/num.cxx b/sw/source/ui/misc/num.cxx
new file mode 100644
index 0000000000..fadef24662
--- /dev/null
+++ b/sw/source/ui/misc/num.cxx
@@ -0,0 +1,949 @@
+/* -*- 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/numitem.hxx>
+#include <cmdid.h>
+#include <wrtsh.hxx>
+#include <docsh.hxx>
+#include <wview.hxx>
+#include <uitool.hxx>
+#include <wdocsh.hxx>
+#include <uiitems.hxx>
+#include <poolfmt.hxx>
+#include <shellres.hxx>
+#include <outline.hxx>
+#include <num.hxx>
+
+#include <SwStyleNameMapper.hxx>
+#include <svx/dialogs.hrc>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/intitem.hxx>
+#include <comphelper/lok.hxx>
+#include <osl/diagnose.h>
+
+static bool bLastRelative = false;
+
+//See cui/uiconfig/ui/numberingpositionpage.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
+SwNumPositionTabPage::SwNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/outlinepositionpage.ui", "OutlinePositionPage", &rSet)
+ , m_pSaveNum(nullptr)
+ , m_pWrtSh(nullptr)
+ , m_pOutlineDlg(nullptr)
+ , m_nActNumLvl(0)
+ , m_bModified(false)
+ , m_bPreset(false)
+ , m_bInInintControl(false)
+ , m_bLabelAlignmentPosAndSpaceModeActive(false)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xPositionFrame(m_xBuilder->weld_widget("numberingframe"))
+ , 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();
+
+ 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_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+
+ m_xRelativeCB->set_active(true);
+ m_xAlignLB->connect_changed(LINK(this, SwNumPositionTabPage, EditModifyHdl));
+ m_xAlign2LB->connect_changed(LINK(this, SwNumPositionTabPage, EditModifyHdl));
+ for (int i = 0; i < m_xAlignLB->get_count(); ++i)
+ {
+ m_xAlign2LB->append_text(m_xAlignLB->get_text(i));
+ }
+ m_xAlign2FT->set_label(m_xAlignFT->get_label());
+
+ Link<weld::MetricSpinButton&, void> aLk = LINK(this, SwNumPositionTabPage, DistanceHdl);
+ m_xDistBorderMF->connect_value_changed(aLk);
+ m_xDistNumMF->connect_value_changed(aLk);
+ m_xIndentMF->connect_value_changed(aLk);
+
+ m_xLabelFollowedByLB->connect_changed( LINK(this, SwNumPositionTabPage, LabelFollowedByHdl_Impl) );
+
+ aLk = LINK(this, SwNumPositionTabPage, ListtabPosHdl_Impl);
+ m_xListtabMF->connect_value_changed(aLk);
+
+ aLk = LINK(this, SwNumPositionTabPage, AlignAtHdl_Impl);
+ m_xAlignedAtMF->connect_value_changed(aLk);
+
+ aLk = LINK(this, SwNumPositionTabPage, IndentAtHdl_Impl);
+ m_xIndentAtMF->connect_value_changed(aLk);
+
+ m_xLevelLB->connect_changed(LINK(this, SwNumPositionTabPage, LevelHdl));
+ m_xRelativeCB->connect_toggled(LINK(this, SwNumPositionTabPage, RelativeHdl));
+ m_xStandardPB->connect_clicked(LINK(this, SwNumPositionTabPage, StandardHdl));
+
+ // insert levels
+ for(sal_uInt16 i = 1; i <= MAXLEVEL; i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ OUString sEntry = "1 - " + OUString::number(MAXLEVEL);
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+
+ m_xRelativeCB->set_active(bLastRelative);
+ m_aPreviewWIN.SetPositionMode();
+}
+
+SwNumPositionTabPage::~SwNumPositionTabPage()
+{
+ m_pActNum.reset();
+ m_pOutlineDlg = nullptr;
+}
+
+void SwNumPositionTabPage::InitControls()
+{
+ m_bInInintControl = true;
+ const bool bRelative = !m_bLabelAlignmentPosAndSpaceModeActive &&
+ m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active();
+ const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 &&
+ USHRT_MAX != m_nActNumLvl;
+
+ m_xDistBorderMF->set_sensitive( !m_bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative || m_pOutlineDlg != nullptr ) );
+ m_xDistBorderFT->set_sensitive( !m_bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative || m_pOutlineDlg != nullptr ) );
+
+ bool bSetDistEmpty = false;
+ bool bSameDistBorderNum = !m_bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameDist = !m_bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndent = !m_bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAdjust = true;
+
+ bool bSameLabelFollowedBy = m_bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameListtab = m_bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAlignAt = m_bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndentAt = m_bLabelAlignmentPosAndSpaceModeActive;
+
+ const SwNumFormat* aNumFormatArr[MAXLEVEL];
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = USHRT_MAX;
+ tools::Long nFirstBorderTextRelative = -1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ aNumFormatArr[i] = &m_pActNum->Get(i);
+ if(m_nActNumLvl & nMask)
+ {
+ if(USHRT_MAX == nLvl)
+ {
+ nLvl = i;
+ }
+
+ if( i > nLvl)
+ {
+ bSameAdjust &= aNumFormatArr[i]->GetNumAdjust() == aNumFormatArr[nLvl]->GetNumAdjust();
+ if ( !m_bLabelAlignmentPosAndSpaceModeActive )
+ {
+ if(bRelative)
+ {
+ const tools::Long nBorderTextRelative =
+ aNumFormatArr[i]->GetAbsLSpace() + aNumFormatArr[i]->GetFirstLineOffset() -
+ aNumFormatArr[i - 1]->GetAbsLSpace() + aNumFormatArr[i - 1]->GetFirstLineOffset();
+ if (nFirstBorderTextRelative == -1)
+ nFirstBorderTextRelative = nBorderTextRelative;
+ else
+ bSameDistBorderNum &= nFirstBorderTextRelative == nBorderTextRelative;
+ }
+ else
+ {
+ bSameDistBorderNum &=
+ aNumFormatArr[i]->GetAbsLSpace() - aNumFormatArr[i]->GetFirstLineOffset() ==
+ aNumFormatArr[i - 1]->GetAbsLSpace() - aNumFormatArr[i - 1]->GetFirstLineOffset();
+ }
+
+ bSameDist &= aNumFormatArr[i]->GetCharTextDistance() == aNumFormatArr[nLvl]->GetCharTextDistance();
+ bSameIndent &= aNumFormatArr[i]->GetFirstLineOffset() == aNumFormatArr[nLvl]->GetFirstLineOffset();
+ }
+ else
+ {
+ bSameLabelFollowedBy &=
+ aNumFormatArr[i]->GetLabelFollowedBy() == aNumFormatArr[nLvl]->GetLabelFollowedBy();
+ bSameListtab &=
+ aNumFormatArr[i]->GetListtabPos() == aNumFormatArr[nLvl]->GetListtabPos();
+ bSameAlignAt &=
+ ( ( aNumFormatArr[i]->GetIndentAt() + aNumFormatArr[i]->GetFirstLineIndent() )
+ == ( aNumFormatArr[nLvl]->GetIndentAt() + aNumFormatArr[nLvl]->GetFirstLineIndent() ) );
+ bSameIndentAt &=
+ aNumFormatArr[i]->GetIndentAt() == aNumFormatArr[nLvl]->GetIndentAt();
+ }
+ }
+ }
+ nMask <<= 1;
+
+ }
+ if (MAXLEVEL <= nLvl)
+ {
+ OSL_ENSURE(false, "cannot happen.");
+ return;
+ }
+ if(bSameDistBorderNum)
+ {
+ tools::Long nDistBorderNum;
+ if(bRelative)
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFormatArr[nLvl]->GetAbsLSpace())+ aNumFormatArr[nLvl]->GetFirstLineOffset();
+ if(nLvl)
+ nDistBorderNum -= static_cast<tools::Long>(aNumFormatArr[nLvl - 1]->GetAbsLSpace())+ aNumFormatArr[nLvl - 1]->GetFirstLineOffset();
+ }
+ else
+ {
+ nDistBorderNum = static_cast<tools::Long>(aNumFormatArr[nLvl]->GetAbsLSpace())+ aNumFormatArr[nLvl]->GetFirstLineOffset();
+ }
+ m_xDistBorderMF->set_value(m_xDistBorderMF->normalize(nDistBorderNum),FieldUnit::TWIP);
+ }
+ else
+ bSetDistEmpty = true;
+
+ if(bSameDist)
+ m_xDistNumMF->set_value(m_xDistNumMF->normalize(aNumFormatArr[nLvl]->GetCharTextDistance()), FieldUnit::TWIP);
+ else
+ m_xDistNumMF->set_text(OUString());
+ if(bSameIndent)
+ m_xIndentMF->set_value(m_xIndentMF->normalize(-aNumFormatArr[nLvl]->GetFirstLineOffset()), FieldUnit::TWIP);
+ else
+ m_xIndentMF->set_text(OUString());
+
+ if(bSameAdjust)
+ {
+ sal_Int32 nPos = 1; // centered
+ if(aNumFormatArr[nLvl]->GetNumAdjust() == SvxAdjust::Left)
+ nPos = 0;
+ else if(aNumFormatArr[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 ( aNumFormatArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ nPos = 1;
+ }
+ else if ( aNumFormatArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
+ {
+ nPos = 2;
+ }
+ else if ( aNumFormatArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
+ {
+ nPos = 3;
+ }
+ m_xLabelFollowedByLB->set_active(nPos);
+ }
+ else
+ {
+ m_xLabelFollowedByLB->set_active(-1);
+ }
+
+ if ( aNumFormatArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
+ {
+ m_xListtabFT->set_sensitive(true);
+ m_xListtabMF->set_sensitive(true);
+ if ( bSameListtab )
+ {
+ m_xListtabMF->set_value(m_xListtabMF->normalize(aNumFormatArr[nLvl]->GetListtabPos()),FieldUnit::TWIP);
+ }
+ else
+ {
+ m_xListtabMF->set_text(OUString());
+ }
+ }
+ else
+ {
+ m_xListtabFT->set_sensitive( false );
+ m_xListtabMF->set_sensitive( false );
+ m_xListtabMF->set_text(OUString());
+ }
+
+ if ( bSameAlignAt )
+ {
+ m_xAlignedAtMF->set_value(
+ m_xAlignedAtMF->normalize( aNumFormatArr[nLvl]->GetIndentAt() +
+ aNumFormatArr[nLvl]->GetFirstLineIndent()),
+ FieldUnit::TWIP );
+ }
+ else
+ {
+ m_xAlignedAtMF->set_text(OUString());
+ }
+
+ if ( bSameIndentAt )
+ {
+ m_xIndentAtMF->set_value(
+ m_xIndentAtMF->normalize( aNumFormatArr[nLvl]->GetIndentAt()), FieldUnit::TWIP );
+ }
+ else
+ {
+ m_xIndentAtMF->set_text(OUString());
+ }
+
+ if (bSetDistEmpty)
+ m_xDistBorderMF->set_text(OUString());
+
+ m_bInInintControl = false;
+}
+
+void SwNumPositionTabPage::ActivatePage(const SfxItemSet& )
+{
+ const SfxPoolItem* pItem;
+ sal_uInt16 nTmpNumLvl =
+ m_pOutlineDlg ? SwOutlineTabDialog::GetActNumLevel() : 0;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet && pExampleSet->GetItemState(FN_PARAM_NUM_PRESET, false, &pItem) != SfxItemState::UNKNOWN)
+ {
+ m_bPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ }
+ m_bModified = (!m_pActNum->GetNumFormat( 0 ) || m_bPreset);
+ if(*m_pActNum != *m_pSaveNum ||
+ m_nActNumLvl != nTmpNumLvl )
+ {
+ *m_pActNum = *m_pSaveNum;
+ m_nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (m_nActNumLvl == USHRT_MAX)
+ m_xLevelLB->select(MAXLEVEL);
+ else
+ {
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ if (m_nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ }
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ }
+ m_xRelativeCB->set_sensitive(1 != m_nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+DeactivateRC SwNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ SwOutlineTabDialog::SetActNumLevel(m_nActNumLvl);
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+
+}
+
+bool SwNumPositionTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if(m_pOutlineDlg)
+ *m_pOutlineDlg->GetNumRule() = *m_pActNum;
+ else if(m_bModified && m_pActNum)
+ {
+ *m_pSaveNum = *m_pActNum;
+ rSet->Put(SwUINumRuleItem( *m_pSaveNum ));
+ rSet->Put(SfxBoolItem(FN_PARAM_NUM_PRESET, false));
+ }
+ return m_bModified;
+}
+
+void SwNumPositionTabPage::Reset( const SfxItemSet* rSet )
+{
+ if (m_pOutlineDlg)
+ {
+ m_pSaveNum = m_pOutlineDlg->GetNumRule();
+ m_xLevelLB->set_selection_mode(SelectionMode::Single);
+ }
+ else if(const SwUINumRuleItem* pNumberItem = rSet->GetItemIfSet(FN_PARAM_ACT_NUMBER, false))
+ m_pSaveNum = const_cast<SwUINumRuleItem*>(pNumberItem)->GetNumRule();
+
+ m_nActNumLvl = SwOutlineTabDialog::GetActNumLevel();
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if(m_nActNumLvl == USHRT_MAX)
+ {
+ m_xLevelLB->select(MAXLEVEL);
+ }
+ else
+ {
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ if (m_nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1;
+ }
+ }
+
+ if(!m_pActNum)
+ m_pActNum.reset(new SwNumRule(*m_pSaveNum));
+ else if(*m_pSaveNum != *m_pActNum)
+ *m_pActNum = *m_pSaveNum;
+ m_aPreviewWIN.SetNumRule(m_pActNum.get());
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+ InitControls();
+ m_bModified = false;
+}
+
+void SwNumPositionTabPage::InitPosAndSpaceMode()
+{
+ if ( m_pActNum == nullptr )
+ {
+ OSL_FAIL( "<SwNumPositionTabPage::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 < MAXLEVEL; ++i )
+ {
+ if(m_nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFormat( m_pActNum->Get(i) );
+ ePosAndSpaceMode = aNumFormat.GetPositionAndSpaceMode();
+ if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ break;
+ }
+ }
+ nMask <<= 1;
+ }
+
+ m_bLabelAlignmentPosAndSpaceModeActive =
+ ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
+}
+
+void SwNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode()
+{
+ m_xDistBorderFT->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistBorderMF->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xRelativeCB->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentFT->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentMF->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistNumFT->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistNumMF->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignFT->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignLB->set_visible( !m_bLabelAlignmentPosAndSpaceModeActive );
+
+ m_xLabelFollowedByFT->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xLabelFollowedByLB->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabFT->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabMF->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2FT->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2LB->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtFT->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtMF->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtFT->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtMF->set_visible( m_bLabelAlignmentPosAndSpaceModeActive );
+}
+
+std::unique_ptr<SfxTabPage> SwNumPositionTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwNumPositionTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SwNumPositionTabPage::SetWrtShell(SwWrtShell* pSh)
+{
+ m_pWrtSh = pSh;
+
+ const SwTwips nWidth = m_pWrtSh->GetAnyCurRect(CurRectType::Frame).Width();
+
+ m_xDistBorderMF->set_max(m_xDistBorderMF->normalize( nWidth ), FieldUnit::TWIP );
+ m_xDistNumMF->set_max(m_xDistNumMF->normalize( nWidth ), FieldUnit::TWIP);
+ m_xIndentMF->set_max(m_xIndentMF->normalize( nWidth ), FieldUnit::TWIP );
+
+ const SwRect& rPrtRect = m_pWrtSh->GetAnyCurRect(CurRectType::Page);
+ m_aPreviewWIN.SetPageWidth(rPrtRect.Width());
+ FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &m_pWrtSh->GetView()) != nullptr );
+ 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(SwNumPositionTabPage, EditModifyHdl, weld::ComboBox&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActNumLvl & nMask)
+ {
+ SwNumFormat aNumFormat(m_pActNum->Get(i));
+
+ const int 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;
+ aNumFormat.SetNumAdjust( eAdjust );
+ m_pActNum->Set(i, aNumFormat);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK( SwNumPositionTabPage, LevelHdl, weld::TreeView&, rBox, void )
+{
+ sal_uInt16 nSaveNumLvl = m_nActNumLvl;
+ m_nActNumLvl = 0;
+ auto aRows = rBox.get_selected_rows();
+ if ((std::find(aRows.begin(), aRows.end(), MAXLEVEL) != aRows.end()) &&
+ (aRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ m_nActNumLvl = 0xFFFF;
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ rBox.unselect(i);
+ }
+ else if (!aRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ if (std::find(aRows.begin(), aRows.end(), i) != aRows.end())
+ m_nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ rBox.unselect(MAXLEVEL);
+ }
+ else
+ {
+ m_nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ if(m_nActNumLvl & nMask)
+ {
+ rBox.select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ m_xRelativeCB->set_sensitive(1 != m_nActNumLvl);
+ SetModified();
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+ InitControls();
+}
+
+IMPL_LINK(SwNumPositionTabPage, DistanceHdl, weld::MetricSpinButton&, rField, void)
+{
+ if(m_bInInintControl)
+ return;
+ tools::Long nValue = static_cast< tools::Long >(rField.denormalize(rField.get_value(FieldUnit::TWIP)));
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActNumLvl & nMask)
+ {
+ SwNumFormat aNumFormat( m_pActNum->Get( i ) );
+ if (&rField == m_xDistBorderMF.get())
+ {
+
+ if (m_xRelativeCB->get_active() && m_xRelativeCB->get_sensitive())
+ {
+ if(0 == i)
+ {
+ auto const nTmp = aNumFormat.GetFirstLineOffset();
+ aNumFormat.SetAbsLSpace( nValue - nTmp );
+ }
+ else
+ {
+ tools::Long nTmp = m_pActNum->Get( i - 1 ).GetAbsLSpace() +
+ m_pActNum->Get( i - 1 ).GetFirstLineOffset() -
+ m_pActNum->Get( i ).GetFirstLineOffset();
+
+ aNumFormat.SetAbsLSpace( nValue + nTmp );
+ }
+ }
+ else
+ {
+ aNumFormat.SetAbsLSpace( nValue - aNumFormat.GetFirstLineOffset());
+ }
+ }
+ else if (&rField == m_xDistNumMF.get())
+ {
+ aNumFormat.SetCharTextDistance( nValue );
+ }
+ else if (&rField == m_xIndentMF.get())
+ {
+ // now AbsLSpace also has to be modified by FirstLineOffset
+ tools::Long nDiff = nValue + aNumFormat.GetFirstLineOffset();
+ auto const nAbsLSpace = aNumFormat.GetAbsLSpace();
+ aNumFormat.SetAbsLSpace( nAbsLSpace + nDiff );
+ aNumFormat.SetFirstLineOffset( -nValue );
+ }
+
+ m_pActNum->Set( i, aNumFormat );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+ if(!m_xDistBorderMF->get_sensitive())
+ m_xDistBorderMF->set_text(OUString());
+}
+
+IMPL_LINK( SwNumPositionTabPage, RelativeHdl, weld::Toggleable&, rBox, void )
+{
+ bool bOn = rBox.get_active();
+ bool bSingleSelection = m_xLevelLB->n_children() == 1 && USHRT_MAX != m_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 < MAXLEVEL; i++)
+ {
+ if(m_nActNumLvl & nMask)
+ {
+ const SwNumFormat &rNumFormat = m_pActNum->Get(i);
+ if(bFirst)
+ {
+ nValue = rNumFormat.GetAbsLSpace();
+ if(bOn && i)
+ nValue -= m_pActNum->Get(i - 1).GetAbsLSpace();
+ }
+ else
+ bSetValue = nValue == rNumFormat.GetAbsLSpace() - m_pActNum->Get(i - 1).GetAbsLSpace();
+ bFirst = false;
+ }
+ nMask <<= 1;
+ }
+
+ }
+ if(bSetValue)
+ m_xDistBorderMF->set_value(m_xDistBorderMF->normalize(nValue), FieldUnit::TWIP);
+ else
+ m_xDistBorderMF->set_text(OUString());
+ m_xDistBorderMF->set_sensitive(bOn || bSingleSelection || m_pOutlineDlg);
+ bLastRelative = bOn;
+}
+
+IMPL_LINK_NOARG(SwNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void)
+{
+ // determine value to be set at the chosen list levels
+ SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB;
+ {
+ const int 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 = USHRT_MAX;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
+ {
+ if ( m_nActNumLvl & nMask )
+ {
+ SwNumFormat aNumFormat( m_pActNum->Get(i) );
+ aNumFormat.SetLabelFollowedBy( eLabelFollowedBy );
+ m_pActNum->Set( i, aNumFormat );
+
+ if ( nFirstLvl == USHRT_MAX )
+ {
+ nFirstLvl = i;
+ }
+ else
+ {
+ bSameListtabPos &= aNumFormat.GetListtabPos() ==
+ m_pActNum->Get( 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 )
+ {
+ m_xListtabMF->set_value(
+ m_xListtabMF->normalize( m_pActNum->Get( nFirstLvl ).GetListtabPos() ),
+ FieldUnit::TWIP );
+ }
+ else
+ {
+ m_xListtabMF->set_text(OUString());
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SwNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rField, void )
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = static_cast< tools::Long >(rField.denormalize(rField.get_value(FieldUnit::TWIP)));
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
+ {
+ if ( m_nActNumLvl & nMask )
+ {
+ SwNumFormat aNumFormat( m_pActNum->Get(i) );
+ aNumFormat.SetListtabPos( nValue );
+ m_pActNum->Set( i, aNumFormat );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SwNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rField, void )
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = static_cast< tools::Long >(rField.denormalize(rField.get_value(FieldUnit::TWIP)));
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
+ {
+ if ( m_nActNumLvl & nMask )
+ {
+ SwNumFormat aNumFormat( m_pActNum->Get(i) );
+ const tools::Long nFirstLineIndent = nValue - aNumFormat.GetIndentAt();
+ aNumFormat.SetFirstLineIndent( nFirstLineIndent );
+ m_pActNum->Set( i, aNumFormat );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SwNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rField, void )
+{
+ // determine value to be set at the chosen list levels
+ const tools::Long nValue = static_cast< tools::Long >(rField.denormalize(rField.get_value(FieldUnit::TWIP)));
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
+ {
+ if ( m_nActNumLvl & nMask )
+ {
+ SwNumFormat aNumFormat( m_pActNum->Get(i) );
+ const tools::Long nAlignedAt = aNumFormat.GetIndentAt() +
+ aNumFormat.GetFirstLineIndent();
+ aNumFormat.SetIndentAt( nValue );
+ const tools::Long nNewFirstLineIndent = nAlignedAt - nValue;
+ aNumFormat.SetFirstLineIndent( nNewFirstLineIndent );
+ m_pActNum->Set( i, aNumFormat );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SwNumPositionTabPage, StandardHdl, weld::Button&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActNumLvl & nMask)
+ {
+ SwNumFormat aNumFormat( m_pActNum->Get( i ) );
+ SwNumRule aTmpNumRule( m_pWrtSh->GetUniqueNumRuleName(),
+ aNumFormat.GetPositionAndSpaceMode(),
+ m_pOutlineDlg ? OUTLINE_RULE : NUM_RULE );
+ const SwNumFormat& aTempFormat(aTmpNumRule.Get( i ));
+ aNumFormat.SetPositionAndSpaceMode( aTempFormat.GetPositionAndSpaceMode() );
+ if ( aTempFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ aNumFormat.SetAbsLSpace( aTempFormat.GetAbsLSpace());
+ aNumFormat.SetCharTextDistance( aTempFormat.GetCharTextDistance() );
+ aNumFormat.SetFirstLineOffset( aTempFormat.GetFirstLineOffset() );
+ }
+ else if ( aTempFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ aNumFormat.SetNumAdjust( aTempFormat.GetNumAdjust() );
+ aNumFormat.SetLabelFollowedBy( aTempFormat.GetLabelFollowedBy() );
+ aNumFormat.SetListtabPos( aTempFormat.GetListtabPos() );
+ aNumFormat.SetFirstLineIndent( aTempFormat.GetFirstLineIndent() );
+ aNumFormat.SetIndentAt( aTempFormat.GetIndentAt() );
+ }
+ m_pActNum->Set( i, aNumFormat );
+ }
+ nMask <<= 1;
+ }
+
+ InitControls();
+ SetModified();
+}
+
+#ifdef DBG_UTIL
+void SwNumPositionTabPage::SetModified()
+{
+ m_bModified = true;
+ m_aPreviewWIN.SetLevel(m_nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+#endif
+
+SwSvxNumBulletTabDialog::SwSvxNumBulletTabDialog(weld::Window* pParent,
+ const SfxItemSet& rSwItemSet, SwWrtShell & rSh)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/bulletsandnumbering.ui", "BulletsAndNumberingDialog",
+ &rSwItemSet)
+ , m_rWrtSh(rSh)
+ , m_xDummyCombo(m_xBuilder->weld_combo_box("dummycombo"))
+{
+ weld::Button* pButton = GetUserButton();
+ pButton->connect_clicked(LINK(this, SwSvxNumBulletTabDialog, RemoveNumberingHdl));
+ pButton->set_sensitive(m_rWrtSh.GetNumRuleAtCurrCursorPos() != nullptr);
+ AddTabPage("singlenum", RID_SVXPAGE_PICK_SINGLE_NUM );
+ AddTabPage("bullets", RID_SVXPAGE_PICK_BULLET );
+ AddTabPage("outlinenum", RID_SVXPAGE_PICK_NUM );
+ AddTabPage("graphics", RID_SVXPAGE_PICK_BMP );
+ AddTabPage("customize", RID_SVXPAGE_NUM_OPTIONS );
+ AddTabPage("position", RID_SVXPAGE_NUM_POSITION );
+}
+
+SwSvxNumBulletTabDialog::~SwSvxNumBulletTabDialog()
+{
+}
+
+void SwSvxNumBulletTabDialog::PageCreated(const OUString& rPageId, SfxTabPage& rPage)
+{
+ // set styles' names and metric
+ OUString sNumCharFormat, sBulletCharFormat;
+ SwStyleNameMapper::FillUIName( RES_POOLCHR_NUM_LEVEL, sNumCharFormat );
+ SwStyleNameMapper::FillUIName( RES_POOLCHR_BULLET_LEVEL, sBulletCharFormat );
+
+ if (rPageId == "singlenum")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put (SfxStringItem(SID_NUM_CHAR_FMT,sNumCharFormat));
+ aSet.Put (SfxStringItem(SID_BULLET_CHAR_FMT,sBulletCharFormat));
+ rPage.PageCreated(aSet);
+ }
+ else if (rPageId == "bullets")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put (SfxStringItem(SID_BULLET_CHAR_FMT,sBulletCharFormat));
+ rPage.PageCreated(aSet);
+ }
+ else if (rPageId == "customize")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put (SfxStringItem(SID_NUM_CHAR_FMT,sNumCharFormat));
+ aSet.Put (SfxStringItem(SID_BULLET_CHAR_FMT,sBulletCharFormat));
+ // collect char styles
+ m_xDummyCombo->clear();
+ m_xDummyCombo->append_text(SwViewShell::GetShellRes()->aStrNone);
+ SwDocShell* pDocShell = m_rWrtSh.GetView().GetDocShell();
+ ::FillCharStyleListBox(*m_xDummyCombo, pDocShell);
+
+ std::vector<OUString> aList;
+ aList.reserve(m_xDummyCombo->get_count());
+ for (sal_Int32 j = 0; j < m_xDummyCombo->get_count(); j++)
+ aList.push_back(m_xDummyCombo->get_text(j));
+
+ aSet.Put( SfxStringListItem( SID_CHAR_FMT_LIST_BOX,&aList ) ) ;
+
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast< const SwWebDocShell *>( pDocShell ) != nullptr);
+ aSet.Put ( SfxUInt16Item(SID_METRIC_ITEM, static_cast< sal_uInt16 >(eMetric) ) );
+ rPage.PageCreated(aSet);
+ }
+ else if (rPageId == "position")
+ {
+ SwDocShell* pDocShell = m_rWrtSh.GetView().GetDocShell();
+ FieldUnit eMetric = ::GetDfltMetric(dynamic_cast< const SwWebDocShell *>( pDocShell ) != nullptr);
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put ( SfxUInt16Item(SID_METRIC_ITEM, static_cast< sal_uInt16 >(eMetric)) );
+ rPage.PageCreated(aSet);
+ }
+}
+
+short SwSvxNumBulletTabDialog::Ok()
+{
+ short nRet = SfxTabDialogController::Ok();
+ m_xExampleSet->ClearItem(SID_PARAM_NUM_PRESET);
+ return nRet;
+}
+
+IMPL_LINK_NOARG(SwSvxNumBulletTabDialog, RemoveNumberingHdl, weld::Button&, void)
+{
+ m_xDialog->response(RET_USER);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/outline.cxx b/sw/source/ui/misc/outline.cxx
new file mode 100644
index 0000000000..6500bfdd6e
--- /dev/null
+++ b/sw/source/ui/misc/outline.cxx
@@ -0,0 +1,1073 @@
+/* -*- 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 <hintids.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/virdev.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <editeng/brushitem.hxx>
+#include <unotools/configmgr.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <num.hxx>
+#include <view.hxx>
+#include <docsh.hxx>
+#include <uitool.hxx>
+#include <wrtsh.hxx>
+#include <swmodule.hxx>
+#include <fmtcol.hxx>
+#include <outline.hxx>
+#include <uinums.hxx>
+#include <poolfmt.hxx>
+#include <shellres.hxx>
+#include <svl/style.hxx>
+#include <charfmt.hxx>
+#include <docstyle.hxx>
+#include <viewopt.hxx>
+#include <outline.hrc>
+#include <strings.hrc>
+#include <paratr.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <IDocumentOutlineNodes.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class SwNumNamesDlg : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Entry> m_xFormEdit;
+ std::unique_ptr<weld::TreeView> m_xFormBox;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( SelectHdl, weld::TreeView&, void );
+ DECL_LINK( DoubleClickHdl, weld::TreeView&, bool );
+
+public:
+ explicit SwNumNamesDlg(weld::Window *pParent);
+ void SetUserNames(const OUString *pList[]);
+ OUString GetName() const { return m_xFormEdit->get_text(); }
+ int GetCurEntryPos() const { return m_xFormBox->get_selected_index(); }
+};
+
+}
+
+// remember selected entry
+IMPL_LINK( SwNumNamesDlg, SelectHdl, weld::TreeView&, rBox, void )
+{
+ m_xFormEdit->set_text(rBox.get_selected_text());
+ m_xFormEdit->select_region(0, -1);
+}
+
+/** set user defined names
+ *
+ * @param pList list of user defined names; unknown positions for the user are 0.
+ */
+void SwNumNamesDlg::SetUserNames(const OUString *pList[])
+{
+ sal_uInt16 nSelect = 0;
+ for (sal_uInt16 i = 0; i < SwChapterNumRules::nMaxRules; ++i)
+ {
+ if(pList[i])
+ {
+ m_xFormBox->remove(i);
+ m_xFormBox->insert_text(i, *pList[i]);
+ if (i == nSelect)
+ nSelect++;
+ }
+ }
+ m_xFormBox->select(std::min(nSelect, o3tl::narrowing<sal_uInt16>(m_xFormBox->n_children() - 1)));
+ SelectHdl(*m_xFormBox);
+}
+
+// unlock OK-Button when text is in Edit
+IMPL_LINK( SwNumNamesDlg, ModifyHdl, weld::Entry&, rBox, void )
+{
+ m_xOKBtn->set_sensitive(!rBox.get_text().isEmpty());
+}
+
+// DoubleClickHdl
+IMPL_LINK_NOARG(SwNumNamesDlg, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+SwNumNamesDlg::SwNumNamesDlg(weld::Window *pParent)
+ : GenericDialogController(pParent,
+ "modules/swriter/ui/numberingnamedialog.ui",
+ "NumberingNameDialog")
+ , m_xFormEdit(m_xBuilder->weld_entry("entry"))
+ , m_xFormBox(m_xBuilder->weld_tree_view("form"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ for (auto const& aID : OUTLINE_STYLE)
+ m_xFormBox->append_text(SwResId(aID));
+
+ m_xFormEdit->connect_changed(LINK(this, SwNumNamesDlg, ModifyHdl));
+ m_xFormBox->connect_changed(LINK(this, SwNumNamesDlg, SelectHdl));
+ m_xFormBox->connect_row_activated(LINK(this, SwNumNamesDlg, DoubleClickHdl));
+ m_xFormBox->set_size_request(-1, m_xFormBox->get_height_rows(9));
+}
+
+static sal_uInt16 lcl_BitToLevel(sal_uInt16 nActLevel)
+{
+ constexpr sal_uInt16 MAXLEVEL_MASK = USHRT_MAX >> (sizeof(sal_uInt16) * CHAR_BIT - MAXLEVEL);
+ assert((nActLevel & MAXLEVEL_MASK) == nActLevel);
+ sal_uInt16 nTmp = nActLevel & MAXLEVEL_MASK; // a safety measure
+ sal_uInt16 nTmpLevel = 0;
+ while( 0 != (nTmp >>= 1) )
+ nTmpLevel++;
+ return nTmpLevel;
+}
+
+sal_uInt16 SwOutlineTabDialog::s_nNumLevel = 1;
+
+SwOutlineTabDialog::SwOutlineTabDialog(weld::Window* pParent, const SfxItemSet* pSwItemSet,
+ SwWrtShell &rSh)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/outlinenumbering.ui", "OutlineNumberingDialog", pSwItemSet)
+ , m_rWrtSh(rSh)
+ , m_pChapterNumRules(SW_MOD()->GetChapterNumRules())
+ , m_bModified(m_rWrtSh.IsModified())
+ , m_xMenuButton(m_xBuilder->weld_menu_button("format"))
+{
+ m_xMenuButton->connect_toggled(LINK(this, SwOutlineTabDialog, FormHdl));
+ m_xMenuButton->connect_selected(LINK(this, SwOutlineTabDialog, MenuSelectHdl));
+
+ m_xNumRule.reset(new SwNumRule(*rSh.GetOutlineNumRule()));
+ GetCancelButton().connect_clicked(LINK(this, SwOutlineTabDialog, CancelHdl));
+
+ if (auto nOutlinePos = m_rWrtSh.GetOutlinePos(MAXLEVEL); nOutlinePos != SwOutlineNodes::npos)
+ {
+ int nTmp = m_rWrtSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos);
+ assert(nTmp < MAXLEVEL);
+ SetActNumLevel(nTmp < 0 ? USHRT_MAX : (1 << nTmp));
+ }
+
+ AddTabPage("position", &SwNumPositionTabPage::Create, nullptr);
+ AddTabPage("numbering", &SwOutlineSettingsTabPage::Create, nullptr);
+
+ OUString sHeadline;
+ sal_uInt16 i;
+
+ for( i = 0; i < MAXLEVEL; ++i )
+ {
+ // if the style wasn't created yet, it's still at this position
+ if( !m_rWrtSh.GetParaStyle( sHeadline =
+ SwStyleNameMapper::GetUIName( static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i),
+ sHeadline )) )
+ m_aCollNames[i] = sHeadline;
+ }
+
+ // query the text templates' outlining levels
+ const sal_uInt16 nCount = m_rWrtSh.GetTextFormatCollCount();
+ for(i = 0; i < nCount; ++i )
+ {
+ SwTextFormatColl &rTextColl = m_rWrtSh.GetTextFormatColl(i);
+ if(!rTextColl.IsDefault())
+ {
+ if(rTextColl.IsAssignedToListLevelOfOutlineStyle())
+ {
+ int nOutLevel = rTextColl.GetAssignedOutlineStyleLevel();
+ m_aCollNames[ nOutLevel ] = rTextColl.GetName();
+ }
+ }
+ }
+}
+
+SwOutlineTabDialog::~SwOutlineTabDialog()
+{
+}
+
+void SwOutlineTabDialog::PageCreated(const OUString& rPageId, SfxTabPage& rPage)
+{
+ if (rPageId == "position")
+ {
+ static_cast<SwNumPositionTabPage&>(rPage).SetWrtShell(&m_rWrtSh);
+ static_cast<SwNumPositionTabPage&>(rPage).SetOutlineTabDialog(this);
+ }
+ else if (rPageId == "numbering")
+ {
+ static_cast<SwOutlineSettingsTabPage&>(rPage).SetWrtShell(&m_rWrtSh);
+ }
+}
+
+IMPL_LINK_NOARG(SwOutlineTabDialog, CancelHdl, weld::Button&, void)
+{
+ if (!m_bModified)
+ m_rWrtSh.ResetModified();
+ m_xDialog->response(RET_CANCEL);
+}
+
+IMPL_LINK_NOARG(SwOutlineTabDialog, FormHdl, weld::Toggleable&, void)
+{
+ if (!m_xMenuButton->get_active())
+ return;
+
+ // fill PopupMenu
+ for(sal_uInt16 i = 0; i < SwChapterNumRules::nMaxRules; ++i)
+ {
+ const SwNumRulesWithName *pRules = m_pChapterNumRules->GetRules(i);
+ if (!pRules)
+ continue;
+ m_xMenuButton->set_item_label("form" + OUString::number(i + 1), pRules->GetName());
+ }
+}
+
+IMPL_LINK(SwOutlineTabDialog, MenuSelectHdl, const OUString&, rIdent, void)
+{
+ sal_uInt8 nLevelNo = 0;
+
+ if (rIdent == "form1")
+ nLevelNo = 1;
+ else if (rIdent == "form2")
+ nLevelNo = 2;
+ else if (rIdent == "form3")
+ nLevelNo = 3;
+ else if (rIdent == "form4")
+ nLevelNo = 4;
+ else if (rIdent == "form5")
+ nLevelNo = 5;
+ else if (rIdent == "form6")
+ nLevelNo = 6;
+ else if (rIdent == "form7")
+ nLevelNo = 7;
+ else if (rIdent == "form8")
+ nLevelNo = 8;
+ else if (rIdent == "form9")
+ nLevelNo = 9;
+ else if (rIdent == "saveas")
+ {
+ SwNumNamesDlg aDlg(m_xDialog.get());
+ const OUString *aStrArr[SwChapterNumRules::nMaxRules];
+ for(sal_uInt16 i = 0; i < SwChapterNumRules::nMaxRules; ++i)
+ {
+ const SwNumRulesWithName *pRules = m_pChapterNumRules->GetRules(i);
+ if(pRules)
+ aStrArr[i] = &pRules->GetName();
+ else
+ aStrArr[i] = nullptr;
+ }
+ aDlg.SetUserNames(aStrArr);
+ if (aDlg.run() == RET_OK)
+ {
+ const OUString aName(aDlg.GetName());
+ m_pChapterNumRules->ApplyNumRules( SwNumRulesWithName(
+ *m_xNumRule, aName ), aDlg.GetCurEntryPos() );
+ m_xMenuButton->set_item_label("form" + OUString::number(aDlg.GetCurEntryPos() + 1), aName);
+ }
+ return;
+ }
+
+ if( nLevelNo-- )
+ {
+ const SwNumRulesWithName *pRules = m_pChapterNumRules->GetRules( nLevelNo );
+ if( pRules )
+ {
+ pRules->ResetNumRule(m_rWrtSh, *m_xNumRule);
+ m_xNumRule->SetRuleType( OUTLINE_RULE );
+ SfxTabPage* pOutlinePage = GetTabPage(u"numbering");
+ assert(pOutlinePage);
+ static_cast<SwOutlineSettingsTabPage*>(pOutlinePage)->SetNumRule(m_xNumRule.get());
+ }
+ else
+ *m_xNumRule = *m_rWrtSh.GetOutlineNumRule();
+ }
+
+ SfxTabPage* pPage = GetCurTabPage();
+ pPage->Reset(GetOutputItemSet());
+}
+
+sal_uInt16 SwOutlineTabDialog::GetLevel(std::u16string_view rFormatName) const
+{
+ for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ if(m_aCollNames[i] == rFormatName)
+ return i;
+ }
+ return MAXLEVEL;
+}
+
+short SwOutlineTabDialog::Ok()
+{
+ SfxTabDialogController::Ok();
+ // set levels for all created templates; has to be done in order to
+ // delete possibly cancelled assignments again.
+
+ // encapsulate changes into an action to avoid effects on the current cursor
+ // position during the changes.
+ m_rWrtSh.StartAction();
+
+ const SwNumRule * pOutlineRule = m_rWrtSh.GetOutlineNumRule();
+
+ sal_uInt16 i, nCount = m_rWrtSh.GetTextFormatCollCount();
+ for( i = 0; i < nCount; ++i )
+ {
+ SwTextFormatColl &rTextColl = m_rWrtSh.GetTextFormatColl(i);
+ if( !rTextColl.IsDefault() )
+ {
+ const SfxPoolItem & rItem =
+ rTextColl.GetFormatAttr(RES_PARATR_NUMRULE, false);
+
+ if (static_cast<sal_uInt8>(GetLevel(rTextColl.GetName())) == MAXLEVEL)
+ {
+ if(rTextColl.IsAssignedToListLevelOfOutlineStyle())
+ {
+ rTextColl.DeleteAssignmentToListLevelOfOutlineStyle();
+ }
+ if (static_cast<const SwNumRuleItem &>(rItem).GetValue() ==
+ pOutlineRule->GetName())
+ {
+ rTextColl.ResetFormatAttr(RES_PARATR_NUMRULE);
+ }
+ }
+ else
+ {
+ rTextColl.AssignToListLevelOfOutlineStyle(GetLevel(rTextColl.GetName()));
+
+ if (static_cast<const SwNumRuleItem &>(rItem).GetValue() !=
+ pOutlineRule->GetName())
+ {
+ SwNumRuleItem aItem(pOutlineRule->GetName());
+ rTextColl.SetFormatAttr(aItem);
+ }
+ }
+ }
+ }
+
+ for(i = 0; i < MAXLEVEL; ++i )
+ {
+ OUString sHeadline;
+ ::SwStyleNameMapper::FillUIName( static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i),
+ sHeadline );
+ SwTextFormatColl* pColl = m_rWrtSh.FindTextFormatCollByName( sHeadline );
+ if( !pColl && m_aCollNames[i] != sHeadline)
+ {
+ SwTextFormatColl* pTextColl = m_rWrtSh.GetTextCollFromPool(
+ static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i) );
+ pTextColl->DeleteAssignmentToListLevelOfOutlineStyle();
+ pTextColl->ResetFormatAttr(RES_PARATR_NUMRULE);
+
+ if( !m_aCollNames[i].isEmpty() )
+ {
+ pTextColl = m_rWrtSh.GetParaStyle(
+ m_aCollNames[i], SwWrtShell::GETSTYLE_CREATESOME);
+ if(pTextColl)
+ {
+ pTextColl->AssignToListLevelOfOutlineStyle(i);
+ SwNumRuleItem aItem(pOutlineRule->GetName());
+ pTextColl->SetFormatAttr(aItem);
+ }
+ }
+ }
+ }
+
+ m_rWrtSh.SetOutlineNumRule(*m_xNumRule);
+
+ // #i30443#
+ m_rWrtSh.EndAction();
+
+ return RET_OK;
+}
+
+SwOutlineSettingsTabPage::SwOutlineSettingsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/outlinenumberingpage.ui", "OutlineNumberingPage", &rSet)
+ , m_aNoFormatName(SwResId(SW_STR_NONE))
+ , m_pSh(nullptr)
+ , m_pNumRule(nullptr)
+ , m_pCollNames(nullptr)
+ , m_nActLevel(1)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("level"))
+ , m_xCollBox(m_xBuilder->weld_combo_box("style"))
+ , m_xNumberBox(new SwNumberingTypeListBox(m_xBuilder->weld_combo_box("numbering")))
+ , m_xCharFormatLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xAllLevelFT(m_xBuilder->weld_label("sublevelsft"))
+ , m_xAllLevelNF(m_xBuilder->weld_spin_button("sublevelsnf"))
+ , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
+ , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
+ , m_xStartEdit(m_xBuilder->weld_spin_button("startat"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ SetExchangeSupport();
+
+ m_xNumberBox->Reload(SwInsertNumTypes::NoNumbering | SwInsertNumTypes::Extended);
+ m_xCollBox->make_sorted();
+ m_xCollBox->append_text(m_aNoFormatName);
+ m_xLevelLB->connect_changed(LINK(this, SwOutlineSettingsTabPage, LevelHdl));
+ m_xAllLevelNF->connect_value_changed(LINK(this, SwOutlineSettingsTabPage, ToggleComplete));
+ m_xCollBox->connect_changed(LINK(this, SwOutlineSettingsTabPage, CollSelect));
+ m_xNumberBox->connect_changed(LINK(this, SwOutlineSettingsTabPage, NumberSelect));
+ m_xPrefixED->connect_changed(LINK(this, SwOutlineSettingsTabPage, DelimModify));
+ m_xSuffixED->connect_changed(LINK(this, SwOutlineSettingsTabPage, DelimModify));
+ m_xStartEdit->connect_value_changed(LINK(this, SwOutlineSettingsTabPage, StartModified));
+ m_xCharFormatLB->make_sorted();
+ m_xCharFormatLB->connect_changed(LINK(this, SwOutlineSettingsTabPage, CharFormatHdl));
+}
+
+void SwOutlineSettingsTabPage::Update()
+{
+ // if a template was already selected for this level, select it in the ListBox
+ m_xCollBox->set_sensitive(USHRT_MAX != m_nActLevel);
+ if(USHRT_MAX == m_nActLevel)
+ {
+ bool bSamePrefix = true;
+ bool bSameSuffix = true;
+ bool bSameType = true;
+ bool bSameComplete = true;
+ bool bSameStart = true;
+ bool bSameCharFormat = true;
+
+ const SwNumFormat* aNumFormatArr[MAXLEVEL];
+ const SwCharFormat* pFirstFormat = nullptr;
+
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+
+ aNumFormatArr[ i ] = &m_pNumRule->Get(i);
+ if(i == 0)
+ pFirstFormat = aNumFormatArr[i]->GetCharFormat();
+ else
+ {
+ bSameType &= aNumFormatArr[i]->GetNumberingType() == aNumFormatArr[0]->GetNumberingType();
+ bSameStart &= aNumFormatArr[i]->GetStart() == aNumFormatArr[0]->GetStart();
+ bSamePrefix &= aNumFormatArr[i]->GetPrefix() == aNumFormatArr[0]->GetPrefix();
+ bSameSuffix &= aNumFormatArr[i]->GetSuffix() == aNumFormatArr[0]->GetSuffix();
+ bSameComplete &= aNumFormatArr[i]->GetIncludeUpperLevels() == aNumFormatArr[0]->GetIncludeUpperLevels();
+ const SwCharFormat* pFormat = aNumFormatArr[i]->GetCharFormat();
+ bSameCharFormat &= (!pFirstFormat && !pFormat)
+ || (pFirstFormat && pFormat && pFormat->GetName() == pFirstFormat->GetName());
+ }
+ }
+ CheckForStartValue_Impl(aNumFormatArr[0]->GetNumberingType());
+ if (bSameType)
+ m_xNumberBox->SelectNumberingType( aNumFormatArr[0]->GetNumberingType() );
+ else
+ m_xNumberBox->SetNoSelection();
+ if(bSameStart)
+ m_xStartEdit->set_value(aNumFormatArr[0]->GetStart());
+ else
+ m_xStartEdit->set_text(OUString());
+ if(bSamePrefix)
+ m_xPrefixED->set_text(aNumFormatArr[0]->GetPrefix());
+ else
+ m_xPrefixED->set_text(OUString());
+ if(bSameSuffix)
+ m_xSuffixED->set_text(aNumFormatArr[0]->GetSuffix());
+ else
+ m_xSuffixED->set_text(OUString());
+
+ if (bSameCharFormat)
+ {
+ if (pFirstFormat)
+ m_xCharFormatLB->set_active_text(pFirstFormat->GetName());
+ else
+ m_xCharFormatLB->set_active_text(SwViewShell::GetShellRes()->aStrNone);
+ }
+ else
+ m_xCharFormatLB->set_active(-1);
+
+ m_xAllLevelFT->set_sensitive(true);
+ m_xAllLevelNF->set_sensitive(true);
+ m_xAllLevelNF->set_max(MAXLEVEL);
+ if (bSameComplete)
+ {
+ m_xAllLevelNF->set_value(aNumFormatArr[0]->GetIncludeUpperLevels());
+ }
+ else
+ {
+ m_xAllLevelNF->set_text(OUString());
+ }
+ }
+ else
+ {
+ sal_uInt16 nTmpLevel = lcl_BitToLevel(m_nActLevel);
+ OUString aColl(m_pCollNames[nTmpLevel]);
+ if(!aColl.isEmpty())
+ m_xCollBox->set_active_text(aColl);
+ else
+ m_xCollBox->set_active_text(m_aNoFormatName);
+ const SwNumFormat &rFormat = m_pNumRule->Get(nTmpLevel);
+
+ m_xNumberBox->SelectNumberingType( rFormat.GetNumberingType() );
+ m_xPrefixED->set_text(rFormat.GetPrefix());
+ m_xSuffixED->set_text(rFormat.GetSuffix());
+ const SwCharFormat* pFormat = rFormat.GetCharFormat();
+ if(pFormat)
+ m_xCharFormatLB->set_active_text(pFormat->GetName());
+ else
+ m_xCharFormatLB->set_active_text(SwViewShell::GetShellRes()->aStrNone);
+
+ if (nTmpLevel || rFormat.HasListFormat())
+ {
+ m_xAllLevelFT->set_sensitive(true);
+ m_xAllLevelNF->set_sensitive(true);
+ m_xAllLevelNF->set_max(nTmpLevel + 1);
+ m_xAllLevelNF->set_min(rFormat.HasListFormat() ? 0 : 1);
+ m_xAllLevelNF->set_value(rFormat.GetIncludeUpperLevels());
+ }
+ else
+ {
+ m_xAllLevelNF->set_text(OUString());
+ m_xAllLevelNF->set_sensitive(false);
+ m_xAllLevelFT->set_sensitive(false);
+ }
+ CheckForStartValue_Impl(rFormat.GetNumberingType());
+ m_xStartEdit->set_value( rFormat.GetStart() );
+ }
+ SetModified();
+}
+
+IMPL_LINK( SwOutlineSettingsTabPage, LevelHdl, weld::TreeView&, rBox, void )
+{
+ auto aRows = rBox.get_selected_rows();
+ assert(aRows.empty() || aRows.size() == 1); // Single selection only
+ if (aRows.empty() || aRows[0] == MAXLEVEL)
+ {
+ m_nActLevel = USHRT_MAX;
+ }
+ else
+ {
+ m_nActLevel = 1 << aRows[0];
+ }
+ Update();
+}
+
+IMPL_LINK(SwOutlineSettingsTabPage, ToggleComplete, weld::SpinButton&, rEdit, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActLevel & nMask)
+ {
+ SwNumFormat aNumFormat(m_pNumRule->Get(i));
+ aNumFormat.SetIncludeUpperLevels( std::min( static_cast<sal_uInt8>(rEdit.get_value()),
+ static_cast<sal_uInt8>(i + 1)) );
+ // Set the same prefix/suffix to generate list format with changed IncludedUpperLevels
+ aNumFormat.SetListFormat(aNumFormat.GetPrefix(), aNumFormat.GetSuffix(), i);
+ m_pNumRule->Set(i, aNumFormat);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK( SwOutlineSettingsTabPage, CollSelect, weld::ComboBox&, rBox, void )
+{
+ sal_uInt8 i;
+
+ const OUString aCollName(rBox.get_active_text());
+ //0xFFFF not allowed here (disable)
+ sal_uInt16 nTmpLevel = lcl_BitToLevel(m_nActLevel);
+ OUString sOldName( m_pCollNames[nTmpLevel] );
+
+ for( i = 0; i < MAXLEVEL; ++i)
+ m_pCollNames[i] = m_aSaveCollNames[i];
+
+ m_pCollNames[nTmpLevel] = aCollName;
+ // template already in use?
+ for( i = 0; i < MAXLEVEL; ++i)
+ if(i != nTmpLevel && m_pCollNames[i] == aCollName )
+ m_pCollNames[i].clear();
+
+ // search the oldname and put it into the current entries
+ if( !sOldName.isEmpty() )
+ for( i = 0; i < MAXLEVEL; ++i)
+ if( m_aSaveCollNames[ i ] == sOldName && i != nTmpLevel &&
+ m_pCollNames[ i ].isEmpty() )
+ {
+ sal_uInt8 n;
+ for( n = 0; n < MAXLEVEL; ++n )
+ if( m_pCollNames[ n ] == sOldName )
+ break;
+
+ if( MAXLEVEL == n )
+ // it was an outline level name and the current entries is zero.
+ m_pCollNames[ i ] = sOldName;
+ }
+
+ SetModified();
+ CollSave();
+}
+
+void SwOutlineSettingsTabPage::CollSave()
+{
+ for (sal_uInt8 i = 0; i < MAXLEVEL; ++i)
+ m_aSaveCollNames[i] = m_pCollNames[i];
+}
+
+IMPL_LINK_NOARG(SwOutlineSettingsTabPage, NumberSelect, weld::ComboBox&, void)
+{
+ sal_uInt16 nMask = 1;
+ SvxNumType nNumberType = m_xNumberBox->GetSelectedNumberingType();
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActLevel & nMask)
+ {
+ SwNumFormat aNumFormat(m_pNumRule->Get(i));
+ aNumFormat.SetNumberingType(nNumberType);
+ m_pNumRule->Set(i, aNumFormat);
+ CheckForStartValue_Impl(nNumberType);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SwOutlineSettingsTabPage, DelimModify, weld::Entry&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActLevel & nMask)
+ {
+ SwNumFormat aNumFormat(m_pNumRule->Get(i));
+ aNumFormat.SetListFormat( m_xPrefixED->get_text(), m_xSuffixED->get_text(), i );
+ m_pNumRule->Set(i, aNumFormat);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK( SwOutlineSettingsTabPage, StartModified, weld::SpinButton&, rEdit, void )
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActLevel & nMask)
+ {
+ SwNumFormat aNumFormat(m_pNumRule->Get(i));
+ aNumFormat.SetStart(o3tl::narrowing<sal_uInt16>(rEdit.get_value()));
+ m_pNumRule->Set(i, aNumFormat);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SwOutlineSettingsTabPage, CharFormatHdl, weld::ComboBox&, void)
+{
+ OUString sEntry = m_xCharFormatLB->get_active_text();
+ sal_uInt16 nMask = 1;
+ bool bFormatNone = sEntry == SwViewShell::GetShellRes()->aStrNone;
+ SwCharFormat* pFormat = nullptr;
+ if(!bFormatNone)
+ {
+ sal_uInt16 nChCount = m_pSh->GetCharFormatCount();
+ for(sal_uInt16 i = 0; i < nChCount; i++)
+ {
+ SwCharFormat& rChFormat = m_pSh->GetCharFormat(i);
+ if(rChFormat.GetName() == sEntry)
+ {
+ pFormat = &rChFormat;
+ break;
+ }
+ }
+ if(!pFormat)
+ {
+ SfxStyleSheetBasePool* pPool = m_pSh->GetView().GetDocShell()->GetStyleSheetPool();
+ SfxStyleSheetBase* pBase;
+ pBase = pPool->Find(sEntry, SfxStyleFamily::Char);
+ if(!pBase)
+ pBase = &pPool->Make(sEntry, SfxStyleFamily::Page);
+ pFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
+
+ }
+ }
+
+ for(sal_uInt16 i = 0; i < MAXLEVEL; i++)
+ {
+ if(m_nActLevel & nMask)
+ {
+ SwNumFormat aNumFormat(m_pNumRule->Get(i));
+ if(bFormatNone)
+ aNumFormat.SetCharFormat(nullptr);
+ else
+ aNumFormat.SetCharFormat(pFormat);
+ m_pNumRule->Set(i, aNumFormat);
+ }
+ nMask <<= 1;
+ }
+}
+
+SwOutlineSettingsTabPage::~SwOutlineSettingsTabPage()
+{
+}
+
+void SwOutlineSettingsTabPage::SetWrtShell(SwWrtShell* pShell)
+{
+ m_pSh = pShell;
+ // query this document's NumRules
+ m_pNumRule = static_cast<SwOutlineTabDialog*>(GetDialogController())->GetNumRule();
+ m_pCollNames = static_cast<SwOutlineTabDialog*>(GetDialogController())->GetCollNames();
+
+ CollSave();
+
+ m_aPreviewWIN.SetNumRule(m_pNumRule);
+ m_aPreviewWIN.SetOutlineNames(m_pCollNames);
+ // set start value - nActLevel must be 1 here
+ sal_uInt16 nTmpLevel = lcl_BitToLevel(m_nActLevel);
+ const SwNumFormat& rNumFormat = m_pNumRule->Get( nTmpLevel );
+ m_xStartEdit->set_value( rNumFormat.GetStart() );
+
+ // create pool formats for headlines
+ for (sal_uInt16 i = 0; i < MAXLEVEL; ++i)
+ {
+ m_xCollBox->append_text( SwStyleNameMapper::GetUIName(
+ static_cast< sal_uInt16 >(RES_POOLCOLL_HEADLINE1 + i), OUString()));
+ m_xLevelLB->append_text( OUString::number(i + 1) );
+ }
+ OUString sStr = "1 - " + OUString::number(MAXLEVEL);
+ m_xLevelLB->append_text(sStr);
+
+ // query the texttemplates' outlining levels
+ const sal_uInt16 nCount = m_pSh->GetTextFormatCollCount();
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ SwTextFormatColl &rTextColl = m_pSh->GetTextFormatColl(i);
+ if(!rTextColl.IsDefault())
+ {
+ sStr = rTextColl.GetName();
+ if (m_xCollBox->find_text(sStr) == -1)
+ m_xCollBox->append_text(sStr);
+ }
+ }
+
+ m_xNumberBox->SelectNumberingType(rNumFormat.GetNumberingType());
+
+ // collect char styles
+ m_xCharFormatLB->clear();
+ m_xCharFormatLB->append_text(SwViewShell::GetShellRes()->aStrNone);
+
+ // char styles
+ ::FillCharStyleListBox(*m_xCharFormatLB,
+ m_pSh->GetView().GetDocShell());
+ Update();
+}
+
+void SwOutlineSettingsTabPage::ActivatePage(const SfxItemSet& )
+{
+ m_nActLevel = SwOutlineTabDialog::GetActNumLevel();
+ if(m_nActLevel != USHRT_MAX)
+ m_xLevelLB->select(lcl_BitToLevel(m_nActLevel));
+ else
+ m_xLevelLB->select(MAXLEVEL);
+ LevelHdl(*m_xLevelLB);
+}
+
+DeactivateRC SwOutlineSettingsTabPage::DeactivatePage(SfxItemSet*)
+{
+ SwOutlineTabDialog::SetActNumLevel(m_nActLevel);
+ return DeactivateRC::LeavePage;
+}
+
+bool SwOutlineSettingsTabPage::FillItemSet( SfxItemSet* )
+{
+ return true;
+}
+
+void SwOutlineSettingsTabPage::Reset( const SfxItemSet* rSet )
+{
+ ActivatePage(*rSet);
+}
+
+std::unique_ptr<SfxTabPage> SwOutlineSettingsTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwOutlineSettingsTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SwOutlineSettingsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
+{
+ bool bIsNull = m_xStartEdit->get_value() == 0;
+ bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
+ SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
+ SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
+ m_xStartEdit->set_min(bNoZeroAllowed ? 1 : 0);
+ if (bIsNull && bNoZeroAllowed)
+ StartModified(*m_xStartEdit);
+}
+
+static tools::Long lcl_DrawBullet(vcl::RenderContext* pVDev, const SwNumFormat& rFormat, 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(rFormat.GetBulletFont() ? *rFormat.GetBulletFont() : aTmpFont);
+ Size aTmpSize(rSize);
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFormat.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFormat.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 = rFormat.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 cBullet = rFormat.GetBulletChar();
+ OUString aText(&cBullet, 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;
+}
+
+static tools::Long lcl_DrawGraphic(vcl::RenderContext& rVDev, const SwNumFormat &rFormat, tools::Long nXStart, tools::Long nYStart, tools::Long nDivision)
+{
+ const SvxBrushItem* pBrushItem = rFormat.GetBrush();
+ tools::Long nRet = 0;
+ if (pBrushItem)
+ {
+ const Graphic* pGraphic = pBrushItem->GetGraphic();
+ if (pGraphic)
+ {
+ Size aGSize( rFormat.GetGraphicSize());
+ aGSize.setWidth( aGSize.Width() / nDivision );
+ nRet = aGSize.Width();
+ aGSize.setHeight( aGSize.Height() / nDivision );
+ pGraphic->Draw(rVDev, Point(nXStart, nYStart), rVDev.PixelToLogic(aGSize));
+ }
+ }
+ return nRet;
+}
+
+void NumberingPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ const Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+
+ ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
+ pVDev->SetMapMode(rRenderContext.GetMapMode());
+ pVDev->SetOutputSize(aSize);
+
+ const SwViewOption& pOpt = SwViewOption::GetCurrentViewOptions();
+ const Color& rDocColor = pOpt.GetDocColor();
+ const Color& rDocBoundariesColor = pOpt.GetDocBoundariesColor();
+ const Color& rFontColor = pOpt.GetFontColor();
+ // #101524# OJ
+ pVDev->SetFillColor(rDocColor);
+ pVDev->SetLineColor(rDocBoundariesColor);
+ pVDev->DrawRect(tools::Rectangle(Point(0,0), aSize));
+
+ if (m_pActNum)
+ {
+ tools::Long nWidthRelation = 30; // chapter dialog
+ if(m_nPageWidth)
+ {
+ nWidthRelation = m_nPageWidth / aSize.Width();
+ if(m_bPosition)
+ nWidthRelation = nWidthRelation * 2 / 3;
+ else
+ nWidthRelation = nWidthRelation / 4;
+ }
+
+ // height per level
+ const tools::Long nXStep = aSize.Width() / (3 * MAXLEVEL * ((MAXLEVEL < 10) ? 2 : 1));
+ const tools::Long nYStep = (aSize.Height() - 6)/ MAXLEVEL;
+ tools::Long nYStart = 4;
+ m_aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, GetAppLanguage(),
+ GetDefaultFontFlags::OnlyOne, &rRenderContext);
+
+ if (svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR, false).nColor == COL_AUTO)
+ m_aStdFont.SetColor( rDocColor.IsDark() ? COL_WHITE : COL_BLACK );
+ else
+ m_aStdFont.SetColor( rFontColor );
+
+ const tools::Long nFontHeight = nYStep * ( m_bPosition ? 15 : 6 ) / 10;
+ m_aStdFont.SetFontSize(Size( 0, nFontHeight ));
+
+ tools::Long nPreNum = m_pActNum->Get(0).GetStart();
+
+ if (m_bPosition)
+ {
+ const tools::Long nLineHeight = nFontHeight * 8 / 7;
+ sal_uInt8 nStart = 0;
+ while (!(m_nActLevel & (1 << nStart)))
+ {
+ nStart++;
+ }
+ if(nStart) // so that possible predecessors and successors are showed
+ nStart--;
+
+ SwNumberTree::tNumberVector aNumVector;
+ sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), MAXLEVEL);
+ for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
+ {
+ const SwNumFormat &rFormat = m_pActNum->Get(nLevel);
+ aNumVector.push_back(rFormat.GetStart());
+
+ tools::Long nXStart( 0 );
+ tools::Long nTextOffset( 0 );
+ tools::Long nNumberXPos( 0 );
+ if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFormat.GetAbsLSpace() / nWidthRelation;
+ nTextOffset = rFormat.GetCharTextDistance() / nWidthRelation;
+ nNumberXPos = nXStart;
+ const tools::Long nFirstLineOffset = (-rFormat.GetFirstLineOffset()) / nWidthRelation;
+
+ if(nFirstLineOffset <= nNumberXPos)
+ nNumberXPos -= nFirstLineOffset;
+ else
+ nNumberXPos = 0;
+ }
+ else if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpNumberXPos((rFormat.GetIndentAt() + rFormat.GetFirstLineIndent()) / nWidthRelation);
+ nNumberXPos = (nTmpNumberXPos < 0) ? 0 : nTmpNumberXPos;
+ }
+
+ tools::Long nBulletWidth = 0;
+ if (SVX_NUM_BITMAP == rFormat.GetNumberingType())
+ {
+ nBulletWidth = lcl_DrawGraphic(*pVDev, rFormat, nNumberXPos,
+ nYStart, nWidthRelation);
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType())
+ {
+ nBulletWidth = lcl_DrawBullet(pVDev.get(), rFormat, nNumberXPos,
+ nYStart, m_aStdFont.GetFontSize());
+ }
+ else
+ {
+ pVDev->SetFont(m_aStdFont);
+ if(m_pActNum->IsContinusNum())
+ aNumVector[nLevel] = nPreNum;
+ OUString aText(m_pActNum->MakeNumString( aNumVector ));
+ pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
+ nBulletWidth = pVDev->GetTextWidth(aText);
+ nPreNum++;
+ }
+ if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
+ rFormat.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ pVDev->SetFont(m_aStdFont);
+ OUString aText(' ');
+ pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
+ nBulletWidth += pVDev->GetTextWidth(aText);
+ }
+
+ tools::Long nTextXPos(0);
+ if (rFormat.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 (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ switch (rFormat.GetLabelFollowedBy())
+ {
+ case SvxNumberFormat::LISTTAB:
+ {
+ nTextXPos = rFormat.GetListtabPos() / nWidthRelation;
+ if (nTextXPos < nNumberXPos + nBulletWidth)
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ }
+ break;
+ case SvxNumberFormat::SPACE:
+ case SvxNumberFormat::NOTHING:
+ case SvxNumberFormat::NEWLINE:
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ break;
+ }
+
+ nXStart = rFormat.GetIndentAt() / nWidthRelation;
+ }
+
+ tools::Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2));
+ pVDev->SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor()); // COL_BLACK );
+ pVDev->DrawRect(aRect1);
+
+ tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2), Size(aSize.Width() / 2, 2));
+ pVDev->DrawRect(aRect2);
+ nYStart += 2 * nLineHeight;
+ }
+ }
+ else
+ {
+ SwNumberTree::tNumberVector aNumVector;
+ const tools::Long nLineHeight = nFontHeight * 3 / 2;
+ for (sal_uInt8 nLevel = 0; nLevel < MAXLEVEL; ++nLevel, nYStart = nYStart + nYStep)
+ {
+ const SwNumFormat &rFormat = m_pActNum->Get(nLevel);
+ aNumVector.push_back(rFormat.GetStart());
+ tools::Long nXStart(0);
+ if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFormat.GetAbsLSpace() / nWidthRelation;
+ }
+ else if (rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const tools::Long nTmpXStart((rFormat.GetIndentAt() + rFormat.GetFirstLineIndent() ) / nWidthRelation);
+ nXStart = (nTmpXStart < 0) ? 0 : nTmpXStart;
+ }
+ nXStart /= 2;
+ nXStart += 2;
+ tools::Long nTextOffset;
+ if (SVX_NUM_BITMAP == rFormat.GetNumberingType())
+ {
+ lcl_DrawGraphic(*pVDev, rFormat, nXStart, nYStart, nWidthRelation);
+ nTextOffset = nLineHeight + nXStep;
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType())
+ {
+ nTextOffset = lcl_DrawBullet(pVDev.get(), rFormat, nXStart, nYStart, m_aStdFont.GetFontSize());
+ nTextOffset += nXStep;
+ }
+ else
+ {
+ pVDev->SetFont(m_aStdFont);
+ if (m_pActNum->IsContinusNum())
+ aNumVector[nLevel] = nPreNum;
+ OUString aText(m_pActNum->MakeNumString( aNumVector ));
+ pVDev->DrawText( Point(nXStart, nYStart), aText );
+ nTextOffset = pVDev->GetTextWidth(aText) + nXStep;
+ nPreNum++;
+ }
+ pVDev->SetFont(m_aStdFont);
+ pVDev->DrawText(
+ Point(nXStart + nTextOffset, nYStart),
+ (m_pOutlineNames == nullptr
+ ? utl::ConfigManager::getProductName()
+ : m_pOutlineNames[nLevel]));
+ }
+ }
+ }
+ rRenderContext.DrawOutDev(Point(0,0), aSize, Point(0,0), aSize, *pVDev);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/pagenumberdlg.cxx b/sw/source/ui/misc/pagenumberdlg.cxx
new file mode 100644
index 0000000000..fe965d69db
--- /dev/null
+++ b/sw/source/ui/misc/pagenumberdlg.cxx
@@ -0,0 +1,143 @@
+/* -*- 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 <pagenumberdlg.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/BitmapTools.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/gen.hxx>
+
+SwPageNumberDlg::SwPageNumberDlg(weld::Window* pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/pagenumberdlg.ui", "PageNumberDialog")
+ , m_xOk(m_xBuilder->weld_button("ok"))
+ , m_xCancel(m_xBuilder->weld_button("cancel"))
+ , m_xPageNumberPosition(m_xBuilder->weld_combo_box("positionCombo"))
+ , m_xPageNumberAlignment(m_xBuilder->weld_combo_box("alignmentCombo"))
+ , m_xMirrorOnEvenPages(m_xBuilder->weld_check_button("mirrorCheckbox"))
+ , m_xIncludePageTotal(m_xBuilder->weld_check_button("pagetotalCheckbox"))
+ , m_xPageNumberTypeLB(new SvxPageNumberListBox(m_xBuilder->weld_combo_box("numfmtlb")))
+ , m_xPreviewImage(m_xBuilder->weld_image("previewImage"))
+ , m_aPageNumberPosition(1) // bottom
+ , m_aPageNumberAlignment(1) // center
+ , m_nPageNumberType(SVX_NUM_CHARS_UPPER_LETTER)
+{
+ m_xOk->connect_clicked(LINK(this, SwPageNumberDlg, OkHdl));
+ m_xPageNumberPosition->connect_changed(LINK(this, SwPageNumberDlg, PositionSelectHdl));
+ m_xPageNumberAlignment->connect_changed(LINK(this, SwPageNumberDlg, AlignmentSelectHdl));
+ m_xPageNumberPosition->set_active(m_aPageNumberPosition);
+ m_xPageNumberAlignment->set_active(m_aPageNumberAlignment);
+ m_xMirrorOnEvenPages->set_sensitive(false);
+ m_xMirrorOnEvenPages->set_state(TRISTATE_TRUE);
+ m_xIncludePageTotal->set_state(TRISTATE_FALSE);
+ SvxNumOptionsTabPageHelper::GetI18nNumbering(m_xPageNumberTypeLB->get_widget(),
+ ::std::numeric_limits<sal_uInt16>::max());
+ m_xPageNumberTypeLB->connect_changed(LINK(this, SwPageNumberDlg, NumberTypeSelectHdl));
+ m_xIncludePageTotal->connect_toggled(LINK(this, SwPageNumberDlg, IncludePageTotalChangeHdl));
+ updateImage();
+}
+
+IMPL_LINK_NOARG(SwPageNumberDlg, OkHdl, weld::Button&, void) { m_xDialog->response(RET_OK); }
+
+IMPL_LINK_NOARG(SwPageNumberDlg, PositionSelectHdl, weld::ComboBox&, void)
+{
+ m_aPageNumberPosition = m_xPageNumberPosition->get_active();
+ updateImage();
+}
+
+IMPL_LINK_NOARG(SwPageNumberDlg, AlignmentSelectHdl, weld::ComboBox&, void)
+{
+ m_aPageNumberAlignment = m_xPageNumberAlignment->get_active();
+ updateImage();
+
+ if (m_aPageNumberAlignment == 1) // centered
+ m_xMirrorOnEvenPages->set_sensitive(false);
+ else
+ m_xMirrorOnEvenPages->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SwPageNumberDlg, NumberTypeSelectHdl, weld::ComboBox&, void)
+{
+ m_nPageNumberType = m_xPageNumberTypeLB->get_active_id();
+}
+
+IMPL_LINK_NOARG(SwPageNumberDlg, IncludePageTotalChangeHdl, weld::Toggleable&, void)
+{
+ updateImage();
+}
+
+bool SwPageNumberDlg::GetMirrorOnEvenPages()
+{
+ return m_xMirrorOnEvenPages->get_sensitive()
+ && m_xMirrorOnEvenPages->get_state() == TRISTATE_TRUE;
+}
+
+bool SwPageNumberDlg::GetIncludePageTotal()
+{
+ return m_xIncludePageTotal->get_state() == TRISTATE_TRUE;
+}
+
+void SwPageNumberDlg::SetPageNumberType(SvxNumType nSet)
+{
+ m_nPageNumberType = nSet;
+ m_xPageNumberTypeLB->set_active_id(nSet);
+}
+
+void SwPageNumberDlg::updateImage()
+{
+ int nBackgroundWidth = 75;
+ int nBackgroundHeight = 105;
+
+ int nMargin = 7;
+
+ ScopedVclPtrInstance<VirtualDevice> pVirtualDev;
+ Size aVDSize(nBackgroundWidth, nBackgroundHeight);
+ pVirtualDev->SetOutputSizePixel(aVDSize);
+ pVirtualDev->SetBackground(Color(0xF0, 0xF0, 0xF0));
+ pVirtualDev->Erase();
+
+ OUString sText = "#";
+
+ if (m_xIncludePageTotal->get_state() == TRISTATE_TRUE)
+ {
+ sText += " / #";
+ }
+
+ DrawTextFlags eFlags = DrawTextFlags::Left;
+
+ if (m_aPageNumberAlignment == 1)
+ {
+ eFlags = DrawTextFlags::Center;
+ }
+ else if (m_aPageNumberAlignment == 2)
+ {
+ eFlags = DrawTextFlags::Right;
+ }
+
+ eFlags |= m_aPageNumberPosition ? DrawTextFlags::Bottom : DrawTextFlags::Top;
+
+ pVirtualDev->DrawText(
+ tools::Rectangle(nMargin, nMargin, nBackgroundWidth - nMargin, nBackgroundHeight - nMargin),
+ sText, eFlags);
+
+ m_xPreviewImage->set_image(pVirtualDev);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/pgfnote.cxx b/sw/source/ui/misc/pgfnote.cxx
new file mode 100644
index 0000000000..14eec4b21b
--- /dev/null
+++ b/sw/source/ui/misc/pgfnote.cxx
@@ -0,0 +1,313 @@
+/* -*- 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 <cmdid.h>
+#include <fmtfsize.hxx>
+#include <hintids.hxx>
+#include <svtools/unitconv.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <editeng/borderline.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/pageitem.hxx>
+#include <svl/eitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <uitool.hxx>
+#include <pagedesc.hxx>
+#include <pgfnote.hxx>
+#include <uiitems.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+
+const WhichRangesContainer SwFootNotePage::s_aPageRg(svl::Items<FN_PARAM_FTN_INFO, FN_PARAM_FTN_INFO>);
+
+// handler to switch between the different possibilities how the footnote
+// region's height can be set.
+IMPL_LINK_NOARG(SwFootNotePage, HeightPage, weld::Toggleable&, void)
+{
+ if (m_xMaxHeightPageBtn->get_active())
+ m_xMaxHeightEdit->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SwFootNotePage, HeightMetric, weld::Toggleable&, void)
+{
+ if (m_xMaxHeightBtn->get_active())
+ {
+ m_xMaxHeightEdit->set_sensitive(true);
+ m_xMaxHeightEdit->grab_focus();
+ }
+}
+
+// handler limit values
+IMPL_LINK_NOARG(SwFootNotePage, HeightModify, weld::MetricSpinButton&, void)
+{
+ m_xMaxHeightEdit->set_max(m_xMaxHeightEdit->normalize(m_lMaxHeight -
+ (m_xDistEdit->denormalize(m_xDistEdit->get_value(FieldUnit::TWIP)) +
+ m_xLineDistEdit->denormalize(m_xLineDistEdit->get_value(FieldUnit::TWIP)))),
+ FieldUnit::TWIP);
+ if (m_xMaxHeightEdit->get_value(FieldUnit::NONE) < 0)
+ m_xMaxHeightEdit->set_value(0, FieldUnit::NONE);
+ m_xDistEdit->set_max(m_xDistEdit->normalize(m_lMaxHeight -
+ (m_xMaxHeightEdit->denormalize(m_xMaxHeightEdit->get_value(FieldUnit::TWIP)) +
+ m_xLineDistEdit->denormalize(m_xLineDistEdit->get_value(FieldUnit::TWIP)))),
+ FieldUnit::TWIP);
+ if (m_xDistEdit->get_value(FieldUnit::NONE) < 0)
+ m_xDistEdit->set_value(0, FieldUnit::NONE);
+ m_xLineDistEdit->set_max(m_xLineDistEdit->normalize(m_lMaxHeight -
+ (m_xMaxHeightEdit->denormalize(m_xMaxHeightEdit->get_value(FieldUnit::TWIP)) +
+ m_xDistEdit->denormalize(m_xDistEdit->get_value(FieldUnit::TWIP)))),
+ FieldUnit::TWIP);
+}
+
+IMPL_LINK_NOARG(SwFootNotePage, LineWidthChanged_Impl, weld::MetricSpinButton&, void)
+{
+ sal_Int64 nVal = m_xLineWidthEdit->get_value(FieldUnit::NONE);
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nVal,
+ m_xLineWidthEdit->get_digits(),
+ m_xLineWidthEdit->get_unit(), MapUnit::MapTwip ));
+ m_xLineTypeBox->SetWidth(nVal);
+}
+
+IMPL_LINK(SwFootNotePage, LineColorSelected_Impl, ColorListBox&, rColorBox, void)
+{
+ m_xLineTypeBox->SetColor(rColorBox.GetSelectEntryColor());
+}
+
+SwFootNotePage::SwFootNotePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/footnoteareapage.ui", "FootnoteAreaPage", &rSet)
+ , m_lMaxHeight(0)
+ , m_xMaxHeightPageBtn(m_xBuilder->weld_radio_button("maxheightpage"))
+ , m_xMaxHeightBtn(m_xBuilder->weld_radio_button("maxheight"))
+ , m_xMaxHeightEdit(m_xBuilder->weld_metric_spin_button("maxheightsb", FieldUnit::CM))
+ , m_xDistEdit(m_xBuilder->weld_metric_spin_button("spacetotext", FieldUnit::CM))
+ , m_xLinePosBox(m_xBuilder->weld_combo_box("position"))
+ , m_xLineTypeBox(new SvtLineListBox(m_xBuilder->weld_menu_button("style")))
+ , m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button("thickness", FieldUnit::POINT))
+ , m_xLineColorBox(new ColorListBox(m_xBuilder->weld_menu_button("color"),
+ [this]{ return GetDialogController()->getDialog(); }))
+ , m_xLineLengthEdit(m_xBuilder->weld_metric_spin_button("length", FieldUnit::PERCENT))
+ , m_xLineDistEdit(m_xBuilder->weld_metric_spin_button("spacingtocontents", FieldUnit::CM))
+{
+ SetExchangeSupport();
+ FieldUnit aMetric = ::GetDfltMetric(false);
+ ::SetFieldUnit(*m_xMaxHeightEdit, aMetric);
+ ::SetFieldUnit(*m_xDistEdit, aMetric);
+ ::SetFieldUnit(*m_xLineDistEdit, aMetric);
+ MeasurementSystem eSys = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
+ tools::Long nHeightValue = MeasurementSystem::Metric != eSys ? 1440 : 1134;
+ m_xMaxHeightEdit->set_value(m_xMaxHeightEdit->normalize(nHeightValue),FieldUnit::TWIP);
+}
+
+SwFootNotePage::~SwFootNotePage()
+{
+ m_xLineColorBox.reset();
+ m_xLineTypeBox.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwFootNotePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwFootNotePage>(pPage, pController, *rSet);
+}
+
+void SwFootNotePage::Reset(const SfxItemSet *rSet)
+{
+ // if no example exists, otherwise Init here in Activate
+ std::optional<SwPageFootnoteInfo> pDefFootnoteInfo;
+ const SwPageFootnoteInfo* pFootnoteInfo;
+ const SfxPoolItem* pItem = SfxTabPage::GetItem(*rSet, FN_PARAM_FTN_INFO);
+ if( pItem )
+ {
+ pFootnoteInfo = &static_cast<const SwPageFootnoteInfoItem*>(pItem)->GetPageFootnoteInfo();
+ }
+ else
+ {
+ // when "standard" is being activated the footnote item is deleted,
+ // that's why a footnote structure has to be created here
+ pDefFootnoteInfo.emplace();
+ pFootnoteInfo = &*pDefFootnoteInfo;
+ }
+ // footnote area's height
+ SwTwips lHeight = pFootnoteInfo->GetHeight();
+ if(lHeight)
+ {
+ m_xMaxHeightEdit->set_value(m_xMaxHeightEdit->normalize(lHeight),FieldUnit::TWIP);
+ m_xMaxHeightBtn->set_active(true);
+ }
+ else
+ {
+ m_xMaxHeightPageBtn->set_active(true);
+ m_xMaxHeightEdit->set_sensitive(false);
+ }
+ m_xMaxHeightPageBtn->connect_toggled(LINK(this,SwFootNotePage,HeightPage));
+ m_xMaxHeightBtn->connect_toggled(LINK(this,SwFootNotePage,HeightMetric));
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwFootNotePage, HeightModify);
+ m_xMaxHeightEdit->connect_value_changed(aLk);
+ m_xDistEdit->connect_value_changed(aLk);
+ m_xLineDistEdit->connect_value_changed(aLk);
+
+ // Separator width
+ m_xLineWidthEdit->connect_value_changed(LINK(this, SwFootNotePage, LineWidthChanged_Impl));
+
+ sal_Int64 nWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ sal_Int64( pFootnoteInfo->GetLineWidth() ), m_xLineWidthEdit->get_digits(),
+ MapUnit::MapTwip, m_xLineWidthEdit->get_unit( ) ));
+ m_xLineWidthEdit->set_value(nWidthPt, FieldUnit::NONE);
+
+ // Separator style
+ m_xLineTypeBox->SetSourceUnit( FieldUnit::TWIP );
+
+ m_xLineTypeBox->InsertEntry(
+ ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::SOLID),
+ SvxBorderLineStyle::SOLID );
+ m_xLineTypeBox->InsertEntry(
+ ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DOTTED),
+ SvxBorderLineStyle::DOTTED );
+ m_xLineTypeBox->InsertEntry(
+ ::editeng::SvxBorderLine::getWidthImpl(SvxBorderLineStyle::DASHED),
+ SvxBorderLineStyle::DASHED );
+ m_xLineTypeBox->SetWidth( pFootnoteInfo->GetLineWidth( ) );
+ m_xLineTypeBox->SelectEntry( pFootnoteInfo->GetLineStyle() );
+
+ // Separator Color
+ m_xLineColorBox->SelectEntry(pFootnoteInfo->GetLineColor());
+ m_xLineColorBox->SetSelectHdl(LINK(this, SwFootNotePage, LineColorSelected_Impl));
+ m_xLineTypeBox->SetColor(pFootnoteInfo->GetLineColor());
+
+ // position
+ m_xLinePosBox->set_active(static_cast<sal_Int32>(pFootnoteInfo->GetAdj()));
+
+ // width
+ Fraction aTmp( 100, 1 );
+ aTmp *= pFootnoteInfo->GetWidth();
+ m_xLineLengthEdit->set_value(static_cast<tools::Long>(aTmp), FieldUnit::PERCENT);
+
+ // gap footnote area
+ m_xDistEdit->set_value(m_xDistEdit->normalize(pFootnoteInfo->GetTopDist()), FieldUnit::TWIP);
+ m_xLineDistEdit->set_value(
+ m_xLineDistEdit->normalize(pFootnoteInfo->GetBottomDist()), FieldUnit::TWIP);
+ ActivatePage( *rSet );
+}
+
+// stuff attributes into the set, when OK
+bool SwFootNotePage::FillItemSet(SfxItemSet *rSet)
+{
+ SwPageFootnoteInfoItem aItem(GetItemSet().Get(FN_PARAM_FTN_INFO));
+
+ // that's the original
+ SwPageFootnoteInfo &rFootnoteInfo = aItem.GetPageFootnoteInfo();
+
+ // footnote area's height
+ if (m_xMaxHeightBtn->get_active())
+ rFootnoteInfo.SetHeight( static_cast< SwTwips >(
+ m_xMaxHeightEdit->denormalize(m_xMaxHeightEdit->get_value(FieldUnit::TWIP))));
+ else
+ rFootnoteInfo.SetHeight(0);
+
+ // gap footnote area
+ rFootnoteInfo.SetTopDist( static_cast< SwTwips >(
+ m_xDistEdit->denormalize(m_xDistEdit->get_value(FieldUnit::TWIP))));
+ rFootnoteInfo.SetBottomDist( static_cast< SwTwips >(
+ m_xLineDistEdit->denormalize(m_xLineDistEdit->get_value(FieldUnit::TWIP))));
+
+ // Separator style
+ rFootnoteInfo.SetLineStyle(m_xLineTypeBox->GetSelectEntryStyle());
+
+ // Separator width
+ sal_Int64 nWidth = m_xLineWidthEdit->get_value(FieldUnit::NONE);
+ nWidth = static_cast<tools::Long>(vcl::ConvertDoubleValue(
+ nWidth,
+ m_xLineWidthEdit->get_digits(),
+ m_xLineWidthEdit->get_unit(), MapUnit::MapTwip ));
+ rFootnoteInfo.SetLineWidth( nWidth );
+
+ // Separator color
+ rFootnoteInfo.SetLineColor(m_xLineColorBox->GetSelectEntryColor());
+
+ // Position
+ rFootnoteInfo.SetAdj(static_cast<css::text::HorizontalAdjust>(m_xLinePosBox->get_active()));
+
+ // Width
+ rFootnoteInfo.SetWidth(Fraction(m_xLineLengthEdit->get_value(FieldUnit::PERCENT), 100));
+
+ const SfxPoolItem* pOldItem;
+ if(nullptr == (pOldItem = GetOldItem( *rSet, FN_PARAM_FTN_INFO )) ||
+ aItem != *pOldItem )
+ rSet->Put(aItem);
+
+ return true;
+}
+
+void SwFootNotePage::ActivatePage(const SfxItemSet& rSet)
+{
+ auto const & rSize = rSet.Get( RES_FRM_SIZE );
+ m_lMaxHeight = rSize.GetHeight();
+
+ if( const SvxSetItem* pHeaderSetItem = rSet.GetItemIfSet( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_HEADERSET), false ) )
+ {
+ const SfxItemSet& rHeaderSet = pHeaderSetItem->GetItemSet();
+ const SfxBoolItem& rHeaderOn =
+ rHeaderSet.Get( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_ON ) );
+
+ if ( rHeaderOn.GetValue() )
+ {
+ const SvxSizeItem& rSizeItem =
+ rHeaderSet.Get(rSet.GetPool()->GetWhich(SID_ATTR_PAGE_SIZE));
+ m_lMaxHeight -= rSizeItem.GetSize().Height();
+ }
+ }
+
+ if( const SvxSetItem* pFooterSetItem = rSet.GetItemIfSet( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_FOOTERSET),
+ false ) )
+ {
+ const SfxItemSet& rFooterSet = pFooterSetItem->GetItemSet();
+ const SfxBoolItem& rFooterOn = rFooterSet.Get( SID_ATTR_PAGE_ON );
+
+ if ( rFooterOn.GetValue() )
+ {
+ const SvxSizeItem& rSizeItem =
+ rFooterSet.Get( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_SIZE ) );
+ m_lMaxHeight -= rSizeItem.GetSize().Height();
+ }
+ }
+
+ if ( const SvxULSpaceItem* pSpaceItem = rSet.GetItemIfSet( RES_UL_SPACE , false ) )
+ {
+ m_lMaxHeight -= pSpaceItem->GetUpper() + pSpaceItem->GetLower();
+ }
+
+ m_lMaxHeight *= 8;
+ m_lMaxHeight /= 10;
+
+ // set maximum values
+ HeightModify(*m_xMaxHeightEdit);
+}
+
+DeactivateRC SwFootNotePage::DeactivatePage( SfxItemSet* _pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+
+ return DeactivateRC::LeavePage;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/pggrid.cxx b/sw/source/ui/misc/pggrid.cxx
new file mode 100644
index 0000000000..3eef17523c
--- /dev/null
+++ b/sw/source/ui/misc/pggrid.cxx
@@ -0,0 +1,550 @@
+/* -*- 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 <cmdid.h>
+#include <hintids.hxx>
+#include <svx/colorbox.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/ruler.hxx>
+#include <pggrid.hxx>
+#include <tgrditem.hxx>
+#include <svx/pageitem.hxx>
+
+#include <wrtsh.hxx>
+#include <doc.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+
+constexpr tools::Long constTwips_5mm = o3tl::toTwips(5, o3tl::Length::mm);
+
+SwTextGridPage::SwTextGridPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/textgridpage.ui", "TextGridPage", &rSet)
+ , m_nRubyUserValue(0)
+ , m_bRubyUserValue(false)
+ , m_aPageSize(constTwips_5mm, constTwips_5mm)
+ , m_bVertical(false)
+ , m_bSquaredMode(false)
+ , m_bHRulerChanged(false)
+ , m_bVRulerChanged(false)
+ , m_xNoGridRB(m_xBuilder->weld_radio_button("radioRB_NOGRID"))
+ , m_xLinesGridRB(m_xBuilder->weld_radio_button("radioRB_LINESGRID"))
+ , m_xCharsGridRB(m_xBuilder->weld_radio_button("radioRB_CHARSGRID"))
+ , m_xSnapToCharsCB(m_xBuilder->weld_check_button("checkCB_SNAPTOCHARS"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWN))
+ , m_xLayoutFL(m_xBuilder->weld_widget("frameFL_LAYOUT"))
+ , m_xLinesPerPageNF(m_xBuilder->weld_spin_button("spinNF_LINESPERPAGE"))
+ , m_xLinesRangeFT(m_xBuilder->weld_label("labelFT_LINERANGE"))
+ , m_xTextSizeMF(m_xBuilder->weld_metric_spin_button("spinMF_TEXTSIZE", FieldUnit::POINT))
+ , m_xCharsPerLineFT(m_xBuilder->weld_label("labelFT_CHARSPERLINE"))
+ , m_xCharsPerLineNF(m_xBuilder->weld_spin_button("spinNF_CHARSPERLINE"))
+ , m_xCharsRangeFT(m_xBuilder->weld_label("labelFT_CHARRANGE"))
+ , m_xCharWidthFT(m_xBuilder->weld_label("labelFT_CHARWIDTH"))
+ , m_xCharWidthMF(m_xBuilder->weld_metric_spin_button("spinMF_CHARWIDTH", FieldUnit::POINT))
+ , m_xRubySizeFT(m_xBuilder->weld_label("labelFT_RUBYSIZE"))
+ , m_xRubySizeMF(m_xBuilder->weld_metric_spin_button("spinMF_RUBYSIZE", FieldUnit::POINT))
+ , m_xRubyBelowCB(m_xBuilder->weld_check_button("checkCB_RUBYBELOW"))
+ , m_xDisplayFL(m_xBuilder->weld_widget("frameFL_DISPLAY"))
+ , m_xDisplayCB(m_xBuilder->weld_check_button("checkCB_DISPLAY"))
+ , m_xPrintCB(m_xBuilder->weld_check_button("checkCB_PRINT"))
+ , m_xColorLB(new ColorListBox(m_xBuilder->weld_menu_button("listLB_COLOR"),
+ [this]{ return GetDialogController()->getDialog(); }))
+{
+ Link<weld::SpinButton&,void> aLink = LINK(this, SwTextGridPage, CharorLineChangedHdl);
+ m_xCharsPerLineNF->connect_value_changed(aLink);
+ m_xLinesPerPageNF->connect_value_changed(aLink);
+
+ Link<weld::MetricSpinButton&,void> aSizeLink = LINK(this, SwTextGridPage, TextSizeChangedHdl);
+ m_xTextSizeMF->connect_value_changed(aSizeLink);
+ m_xRubySizeMF->connect_value_changed(aSizeLink);
+ m_xCharWidthMF->connect_value_changed(aSizeLink);
+
+ Link<weld::Toggleable&,void> aGridTypeHdl = LINK(this, SwTextGridPage, GridTypeHdl);
+ m_xNoGridRB->connect_toggled(aGridTypeHdl);
+ m_xLinesGridRB->connect_toggled(aGridTypeHdl);
+ m_xCharsGridRB->connect_toggled(aGridTypeHdl);
+
+ m_xColorLB->SetSelectHdl(LINK(this, SwTextGridPage, ColorModifyHdl));
+ m_xPrintCB->connect_toggled(LINK(this, SwTextGridPage, GridModifyClickHdl));
+ m_xRubyBelowCB->connect_toggled(LINK(this, SwTextGridPage, GridModifyClickHdl));
+
+ m_xDisplayCB->connect_toggled(LINK(this, SwTextGridPage, DisplayGridHdl));
+
+ //Get the default paper mode
+ if (SwView *pView = GetActiveView())
+ {
+ if (SwWrtShell* pSh = pView->GetWrtShellPtr())
+ {
+ m_bSquaredMode = pSh->GetDoc()->IsSquaredPageMode();
+ }
+ }
+ if( m_bSquaredMode )
+ {
+
+ m_xRubySizeFT->show();
+ m_xRubySizeMF->show();
+ m_xRubyBelowCB->show();
+ m_xSnapToCharsCB->hide();
+ m_xCharWidthFT->hide();
+ m_xCharWidthMF->hide();
+ }
+ else
+ {
+ m_xRubySizeFT->hide();
+ m_xRubySizeMF->hide();
+ m_xRubyBelowCB->hide();
+ m_xSnapToCharsCB->show();
+ m_xCharWidthFT->show();
+ m_xCharWidthMF->show();
+ }
+}
+
+SwTextGridPage::~SwTextGridPage()
+{
+ m_xColorLB.reset();
+}
+
+std::unique_ptr<SfxTabPage> SwTextGridPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SwTextGridPage>(pPage, pController, *rSet);
+}
+
+bool SwTextGridPage::FillItemSet(SfxItemSet *rSet)
+{
+ bool bRet = false;
+ if (m_xNoGridRB->get_state_changed_from_saved() ||
+ m_xLinesGridRB->get_state_changed_from_saved() ||
+ m_xLinesPerPageNF->get_value_changed_from_saved() ||
+ m_xTextSizeMF->get_value_changed_from_saved() ||
+ m_xCharsPerLineNF->get_value_changed_from_saved() ||
+ m_xSnapToCharsCB->get_state_changed_from_saved() ||
+ m_xRubySizeMF->get_value_changed_from_saved() ||
+ m_xCharWidthMF->get_value_changed_from_saved() ||
+ m_xRubyBelowCB->get_state_changed_from_saved() ||
+ m_xDisplayCB->get_state_changed_from_saved() ||
+ m_xPrintCB->get_state_changed_from_saved() ||
+ m_xColorLB->IsValueChangedFromSaved())
+ {
+ PutGridItem(*rSet);
+ bRet = true;
+ }
+
+ // draw ticks of ruler
+ if (SwView * pView = GetActiveView())
+ {
+ if ( m_bHRulerChanged )
+ pView->GetHRuler().DrawTicks();
+ if ( m_bVRulerChanged )
+ pView->GetVRuler().DrawTicks();
+ }
+ return bRet;
+}
+
+void SwTextGridPage::Reset(const SfxItemSet *rSet)
+{
+ sal_Int32 nLinesPerPage = 0;
+
+ if(SfxItemState::DEFAULT <= rSet->GetItemState(RES_TEXTGRID))
+ {
+ const SwTextGridItem& rGridItem = rSet->Get(RES_TEXTGRID);
+ weld::RadioButton* pButton = nullptr;
+ switch(rGridItem.GetGridType())
+ {
+ case GRID_NONE : pButton = m_xNoGridRB.get(); break;
+ case GRID_LINES_ONLY : pButton = m_xLinesGridRB.get(); break;
+ default: pButton = m_xCharsGridRB.get();
+ }
+ pButton->set_active(true);
+ m_xDisplayCB->set_active(rGridItem.IsDisplayGrid());
+ GridTypeHdl(*pButton);
+ m_xSnapToCharsCB->set_active(rGridItem.IsSnapToChars());
+ nLinesPerPage = rGridItem.GetLines();
+
+ SetLinesOrCharsRanges(*m_xLinesRangeFT , m_xLinesPerPageNF->get_max());
+ m_nRubyUserValue = rGridItem.GetBaseHeight();
+ m_bRubyUserValue = true;
+ m_xTextSizeMF->set_value(m_xTextSizeMF->normalize(m_nRubyUserValue), FieldUnit::TWIP);
+ m_xRubySizeMF->set_value(m_xRubySizeMF->normalize(rGridItem.GetRubyHeight()), FieldUnit::TWIP);
+ m_xCharWidthMF->set_value(m_xCharWidthMF->normalize(rGridItem.GetBaseWidth()), FieldUnit::TWIP);
+ m_xRubyBelowCB->set_active(rGridItem.IsRubyTextBelow());
+ m_xPrintCB->set_active(rGridItem.IsPrintGrid());
+ m_xColorLB->SelectEntry(rGridItem.GetColor());
+ }
+ UpdatePageSize(*rSet);
+
+ if (nLinesPerPage > 0)
+ m_xLinesPerPageNF->set_value(nLinesPerPage);
+
+ m_xNoGridRB->save_state();
+ m_xLinesGridRB->save_state();
+ m_xSnapToCharsCB->save_state();
+ m_xLinesPerPageNF->save_value();
+ m_xTextSizeMF->save_value();
+ m_xCharsPerLineNF->save_value();
+ m_xRubySizeMF->save_value();
+ m_xCharWidthMF->save_value();
+ m_xRubyBelowCB->save_state();
+ m_xDisplayCB->save_state();
+ m_xPrintCB->save_state();
+ m_xColorLB->SaveValue();
+}
+
+void SwTextGridPage::ActivatePage( const SfxItemSet& rSet )
+{
+ m_aExampleWN.Hide();
+ m_aExampleWN.UpdateExample(rSet);
+ UpdatePageSize(rSet);
+ m_aExampleWN.Show();
+ m_aExampleWN.Invalidate();
+}
+
+DeactivateRC SwTextGridPage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+void SwTextGridPage::PutGridItem(SfxItemSet& rSet)
+{
+ SwTextGridItem aGridItem;
+ aGridItem.SetGridType(m_xNoGridRB->get_active() ? GRID_NONE :
+ m_xLinesGridRB->get_active() ? GRID_LINES_ONLY : GRID_LINES_CHARS );
+ aGridItem.SetSnapToChars(m_xSnapToCharsCB->get_active());
+ aGridItem.SetLines( static_cast< sal_Int32 >(m_xLinesPerPageNF->get_value()) );
+ aGridItem.SetBaseHeight( static_cast< sal_uInt16 >(
+ m_bRubyUserValue ? m_nRubyUserValue :
+ m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP))) );
+ // Tdf#151544: set ruby height from the value get from UI only when in square page mode.
+ // When in normal mode, the ruby height should be zero.
+ if (m_bSquaredMode)
+ aGridItem.SetRubyHeight(static_cast<sal_uInt16>(m_xRubySizeMF->denormalize(m_xRubySizeMF->get_value(FieldUnit::TWIP))));
+ else
+ aGridItem.SetRubyHeight(0);
+ aGridItem.SetBaseWidth( static_cast< sal_uInt16 >(m_xCharWidthMF->denormalize(m_xCharWidthMF->get_value(FieldUnit::TWIP))) );
+ aGridItem.SetRubyTextBelow(m_xRubyBelowCB->get_active());
+ aGridItem.SetSquaredMode(m_bSquaredMode);
+ aGridItem.SetDisplayGrid(m_xDisplayCB->get_active());
+ aGridItem.SetPrintGrid(m_xPrintCB->get_active());
+ aGridItem.SetColor(m_xColorLB->GetSelectEntryColor());
+ rSet.Put(aGridItem);
+
+ SwView * pView = ::GetActiveView();
+ if (pView && aGridItem.GetGridType() != GRID_NONE)
+ {
+ if ( aGridItem.GetGridType() == GRID_LINES_CHARS )
+ {
+ m_bHRulerChanged = true;
+ }
+ m_bVRulerChanged = true;
+ pView->GetHRuler().SetCharWidth(m_xCharWidthMF->get_value(FieldUnit::MM));
+ pView->GetVRuler().SetLineHeight(m_xTextSizeMF->get_value(FieldUnit::MM));
+ }
+}
+
+void SwTextGridPage::UpdatePageSize(const SfxItemSet& rSet)
+{
+ if( SfxItemState::UNKNOWN != rSet.GetItemState( RES_FRAMEDIR ))
+ {
+ const SvxFrameDirectionItem& rDirItem =
+ rSet.Get(RES_FRAMEDIR);
+ m_bVertical = rDirItem.GetValue() == SvxFrameDirection::Vertical_RL_TB||
+ rDirItem.GetValue() == SvxFrameDirection::Vertical_LR_TB;
+ }
+
+ if( SfxItemState::SET != rSet.GetItemState( SID_ATTR_PAGE_SIZE ))
+ return;
+
+ const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
+ const SvxLRSpaceItem& rLRSpace = rSet.Get( RES_LR_SPACE );
+ const SvxULSpaceItem& rULSpace = rSet.Get( RES_UL_SPACE );
+ const SvxBoxItem& rBox = rSet.Get(RES_BOX);
+ sal_Int32 nDistanceLR = rLRSpace.GetLeft() + rLRSpace.GetRight();
+ sal_Int32 nDistanceUL = rULSpace.GetUpper() + rULSpace.GetLower();
+
+ for( const TypedWhichId<SvxSetItem> & nId : { SID_ATTR_PAGE_HEADERSET, SID_ATTR_PAGE_FOOTERSET })
+ {
+ if( const SvxSetItem* pItem = rSet.GetItemIfSet( nId, false ) )
+ {
+ const SfxItemSet& rExtraSet = pItem->GetItemSet();
+ const SfxBoolItem& rOn =
+ rExtraSet.Get( rSet.GetPool()->GetWhich( SID_ATTR_PAGE_ON ) );
+
+ if ( rOn.GetValue() )
+ {
+ const SvxSizeItem& rSizeItem =
+ rExtraSet.Get(rSet.GetPool()->GetWhich(SID_ATTR_PAGE_SIZE));
+ nDistanceUL += rSizeItem.GetSize().Height();
+ }
+ }
+ }
+
+ sal_Int32 nValue1 = rSize.GetSize().Height() - nDistanceUL -
+ rBox.GetDistance(SvxBoxItemLine::TOP) -
+ rBox.GetDistance(SvxBoxItemLine::BOTTOM);
+ sal_Int32 nValue2 = rSize.GetSize().Width() - nDistanceLR -
+ rBox.GetDistance(SvxBoxItemLine::LEFT) -
+ rBox.GetDistance(SvxBoxItemLine::RIGHT);
+ if(m_bVertical)
+ {
+ m_aPageSize.setWidth( nValue1 );
+ m_aPageSize.setHeight( nValue2 );
+ }
+ else
+ {
+ m_aPageSize.setWidth( nValue2 );
+ m_aPageSize.setHeight( nValue1 );
+ }
+
+ sal_Int32 nTextSize = static_cast< sal_Int32 >(m_bRubyUserValue ?
+ m_nRubyUserValue :
+ m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP)));
+
+ if ( m_bSquaredMode )
+ {
+ sal_Int32 nCharsPerLine = m_aPageSize.Width() / nTextSize;
+ m_xCharsPerLineNF->set_max(nCharsPerLine);
+ m_xCharsPerLineNF->set_sensitive(nCharsPerLine != 0);
+ m_xCharsPerLineNF->set_value(nCharsPerLine);
+ sal_Int32 nMaxLines = m_aPageSize.Height() /
+ ( m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP)) +
+ m_xRubySizeMF->denormalize(m_xRubySizeMF->get_value(FieldUnit::TWIP)));
+ m_xLinesPerPageNF->set_max(nMaxLines);
+ m_xLinesPerPageNF->set_sensitive(nMaxLines != 0);
+ SetLinesOrCharsRanges( *m_xCharsRangeFT , m_xCharsPerLineNF->get_max() );
+ SetLinesOrCharsRanges( *m_xLinesRangeFT , m_xLinesPerPageNF->get_max() );
+ }
+ else
+ {
+ sal_Int32 nTextWidth = static_cast< sal_Int32 >(m_xCharWidthMF->denormalize(m_xCharWidthMF->get_value(FieldUnit::TWIP)));
+ m_xLinesPerPageNF->set_value(m_aPageSize.Height() / nTextSize);
+ if (nTextWidth)
+ m_xCharsPerLineNF->set_value(m_aPageSize.Width() / nTextWidth);
+ else
+ m_xCharsPerLineNF->set_value(45);
+ SetLinesOrCharsRanges( *m_xCharsRangeFT , m_xCharsPerLineNF->get_max() );
+ SetLinesOrCharsRanges( *m_xLinesRangeFT , m_xLinesPerPageNF->get_max() );
+ }
+}
+
+void SwTextGridPage::SetLinesOrCharsRanges(weld::Label& rField, const sal_Int32 nValue )
+{
+ OUString aFieldStr = "( 1 -" + OUString::number(nValue) + " )";
+ rField.set_label(aFieldStr);
+}
+
+WhichRangesContainer SwTextGridPage::GetRanges()
+{
+ return WhichRangesContainer(svl::Items<RES_TEXTGRID, RES_TEXTGRID>);
+}
+
+IMPL_LINK(SwTextGridPage, CharorLineChangedHdl, weld::SpinButton&, rField, void)
+{
+ //if in squared mode
+ if ( m_bSquaredMode )
+ {
+ if (m_xCharsPerLineNF.get() == &rField)
+ {
+ auto nValue = m_xCharsPerLineNF->get_value();
+ assert(nValue && "div-by-zero");
+ auto nWidth = m_aPageSize.Width() / nValue;
+ m_xTextSizeMF->set_value(m_xTextSizeMF->normalize(nWidth), FieldUnit::TWIP);
+ //prevent rounding errors in the MetricField by saving the used value
+ m_nRubyUserValue = nWidth;
+ m_bRubyUserValue = true;
+
+ }
+ //set maximum line per page
+ {
+ sal_Int32 nMaxLines = static_cast< sal_Int32 >(m_aPageSize.Height() /
+ ( m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP)) +
+ m_xRubySizeMF->denormalize(m_xRubySizeMF->get_value(FieldUnit::TWIP))));
+ m_xLinesPerPageNF->set_max(nMaxLines);
+ m_xLinesPerPageNF->set_sensitive(nMaxLines != 0);
+ }
+ SetLinesOrCharsRanges( *m_xLinesRangeFT , m_xLinesPerPageNF->get_max() );
+ SetLinesOrCharsRanges( *m_xCharsRangeFT , m_xCharsPerLineNF->get_max() );
+ }
+ else//in normal mode
+ {
+ if (m_xLinesPerPageNF.get() == &rField)
+ {
+ auto nValue = m_xLinesPerPageNF->get_value();
+ assert(nValue && "div-by-zero");
+ auto nHeight = m_aPageSize.Height() / nValue;
+ m_xTextSizeMF->set_value(m_xTextSizeMF->normalize(nHeight), FieldUnit::TWIP);
+ SetLinesOrCharsRanges( *m_xLinesRangeFT , m_xLinesPerPageNF->get_max() );
+
+ m_nRubyUserValue = nHeight;
+ m_bRubyUserValue = true;
+ }
+ else if (m_xCharsPerLineNF.get() == &rField)
+ {
+ auto nValue = m_xCharsPerLineNF->get_value();
+ assert(nValue && "div-by-zero");
+ auto nWidth = m_aPageSize.Width() / nValue;
+ m_xCharWidthMF->set_value(m_xCharWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ SetLinesOrCharsRanges( *m_xCharsRangeFT , m_xCharsPerLineNF->get_max() );
+ }
+ }
+ GridModifyHdl();
+}
+
+IMPL_LINK(SwTextGridPage, TextSizeChangedHdl, weld::MetricSpinButton&, rField, void)
+{
+ //if in squared mode
+ if( m_bSquaredMode )
+ {
+ if (m_xTextSizeMF.get() == &rField)
+ {
+ m_bRubyUserValue = false;
+
+ // fdo#50941: set maximum characters per line
+ sal_Int32 nTextSize = static_cast< sal_Int32 >(m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP)));
+ if (nTextSize > 0)
+ {
+ sal_Int32 nMaxChars = m_aPageSize.Width() / nTextSize;
+ m_xCharsPerLineNF->set_value(nMaxChars);
+ m_xCharsPerLineNF->set_max(nMaxChars);
+ m_xCharsPerLineNF->set_sensitive(nMaxChars != 0);
+ SetLinesOrCharsRanges( *m_xCharsRangeFT , m_xCharsPerLineNF->get_max() );
+ }
+ }
+ //set maximum line per page
+ {
+ sal_Int32 nMaxLines = static_cast< sal_Int32 >(m_aPageSize.Height() /
+ ( m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP)) +
+ m_xRubySizeMF->denormalize(m_xRubySizeMF->get_value(FieldUnit::TWIP))));
+ m_xLinesPerPageNF->set_max(nMaxLines);
+ m_xLinesPerPageNF->set_sensitive(nMaxLines != 0);
+ SetLinesOrCharsRanges( *m_xLinesRangeFT , m_xLinesPerPageNF->get_max() );
+ }
+ }
+ else
+ {
+ if (m_xTextSizeMF.get() == &rField)
+ {
+ sal_Int32 nTextSize = static_cast< sal_Int32 >(m_xTextSizeMF->denormalize(m_xTextSizeMF->get_value(FieldUnit::TWIP)));
+ m_xLinesPerPageNF->set_value(m_aPageSize.Height() / nTextSize);
+ m_bRubyUserValue = false;
+ SetLinesOrCharsRanges( *m_xLinesRangeFT , m_xLinesPerPageNF->get_max() );
+ }
+ else if (m_xCharWidthMF.get() == &rField)
+ {
+ sal_Int32 nTextWidth = static_cast< sal_Int32 >(m_xCharWidthMF->denormalize(m_xCharWidthMF->get_value(FieldUnit::TWIP)));
+ sal_Int32 nMaxChar = 45 ;
+ if (nTextWidth)
+ nMaxChar = m_aPageSize.Width() / nTextWidth;
+ m_xCharsPerLineNF->set_value( nMaxChar );
+ SetLinesOrCharsRanges( *m_xCharsRangeFT , m_xCharsPerLineNF->get_max() );
+ }
+ //rubySize is disabled
+ }
+ GridModifyHdl();
+}
+
+IMPL_LINK(SwTextGridPage, GridTypeHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+
+ if (m_xNoGridRB.get() == &rButton)
+ {
+ // GRID_NONE mode:
+ // "Layout" and "Display" sections should all be disabled.
+ m_xLayoutFL->set_sensitive(false);
+ m_xDisplayFL->set_sensitive(false);
+ }
+ else
+ {
+ // GRID_LINES_ONLY or GRID_LINES_CHARS mode:
+ // "Layout" and "Display" sections should all be enabled;
+ // DisplayGridHdl should be executed;
+ m_xLayoutFL->set_sensitive(true);
+ m_xDisplayFL->set_sensitive(true);
+ DisplayGridHdl(*m_xDisplayCB);
+ }
+
+ if (m_xCharsGridRB.get() == &rButton)
+ {
+ // GRID_LINES_CHARS mode:
+ // "Snap to character" should be enabled;
+ // "Characters per line" should be enabled;
+ // "Characters range" should be enabled;
+ m_xSnapToCharsCB->set_sensitive(true);
+ m_xCharsPerLineFT->set_sensitive(true);
+ m_xCharsPerLineNF->set_sensitive(true);
+ m_xCharsRangeFT->set_sensitive(true);
+ m_xCharWidthFT->set_sensitive(true);
+ m_xCharWidthMF->set_sensitive(true);
+ }
+ else
+ {
+ // GRID_NONE or GRID_LINES_ONLY mode:
+ // "Snap to character" should be disabled;
+ // "Characters per line" should be disabled;
+ // "Characters range" should be disabled;
+ m_xSnapToCharsCB->set_sensitive(false);
+ m_xCharsPerLineFT->set_sensitive(false);
+ m_xCharsPerLineNF->set_sensitive(false);
+ m_xCharsRangeFT->set_sensitive(false);
+ m_xCharWidthFT->set_sensitive(false);
+ m_xCharWidthMF->set_sensitive(false);
+ }
+
+ if (m_xNoGridRB.get() != &rButton)
+ {
+ // GRID_LINES_ONLY or GRID_LINES_CHARS mode: (additionally)
+ // TextSizeChangedHdl should be executed to recalculate which dependencies are sensitive.
+ TextSizeChangedHdl(*m_xTextSizeMF);
+ }
+
+ GridModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwTextGridPage, DisplayGridHdl, weld::Toggleable&, void)
+{
+ bool bChecked = m_xDisplayCB->get_active();
+ m_xPrintCB->set_sensitive(bChecked);
+ m_xPrintCB->set_active(bChecked);
+}
+
+IMPL_LINK_NOARG(SwTextGridPage, GridModifyClickHdl, weld::Toggleable&, void)
+{
+ GridModifyHdl();
+}
+
+IMPL_LINK_NOARG(SwTextGridPage, ColorModifyHdl, ColorListBox&, void)
+{
+ GridModifyHdl();
+}
+
+void SwTextGridPage::GridModifyHdl()
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+ SfxItemSet aSet(rOldSet);
+ const SfxItemSet* pExSet = GetDialogExampleSet();
+ if(pExSet)
+ aSet.Put(*pExSet);
+ PutGridItem(aSet);
+ m_aExampleWN.UpdateExample(aSet);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/srtdlg.cxx b/sw/source/ui/misc/srtdlg.cxx
new file mode 100644
index 0000000000..cd45654b8d
--- /dev/null
+++ b/sw/source/ui/misc/srtdlg.cxx
@@ -0,0 +1,428 @@
+/* -*- 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 <srtdlg.hxx>
+
+#include <editeng/editids.hrc>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/intitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <svtools/collatorres.hxx>
+#include <swwait.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <strings.hrc>
+#include <swtable.hxx>
+#include <sortopt.hxx>
+#include <node.hxx>
+#include <tblsel.hxx>
+#include <memory>
+
+static bool bCheck1 = true;
+static bool bCheck2 = false;
+static bool bCheck3 = false;
+
+static sal_uInt16 nCol1 = 1;
+static sal_uInt16 nCol2 = 1;
+static sal_uInt16 nCol3 = 1;
+
+static sal_uInt16 nType1 = 0;
+static sal_uInt16 nType2 = 0;
+static sal_uInt16 nType3 = 0;
+
+static LanguageType nLang = LANGUAGE_NONE;
+
+static bool bAsc1 = true;
+static bool bAsc2 = true;
+static bool bAsc3 = true;
+static bool bCol = false;
+static bool bCsSens= false;
+
+static sal_Unicode cDeli = '\t';
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+// determine lines and columns for table selection
+static bool lcl_GetSelTable( SwWrtShell const &rSh, sal_uInt16& rX, sal_uInt16& rY )
+{
+ const SwTableNode* pTableNd = rSh.IsCursorInTable();
+ if( !pTableNd )
+ return false;
+
+ FndBox_ aFndBox( nullptr, nullptr );
+
+ // look for all boxes / lines
+ {
+ SwSelBoxes aSelBoxes;
+ ::GetTableSel( rSh, aSelBoxes );
+ FndPara aPara( aSelBoxes, &aFndBox );
+ const SwTable& rTable = pTableNd->GetTable();
+ ForEach_FndLineCopyCol( const_cast<SwTableLines&>(rTable.GetTabLines()), &aPara );
+ }
+ rX = aFndBox.GetLines().size();
+ if( !rX )
+ return false;
+
+ rY = aFndBox.GetLines().front()->GetBoxes().size();
+ return true;
+}
+
+// init list
+SwSortDlg::SwSortDlg(weld::Window* pParent, SwWrtShell &rShell)
+ : GenericDialogController(pParent, "modules/swriter/ui/sortdialog.ui", "SortDialog")
+ , m_pParent(pParent)
+ , m_xColLbl(m_xBuilder->weld_label("column"))
+ , m_xKeyCB1(m_xBuilder->weld_check_button("key1"))
+ , m_xColEdt1(m_xBuilder->weld_spin_button("colsb1"))
+ , m_xTypDLB1(m_xBuilder->weld_combo_box("typelb1"))
+ , m_xSortUp1RB(m_xBuilder->weld_radio_button("up1"))
+ , m_xSortDn1RB(m_xBuilder->weld_radio_button("down1"))
+ , m_xKeyCB2(m_xBuilder->weld_check_button("key2"))
+ , m_xColEdt2(m_xBuilder->weld_spin_button("colsb2"))
+ , m_xTypDLB2(m_xBuilder->weld_combo_box("typelb2"))
+ , m_xSortUp2RB(m_xBuilder->weld_radio_button("up2"))
+ , m_xSortDn2RB(m_xBuilder->weld_radio_button("down2"))
+ , m_xKeyCB3(m_xBuilder->weld_check_button("key3"))
+ , m_xColEdt3(m_xBuilder->weld_spin_button("colsb3"))
+ , m_xTypDLB3(m_xBuilder->weld_combo_box("typelb3"))
+ , m_xSortUp3RB(m_xBuilder->weld_radio_button("up3"))
+ , m_xSortDn3RB(m_xBuilder->weld_radio_button("down3"))
+ , m_xColumnRB(m_xBuilder->weld_radio_button("columns"))
+ , m_xRowRB(m_xBuilder->weld_radio_button("rows"))
+ , m_xDelimTabRB(m_xBuilder->weld_radio_button("tabs"))
+ , m_xDelimFreeRB(m_xBuilder->weld_radio_button("character"))
+ , m_xDelimEdt(m_xBuilder->weld_entry("separator"))
+ , m_xDelimPB(m_xBuilder->weld_button("delimpb"))
+ , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("langlb")))
+ , m_xCaseCB(m_xBuilder->weld_check_button("matchcase"))
+ , m_aColText(SwResId(STR_COL))
+ , m_aRowText(SwResId(STR_ROW))
+ , m_aNumericText(SwResId(STR_NUMERIC))
+ , m_rSh(rShell)
+ , m_nX(99)
+ , m_nY(99)
+{
+ if(m_rSh.GetSelectionType() &
+ (SelectionType::Table|SelectionType::TableCell) )
+ {
+ m_xColumnRB->set_active(bCol);
+ m_xColLbl->set_label(bCol ? m_aRowText : m_aColText);
+ m_xRowRB->set_active(!bCol);
+ m_xDelimTabRB->set_sensitive(false);
+ m_xDelimFreeRB->set_sensitive(false);
+ m_xDelimEdt->set_sensitive(false);
+ }
+ else
+ {
+ m_xColumnRB->set_sensitive(false);
+ m_xRowRB->set_active(true);
+ m_xColLbl->set_label(m_aColText);
+ }
+
+ // Set accessible names here because text of m_xColLbl may be changed
+ // by the if-else block above
+ m_xColEdt1->set_accessible_name(m_xColLbl->get_label());
+ m_xColEdt2->set_accessible_name(m_xColLbl->get_label());
+ m_xColEdt3->set_accessible_name(m_xColLbl->get_label());
+
+ // initialise
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwSortDlg, CheckHdl);
+ m_xKeyCB1->connect_toggled( aLk );
+ m_xKeyCB2->connect_toggled( aLk );
+ m_xKeyCB3->connect_toggled( aLk );
+ m_xColumnRB->connect_toggled( aLk );
+ m_xRowRB->connect_toggled( aLk );
+
+ aLk = LINK(this, SwSortDlg, DelimHdl);
+ m_xDelimFreeRB->connect_toggled(aLk);
+ m_xDelimTabRB->connect_toggled(aLk);
+
+ m_xDelimPB->connect_clicked( LINK( this, SwSortDlg, DelimCharHdl ));
+
+ m_xKeyCB1->set_active(bCheck1);
+ m_xKeyCB2->set_active(bCheck2);
+ m_xKeyCB3->set_active(bCheck3);
+
+ m_xColEdt1->set_value(nCol1);
+ m_xColEdt2->set_value(nCol2);
+ m_xColEdt3->set_value(nCol3);
+
+ // first initialise the language, then select the
+ if( LANGUAGE_NONE == nLang || LANGUAGE_DONTKNOW == nLang )
+ nLang = GetAppLanguage();
+
+ m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, true );
+ m_xLangLB->set_active_id(nLang);
+
+ LanguageHdl( nullptr );
+ m_xLangLB->connect_changed( LINK( this, SwSortDlg, LanguageListBoxHdl ));
+
+ m_xSortUp1RB->set_active(bAsc1);
+ m_xSortDn1RB->set_active(!bAsc1);
+ m_xSortUp2RB->set_active(bAsc2);
+ m_xSortDn2RB->set_active(!bAsc2);
+ m_xSortUp3RB->set_active(bAsc3);
+ m_xSortDn3RB->set_active(!bAsc3);
+
+ m_xCaseCB->set_active( bCsSens );
+
+ m_xDelimTabRB->set_active(cDeli == '\t');
+ if(!m_xDelimTabRB->get_active())
+ {
+ m_xDelimEdt->set_text(OUString(cDeli));
+ m_xDelimFreeRB->set_active(true);
+ DelimHdl(*m_xDelimFreeRB);
+ }
+ else
+ DelimHdl(*m_xDelimTabRB);
+
+ if( ::lcl_GetSelTable( m_rSh, m_nX, m_nY) )
+ {
+ sal_uInt16 nMax = m_xRowRB->get_active()? m_nY : m_nX;
+ m_xColEdt1->set_max(nMax);
+ m_xColEdt2->set_max(nMax);
+ m_xColEdt3->set_max(nMax);
+ }
+}
+
+sal_Unicode SwSortDlg::GetDelimChar() const
+{
+ sal_Unicode cRet = '\t';
+ if( !m_xDelimTabRB->get_active() )
+ {
+ OUString aTmp(m_xDelimEdt->get_text());
+ if( !aTmp.isEmpty() )
+ cRet = aTmp[0];
+ }
+ return cRet;
+}
+
+short SwSortDlg::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+// pass on to the Core
+void SwSortDlg::Apply()
+{
+ // save all settings
+ bCheck1 = m_xKeyCB1->get_active();
+ bCheck2 = m_xKeyCB2->get_active();
+ bCheck3 = m_xKeyCB3->get_active();
+
+ nCol1 = m_xColEdt1->get_value();
+ nCol2 = m_xColEdt2->get_value();
+ nCol3 = m_xColEdt3->get_value();
+
+ nType1 = m_xTypDLB1->get_active();
+ nType2 = m_xTypDLB2->get_active();
+ nType3 = m_xTypDLB3->get_active();
+
+ bAsc1 = m_xSortUp1RB->get_active();
+ bAsc2 = m_xSortUp2RB->get_active();
+ bAsc3 = m_xSortUp3RB->get_active();
+ bCol = m_xColumnRB->get_active();
+ nLang = m_xLangLB->get_active_id();
+ cDeli = GetDelimChar();
+ bCsSens = m_xCaseCB->get_active();
+
+ SwSortOptions aOptions;
+ if( bCheck1 )
+ {
+ OUString sEntry( m_xTypDLB1->get_active_text() );
+ if( sEntry == m_aNumericText )
+ sEntry.clear();
+ else if (!m_xTypDLB1->get_active_id().isEmpty())
+ sEntry = m_xTypDLB1->get_active_id();
+
+ aOptions.aKeys.push_back(
+ SwSortKey( nCol1, sEntry,
+ bAsc1 ? SwSortOrder::Ascending : SwSortOrder::Descending ));
+ }
+
+ if( bCheck2 )
+ {
+ OUString sEntry( m_xTypDLB2->get_active_text() );
+ if( sEntry == m_aNumericText )
+ sEntry.clear();
+ else if (!m_xTypDLB2->get_active_id().isEmpty())
+ sEntry = m_xTypDLB2->get_active_id();
+
+ aOptions.aKeys.push_back(
+ SwSortKey( nCol2, sEntry,
+ bAsc2 ? SwSortOrder::Ascending : SwSortOrder::Descending ));
+ }
+
+ if( bCheck3 )
+ {
+ OUString sEntry( m_xTypDLB3->get_active_text() );
+ if( sEntry == m_aNumericText )
+ sEntry.clear();
+ else if (!m_xTypDLB3->get_active_id().isEmpty())
+ sEntry = m_xTypDLB3->get_active_id();
+
+ aOptions.aKeys.push_back(
+ SwSortKey( nCol3, sEntry,
+ bAsc3 ? SwSortOrder::Ascending : SwSortOrder::Descending ));
+ }
+
+ aOptions.eDirection = bCol ? SwSortDirection::Columns : SwSortDirection::Rows;
+ aOptions.cDeli = cDeli;
+ aOptions.nLanguage = nLang;
+ aOptions.bTable = m_rSh.IsTableMode();
+ aOptions.bIgnoreCase = !bCsSens;
+
+ bool bRet;
+ {
+ SwWait aWait( *m_rSh.GetView().GetDocShell(), true );
+ m_rSh.StartAllAction();
+ bRet = m_rSh.Sort( aOptions );
+ if( bRet )
+ m_rSh.SetModified();
+ m_rSh.EndAllAction();
+ }
+
+ if (!bRet)
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_pParent,
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_SRTERR)));
+ xInfoBox->run();
+ }
+}
+
+IMPL_LINK( SwSortDlg, DelimHdl, weld::Toggleable&, rButton, void )
+{
+ bool bEnable = &rButton == m_xDelimFreeRB.get() && m_xDelimFreeRB->get_sensitive();
+ m_xDelimEdt->set_sensitive( bEnable );
+ m_xDelimPB->set_sensitive( bEnable );
+}
+
+IMPL_LINK_NOARG(SwSortDlg, DelimCharHdl, weld::Button&, void)
+{
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAllItemSet aSet( m_rSh.GetAttrPool() );
+ aSet.Put( SfxInt32Item( SID_ATTR_CHAR, GetDelimChar() ) );
+ ScopedVclPtr<SfxAbstractDialog> pMap(pFact->CreateCharMapDialog(m_xDialog.get(), aSet, nullptr));
+ if( RET_OK == pMap->Execute() )
+ {
+ const SfxInt32Item* pItem = SfxItemSet::GetItem<SfxInt32Item>(pMap->GetOutputItemSet(), SID_ATTR_CHAR, false);
+ if ( pItem )
+ m_xDelimEdt->set_text(OUString(sal_Unicode(pItem->GetValue())));
+ }
+}
+
+IMPL_LINK( SwSortDlg, CheckHdl, weld::Toggleable&, rControl, void )
+{
+ if (&rControl == m_xRowRB.get())
+ {
+ m_xColLbl->set_label(m_aColText);
+ m_xColEdt1->set_max(m_nY);
+ m_xColEdt2->set_max(m_nY);
+ m_xColEdt3->set_max(m_nY);
+
+ m_xColEdt1->set_accessible_name(m_aColText);
+ m_xColEdt2->set_accessible_name(m_aColText);
+ m_xColEdt3->set_accessible_name(m_aColText);
+ }
+ else if (&rControl == m_xColumnRB.get())
+ {
+ m_xColLbl->set_label(m_aRowText);
+ m_xColEdt1->set_max(m_nX);
+ m_xColEdt2->set_max(m_nX);
+ m_xColEdt3->set_max(m_nX);
+
+ m_xColEdt1->set_accessible_name(m_aRowText);
+ m_xColEdt2->set_accessible_name(m_aRowText);
+ m_xColEdt3->set_accessible_name(m_aRowText);
+ }
+ else if(!m_xKeyCB1->get_active() &&
+ !m_xKeyCB2->get_active() &&
+ !m_xKeyCB3->get_active())
+ {
+ rControl.set_active(true);
+ }
+}
+
+IMPL_LINK( SwSortDlg, LanguageListBoxHdl, weld::ComboBox&, rLBox, void )
+{
+ LanguageHdl(&rLBox);
+}
+
+void SwSortDlg::LanguageHdl(weld::ComboBox const* pLBox)
+{
+ Sequence < OUString > aSeq( GetAppCollator().listCollatorAlgorithms(
+ LanguageTag( m_xLangLB->get_active_id()).getLocale() ));
+
+ if (!m_xColRes)
+ m_xColRes.reset(new CollatorResource);
+
+ const int nLstBoxCnt = 3;
+ weld::ComboBox* aLstArr[ nLstBoxCnt ] = { m_xTypDLB1.get(), m_xTypDLB2.get(), m_xTypDLB3.get() };
+ sal_uInt16* const aTypeArr[ nLstBoxCnt ] = { &nType1, &nType2, &nType3 };
+ OUString aOldStrArr[ nLstBoxCnt ];
+
+ for( int n = 0; n < nLstBoxCnt; ++n )
+ {
+ weld::ComboBox* pL = aLstArr[ n ];
+ OUString sUserData = pL->get_active_id();
+ if (!sUserData.isEmpty())
+ aOldStrArr[ n ] = sUserData;
+ pL->clear();
+ }
+
+ OUString sAlg, sUINm;
+ const sal_Int32 nEnd = aSeq.getLength();
+ for( sal_Int32 nCnt = 0; nCnt <= nEnd; ++nCnt )
+ {
+ if( nCnt < nEnd )
+ {
+ sAlg = aSeq[ nCnt ];
+ sUINm = m_xColRes->GetTranslation( sAlg );
+ }
+ else
+ sUINm = sAlg = m_aNumericText;
+
+ for( int n = 0; n < nLstBoxCnt; ++n )
+ {
+ weld::ComboBox* pL = aLstArr[ n ];
+ pL->append(sAlg, sUINm);
+ if (pLBox && sAlg == aOldStrArr[n])
+ pL->set_active_id(sAlg);
+ }
+ }
+
+ for( int n = 0; n < nLstBoxCnt; ++n )
+ {
+ weld::ComboBox* pL = aLstArr[ n ];
+ if( !pLBox )
+ pL->set_active(*aTypeArr[n]);
+ else if (pL->get_active() == -1)
+ pL->set_active(0);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/swmodalredlineacceptdlg.cxx b/sw/source/ui/misc/swmodalredlineacceptdlg.cxx
new file mode 100644
index 0000000000..8bc8baf755
--- /dev/null
+++ b/sw/source/ui/misc/swmodalredlineacceptdlg.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 <svx/ctredlin.hxx>
+#include <unotools/viewoptions.hxx>
+
+#include <redlndlg.hxx>
+#include <swmodalredlineacceptdlg.hxx>
+
+SwModalRedlineAcceptDlg::SwModalRedlineAcceptDlg(weld::Window *pParent)
+ : SfxDialogController(pParent, "svx/ui/acceptrejectchangesdialog.ui",
+ "AcceptRejectChangesDialog")
+ , m_xContentArea(m_xDialog->weld_content_area())
+{
+ m_xDialog->set_modal(true);
+
+ m_xImplDlg.reset(new SwRedlineAcceptDlg(m_xDialog, m_xBuilder.get(), m_xContentArea.get(), true));
+
+ SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
+ if (aDlgOpt.Exists())
+ {
+ css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem");
+ OUString sExtraData;
+ aUserItem >>= sExtraData;
+ m_xImplDlg->Initialize(sExtraData);
+ }
+ m_xImplDlg->Activate(); // for data's initialisation
+}
+
+SwModalRedlineAcceptDlg::~SwModalRedlineAcceptDlg()
+{
+ AcceptAll(false); // refuse everything remaining
+
+ OUString sExtraData;
+ m_xImplDlg->FillInfo(sExtraData);
+ SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
+ aDlgOpt.SetUserItem("UserItem", css::uno::Any(sExtraData));
+
+ m_xDialog->set_modal(false);
+}
+
+void SwModalRedlineAcceptDlg::Activate()
+{
+}
+
+void SwModalRedlineAcceptDlg::AcceptAll( bool bAccept )
+{
+ SvxTPFilter* pFilterTP = m_xImplDlg->GetChgCtrl().GetFilterPage();
+
+ if (pFilterTP->IsDate() || pFilterTP->IsAuthor() ||
+ pFilterTP->IsRange() || pFilterTP->IsAction())
+ {
+ pFilterTP->CheckDate(false); // turn off all filters
+ pFilterTP->CheckAuthor(false);
+ pFilterTP->CheckRange(false);
+ pFilterTP->CheckAction(false);
+ m_xImplDlg->FilterChangedHdl(nullptr);
+ }
+
+ m_xImplDlg->CallAcceptReject( false, bAccept );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/titlepage.cxx b/sw/source/ui/misc/titlepage.cxx
new file mode 100644
index 0000000000..0d8c776cce
--- /dev/null
+++ b/sw/source/ui/misc/titlepage.cxx
@@ -0,0 +1,335 @@
+/* -*- 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 <view.hxx>
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <poolfmt.hxx>
+#include <docsh.hxx>
+
+#include <titlepage.hxx>
+#include <fmtpdsc.hxx>
+#include <pagedesc.hxx>
+
+namespace
+{
+ bool lcl_GetPageDesc(SwWrtShell& rSh, sal_uInt16 &rPageNo, std::unique_ptr<const SwFormatPageDesc>* ppPageFormatDesc)
+ {
+ bool bRet = false;
+ SfxItemSetFixed<RES_PAGEDESC, RES_PAGEDESC> aSet(rSh.GetAttrPool());
+ if (rSh.GetCurAttr(aSet))
+ {
+ if (const SwFormatPageDesc* pDescItem = aSet.GetItemIfSet( RES_PAGEDESC ))
+ {
+ ::std::optional<sal_uInt16> oNumOffset = pDescItem->GetNumOffset();
+ if (oNumOffset)
+ rPageNo = *oNumOffset;
+ if (ppPageFormatDesc)
+ ppPageFormatDesc->reset(static_cast<const SwFormatPageDesc *>(pDescItem->Clone()));
+ bRet = true;
+ }
+ }
+ return bRet;
+ }
+
+ void lcl_ChangePage(SwWrtShell& rSh, sal_uInt16 nNewNumber, const SwPageDesc *pNewDesc)
+ {
+ const size_t nCurIdx = rSh.GetCurPageDesc();
+ const SwPageDesc &rCurrentDesc = rSh.GetPageDesc(nCurIdx);
+
+ std::unique_ptr<const SwFormatPageDesc> pPageFormatDesc;
+ sal_uInt16 nDontCare;
+ lcl_GetPageDesc(rSh, nDontCare, &pPageFormatDesc);
+
+ // If we want a new number then set it, otherwise reuse the existing one
+ sal_uInt16 nPgNo = 0;
+ if (nNewNumber)
+ {
+ // -1: Allow special case to prevent inheriting re-numbering from the existing page.
+ nPgNo = nNewNumber == SAL_MAX_UINT16 ? 0 : nNewNumber;
+ }
+ else if (pPageFormatDesc)
+ {
+ ::std::optional<sal_uInt16> oNumOffset = pPageFormatDesc->GetNumOffset();
+ if (oNumOffset)
+ nPgNo = *oNumOffset;
+ }
+
+ // If we want a new descriptor then set it, otherwise reuse the existing one
+ if (pNewDesc || nPgNo)
+ {
+ SwFormatPageDesc aPageFormatDesc(pNewDesc ? pNewDesc : &rCurrentDesc);
+ if (nPgNo) aPageFormatDesc.SetNumOffset(nPgNo);
+ rSh.SetAttrItem(aPageFormatDesc);
+ }
+ }
+
+ void lcl_PushCursor(SwWrtShell& rSh)
+ {
+ rSh.LockView(true);
+ rSh.StartAllAction();
+ rSh.SwCursorShell::Push();
+ }
+
+ void lcl_PopCursor(SwWrtShell& rSh)
+ {
+ rSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
+ rSh.EndAllAction();
+ rSh.LockView(false);
+ }
+
+ sal_uInt16 lcl_GetCurrentPage(const SwWrtShell& rSh)
+ {
+ OUString sDummy;
+ sal_uInt16 nPhyNum=1, nVirtNum=1;
+ rSh.GetPageNumber(0, true, nPhyNum, nVirtNum, sDummy);
+ return nPhyNum;
+ }
+
+bool lcl_GotoPage(SwWrtShell& rSh, const sal_uInt16 nStartingPage, sal_uInt16 nOffset = 0)
+{
+ rSh.GotoPage(nStartingPage, /*bRecord=*/false);
+
+ sal_uInt16 nCurrentPage = lcl_GetCurrentPage(rSh);
+ // return false if at document end (unless that was the requested destination)
+ if (nCurrentPage == rSh.GetPageCnt())
+ return nCurrentPage == nStartingPage + nOffset;
+
+ if (nCurrentPage != nStartingPage)
+ {
+ assert(nStartingPage != 1 && "Physical page 1 couldn't be found/moved to?");
+ // Probably there is an auto-inserted blank page to handle odd/even, which Goto doesn't understand.
+ rSh.GotoPage(nStartingPage + 1, /*bRecord=*/false);
+
+ nCurrentPage = lcl_GetCurrentPage(rSh);
+ assert(nCurrentPage == nStartingPage + 1 && "Impossible, since unknown goes to last page");
+ if (nCurrentPage != nStartingPage + 1)
+ return false;
+ }
+ // Now that we have the correct starting point, move to the correct offset.
+ while (nOffset--)
+ rSh.SttNxtPg();
+ return true;
+}
+} // namespace
+
+/*
+ * Only include the Index page in the list if the page count implies one
+ * to reduce confusing things
+ */
+void SwTitlePageDlg::FillList()
+{
+ sal_uInt16 nTitlePages = m_xPageCountNF->get_value();
+ m_xPagePropertiesLB->clear();
+ if (mpTitleDesc)
+ m_xPagePropertiesLB->append_text(mpTitleDesc->GetName());
+ if (nTitlePages > 1 && mpIndexDesc)
+ m_xPagePropertiesLB->append_text(mpIndexDesc->GetName());
+ if (mpNormalDesc)
+ m_xPagePropertiesLB->append_text(mpNormalDesc->GetName());
+ m_xPagePropertiesLB->set_active(0);
+}
+
+sal_uInt16 SwTitlePageDlg::GetInsertPosition() const
+{
+ sal_uInt16 nPage = 1;
+ if (m_xPageStartNF->get_sensitive())
+ nPage = m_xPageStartNF->get_value();
+ return nPage;
+}
+
+SwTitlePageDlg::SwTitlePageDlg(weld::Window *pParent)
+ : SfxDialogController(pParent, "modules/swriter/ui/titlepage.ui", "DLG_TITLEPAGE")
+ , mpTitleDesc(nullptr)
+ , mpIndexDesc(nullptr)
+ , mpNormalDesc(nullptr)
+ , m_xUseExistingPagesRB(m_xBuilder->weld_radio_button("RB_USE_EXISTING_PAGES"))
+ , m_xInsertNewPagesRB(m_xBuilder->weld_radio_button("RB_INSERT_NEW_PAGES"))
+ , m_xPageCountNF(m_xBuilder->weld_spin_button("NF_PAGE_COUNT"))
+ , m_xDocumentStartRB(m_xBuilder->weld_radio_button("RB_DOCUMENT_START"))
+ , m_xPageStartRB(m_xBuilder->weld_radio_button("RB_PAGE_START"))
+ , m_xPageStartNF(m_xBuilder->weld_spin_button("NF_PAGE_START"))
+ , m_xRestartNumberingCB(m_xBuilder->weld_check_button("CB_RESTART_NUMBERING"))
+ , m_xRestartNumberingNF(m_xBuilder->weld_spin_button("NF_RESTART_NUMBERING"))
+ , m_xSetPageNumberCB(m_xBuilder->weld_check_button("CB_SET_PAGE_NUMBER"))
+ , m_xSetPageNumberNF(m_xBuilder->weld_spin_button("NF_SET_PAGE_NUMBER"))
+ , m_xPagePropertiesLB(m_xBuilder->weld_combo_box("LB_PAGE_PROPERTIES"))
+ , m_xPagePropertiesPB(m_xBuilder->weld_button("PB_PAGE_PROPERTIES"))
+ , m_xOkPB(m_xBuilder->weld_button("ok"))
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+
+ m_xOkPB->connect_clicked(LINK(this, SwTitlePageDlg, OKHdl));
+ m_xRestartNumberingCB->connect_toggled(LINK(this, SwTitlePageDlg, RestartNumberingHdl));
+ m_xSetPageNumberCB->connect_toggled(LINK(this, SwTitlePageDlg, SetPageNumberHdl));
+ m_xPageStartNF->set_max(rWrtShell.GetPageCnt() + 1);
+
+ sal_uInt16 nSetPage = 1;
+ sal_uInt16 nResetPage = 1;
+ sal_uInt16 nTitlePages = 1;
+ lcl_PushCursor(rWrtShell);
+
+ SwView& rView = rWrtShell.GetView();
+ rView.InvalidateRulerPos();
+
+ bool bMaybeResetNumbering = false;
+
+ mpTitleDesc = rWrtShell.GetPageDescFromPool(RES_POOLPAGE_FIRST);
+ mpIndexDesc = rWrtShell.GetPageDescFromPool(RES_POOLPAGE_REGISTER);
+ mpNormalDesc = rWrtShell.GetPageDescFromPool(RES_POOLPAGE_STANDARD);
+
+ rWrtShell.StartOfSection();
+ if (lcl_GetPageDesc(rWrtShell, nSetPage, &mpPageFormatDesc))
+ {
+ if (mpPageFormatDesc->GetPageDesc() == mpTitleDesc)
+ {
+ while (rWrtShell.SttNxtPg())
+ {
+ const size_t nCurIdx = rWrtShell.GetCurPageDesc();
+ const SwPageDesc& rPageDesc = rWrtShell.GetPageDesc(nCurIdx);
+
+ if (mpIndexDesc != &rPageDesc)
+ {
+ mpNormalDesc = &rPageDesc;
+ bMaybeResetNumbering = lcl_GetPageDesc(rWrtShell, nResetPage, nullptr);
+ break;
+ }
+ ++nTitlePages;
+ }
+ }
+ }
+ lcl_PopCursor(rWrtShell);
+
+ m_xUseExistingPagesRB->set_active(true);
+ m_xPageCountNF->set_value(nTitlePages);
+ m_xPageCountNF->connect_value_changed(LINK(this, SwTitlePageDlg, ValueChangeHdl));
+
+ m_xDocumentStartRB->set_active(true);
+ m_xPageStartNF->set_sensitive(false);
+ m_xPageStartNF->set_value(lcl_GetCurrentPage(rWrtShell));
+ Link<weld::Toggleable&,void> aStartPageHdl = LINK(this, SwTitlePageDlg, StartPageHdl);
+ m_xDocumentStartRB->connect_toggled(aStartPageHdl);
+ m_xPageStartRB->connect_toggled(aStartPageHdl);
+
+ m_xRestartNumberingNF->set_value(nResetPage);
+ if (bMaybeResetNumbering && nResetPage > 0)
+ {
+ m_xRestartNumberingCB->set_active(true);
+ }
+ m_xRestartNumberingNF->set_sensitive(m_xRestartNumberingCB->get_active());
+
+ m_xSetPageNumberNF->set_value(nSetPage);
+ if (nSetPage > 1)
+ m_xSetPageNumberCB->set_active(true);
+ m_xSetPageNumberNF->set_sensitive(m_xSetPageNumberCB->get_active());
+
+ FillList();
+ m_xPagePropertiesPB->connect_clicked(LINK(this, SwTitlePageDlg, EditHdl));
+}
+
+IMPL_LINK_NOARG(SwTitlePageDlg, ValueChangeHdl, weld::SpinButton&, void)
+{
+ if (m_xPageCountNF->get_value() == 1 || m_xPageCountNF->get_value() == 2)
+ FillList();
+}
+
+IMPL_LINK_NOARG(SwTitlePageDlg, RestartNumberingHdl, weld::Toggleable&, void)
+{
+ m_xRestartNumberingNF->set_sensitive(m_xRestartNumberingCB->get_active());
+}
+
+IMPL_LINK_NOARG(SwTitlePageDlg, SetPageNumberHdl, weld::Toggleable&, void)
+{
+ m_xSetPageNumberNF->set_sensitive(m_xSetPageNumberCB->get_active());
+}
+
+IMPL_LINK_NOARG(SwTitlePageDlg, StartPageHdl, weld::Toggleable&, void)
+{
+ m_xPageStartNF->set_sensitive(m_xPageStartRB->get_active());
+}
+
+SwTitlePageDlg::~SwTitlePageDlg()
+{
+}
+
+IMPL_LINK_NOARG(SwTitlePageDlg, EditHdl, weld::Button&, void)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+ SwView& rView = rWrtShell.GetView();
+ rView.GetDocShell()->FormatPage(getDialog(), m_xPagePropertiesLB->get_active_text(), "page", rWrtShell);
+ rView.InvalidateRulerPos();
+}
+
+IMPL_LINK_NOARG(SwTitlePageDlg, OKHdl, weld::Button&, void)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+ SwWrtShell& rWrtShell = pView->GetWrtShell();
+ lcl_PushCursor(rWrtShell);
+
+ rWrtShell.StartUndo();
+
+ SwFormatPageDesc aTitleDesc(mpTitleDesc);
+
+ if (m_xSetPageNumberCB->get_active())
+ aTitleDesc.SetNumOffset(m_xSetPageNumberNF->get_value());
+ else if (mpPageFormatDesc)
+ aTitleDesc.SetNumOffset(mpPageFormatDesc->GetNumOffset());
+
+ sal_uInt16 nNumTitlePages = m_xPageCountNF->get_value();
+ if (!m_xUseExistingPagesRB->get_active())
+ {
+ // Assuming that a failure to GotoPage means the end of the document,
+ // insert new pages after the last page.
+ if (!lcl_GotoPage(rWrtShell, GetInsertPosition()))
+ {
+ rWrtShell.EndPg();
+ // Add one more page as a content page to follow the new title pages.
+ rWrtShell.InsertPageBreak();
+ }
+ for (sal_uInt16 nI = 0; nI < nNumTitlePages; ++nI)
+ rWrtShell.InsertPageBreak();
+ // In order to be able to access these new pages, the layout needs to be recalculated first.
+ rWrtShell.CalcLayout();
+ }
+
+ if (lcl_GotoPage(rWrtShell, GetInsertPosition()))
+ {
+ rWrtShell.SetAttrItem(aTitleDesc);
+ for (sal_uInt16 nI = 1; nI < nNumTitlePages; ++nI)
+ {
+ if (rWrtShell.SttNxtPg())
+ lcl_ChangePage(rWrtShell, SAL_MAX_UINT16, mpIndexDesc);
+ }
+ }
+
+ if ((m_xRestartNumberingCB->get_active() || nNumTitlePages > 1)
+ && lcl_GotoPage(rWrtShell, GetInsertPosition(), nNumTitlePages))
+ {
+ sal_uInt16 nPgNo
+ = m_xRestartNumberingCB->get_active() ? m_xRestartNumberingNF->get_value() : 0;
+ const SwPageDesc* pNewDesc = nNumTitlePages > 1 ? mpNormalDesc : nullptr;
+ lcl_ChangePage(rWrtShell, nPgNo, pNewDesc);
+ }
+
+ rWrtShell.EndUndo();
+ lcl_PopCursor(rWrtShell);
+ if (!m_xUseExistingPagesRB->get_active())
+ lcl_GotoPage(rWrtShell, GetInsertPosition());
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/misc/translatelangselect.cxx b/sw/source/ui/misc/translatelangselect.cxx
new file mode 100644
index 0000000000..f03d64c755
--- /dev/null
+++ b/sw/source/ui/misc/translatelangselect.cxx
@@ -0,0 +1,164 @@
+/* -*- 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 <osl/diagnose.h>
+#include <uitool.hxx>
+#include <swtypes.hxx>
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <translatelangselect.hxx>
+#include <pagedesc.hxx>
+#include <poolfmt.hxx>
+#include <sal/log.hxx>
+#include <ndtxt.hxx>
+#include <shellio.hxx>
+#include <vcl/idle.hxx>
+#include <mdiexp.hxx>
+#include <strings.hrc>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <linguistic/translate.hxx>
+#include <officecfg/Office/Linguistic.hxx>
+
+static const std::vector<SwLanguageListItem>& getLanguageVec()
+{
+ static const std::vector<SwLanguageListItem> gLanguageVec{
+ SwLanguageListItem("BG"_ostr, "Bulgarian"_ostr),
+ SwLanguageListItem("CS"_ostr, "Czech"_ostr),
+ SwLanguageListItem("DA"_ostr, "Danish"_ostr),
+ SwLanguageListItem("DE"_ostr, "German"_ostr),
+ SwLanguageListItem("EL"_ostr, "Greek"_ostr),
+ SwLanguageListItem("EN-GB"_ostr, "English (British)"_ostr),
+ SwLanguageListItem("EN-US"_ostr, "English (American)"_ostr),
+ SwLanguageListItem("ES"_ostr, "Spanish"_ostr),
+ SwLanguageListItem("ET"_ostr, "Estonian"_ostr),
+ SwLanguageListItem("FI"_ostr, "Finnish"_ostr),
+ SwLanguageListItem("FR"_ostr, "French"_ostr),
+ SwLanguageListItem("HU"_ostr, "Hungarian"_ostr),
+ SwLanguageListItem("ID"_ostr, "Indonesian"_ostr),
+ SwLanguageListItem("IT"_ostr, "Italian"_ostr),
+ SwLanguageListItem("JA"_ostr, "Japanese"_ostr),
+ SwLanguageListItem("LT"_ostr, "Lithuanian"_ostr),
+ SwLanguageListItem("LV"_ostr, "Latvian"_ostr),
+ SwLanguageListItem("NL"_ostr, "Dutch"_ostr),
+ SwLanguageListItem("PL"_ostr, "Polish"_ostr),
+ SwLanguageListItem("PT-BR"_ostr, "Portuguese (Brazilian)"_ostr),
+ SwLanguageListItem("PT-PT"_ostr, "Portuguese (European)"_ostr),
+ SwLanguageListItem("RO"_ostr, "Romanian"_ostr),
+ SwLanguageListItem("RU"_ostr, "Russian"_ostr),
+ SwLanguageListItem("SK"_ostr, "Slovak"_ostr),
+ SwLanguageListItem("SL"_ostr, "Slovenian"_ostr),
+ SwLanguageListItem("SV"_ostr, "Swedish"_ostr),
+ SwLanguageListItem("TR"_ostr, "Turkish"_ostr),
+ SwLanguageListItem("ZH"_ostr, "Chinese (simplified)"_ostr)
+ };
+ return gLanguageVec;
+}
+
+int SwTranslateLangSelectDlg::selectedLangIdx = -1;
+SwTranslateLangSelectDlg::SwTranslateLangSelectDlg(weld::Window* pParent, SwWrtShell& rSh)
+ : GenericDialogController(pParent, "modules/swriter/ui/translationdialog.ui",
+ "LanguageSelectDialog")
+ , m_rWrtSh(rSh)
+ , m_xLanguageListBox(m_xBuilder->weld_combo_box("combobox1"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+ , m_xBtnTranslate(m_xBuilder->weld_button("translate"))
+ , m_bTranslationStarted(false)
+ , m_bCancelTranslation(false)
+{
+ m_xLanguageListBox->connect_changed(LINK(this, SwTranslateLangSelectDlg, LangSelectHdl));
+ m_xBtnCancel->connect_clicked(LINK(this, SwTranslateLangSelectDlg, LangSelectCancelHdl));
+ m_xBtnTranslate->connect_clicked(LINK(this, SwTranslateLangSelectDlg, LangSelectTranslateHdl));
+
+ for (const auto& item : getLanguageVec())
+ {
+ m_xLanguageListBox->append_text(OStringToOUString(item.getName(), RTL_TEXTENCODING_UTF8));
+ }
+
+ if (SwTranslateLangSelectDlg::selectedLangIdx != -1)
+ {
+ m_xLanguageListBox->set_active(SwTranslateLangSelectDlg::selectedLangIdx);
+ }
+}
+
+std::optional<SwLanguageListItem> SwTranslateLangSelectDlg::GetSelectedLanguage()
+{
+ if (SwTranslateLangSelectDlg::selectedLangIdx != -1)
+ {
+ return getLanguageVec().at(SwTranslateLangSelectDlg::selectedLangIdx);
+ }
+
+ return {};
+}
+
+IMPL_STATIC_LINK(SwTranslateLangSelectDlg, LangSelectHdl, weld::ComboBox&, rBox, void)
+{
+ const auto selected = rBox.get_active();
+ SwTranslateLangSelectDlg::selectedLangIdx = selected;
+}
+
+IMPL_LINK_NOARG(SwTranslateLangSelectDlg, LangSelectCancelHdl, weld::Button&, void)
+{
+ // stop translation first
+ if (m_bTranslationStarted)
+ m_bCancelTranslation = true;
+ else
+ m_xDialog->response(RET_CANCEL);
+}
+
+IMPL_LINK_NOARG(SwTranslateLangSelectDlg, LangSelectTranslateHdl, weld::Button&, void)
+{
+ if (m_bTranslationStarted)
+ return;
+ if (SwTranslateLangSelectDlg::selectedLangIdx == -1)
+ {
+ m_xDialog->response(RET_CANCEL);
+ return;
+ }
+
+ std::optional<OUString> oDeeplAPIUrl
+ = officecfg::Office::Linguistic::Translation::Deepl::ApiURL::get();
+ std::optional<OUString> oDeeplKey
+ = officecfg::Office::Linguistic::Translation::Deepl::AuthKey::get();
+ if (!oDeeplAPIUrl || oDeeplAPIUrl->isEmpty() || !oDeeplKey || oDeeplKey->isEmpty())
+ {
+ SAL_WARN("sw.ui", "SwTranslateLangSelectDlg: API options are not set");
+ m_xDialog->response(RET_CANCEL);
+ return;
+ }
+
+ const OString aAPIUrl
+ = OUStringToOString(rtl::Concat2View(*oDeeplAPIUrl + "?tag_handling=html"),
+ RTL_TEXTENCODING_UTF8)
+ .trim();
+ const OString aAuthKey = OUStringToOString(*oDeeplKey, RTL_TEXTENCODING_UTF8).trim();
+ const auto aTargetLang
+ = getLanguageVec().at(SwTranslateLangSelectDlg::selectedLangIdx).getLanguage();
+
+ m_bTranslationStarted = true;
+
+ SwTranslateHelper::TranslateAPIConfig aConfig({ aAPIUrl, aAuthKey, aTargetLang });
+ SwTranslateHelper::TranslateDocumentCancellable(m_rWrtSh, aConfig, m_bCancelTranslation);
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/autoformatpreview.cxx b/sw/source/ui/table/autoformatpreview.cxx
new file mode 100644
index 0000000000..e04fffefca
--- /dev/null
+++ b/sw/source/ui/table/autoformatpreview.cxx
@@ -0,0 +1,466 @@
+/* -*- 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/adjustitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <vcl/settings.hxx>
+#include <com/sun/star/i18n/BreakIterator.hpp>
+#include <comphelper/processfactory.hxx>
+#include <svtools/scriptedtext.hxx>
+#include <svx/framelink.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <drawinglayer/processor2d/processor2dtools.hxx>
+#include <strings.hrc>
+#include <svtools/colorcfg.hxx>
+#include <swmodule.hxx>
+
+#include <autoformatpreview.hxx>
+
+#define FRAME_OFFSET 4
+
+AutoFormatPreview::AutoFormatPreview()
+ : maCurrentData(OUString())
+ , mbFitWidth(false)
+ , mbRTL(false)
+ , maStringJan(SwResId(STR_JAN))
+ , maStringFeb(SwResId(STR_FEB))
+ , maStringMar(SwResId(STR_MAR))
+ , maStringNorth(SwResId(STR_NORTH))
+ , maStringMid(SwResId(STR_MID))
+ , maStringSouth(SwResId(STR_SOUTH))
+ , maStringSum(SwResId(STR_SUM))
+{
+ uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ m_xBreak = i18n::BreakIterator::create(xContext);
+ mxNumFormat.reset(new SvNumberFormatter(xContext, LANGUAGE_SYSTEM));
+
+ Init();
+}
+
+void AutoFormatPreview::Resize()
+{
+ Size aSize = GetOutputSizePixel();
+ maPreviousSize = Size(aSize.Width() - 6, aSize.Height() - 30);
+ mnLabelColumnWidth = (maPreviousSize.Width() - 4) / 4 - 12;
+ mnDataColumnWidth1 = (maPreviousSize.Width() - 4 - 2 * mnLabelColumnWidth) / 3;
+ mnDataColumnWidth2 = (maPreviousSize.Width() - 4 - 2 * mnLabelColumnWidth) / 4;
+ mnRowHeight = (maPreviousSize.Height() - 4) / 5;
+ NotifyChange(maCurrentData);
+}
+
+void AutoFormatPreview::DetectRTL(SwWrtShell const* pWrtShell)
+{
+ if (!pWrtShell->IsCursorInTable()) // We haven't created the table yet
+ mbRTL = AllSettings::GetLayoutRTL();
+ else
+ mbRTL = pWrtShell->IsTableRightToLeft();
+}
+
+static void lcl_SetFontProperties(vcl::Font& rFont, const SvxFontItem& rFontItem,
+ const SvxWeightItem& rWeightItem,
+ const SvxPostureItem& rPostureItem)
+{
+ rFont.SetFamily(rFontItem.GetFamily());
+ rFont.SetFamilyName(rFontItem.GetFamilyName());
+ rFont.SetStyleName(rFontItem.GetStyleName());
+ rFont.SetCharSet(rFontItem.GetCharSet());
+ rFont.SetPitch(rFontItem.GetPitch());
+ rFont.SetWeight(rWeightItem.GetValue());
+ rFont.SetItalic(rPostureItem.GetValue());
+}
+
+#define SETONALLFONTS(MethodName, Value) \
+ rFont.MethodName(Value); \
+ rCJKFont.MethodName(Value); \
+ rCTLFont.MethodName(Value);
+
+void AutoFormatPreview::MakeFonts(vcl::RenderContext const& rRenderContext, sal_uInt8 nIndex,
+ vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont)
+{
+ const SwBoxAutoFormat& rBoxFormat = maCurrentData.GetBoxFormat(nIndex);
+
+ rFont = rCJKFont = rCTLFont = rRenderContext.GetFont();
+ Size aFontSize(rFont.GetFontSize().Width(), 10 * rRenderContext.GetDPIScaleFactor());
+
+ lcl_SetFontProperties(rFont, rBoxFormat.GetFont(), rBoxFormat.GetWeight(),
+ rBoxFormat.GetPosture());
+ lcl_SetFontProperties(rCJKFont, rBoxFormat.GetCJKFont(), rBoxFormat.GetCJKWeight(),
+ rBoxFormat.GetCJKPosture());
+ lcl_SetFontProperties(rCTLFont, rBoxFormat.GetCTLFont(), rBoxFormat.GetCTLWeight(),
+ rBoxFormat.GetCTLPosture());
+
+ SETONALLFONTS(SetUnderline, rBoxFormat.GetUnderline().GetValue());
+ SETONALLFONTS(SetOverline, rBoxFormat.GetOverline().GetValue());
+ SETONALLFONTS(SetStrikeout, rBoxFormat.GetCrossedOut().GetValue());
+ SETONALLFONTS(SetOutline, rBoxFormat.GetContour().GetValue());
+ SETONALLFONTS(SetShadow, rBoxFormat.GetShadowed().GetValue());
+ SETONALLFONTS(SetColor, rBoxFormat.GetColor().GetValue());
+ SETONALLFONTS(SetFontSize, aFontSize);
+ SETONALLFONTS(SetTransparent, true);
+}
+
+sal_uInt8 AutoFormatPreview::GetFormatIndex(size_t nCol, size_t nRow) const
+{
+ static const sal_uInt8 pnFormatMap[]
+ = { 0, 1, 2, 1, 3, 4, 5, 6, 5, 7, 8, 9, 10, 9, 11, 4, 5, 6, 5, 7, 12, 13, 14, 13, 15 };
+ return pnFormatMap[maArray.GetCellIndex(nCol, nRow, mbRTL)];
+}
+
+void AutoFormatPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCol, size_t nRow)
+{
+ // Output of the cell text:
+ sal_uLong nNum;
+ double nVal;
+ OUString cellString;
+ sal_uInt8 nIndex = static_cast<sal_uInt8>(maArray.GetCellIndex(nCol, nRow, mbRTL));
+
+ switch (nIndex)
+ {
+ case 1:
+ cellString = maStringJan;
+ break;
+ case 2:
+ cellString = maStringFeb;
+ break;
+ case 3:
+ cellString = maStringMar;
+ break;
+ case 5:
+ cellString = maStringNorth;
+ break;
+ case 10:
+ cellString = maStringMid;
+ break;
+ case 15:
+ cellString = maStringSouth;
+ break;
+ case 4:
+ case 20:
+ cellString = maStringSum;
+ break;
+ case 6:
+ case 8:
+ case 16:
+ case 18:
+ nVal = nIndex;
+ nNum = 5;
+ goto MAKENUMSTR;
+ case 17:
+ case 7:
+ nVal = nIndex;
+ nNum = 6;
+ goto MAKENUMSTR;
+ case 11:
+ case 12:
+ case 13:
+ nVal = nIndex;
+ nNum = 12 == nIndex ? 10 : 9;
+ goto MAKENUMSTR;
+ case 9:
+ nVal = 21;
+ nNum = 7;
+ goto MAKENUMSTR;
+ case 14:
+ nVal = 36;
+ nNum = 11;
+ goto MAKENUMSTR;
+ case 19:
+ nVal = 51;
+ nNum = 7;
+ goto MAKENUMSTR;
+ case 21:
+ nVal = 33;
+ nNum = 13;
+ goto MAKENUMSTR;
+ case 22:
+ nVal = 36;
+ nNum = 14;
+ goto MAKENUMSTR;
+ case 23:
+ nVal = 39;
+ nNum = 13;
+ goto MAKENUMSTR;
+ case 24:
+ nVal = 108;
+ nNum = 15;
+ goto MAKENUMSTR;
+
+ MAKENUMSTR:
+ if (maCurrentData.IsValueFormat())
+ {
+ OUString sFormat;
+ LanguageType eLng, eSys;
+ maCurrentData.GetBoxFormat(sal_uInt8(nNum)).GetValueFormat(sFormat, eLng, eSys);
+
+ SvNumFormatType nType;
+ bool bNew;
+ sal_Int32 nCheckPos;
+ sal_uInt32 nKey = mxNumFormat->GetIndexPuttingAndConverting(sFormat, eLng, eSys,
+ nType, bNew, nCheckPos);
+ const Color* pDummy;
+ mxNumFormat->GetOutputString(nVal, nKey, cellString, &pDummy);
+ }
+ else
+ cellString = OUString::number(sal_Int32(nVal));
+ break;
+ }
+
+ if (cellString.isEmpty())
+ return;
+
+ SvtScriptedTextHelper aScriptedText(rRenderContext);
+ Size aStrSize;
+ sal_uInt8 nFormatIndex = GetFormatIndex(nCol, nRow);
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow));
+ const tools::Rectangle cellRect(
+ basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
+ basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()));
+ Point aPos = cellRect.TopLeft();
+ tools::Long nRightX = 0;
+
+ Size theMaxStrSize(cellRect.GetWidth() - FRAME_OFFSET, cellRect.GetHeight() - FRAME_OFFSET);
+ if (maCurrentData.IsFont())
+ {
+ vcl::Font aFont, aCJKFont, aCTLFont;
+ MakeFonts(rRenderContext, nFormatIndex, aFont, aCJKFont, aCTLFont);
+ aScriptedText.SetFonts(&aFont, &aCJKFont, &aCTLFont);
+ }
+ else
+ aScriptedText.SetDefaultFont();
+
+ aScriptedText.SetText(cellString, m_xBreak);
+ aStrSize = aScriptedText.GetTextSize();
+
+ if (maCurrentData.IsFont() && theMaxStrSize.Height() < aStrSize.Height())
+ {
+ // If the string in this font does not
+ // fit into the cell, the standard font
+ // is taken again:
+ aScriptedText.SetDefaultFont();
+ aStrSize = aScriptedText.GetTextSize();
+ }
+
+ while (theMaxStrSize.Width() <= aStrSize.Width() && cellString.getLength() > 1)
+ {
+ cellString = cellString.copy(0, cellString.getLength() - 1);
+ aScriptedText.SetText(cellString, m_xBreak);
+ aStrSize = aScriptedText.GetTextSize();
+ }
+
+ nRightX = cellRect.GetWidth() - aStrSize.Width() - FRAME_OFFSET;
+
+ // vertical (always centering):
+ aPos.AdjustY((mnRowHeight - aStrSize.Height()) / 2);
+
+ // horizontal
+ if (mbRTL)
+ aPos.AdjustX(nRightX);
+ else if (maCurrentData.IsJustify())
+ {
+ const SvxAdjustItem& rAdj = maCurrentData.GetBoxFormat(nFormatIndex).GetAdjust();
+ switch (rAdj.GetAdjust())
+ {
+ case SvxAdjust::Left:
+ aPos.AdjustX(FRAME_OFFSET);
+ break;
+ case SvxAdjust::Right:
+ aPos.AdjustX(nRightX);
+ break;
+ default:
+ aPos.AdjustX((cellRect.GetWidth() - aStrSize.Width()) / 2);
+ break;
+ }
+ }
+ else
+ {
+ // Standard align:
+ if (nCol == 0 || nIndex == 4)
+ {
+ // Text-Label left or sum left aligned
+ aPos.AdjustX(FRAME_OFFSET);
+ }
+ else
+ {
+ // numbers/dates right aligned
+ aPos.AdjustX(nRightX);
+ }
+ }
+
+ aScriptedText.DrawText(aPos);
+}
+
+void AutoFormatPreview::DrawBackground(vcl::RenderContext& rRenderContext)
+{
+ for (size_t nRow = 0; nRow < 5; ++nRow)
+ {
+ for (size_t nCol = 0; nCol < 5; ++nCol)
+ {
+ SvxBrushItem aBrushItem(
+ maCurrentData.GetBoxFormat(GetFormatIndex(nCol, nRow)).GetBackground());
+
+ rRenderContext.Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR);
+ rRenderContext.SetLineColor();
+ rRenderContext.SetFillColor(aBrushItem.GetColor());
+ const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow));
+ rRenderContext.DrawRect(tools::Rectangle(
+ basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
+ basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY())));
+ rRenderContext.Pop();
+ }
+ }
+}
+
+void AutoFormatPreview::PaintCells(vcl::RenderContext& rRenderContext)
+{
+ // 1) background
+ if (maCurrentData.IsBackground())
+ DrawBackground(rRenderContext);
+
+ // 2) values
+ for (size_t nRow = 0; nRow < 5; ++nRow)
+ for (size_t nCol = 0; nCol < 5; ++nCol)
+ DrawString(rRenderContext, nCol, nRow);
+
+ // 3) border
+ if (!maCurrentData.IsFrame())
+ return;
+
+ const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
+ std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
+ drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(rRenderContext,
+ aNewViewInformation2D));
+
+ if (pProcessor2D)
+ {
+ pProcessor2D->process(maArray.CreateB2DPrimitiveArray());
+ pProcessor2D.reset();
+ }
+}
+
+void AutoFormatPreview::Init()
+{
+ maArray.Initialize(5, 5);
+ mnLabelColumnWidth = 0;
+ mnDataColumnWidth1 = 0;
+ mnDataColumnWidth2 = 0;
+ mnRowHeight = 0;
+ CalcCellArray(false);
+ CalcLineMap();
+}
+
+void AutoFormatPreview::CalcCellArray(bool _bFitWidth)
+{
+ maArray.SetAllColWidths(_bFitWidth ? mnDataColumnWidth2 : mnDataColumnWidth1);
+ maArray.SetColWidth(0, mnLabelColumnWidth);
+ maArray.SetColWidth(4, mnLabelColumnWidth);
+
+ maArray.SetAllRowHeights(mnRowHeight);
+
+ maPreviousSize.setWidth(maArray.GetWidth() + 4);
+ maPreviousSize.setHeight(maArray.GetHeight() + 4);
+}
+
+static void lclSetStyleFromBorder(svx::frame::Style& rStyle,
+ const ::editeng::SvxBorderLine* pBorder)
+{
+ rStyle.Set(pBorder, 0.05, 5);
+}
+
+void AutoFormatPreview::CalcLineMap()
+{
+ for (size_t nRow = 0; nRow < 5; ++nRow)
+ {
+ for (size_t nCol = 0; nCol < 5; ++nCol)
+ {
+ svx::frame::Style aStyle;
+
+ const SvxBoxItem& rItem
+ = maCurrentData.GetBoxFormat(GetFormatIndex(nCol, nRow)).GetBox();
+ lclSetStyleFromBorder(aStyle, rItem.GetLeft());
+ maArray.SetCellStyleLeft(nCol, nRow, aStyle);
+ lclSetStyleFromBorder(aStyle, rItem.GetRight());
+ maArray.SetCellStyleRight(nCol, nRow, aStyle);
+ lclSetStyleFromBorder(aStyle, rItem.GetTop());
+ maArray.SetCellStyleTop(nCol, nRow, aStyle);
+ lclSetStyleFromBorder(aStyle, rItem.GetBottom());
+ maArray.SetCellStyleBottom(nCol, nRow, aStyle);
+
+ // FIXME - uncomment to draw diagonal borders
+ // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
+ // maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
+ // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
+ // maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
+ }
+ }
+}
+
+void AutoFormatPreview::NotifyChange(const SwTableAutoFormat& rNewData)
+{
+ maCurrentData = rNewData;
+ mbFitWidth = maCurrentData.IsJustify(); // true; //???
+ CalcCellArray(mbFitWidth);
+ CalcLineMap();
+ Invalidate();
+}
+
+void AutoFormatPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ rRenderContext.Push(vcl::PushFlags::ALL);
+
+ const Color& rWinColor = SW_MOD()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR).nColor;
+ rRenderContext.SetBackground(Wallpaper(rWinColor));
+ rRenderContext.Erase();
+
+ DrawModeFlags nOldDrawMode = rRenderContext.GetDrawMode();
+ if (rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
+ rRenderContext.SetDrawMode(DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill
+ | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient);
+
+ Size theWndSize = rRenderContext.GetOutputSizePixel();
+
+ vcl::Font aFont(rRenderContext.GetFont());
+ aFont.SetTransparent(true);
+ rRenderContext.SetFont(aFont);
+
+ // Draw the Frame
+ Color oldColor = rRenderContext.GetLineColor();
+ rRenderContext.SetLineColor();
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), theWndSize));
+ rRenderContext.SetLineColor(oldColor);
+
+ // Center the preview
+ maArray.SetXOffset(2 + (theWndSize.Width() - maPreviousSize.Width()) / 2);
+ maArray.SetYOffset(2 + (theWndSize.Height() - maPreviousSize.Height()) / 2);
+ // Draw cells on virtual device
+ PaintCells(rRenderContext);
+
+ rRenderContext.SetDrawMode(nOldDrawMode);
+ rRenderContext.Pop();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/colwd.cxx b/sw/source/ui/table/colwd.cxx
new file mode 100644
index 0000000000..2440d8696f
--- /dev/null
+++ b/sw/source/ui/table/colwd.cxx
@@ -0,0 +1,75 @@
+/* -*- 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/unitconv.hxx>
+#include <colwd.hxx>
+#include <tablemgr.hxx>
+#include <wrtsh.hxx>
+#include <wdocsh.hxx>
+#include <view.hxx>
+#include <swmodule.hxx>
+#include <usrpref.hxx>
+
+IMPL_LINK_NOARG(SwTableWidthDlg, LoseFocusHdl, weld::SpinButton&, void)
+{
+ sal_uInt16 nId = o3tl::narrowing<sal_uInt16>(m_xColNF->get_value()) - 1;
+ const SwTwips lWidth = m_rFnc.GetColWidth(nId);
+ m_xWidthMF->set_max(m_xWidthMF->normalize(m_rFnc.GetMaxColWidth(nId)), FieldUnit::TWIP);
+ m_xWidthMF->set_value(m_xWidthMF->normalize(lWidth), FieldUnit::TWIP);
+}
+
+SwTableWidthDlg::SwTableWidthDlg(weld::Window *pParent, SwTableFUNC &rTableFnc)
+ : GenericDialogController(pParent, "modules/swriter/ui/columnwidth.ui", "ColumnWidthDialog")
+ , m_rFnc(rTableFnc)
+ , m_xColNF(m_xBuilder->weld_spin_button("column"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+{
+ bool bIsWeb = rTableFnc.GetShell()
+ && (dynamic_cast< const SwWebDocShell* >(
+ rTableFnc.GetShell()->GetView().GetDocShell()) != nullptr );
+ FieldUnit eFieldUnit = SW_MOD()->GetUsrPref( bIsWeb )->GetMetric();
+ ::SetFieldUnit(*m_xWidthMF, eFieldUnit);
+
+ m_xColNF->set_max(m_rFnc.GetColCount() + 1);
+ m_xColNF->set_value(m_rFnc.GetCurColNum() + 1);
+
+ if (m_rFnc.GetColCount() == 0)
+ m_xWidthMF->set_min(m_xWidthMF->normalize(m_rFnc.GetColWidth(0)), FieldUnit::TWIP);
+ else
+ m_xWidthMF->set_min(m_xWidthMF->normalize(MINLAY), FieldUnit::TWIP);
+ m_xColNF->connect_value_changed(LINK(this, SwTableWidthDlg, LoseFocusHdl));
+ LoseFocusHdl(*m_xColNF);
+}
+
+void SwTableWidthDlg::Apply()
+{
+ m_rFnc.InitTabCols();
+ m_rFnc.SetColWidth(o3tl::narrowing<sal_uInt16>(m_xColNF->get_value() - 1),
+ o3tl::narrowing<sal_uInt16>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP))));
+}
+
+short SwTableWidthDlg::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/convert.cxx b/sw/source/ui/table/convert.cxx
new file mode 100644
index 0000000000..fa5184cd69
--- /dev/null
+++ b/sw/source/ui/table/convert.cxx
@@ -0,0 +1,203 @@
+/* -*- 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 <modcfg.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <viewopt.hxx>
+#include <swmodule.hxx>
+#include <convert.hxx>
+#include <tablemgr.hxx>
+#include <view.hxx>
+#include <tblafmt.hxx>
+
+#include <strings.hrc>
+#include <swabstdlg.hxx>
+#include <swuiexp.hxx>
+#include <memory>
+
+//keep the state of the buttons on runtime
+static int nSaveButtonState = -1; // 0: tab, 1: semicolon, 2: paragraph, 3: other, -1: not yet used
+static bool bIsKeepColumn = true;
+static sal_Unicode uOther = ',';
+
+void SwConvertTableDlg::GetValues(sal_Unicode& rDelim, SwInsertTableOptions& rInsTableOpts,
+ SwTableAutoFormat const*& prTAFormat)
+{
+ if (m_xTabBtn->get_active())
+ {
+ //0x0b mustn't be set when re-converting table into text
+ bIsKeepColumn = !m_xKeepColumn->get_visible() || m_xKeepColumn->get_active();
+ rDelim = bIsKeepColumn ? 0x09 : 0x0b;
+ nSaveButtonState = 0;
+ }
+ else if (m_xSemiBtn->get_active())
+ {
+ rDelim = ';';
+ nSaveButtonState = 1;
+ }
+ else if (m_xOtherBtn->get_active() && !m_xOtherEd->get_text().isEmpty())
+ {
+ uOther = m_xOtherEd->get_text()[0];
+ rDelim = uOther;
+ nSaveButtonState = 3;
+ }
+ else
+ {
+ nSaveButtonState = 2;
+ rDelim = cParaDelim;
+ if (m_xOtherBtn->get_active())
+ {
+ nSaveButtonState = 3;
+ uOther = 0;
+ }
+ }
+
+ SwInsertTableFlags nInsMode = SwInsertTableFlags::NONE;
+ if (m_xHeaderCB->get_active())
+ nInsMode |= SwInsertTableFlags::Headline;
+ if (m_xRepeatHeaderCB->get_sensitive() && m_xRepeatHeaderCB->get_active())
+ rInsTableOpts.mnRowsToRepeat = m_xRepeatHeaderNF->get_value();
+ else
+ rInsTableOpts.mnRowsToRepeat = 0;
+ if (!m_xDontSplitCB->get_active())
+ nInsMode |= SwInsertTableFlags::SplitLayout;
+
+ if (mxTAutoFormat)
+ prTAFormat = new SwTableAutoFormat(*mxTAutoFormat);
+
+ rInsTableOpts.mnInsMode = nInsMode;
+}
+
+SwConvertTableDlg::SwConvertTableDlg(SwView& rView, bool bToTable)
+ : SfxDialogController(rView.GetFrameWeld(), "modules/swriter/ui/converttexttable.ui",
+ "ConvertTextTableDialog")
+ , m_xTabBtn(m_xBuilder->weld_radio_button("tabs"))
+ , m_xSemiBtn(m_xBuilder->weld_radio_button("semicolons"))
+ , m_xParaBtn(m_xBuilder->weld_radio_button("paragraph"))
+ , m_xOtherBtn(m_xBuilder->weld_radio_button("other"))
+ , m_xOtherEd(m_xBuilder->weld_entry("othered"))
+ , m_xKeepColumn(m_xBuilder->weld_check_button("keepcolumn"))
+ , m_xOptions(m_xBuilder->weld_container("options"))
+ , m_xHeaderCB(m_xBuilder->weld_check_button("headingcb"))
+ , m_xRepeatHeaderCB(m_xBuilder->weld_check_button("repeatheading"))
+ , m_xRepeatRows(m_xBuilder->weld_container("repeatrows"))
+ , m_xRepeatHeaderNF(m_xBuilder->weld_spin_button("repeatheadersb"))
+ , m_xDontSplitCB(m_xBuilder->weld_check_button("dontsplitcb"))
+ , m_xAutoFormatBtn(m_xBuilder->weld_button("autofmt"))
+ , m_pShell(&rView.GetWrtShell())
+{
+ if (nSaveButtonState > -1)
+ {
+ switch (nSaveButtonState)
+ {
+ case 0:
+ m_xTabBtn->set_active(true);
+ m_xKeepColumn->set_active(bIsKeepColumn);
+ break;
+ case 1:
+ m_xSemiBtn->set_active(true);
+ break;
+ case 2:
+ m_xParaBtn->set_active(true);
+ break;
+ case 3:
+ m_xOtherBtn->set_active(true);
+ if (uOther)
+ m_xOtherEd->set_text(OUString(uOther));
+ break;
+ }
+ }
+ if (bToTable)
+ {
+ m_xDialog->set_title(SwResId(STR_CONVERT_TEXT_TABLE));
+ m_xAutoFormatBtn->connect_clicked(LINK(this, SwConvertTableDlg, AutoFormatHdl));
+ m_xAutoFormatBtn->show();
+ m_xKeepColumn->show();
+ m_xKeepColumn->set_sensitive(m_xTabBtn->get_active());
+ }
+ else
+ {
+ //hide insert options
+ m_xOptions->hide();
+ }
+ m_xKeepColumn->save_state();
+
+ Link<weld::Toggleable&, void> aLk(LINK(this, SwConvertTableDlg, BtnHdl));
+ m_xTabBtn->connect_toggled(aLk);
+ m_xSemiBtn->connect_toggled(aLk);
+ m_xParaBtn->connect_toggled(aLk);
+ m_xOtherBtn->connect_toggled(aLk);
+ m_xOtherEd->set_sensitive(m_xOtherBtn->get_active());
+
+ const SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+
+ bool bHTMLMode = 0 != (::GetHtmlMode(rView.GetDocShell()) & HTMLMODE_ON);
+
+ SwInsertTableOptions aInsOpts = pModOpt->GetInsTableFlags(bHTMLMode);
+ SwInsertTableFlags nInsTableFlags = aInsOpts.mnInsMode;
+
+ m_xHeaderCB->set_active(bool(nInsTableFlags & SwInsertTableFlags::Headline));
+ m_xRepeatHeaderCB->set_active(aInsOpts.mnRowsToRepeat > 0);
+ m_xDontSplitCB->set_active(!(nInsTableFlags & SwInsertTableFlags::SplitLayout));
+
+ m_xHeaderCB->connect_toggled(LINK(this, SwConvertTableDlg, CheckBoxHdl));
+ m_xRepeatHeaderCB->connect_toggled(LINK(this, SwConvertTableDlg, RepeatHeaderCheckBoxHdl));
+ RepeatHeaderCheckBoxHdl(*m_xRepeatHeaderCB);
+ CheckBoxHdl(*m_xHeaderCB);
+}
+
+IMPL_LINK_NOARG(SwConvertTableDlg, AutoFormatHdl, weld::Button&, void)
+{
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+
+ ScopedVclPtr<AbstractSwAutoFormatDlg> pDlg(
+ rFact.CreateSwAutoFormatDlg(m_xDialog.get(), m_pShell, false, mxTAutoFormat.get()));
+ if (RET_OK == pDlg->Execute())
+ mxTAutoFormat = pDlg->FillAutoFormatOfIndex();
+}
+
+IMPL_LINK(SwConvertTableDlg, BtnHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ if (m_xTabBtn->get_active())
+ m_xKeepColumn->set_state(m_xKeepColumn->get_saved_state());
+ else
+ {
+ if (m_xKeepColumn->get_sensitive())
+ m_xKeepColumn->save_state();
+ m_xKeepColumn->set_active(true);
+ }
+ m_xKeepColumn->set_sensitive(m_xTabBtn->get_active());
+ m_xOtherEd->set_sensitive(m_xOtherBtn->get_active());
+}
+
+IMPL_LINK_NOARG(SwConvertTableDlg, CheckBoxHdl, weld::Toggleable&, void)
+{
+ m_xRepeatHeaderCB->set_sensitive(m_xHeaderCB->get_active());
+ RepeatHeaderCheckBoxHdl(*m_xRepeatHeaderCB);
+}
+
+IMPL_LINK_NOARG(SwConvertTableDlg, RepeatHeaderCheckBoxHdl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xHeaderCB->get_active() && m_xRepeatHeaderCB->get_active();
+ m_xRepeatRows->set_sensitive(bEnable);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/instable.cxx b/sw/source/ui/table/instable.cxx
new file mode 100644
index 0000000000..a5aa4cd838
--- /dev/null
+++ b/sw/source/ui/table/instable.cxx
@@ -0,0 +1,298 @@
+/* -*- 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 <instable.hxx>
+#include <shellres.hxx>
+#include <modcfg.hxx>
+#include <swmodule.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <viewopt.hxx>
+#include <comphelper/lok.hxx>
+
+
+void SwInsTableDlg::GetValues( OUString& rName, sal_uInt16& rRow, sal_uInt16& rCol,
+ SwInsertTableOptions& rInsTableOpts, OUString& rAutoName,
+ std::unique_ptr<SwTableAutoFormat>& prTAFormat )
+{
+ SwInsertTableFlags nInsMode = SwInsertTableFlags::NONE;
+ rName = m_xNameEdit->get_text();
+ rRow = m_xRowSpinButton->get_value();
+ rCol = m_xColSpinButton->get_value();
+
+ if (m_xHeaderCB->get_active())
+ nInsMode |= SwInsertTableFlags::Headline;
+ if (m_xRepeatHeaderCB->get_sensitive() && m_xRepeatHeaderCB->get_active())
+ rInsTableOpts.mnRowsToRepeat = m_xRepeatHeaderNF->get_value();
+ else
+ rInsTableOpts.mnRowsToRepeat = 0;
+ if (!m_xDontSplitCB->get_active())
+ nInsMode |= SwInsertTableFlags::SplitLayout;
+ if( m_xTAutoFormat )
+ {
+ prTAFormat.reset(new SwTableAutoFormat( *m_xTAutoFormat ));
+ rAutoName = prTAFormat->GetName();
+ }
+
+ rInsTableOpts.mnInsMode = nInsMode;
+}
+
+IMPL_LINK(SwInsTableDlg, TextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = m_aTextFilter.filter(rTest);
+ return true;
+}
+
+SwInsTableDlg::SwInsTableDlg(SwView& rView)
+ : SfxDialogController(rView.GetFrameWeld(), "modules/swriter/ui/inserttable.ui", "InsertTableDialog")
+ , m_aTextFilter(" .<>")
+ , m_pShell(&rView.GetWrtShell())
+ , m_nEnteredValRepeatHeaderNF(-1)
+ , m_xNameEdit(m_xBuilder->weld_entry("nameedit"))
+ , m_xWarning(m_xBuilder->weld_label("lbwarning"))
+ , m_xColSpinButton(m_xBuilder->weld_spin_button("colspin"))
+ , m_xRowSpinButton(m_xBuilder->weld_spin_button("rowspin"))
+ , m_xHeaderCB(m_xBuilder->weld_check_button("headercb"))
+ , m_xRepeatHeaderCB(m_xBuilder->weld_check_button("repeatcb"))
+ , m_xRepeatHeaderNF(m_xBuilder->weld_spin_button("repeatheaderspin"))
+ , m_xRepeatGroup(m_xBuilder->weld_widget("repeatgroup"))
+ , m_xDontSplitCB(m_xBuilder->weld_check_button("dontsplitcb"))
+ , m_xInsertBtn(m_xBuilder->weld_button("ok"))
+ , m_xLbFormat(m_xBuilder->weld_tree_view("formatlbinstable"))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "previewinstable", m_aWndPreview))
+ , m_xStyleFrame(m_xBuilder->weld_frame("stylesframe"))
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ m_xStyleFrame->hide();
+
+ const int nWidth = m_xLbFormat->get_approximate_digit_width() * 32;
+ const int nHeight = m_xLbFormat->get_height_rows(8);
+ m_xLbFormat->set_size_request(nWidth, nHeight);
+ m_xWndPreview->set_size_request(nWidth, nHeight);
+
+ m_xNameEdit->connect_insert_text(LINK(this, SwInsTableDlg, TextFilterHdl));
+ m_xNameEdit->set_text(m_pShell->GetUniqueTableName());
+ m_xNameEdit->connect_changed(LINK(this, SwInsTableDlg, ModifyName));
+ m_xRowSpinButton->connect_changed(LINK(this, SwInsTableDlg, ModifyRowCol));
+ m_xColSpinButton->connect_changed(LINK(this, SwInsTableDlg, ModifyRowCol));
+
+ m_xInsertBtn->connect_clicked(LINK(this, SwInsTableDlg, OKHdl));
+
+ bool bHTMLMode = 0 != (::GetHtmlMode(rView.GetDocShell())&HTMLMODE_ON);
+ const SwModuleOptions* pModOpt = SW_MOD()->GetModuleConfig();
+
+ SwInsertTableOptions aInsOpts = pModOpt->GetInsTableFlags(bHTMLMode);
+ SwInsertTableFlags nInsTableFlags = aInsOpts.mnInsMode;
+
+ m_xHeaderCB->set_active(bool(nInsTableFlags & SwInsertTableFlags::Headline));
+ m_xRepeatHeaderCB->set_active(aInsOpts.mnRowsToRepeat > 0);
+ if (bHTMLMode)
+ m_xDontSplitCB->hide();
+ else
+ m_xDontSplitCB->set_active(!(nInsTableFlags & SwInsertTableFlags::SplitLayout));
+
+ m_xRepeatHeaderNF->connect_value_changed( LINK( this, SwInsTableDlg, ModifyRepeatHeaderNF_Hdl ) );
+ m_xHeaderCB->connect_toggled( LINK( this, SwInsTableDlg, CheckBoxHdl ) );
+ m_xRepeatHeaderCB->connect_toggled( LINK( this, SwInsTableDlg, RepeatHeaderCheckBoxHdl ) );
+ RepeatHeaderCheckBoxHdl(*m_xRepeatHeaderCB);
+ CheckBoxHdl(*m_xHeaderCB);
+
+ sal_Int64 nMax = m_xRowSpinButton->get_value();
+ if( nMax <= 1 )
+ nMax = 1;
+ else
+ --nMax;
+ m_xRepeatHeaderNF->set_max( nMax );
+
+ InitAutoTableFormat();
+ m_xWarning->set_label_type(weld::LabelType::Warning);
+}
+
+void SwInsTableDlg::InitAutoTableFormat()
+{
+ m_aWndPreview.DetectRTL(m_pShell);
+
+ m_xLbFormat->connect_changed(LINK(this, SwInsTableDlg, SelFormatHdl));
+
+ m_xTableTable.reset(new SwTableAutoFormatTable);
+ m_xTableTable->Load();
+
+ // Add "- none -" style autoformat table.
+ m_xLbFormat->append_text(SwViewShell::GetShellRes()->aStrNone); // Insert to listbox
+
+ // Add other styles of autoformat tables.
+ for (sal_uInt8 i = 0, nCount = static_cast<sal_uInt8>(m_xTableTable->size());
+ i < nCount; i++)
+ {
+ SwTableAutoFormat const& rFormat = (*m_xTableTable)[ i ];
+ m_xLbFormat->append_text(rFormat.GetName());
+ if (m_xTAutoFormat && rFormat.GetName() == m_xTAutoFormat->GetName())
+ m_lbIndex = i;
+ }
+
+ // Change this min variable if you add autotable manually.
+ minTableIndexInLb = 1;
+ maxTableIndexInLb = minTableIndexInLb + static_cast<sal_uInt8>(m_xTableTable->size());
+ // 1 means default table style
+ // unfortunately when the table has a style sw/qa/uitest/writer_tests4/tdf115573.py fails
+ // because tables that have pre-applied style resets the style of the elements in their cells
+ // when a new row is inserted and the ui test above relies on that. For now this is LOK only
+ m_lbIndex = comphelper::LibreOfficeKit::isActive() ? 1 : 0;
+ m_xLbFormat->select(m_lbIndex);
+ m_tbIndex = lbIndexToTableIndex(m_lbIndex);
+
+ SelFormatHdl( *m_xLbFormat );
+}
+
+sal_uInt8 SwInsTableDlg::lbIndexToTableIndex( const sal_uInt8 listboxIndex )
+{
+ if( minTableIndexInLb != maxTableIndexInLb &&
+ minTableIndexInLb <= listboxIndex &&
+ listboxIndex < maxTableIndexInLb )
+ {
+ return listboxIndex - minTableIndexInLb;
+ }
+
+ return 255;
+}
+
+static void lcl_SetProperties( SwTableAutoFormat* pTableAutoFormat, bool bVal )
+{
+ pTableAutoFormat->SetFont( bVal );
+ pTableAutoFormat->SetJustify( bVal );
+ pTableAutoFormat->SetFrame( bVal );
+ pTableAutoFormat->SetBackground( bVal );
+ pTableAutoFormat->SetValueFormat( bVal );
+ pTableAutoFormat->SetWidthHeight( bVal );
+}
+
+IMPL_LINK_NOARG(SwInsTableDlg, SelFormatHdl, weld::TreeView&, void)
+{
+ // Get index of selected item from the listbox
+ m_lbIndex = static_cast<sal_uInt8>(m_xLbFormat->get_selected_index());
+ m_tbIndex = lbIndexToTableIndex( m_lbIndex );
+
+ // To understand this index mapping, look InitAutoTableFormat function to
+ // see how listbox item is implemented.
+ if( m_tbIndex < 255 )
+ m_aWndPreview.NotifyChange( (*m_xTableTable)[m_tbIndex] );
+ else
+ {
+ SwTableAutoFormat aTmp( SwViewShell::GetShellRes()->aStrNone );
+ lcl_SetProperties( &aTmp, false );
+
+ m_aWndPreview.NotifyChange( aTmp );
+ }
+}
+
+IMPL_LINK_NOARG(SwInsTableDlg, OKHdl, weld::Button&, void)
+{
+ if( m_tbIndex < 255 )
+ m_pShell->SetTableStyle((*m_xTableTable)[m_tbIndex]);
+
+ if( m_tbIndex < 255 )
+ {
+ if( m_xTAutoFormat )
+ *m_xTAutoFormat = (*m_xTableTable)[ m_tbIndex ];
+ else
+ m_xTAutoFormat.reset(new SwTableAutoFormat( (*m_xTableTable)[ m_tbIndex ] ));
+ }
+ else
+ {
+ m_xTAutoFormat.reset(new SwTableAutoFormat( SwViewShell::GetShellRes()->aStrNone ));
+ lcl_SetProperties( m_xTAutoFormat.get(), false );
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK( SwInsTableDlg, ModifyName, weld::Entry&, rEdit, void )
+{
+ OUString sTableName = rEdit.get_text();
+ m_xInsertBtn->set_sensitive(m_pShell->GetTableStyle(sTableName) == nullptr);
+}
+
+// We use weld::Entry's "changed" notification here, not weld::SpinButton's "value_changed", because
+// the latter only fires after the control looses focus; so the notification would not fire during
+// typing a big number, so that user typing it and immediately clicking "Insert" would not see the
+// warning.
+// Since the notification is called in weld::Entry context, we can only rely on what's available for
+// used weld::Entry's notification; specifically, we have to call spin buttons' get_text() instead
+// of get_value(), because the latter is not guaranteed to return an up-to-date value at this point
+// (depends on vcl plugin used).
+IMPL_LINK( SwInsTableDlg, ModifyRowCol, weld::Entry&, rEdit, void )
+{
+ sal_Int64 nRow = m_xRowSpinButton->get_text().toInt64();
+ sal_Int64 nCol = m_xColSpinButton->get_text().toInt64();
+ if (nRow > 255)
+ {
+ m_xRowSpinButton->set_message_type(weld::EntryMessageType::Warning);
+ m_xWarning->set_visible(true);
+ }
+ else
+ {
+ m_xRowSpinButton->set_message_type(weld::EntryMessageType::Normal);
+ }
+ if (nCol > 63)
+ {
+ m_xColSpinButton->set_message_type(weld::EntryMessageType::Warning);
+ m_xWarning->set_visible(true);
+ }
+ else
+ {
+ m_xColSpinButton->set_message_type(weld::EntryMessageType::Normal);
+ }
+ if (nRow <= 255 && nCol <= 63)
+ {
+ m_xWarning->set_visible(false);
+ }
+ if (&rEdit == m_xColSpinButton.get())
+ return;
+
+ if(!nRow)
+ nRow = 1;
+
+ // adjust depending NF for repeated rows
+ sal_Int64 nMax = ( nRow == 1 )? 1 : nRow - 1 ;
+ sal_Int64 nActVal = m_xRepeatHeaderNF->get_value();
+
+ m_xRepeatHeaderNF->set_max( nMax );
+
+ if( nActVal > nMax )
+ m_xRepeatHeaderNF->set_value( nMax );
+ else if( nActVal < m_nEnteredValRepeatHeaderNF )
+ m_xRepeatHeaderNF->set_value(std::min(m_nEnteredValRepeatHeaderNF, nMax));
+}
+
+IMPL_LINK_NOARG(SwInsTableDlg, CheckBoxHdl, weld::Toggleable&, void)
+{
+ m_xRepeatHeaderCB->set_sensitive(m_xHeaderCB->get_active());
+ RepeatHeaderCheckBoxHdl(*m_xRepeatHeaderCB);
+}
+
+IMPL_LINK_NOARG(SwInsTableDlg, RepeatHeaderCheckBoxHdl, weld::Toggleable&, void)
+{
+ m_xRepeatGroup->set_sensitive(m_xHeaderCB->get_active() && m_xRepeatHeaderCB->get_active());
+}
+
+IMPL_LINK_NOARG(SwInsTableDlg, ModifyRepeatHeaderNF_Hdl, weld::SpinButton&, void)
+{
+ m_nEnteredValRepeatHeaderNF = m_xRepeatHeaderNF->get_value();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/mergetbl.cxx b/sw/source/ui/table/mergetbl.cxx
new file mode 100644
index 0000000000..c715b8a5f6
--- /dev/null
+++ b/sw/source/ui/table/mergetbl.cxx
@@ -0,0 +1,40 @@
+/* -*- 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 <mergetbl.hxx>
+
+SwMergeTableDlg::SwMergeTableDlg(weld::Window* pParent, bool& rWithPrev)
+ : GenericDialogController(pParent, "modules/swriter/ui/mergetabledialog.ui", "MergeTableDialog")
+ , m_rMergePrev(rWithPrev)
+ , m_xMergePrevRB(m_xBuilder->weld_radio_button("prev"))
+{
+ m_xMergePrevRB->set_active(true);
+}
+
+void SwMergeTableDlg::Apply() { m_rMergePrev = m_xMergePrevRB->get_active(); }
+
+short SwMergeTableDlg::run()
+{
+ int nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/rowht.cxx b/sw/source/ui/table/rowht.cxx
new file mode 100644
index 0000000000..f46297bf7d
--- /dev/null
+++ b/sw/source/ui/table/rowht.cxx
@@ -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 .
+ */
+
+#include <svtools/unitconv.hxx>
+
+#include <fmtfsize.hxx>
+#include <swtypes.hxx>
+#include <rowht.hxx>
+#include <wrtsh.hxx>
+#include <wdocsh.hxx>
+#include <view.hxx>
+#include <swmodule.hxx>
+#include <usrpref.hxx>
+
+void SwTableHeightDlg::Apply()
+{
+ SwTwips nHeight = static_cast< SwTwips >(m_xHeightEdit->denormalize(m_xHeightEdit->get_value(FieldUnit::TWIP)));
+ SwFormatFrameSize aSz(SwFrameSize::Fixed, 0, nHeight);
+
+ SwFrameSize eFrameSize = m_xAutoHeightCB->get_active() ? SwFrameSize::Minimum : SwFrameSize::Fixed;
+ if(eFrameSize != aSz.GetHeightSizeType())
+ {
+ aSz.SetHeightSizeType(eFrameSize);
+ }
+ m_rSh.SetRowHeight(aSz);
+}
+
+SwTableHeightDlg::SwTableHeightDlg(weld::Window *pParent, SwWrtShell &rS)
+ : GenericDialogController(pParent, "modules/swriter/ui/rowheight.ui", "RowHeightDialog")
+ , m_rSh(rS)
+ , m_xHeightEdit(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM))
+ , m_xAutoHeightCB(m_xBuilder->weld_check_button("fit"))
+{
+ FieldUnit eFieldUnit = SW_MOD()->GetUsrPref( dynamic_cast< const SwWebDocShell*>(
+ m_rSh.GetView().GetDocShell() ) != nullptr )->GetMetric();
+ ::SetFieldUnit(*m_xHeightEdit, eFieldUnit);
+
+ m_xHeightEdit->set_min(MINLAY, FieldUnit::TWIP);
+ std::unique_ptr<SwFormatFrameSize> pSz = m_rSh.GetRowHeight();
+ if (pSz)
+ {
+ auto nHeight = pSz->GetHeight();
+ m_xAutoHeightCB->set_active(pSz->GetHeightSizeType() != SwFrameSize::Fixed);
+ m_xHeightEdit->set_value(m_xHeightEdit->normalize(nHeight), FieldUnit::TWIP);
+ }
+}
+
+short SwTableHeightDlg::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/splittbl.cxx b/sw/source/ui/table/splittbl.cxx
new file mode 100644
index 0000000000..5a7ef0ae08
--- /dev/null
+++ b/sw/source/ui/table/splittbl.cxx
@@ -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 .
+ */
+
+#include <wrtsh.hxx>
+#include <splittbl.hxx>
+#include <tblenum.hxx>
+
+SplitTable_HeadlineOption SwSplitTableDlg::m_eRememberedSplitOption
+ = SplitTable_HeadlineOption::ContentCopy;
+
+SwSplitTableDlg::SwSplitTableDlg(weld::Window* pParent, SwWrtShell& rSh)
+ : GenericDialogController(pParent, "modules/swriter/ui/splittable.ui", "SplitTableDialog")
+ , m_xBoxAttrCopyWithParaRB(m_xBuilder->weld_radio_button("customheadingapplystyle"))
+ , m_xBoxAttrCopyNoParaRB(m_xBuilder->weld_radio_button("customheading"))
+ , m_xBorderCopyRB(m_xBuilder->weld_radio_button("noheading"))
+ , m_rShell(rSh)
+ , m_nSplit(SplitTable_HeadlineOption::ContentCopy)
+{
+ // tdf#131759 - remember last used option in split table dialog
+ m_nSplit = m_eRememberedSplitOption;
+ switch (m_nSplit)
+ {
+ case SplitTable_HeadlineOption::BoxAttrAllCopy:
+ m_xBoxAttrCopyWithParaRB->set_active(true);
+ break;
+ case SplitTable_HeadlineOption::BoxAttrCopy:
+ m_xBoxAttrCopyNoParaRB->set_active(true);
+ break;
+ case SplitTable_HeadlineOption::BorderCopy:
+ m_xBorderCopyRB->set_active(true);
+ break;
+ case SplitTable_HeadlineOption::NONE:
+ case SplitTable_HeadlineOption::ContentCopy:
+ default:
+ // Use the default value in case of an invalid option
+ m_nSplit = SplitTable_HeadlineOption::ContentCopy;
+ }
+}
+
+void SwSplitTableDlg::Apply()
+{
+ m_nSplit = SplitTable_HeadlineOption::ContentCopy;
+ if (m_xBoxAttrCopyWithParaRB->get_active())
+ m_nSplit = SplitTable_HeadlineOption::BoxAttrAllCopy;
+ else if (m_xBoxAttrCopyNoParaRB->get_active())
+ m_nSplit = SplitTable_HeadlineOption::BoxAttrCopy;
+ else if (m_xBorderCopyRB->get_active())
+ m_nSplit = SplitTable_HeadlineOption::BorderCopy;
+
+ // tdf#131759 - remember last used option in split table dialog
+ m_eRememberedSplitOption = m_nSplit;
+
+ m_rShell.SplitTable(m_nSplit);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/tabledlg.cxx b/sw/source/ui/table/tabledlg.cxx
new file mode 100644
index 0000000000..daedfffe46
--- /dev/null
+++ b/sw/source/ui/table/tabledlg.cxx
@@ -0,0 +1,1762 @@
+/* -*- 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 <hintids.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svl/ctloptions.hxx>
+#include <swmodule.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtlsplt.hxx>
+
+#include <fmtrowsplt.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/sfxdlg.hxx>
+
+#include <strings.hrc>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <uitool.hxx>
+#include <tabledlg.hxx>
+#include "../../uibase/table/tablepg.hxx"
+#include <tablemgr.hxx>
+#include <pagedesc.hxx>
+#include <uiitems.hxx>
+#include <poolfmt.hxx>
+#include <swtablerep.hxx>
+#include <SwStyleNameMapper.hxx>
+
+#include <cmdid.h>
+#include <svx/dialogs.hrc>
+#include <svx/flagsdef.hxx>
+#include <osl/diagnose.h>
+#include <officecfg/Office/Common.hxx>
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+
+using namespace ::com::sun::star;
+
+SwFormatTablePage::SwFormatTablePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/formattablepage.ui", "FormatTablePage", &rSet)
+ , m_pTableData(nullptr)
+ , m_nSaveWidth(0)
+ , m_nMinTableWidth(MINLAY)
+ , m_bModified(false)
+ , m_bFull(false)
+ , m_bHtmlMode(false)
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xWidthFT(m_xBuilder->weld_label("widthft"))
+ , m_xWidthMF(new SwPercentField(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM)))
+ , m_xRelWidthCB(m_xBuilder->weld_check_button("relwidth"))
+ , m_xFullBtn(m_xBuilder->weld_radio_button("full"))
+ , m_xLeftBtn(m_xBuilder->weld_radio_button("left"))
+ , m_xFromLeftBtn(m_xBuilder->weld_radio_button("fromleft"))
+ , m_xRightBtn(m_xBuilder->weld_radio_button("right"))
+ , m_xCenterBtn(m_xBuilder->weld_radio_button("center"))
+ , m_xFreeBtn(m_xBuilder->weld_radio_button("free"))
+ , m_xLeftFT(m_xBuilder->weld_label("leftft"))
+ , m_xLeftMF(new SwPercentField(m_xBuilder->weld_metric_spin_button("leftmf", FieldUnit::CM)))
+ , m_xRightFT(m_xBuilder->weld_label("rightft"))
+ , m_xRightMF(new SwPercentField(m_xBuilder->weld_metric_spin_button("rightmf", FieldUnit::CM)))
+ , m_xTopFT(m_xBuilder->weld_label("aboveft"))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("abovemf", FieldUnit::CM))
+ , m_xBottomFT(m_xBuilder->weld_label("belowft"))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("belowmf", FieldUnit::CM))
+ , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("textdirection")))
+ , m_xProperties(m_xBuilder->weld_widget("properties"))
+{
+ m_xWidthMF->GetMetricFieldRange(m_nOrigWidthMin, m_nOrigWidthMax);
+ m_xLeftMF->GetMetricFieldRange(m_nOrigLeftMin, m_nOrigLeftMax);
+ m_xRightMF->GetMetricFieldRange(m_nOrigRightMin, m_nOrigRightMax);
+
+ //lock these to initial sizes so they don't change on percent to non percent change
+ Size aPrefSize(m_xLeftMF->get()->get_preferred_size());
+ m_xLeftMF->get()->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+ m_xRightMF->get()->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+ m_xWidthMF->get()->set_size_request(aPrefSize.Width(), aPrefSize.Height());
+
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+ m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+
+ SetExchangeSupport();
+
+ if(const SfxUInt16Item* pModeItem = rSet.GetItemIfSet(SID_HTML_MODE, false))
+ m_bHtmlMode = 0 != (pModeItem->GetValue() & HTMLMODE_ON);
+
+ bool bCTL = SvtCTLOptions::IsCTLFontEnabled();
+ m_xProperties->set_visible(!m_bHtmlMode && bCTL);
+
+ Init();
+}
+
+SwFormatTablePage::~SwFormatTablePage()
+{
+}
+
+void SwFormatTablePage::Init()
+{
+ m_xLeftMF->SetMetricFieldMin(-999999);
+ m_xRightMF->SetMetricFieldMin(-999999);
+
+ //handler
+ Link<weld::Toggleable&,void> aLk2 = LINK( this, SwFormatTablePage, AutoClickHdl );
+ m_xFullBtn->connect_toggled( aLk2 );
+ m_xFreeBtn->connect_toggled( aLk2 );
+ m_xLeftBtn->connect_toggled( aLk2 );
+ m_xFromLeftBtn->connect_toggled( aLk2 );
+ m_xRightBtn->connect_toggled( aLk2 );
+ m_xCenterBtn->connect_toggled( aLk2 );
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwFormatTablePage, ValueChangedHdl);
+ m_xTopMF->connect_value_changed(aLk);
+ m_xBottomMF->connect_value_changed(aLk);
+ m_xRightMF->connect_value_changed(aLk);
+ m_xLeftMF->connect_value_changed(aLk);
+ m_xWidthMF->connect_value_changed(aLk);
+
+ m_xRelWidthCB->connect_toggled(LINK( this, SwFormatTablePage, RelWidthClickHdl ));
+}
+
+IMPL_LINK( SwFormatTablePage, RelWidthClickHdl, weld::Toggleable&, rBtn, void )
+{
+ OSL_ENSURE(m_pTableData, "table data not available?");
+ bool bIsChecked = rBtn.get_active();
+ sal_Int64 nLeft = m_xLeftMF->DenormalizePercent(m_xLeftMF->get_value(FieldUnit::TWIP));
+ sal_Int64 nRight = m_xRightMF->DenormalizePercent(m_xRightMF->get_value(FieldUnit::TWIP));
+ m_xWidthMF->ShowPercent(bIsChecked);
+ m_xLeftMF->ShowPercent(bIsChecked);
+ m_xRightMF->ShowPercent(bIsChecked);
+
+ if (bIsChecked)
+ {
+ m_xWidthMF->SetRefValue(m_pTableData->GetSpace());
+ m_xLeftMF->SetRefValue(m_pTableData->GetSpace());
+ m_xRightMF->SetRefValue(m_pTableData->GetSpace());
+ m_xLeftMF->SetMetricFieldMin(0); //will be overwritten by the Percentfield
+ m_xRightMF->SetMetricFieldMin(0); //ditto
+ m_xLeftMF->SetMetricFieldMax(99);
+ m_xRightMF->SetMetricFieldMax(99);
+ m_xLeftMF->set_value(m_xLeftMF->NormalizePercent(nLeft ), FieldUnit::TWIP );
+ m_xRightMF->set_value(m_xRightMF->NormalizePercent(nRight ), FieldUnit::TWIP );
+ }
+ else
+ ModifyHdl(*m_xLeftMF->get()); //correct values again
+
+ if (m_xFreeBtn->get_active())
+ {
+ bool bEnable = !rBtn.get_active();
+ m_xRightMF->set_sensitive(bEnable);
+ m_xRightFT->set_sensitive(bEnable);
+ }
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SwFormatTablePage, AutoClickHdl, weld::Toggleable&, void)
+{
+ bool bRestore = true,
+ bLeftEnable = false,
+ bRightEnable= false,
+ bWidthEnable= false,
+ bOthers = true;
+ if (m_xFullBtn->get_active())
+ {
+ m_xLeftMF->set_value(0);
+ m_xRightMF->set_value(0);
+ m_nSaveWidth = static_cast<SwTwips>(m_xWidthMF->DenormalizePercent(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ m_xWidthMF->set_value(m_xWidthMF->NormalizePercent(m_pTableData->GetSpace()), FieldUnit::TWIP);
+ m_bFull = true;
+ bRestore = false;
+ }
+ else if (m_xLeftBtn->get_active())
+ {
+ bRightEnable = bWidthEnable = true;
+ m_xLeftMF->set_value(0);
+ }
+ else if (m_xFromLeftBtn->get_active())
+ {
+ bLeftEnable = bWidthEnable = true;
+ m_xRightMF->set_value(0);
+ }
+ else if (m_xRightBtn->get_active())
+ {
+ bLeftEnable = bWidthEnable = true;
+ m_xRightMF->set_value(0);
+ }
+ else if (m_xCenterBtn->get_active())
+ {
+ bLeftEnable = bWidthEnable = true;
+ }
+ else if (m_xFreeBtn->get_active())
+ {
+ RightModify();
+ bLeftEnable = true;
+ bWidthEnable = true;
+ bOthers = false;
+ }
+ m_xLeftMF->set_sensitive(bLeftEnable);
+ m_xLeftFT->set_sensitive(bLeftEnable);
+ m_xWidthMF->set_sensitive(bWidthEnable);
+ m_xWidthFT->set_sensitive(bWidthEnable);
+ if ( bOthers )
+ {
+ m_xRightMF->set_sensitive(bRightEnable);
+ m_xRightFT->set_sensitive(bRightEnable);
+ m_xRelWidthCB->set_sensitive(bWidthEnable);
+ }
+
+ if(m_bFull && bRestore)
+ {
+ //After being switched on automatic, the width was pinned
+ //in order to restore the width while switching back to.
+ m_bFull = false;
+ m_xWidthMF->set_value(m_xWidthMF->NormalizePercent(m_nSaveWidth ), FieldUnit::TWIP );
+ }
+ ModifyHdl(*m_xWidthMF->get());
+ m_bModified = true;
+}
+
+void SwFormatTablePage::RightModify()
+{
+ if (!m_xFreeBtn->get_active())
+ return;
+
+ bool bEnable = m_xRightMF->get_value() == 0;
+ m_xRelWidthCB->set_sensitive(bEnable);
+ if ( !bEnable )
+ {
+ m_xRelWidthCB->set_active(false);
+ RelWidthClickHdl(*m_xRelWidthCB);
+ }
+ bEnable = m_xRelWidthCB->get_active();
+ m_xRightMF->set_sensitive(!bEnable);
+ m_xRightFT->set_sensitive(!bEnable);
+}
+
+IMPL_LINK( SwFormatTablePage, ValueChangedHdl, weld::MetricSpinButton&, rEdit, void )
+{
+ if (m_xRightMF->get() == &rEdit)
+ RightModify();
+ ModifyHdl(rEdit);
+}
+
+void SwFormatTablePage::ModifyHdl(const weld::MetricSpinButton& rEdit, bool bAllowInconsistencies)
+{
+ SwTwips nCurWidth = static_cast< SwTwips >(m_xWidthMF->DenormalizePercent(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ SwTwips nPrevWidth = nCurWidth;
+ SwTwips nRight = static_cast< SwTwips >(m_xRightMF->DenormalizePercent(m_xRightMF->get_value(FieldUnit::TWIP)));
+ SwTwips nLeft = static_cast< SwTwips >(m_xLeftMF->DenormalizePercent(m_xLeftMF->get_value(FieldUnit::TWIP)));
+ SwTwips nDiff;
+
+ if (&rEdit == m_xWidthMF->get())
+ {
+ if( nCurWidth < MINLAY )
+ nCurWidth = MINLAY;
+ nDiff = nRight + nLeft + nCurWidth - m_pTableData->GetSpace() ;
+ //right aligned: only change the left margin
+ if (m_xRightBtn->get_active())
+ nLeft -= nDiff;
+ //left aligned: only change the right margin
+ else if(m_xLeftBtn->get_active())
+ nRight -= nDiff;
+ //left margin and width allowed - first right - then left
+ else if (m_xFromLeftBtn->get_active())
+ {
+ if( nRight >= nDiff )
+ nRight -= nDiff;
+ else
+ {
+ nDiff -= nRight;
+ nRight = 0;
+ if(nLeft >= nDiff)
+ nLeft -= nDiff;
+ else
+ {
+ nRight += nLeft - nDiff;
+ nLeft = 0;
+ nCurWidth = m_pTableData->GetSpace();
+ }
+ }
+ }
+ //centered: change both sides equally
+ else if (m_xCenterBtn->get_active())
+ {
+ if(nLeft != nRight)
+ {
+ nDiff += nLeft + nRight;
+ nLeft = nDiff/2;
+ nRight = nDiff/2;
+ }
+ else
+ {
+ nLeft -= nDiff/2;
+ nRight -= nDiff/2;
+ }
+ }
+ //free alignment: decrease both margins
+ else if (m_xFreeBtn->get_active())
+ {
+ nLeft -= nDiff/2;
+ nRight -= nDiff/2;
+ }
+ }
+ if (&rEdit == m_xRightMF->get())
+ {
+
+ if( nRight + nLeft > m_pTableData->GetSpace() - MINLAY )
+ nRight = m_pTableData->GetSpace() -nLeft - MINLAY;
+
+ nCurWidth = m_pTableData->GetSpace() - nLeft - nRight;
+ }
+ if (&rEdit == m_xLeftMF->get())
+ {
+ if(!m_xFromLeftBtn->get_active())
+ {
+ bool bCenter = m_xCenterBtn->get_active();
+ if( bCenter )
+ nRight = nLeft;
+ if(nRight + nLeft > m_pTableData->GetSpace() - MINLAY )
+ {
+ nLeft = bCenter ? (m_pTableData->GetSpace() - MINLAY) /2 :
+ (m_pTableData->GetSpace() - MINLAY) - nRight;
+ nRight = bCenter ? (m_pTableData->GetSpace() - MINLAY) /2 : nRight;
+ }
+ nCurWidth = m_pTableData->GetSpace() - nLeft - nRight;
+ }
+ else
+ {
+ //Upon changes on the left side the right margin will be changed at first,
+ //thereafter the width.
+ nDiff = nRight + nLeft + nCurWidth - m_pTableData->GetSpace() ;
+
+ nRight -= nDiff;
+ nCurWidth = m_pTableData->GetSpace() - nLeft - nRight;
+ }
+ }
+
+ m_xRightMF->set_value( m_xRightMF->NormalizePercent( nRight ), FieldUnit::TWIP );
+ m_xLeftMF->set_value( m_xLeftMF->NormalizePercent( nLeft ), FieldUnit::TWIP );
+
+ if (nCurWidth != nPrevWidth )
+ {
+ m_xWidthMF->set_value(m_xWidthMF->NormalizePercent(nCurWidth), FieldUnit::TWIP);
+
+ // tdf#135021 if the user changed the width spinbutton, and in this
+ // ModifyHdl we changed the value of that width spinbutton, then rerun
+ // the ModifyHdl on the replaced value so the left/right/width value
+ // relationships are consistent.
+ // But (tdf#135693) only make one effort of rectifying the inconsistency
+ if (&rEdit == m_xWidthMF->get() && !bAllowInconsistencies)
+ ModifyHdl(rEdit, true);
+ }
+
+ m_bModified = true;
+}
+
+std::unique_ptr<SfxTabPage> SwFormatTablePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwFormatTablePage>(pPage, pController, *rAttrSet);
+}
+
+bool SwFormatTablePage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ //Test if one of the controls still has the focus
+ if (m_xWidthMF->has_focus())
+ ModifyHdl(*m_xWidthMF->get());
+ else if (m_xLeftMF->has_focus())
+ ModifyHdl(*m_xLeftMF->get());
+ else if (m_xRightMF->has_focus())
+ ModifyHdl(*m_xRightMF->get());
+ else if (m_xTopMF->has_focus())
+ ModifyHdl(*m_xTopMF);
+ else if (m_xBottomMF->has_focus())
+ ModifyHdl(*m_xBottomMF);
+
+ if (m_bModified)
+ {
+ if (m_xBottomMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() )
+ {
+ SvxULSpaceItem aULSpace(RES_UL_SPACE);
+ aULSpace.SetUpper(m_xTopMF->denormalize(m_xTopMF->get_value(FieldUnit::TWIP)));
+ aULSpace.SetLower(m_xBottomMF->denormalize(m_xBottomMF->get_value(FieldUnit::TWIP)));
+ rCoreSet->Put(aULSpace);
+ }
+
+ }
+ if (m_xNameED->get_value_changed_from_saved())
+ {
+ rCoreSet->Put(SfxStringItem(FN_PARAM_TABLE_NAME, m_xNameED->get_text()));
+ m_bModified = true;
+ }
+
+ if (m_xTextDirectionLB->get_visible())
+ {
+ if (m_xTextDirectionLB->get_value_changed_from_saved())
+ {
+ SvxFrameDirection nDirection = m_xTextDirectionLB->get_active_id();
+ rCoreSet->Put(SvxFrameDirectionItem(nDirection, RES_FRAMEDIR));
+ m_bModified = true;
+ }
+ }
+
+ return m_bModified;
+}
+
+void SwFormatTablePage::Reset( const SfxItemSet* )
+{
+ const SfxItemSet& rSet = GetItemSet();
+
+ if(m_bHtmlMode)
+ {
+ m_xNameED->set_sensitive(false);
+ m_xTopFT->hide();
+ m_xTopMF->hide();
+ m_xBottomFT->hide();
+ m_xBottomMF->hide();
+ m_xFreeBtn->set_sensitive(false);
+ }
+
+ // set back to original state
+ m_xRelWidthCB->set_active(false);
+ m_xWidthMF->ShowPercent(false);
+ m_xLeftMF->ShowPercent(false);
+ m_xRightMF->ShowPercent(false);
+ m_xWidthMF->SetMetricFieldRange(m_nOrigWidthMin, m_nOrigWidthMax);
+ m_xLeftMF->SetMetricFieldRange(m_nOrigLeftMin, m_nOrigLeftMax);
+ m_xRightMF->SetMetricFieldRange(m_nOrigRightMin, m_nOrigRightMax);
+
+ FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
+ m_xWidthMF->SetMetric(aMetric);
+ m_xRightMF->SetMetric(aMetric);
+ m_xLeftMF->SetMetric(aMetric);
+ SetFieldUnit(*m_xTopMF, aMetric);
+ SetFieldUnit(*m_xBottomMF, aMetric);
+
+ //Name
+ if(const SfxStringItem* pNameItem = rSet.GetItemIfSet( FN_PARAM_TABLE_NAME, false ))
+ {
+ m_xNameED->set_text(pNameItem->GetValue());
+ m_xNameED->save_value();
+ }
+
+ if(const SwPtrItem* pRepItem = rSet.GetItemIfSet( FN_TABLE_REP, false ))
+ {
+ m_pTableData = static_cast<SwTableRep*>( pRepItem->GetValue());
+ if (!m_xOrigTableData)
+ m_xOrigTableData.reset(new SwTableRep(*m_pTableData));
+ else // tdf#134925 and tdf#134913, reset back to the original data seen on dialog creation
+ *m_pTableData = *m_xOrigTableData;
+
+ m_nMinTableWidth = m_pTableData->GetColCount() * MINLAY;
+
+ if(m_pTableData->GetWidthPercent())
+ {
+ m_xRelWidthCB->set_active(true);
+ RelWidthClickHdl(*m_xRelWidthCB);
+ m_xWidthMF->set_value(m_pTableData->GetWidthPercent(), FieldUnit::PERCENT);
+
+ m_xWidthMF->save_value();
+ m_nSaveWidth = static_cast< SwTwips >(m_xWidthMF->get_value(FieldUnit::PERCENT));
+ }
+ else
+ {
+ m_xWidthMF->set_value(m_xWidthMF->NormalizePercent(
+ m_pTableData->GetWidth()), FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+ m_nSaveWidth = m_pTableData->GetWidth();
+ m_nMinTableWidth = std::min( m_nSaveWidth, m_nMinTableWidth );
+ }
+
+ m_xWidthMF->SetRefValue(m_pTableData->GetSpace());
+
+ m_xLeftMF->set_value(m_xLeftMF->NormalizePercent(
+ m_pTableData->GetLeftSpace()), FieldUnit::TWIP);
+ m_xRightMF->set_value(m_xRightMF->NormalizePercent(
+ m_pTableData->GetRightSpace()), FieldUnit::TWIP);
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+
+ bool bSetRight = false, bSetLeft = false;
+ switch( m_pTableData->GetAlign() )
+ {
+ case text::HoriOrientation::NONE:
+ m_xFreeBtn->set_active(true);
+ if (m_xRelWidthCB->get_active())
+ bSetRight = true;
+ break;
+ case text::HoriOrientation::FULL:
+ {
+ bSetRight = bSetLeft = true;
+ m_xFullBtn->set_active(true);
+ m_xWidthMF->set_sensitive(false);
+ m_xRelWidthCB->set_sensitive(false);
+ m_xWidthFT->set_sensitive(false);
+ }
+ break;
+ case text::HoriOrientation::LEFT:
+ {
+ bSetLeft = true;
+ m_xLeftBtn->set_active(true);
+ }
+ break;
+ case text::HoriOrientation::LEFT_AND_WIDTH :
+ {
+ bSetRight = true;
+ m_xFromLeftBtn->set_active(true);
+ }
+ break;
+ case text::HoriOrientation::RIGHT:
+ {
+ bSetRight = true;
+ m_xRightBtn->set_active(true);
+ }
+ break;
+ case text::HoriOrientation::CENTER:
+ {
+ bSetRight = true;
+ m_xCenterBtn->set_active(true);
+ }
+ break;
+ }
+ if ( bSetRight )
+ {
+ m_xRightMF->set_sensitive(false);
+ m_xRightFT->set_sensitive(false);
+ }
+ if ( bSetLeft )
+ {
+ m_xLeftMF->set_sensitive(false);
+ m_xLeftFT->set_sensitive(false);
+ }
+
+ }
+
+ //Margins
+ if(const SvxULSpaceItem* pSpaceItem = rSet.GetItemIfSet( RES_UL_SPACE, false ))
+ {
+ m_xTopMF->set_value(m_xTopMF->normalize(
+ pSpaceItem->GetUpper()), FieldUnit::TWIP);
+ m_xBottomMF->set_value(m_xBottomMF->normalize(
+ pSpaceItem->GetLower()), FieldUnit::TWIP);
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ }
+
+ //Text direction
+ if( const SvxFrameDirectionItem* pDirectionItem = rSet.GetItemIfSet( RES_FRAMEDIR ) )
+ {
+ SvxFrameDirection nVal = pDirectionItem->GetValue();
+ m_xTextDirectionLB->set_active_id(nVal);
+ m_xTextDirectionLB->save_value();
+ }
+
+ m_xWidthMF->set_max( 2*m_xWidthMF->NormalizePercent( m_pTableData->GetSpace() ), FieldUnit::TWIP );
+ m_xRightMF->set_max( m_xRightMF->NormalizePercent( m_pTableData->GetSpace() ), FieldUnit::TWIP );
+ m_xLeftMF->set_max( m_xLeftMF->NormalizePercent( m_pTableData->GetSpace() ), FieldUnit::TWIP );
+ m_xWidthMF->set_min( m_xWidthMF->NormalizePercent( m_nMinTableWidth ), FieldUnit::TWIP );
+}
+
+void SwFormatTablePage::ActivatePage( const SfxItemSet& rSet )
+{
+ OSL_ENSURE(m_pTableData, "table data not available?");
+ if(SfxItemState::SET != rSet.GetItemState( FN_TABLE_REP ))
+ return;
+
+ SwTwips nCurWidth = text::HoriOrientation::FULL != m_pTableData->GetAlign() ?
+ m_pTableData->GetWidth() :
+ m_pTableData->GetSpace();
+ if(m_pTableData->GetWidthPercent() != 0 ||
+ nCurWidth == m_xWidthMF->DenormalizePercent(m_xWidthMF->get_value(FieldUnit::TWIP)))
+ return;
+
+ m_xWidthMF->set_value(m_xWidthMF->NormalizePercent(
+ nCurWidth), FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+ m_nSaveWidth = nCurWidth;
+ m_xLeftMF->set_value(m_xLeftMF->NormalizePercent(
+ m_pTableData->GetLeftSpace()), FieldUnit::TWIP);
+ m_xLeftMF->save_value();
+ m_xRightMF->set_value(m_xRightMF->NormalizePercent(
+ m_pTableData->GetRightSpace()), FieldUnit::TWIP);
+ m_xRightMF->save_value();
+}
+
+DeactivateRC SwFormatTablePage::DeactivatePage( SfxItemSet* _pSet )
+{
+ //test the table name for spaces
+ OUString sTableName = m_xNameED->get_text();
+ if(sTableName.indexOf(' ') != -1)
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_WRONG_TABLENAME)));
+ xInfoBox->run();
+ m_xNameED->grab_focus();
+ return DeactivateRC::KeepPage;
+ }
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ if(m_bModified)
+ {
+ SwTwips lLeft = static_cast< SwTwips >(m_xLeftMF->DenormalizePercent(m_xLeftMF->get_value(FieldUnit::TWIP)));
+ SwTwips lRight = static_cast< SwTwips >(m_xRightMF->DenormalizePercent(m_xRightMF->get_value(FieldUnit::TWIP)));
+
+ if( m_xLeftMF->get_value_changed_from_saved() ||
+ m_xRightMF->get_value_changed_from_saved() )
+ {
+ m_pTableData->SetWidthChanged();
+ m_pTableData->SetLeftSpace( lLeft);
+ m_pTableData->SetRightSpace( lRight);
+ }
+
+ SwTwips lWidth;
+ if (m_xRelWidthCB->get_active() && m_xRelWidthCB->get_sensitive())
+ {
+ lWidth = m_pTableData->GetSpace() - lRight - lLeft;
+ const sal_uInt16 nPercentWidth = m_xWidthMF->get_value(FieldUnit::PERCENT);
+ if(m_pTableData->GetWidthPercent() != nPercentWidth)
+ {
+ m_pTableData->SetWidthPercent(nPercentWidth);
+ m_pTableData->SetWidthChanged();
+ }
+ }
+ else
+ {
+ m_pTableData->SetWidthPercent(0);
+ lWidth = static_cast<SwTwips>(m_xWidthMF->DenormalizePercent(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ }
+ m_pTableData->SetWidth(lWidth);
+
+ SwTwips nColSum = 0;
+
+ for( sal_uInt16 i = 0; i < m_pTableData->GetColCount(); i++)
+ {
+ nColSum += m_pTableData->GetColumns()[i].nWidth;
+ }
+ if(nColSum != m_pTableData->GetWidth())
+ {
+ SwTwips nMinWidth = std::min( tools::Long(MINLAY),
+ static_cast<tools::Long>(m_pTableData->GetWidth() /
+ m_pTableData->GetColCount() - 1));
+ SwTwips nDiff = nColSum - m_pTableData->GetWidth();
+ while ( std::abs(nDiff) > m_pTableData->GetColCount() + 1 )
+ {
+ SwTwips nSub = nDiff / m_pTableData->GetColCount();
+ for( sal_uInt16 i = 0; i < m_pTableData->GetColCount(); i++)
+ {
+ if(m_pTableData->GetColumns()[i].nWidth - nMinWidth > nSub)
+ {
+ m_pTableData->GetColumns()[i].nWidth -= nSub;
+ nDiff -= nSub;
+ }
+ else
+ {
+ nDiff -= m_pTableData->GetColumns()[i].nWidth - nMinWidth;
+ m_pTableData->GetColumns()[i].nWidth = nMinWidth;
+ }
+
+ }
+ }
+ }
+
+ sal_Int16 nAlign = 0;
+ if (m_xRightBtn->get_active())
+ nAlign = text::HoriOrientation::RIGHT;
+ else if(m_xLeftBtn->get_active())
+ nAlign = text::HoriOrientation::LEFT;
+ else if(m_xFromLeftBtn->get_active())
+ nAlign = text::HoriOrientation::LEFT_AND_WIDTH;
+ else if(m_xCenterBtn->get_active())
+ nAlign = text::HoriOrientation::CENTER;
+ else if(m_xFreeBtn->get_active())
+ nAlign = text::HoriOrientation::NONE;
+ else if(m_xFullBtn->get_active())
+ {
+ nAlign = text::HoriOrientation::FULL;
+ lWidth = lAutoWidth;
+ }
+ if(nAlign != m_pTableData->GetAlign())
+ {
+ m_pTableData->SetWidthChanged();
+ m_pTableData->SetAlign(nAlign);
+ }
+
+ if(m_pTableData->GetWidth() != lWidth )
+ {
+ m_pTableData->SetWidthChanged();
+ m_pTableData->SetWidth(
+ nAlign == text::HoriOrientation::FULL ? m_pTableData->GetSpace() : lWidth );
+ }
+ if(m_pTableData->HasWidthChanged())
+ _pSet->Put(SwPtrItem(FN_TABLE_REP, m_pTableData));
+ }
+ }
+ return DeactivateRC::LeavePage;
+}
+
+//Description: Page column configuration
+SwTableColumnPage::SwTableColumnPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/tablecolumnpage.ui", "TableColumnPage", &rSet)
+ , m_pTableData(nullptr)
+ , m_pSizeHdlEvent(nullptr)
+ , m_nTableWidth(0)
+ , m_nMinWidth(MINLAY)
+ , m_nMetFields(MET_FIELDS)
+ , m_nNoOfCols(0)
+ , m_nNoOfVisibleCols(0)
+ , m_bModified(false)
+ , m_bModifyTable(false)
+ , m_bPercentMode(false)
+ , m_aFieldArr { m_xBuilder->weld_metric_spin_button("width1", FieldUnit::CM),
+ m_xBuilder->weld_metric_spin_button("width2", FieldUnit::CM),
+ m_xBuilder->weld_metric_spin_button("width3", FieldUnit::CM),
+ m_xBuilder->weld_metric_spin_button("width4", FieldUnit::CM),
+ m_xBuilder->weld_metric_spin_button("width5", FieldUnit::CM)}
+ , m_aTextArr { m_xBuilder->weld_label("1"),
+ m_xBuilder->weld_label("2"),
+ m_xBuilder->weld_label("3"),
+ m_xBuilder->weld_label("4"),
+ m_xBuilder->weld_label("5")}
+ , m_xModifyTableCB(m_xBuilder->weld_check_button("adaptwidth"))
+ , m_xProportionalCB(m_xBuilder->weld_check_button("adaptcolumns"))
+ , m_xSpaceFT(m_xBuilder->weld_label("spaceft"))
+ , m_xSpaceSFT(m_xBuilder->weld_label("space"))
+ , m_xSpaceED(m_xBuilder->weld_metric_spin_button("spacefmt", FieldUnit::CM))
+ , m_xUpBtn(m_xBuilder->weld_button("next"))
+ , m_xDownBtn(m_xBuilder->weld_button("back"))
+{
+ SetExchangeSupport();
+
+ // fire off this handler to happen on next event loop when all the rest of
+ // the pages are instantiated and the dialog preferred size is that of the
+ // all the pages that currently exist and the rest to come after this one
+ m_pSizeHdlEvent = Application::PostUserEvent(LINK(this, SwTableColumnPage, SizeHdl));
+
+ const SfxUInt16Item* pModeItem = GetItemSet().GetItemIfSet(SID_HTML_MODE, false);
+ Init(pModeItem && pModeItem->GetValue() & HTMLMODE_ON);
+}
+
+IMPL_LINK_NOARG(SwTableColumnPage, SizeHdl, void*, void)
+{
+ m_pSizeHdlEvent = nullptr;
+
+ //tdf#120420 keeping showing column width fields unless
+ //the dialog begins to grow, then stop adding them
+ weld::Window* pTopLevel = GetFrameWeld();
+ Size aOrigSize = pTopLevel->get_preferred_size();
+ for (sal_uInt16 i = 0; i < MET_FIELDS; ++i)
+ {
+ m_aFieldArr[i].show();
+ m_aTextArr[i]->show();
+
+ if (pTopLevel->get_preferred_size().Width() > aOrigSize.Width())
+ {
+ m_nMetFields = i + 1;
+ m_aTextArr[i]->set_grid_width(1);
+ m_xUpBtn->set_grid_left_attach(m_nMetFields * 2 - 1);
+ break;
+ }
+ }
+
+ // tdf#143142 m_nMetFields has been updated and we need to re-check whether to show right button or not.
+ if (m_nNoOfVisibleCols > m_nMetFields)
+ {
+ m_xUpBtn->set_sensitive(true);
+ }
+
+}
+
+SwTableColumnPage::~SwTableColumnPage()
+{
+ if (m_pSizeHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pSizeHdlEvent);
+ m_pSizeHdlEvent = nullptr;
+ }
+}
+
+std::unique_ptr<SfxTabPage> SwTableColumnPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwTableColumnPage>(pPage, pController, *rAttrSet);
+}
+
+void SwTableColumnPage::Reset( const SfxItemSet* )
+{
+ const SfxItemSet& rSet = GetItemSet();
+
+ if(const SwPtrItem* pRepItem = rSet.GetItemIfSet( FN_TABLE_REP, false ))
+ {
+ m_pTableData = static_cast<SwTableRep*>( pRepItem->GetValue());
+ if (!m_xOrigTableData)
+ m_xOrigTableData.reset(new SwTableRep(*m_pTableData));
+ else // tdf#134925 and tdf#134913, reset back to the original data seen on dialog creation
+ *m_pTableData = *m_xOrigTableData;
+
+ m_nNoOfVisibleCols = m_pTableData->GetColCount();
+ m_nNoOfCols = m_pTableData->GetAllColCount();
+ m_nTableWidth = m_pTableData->GetAlign() != text::HoriOrientation::FULL &&
+ m_pTableData->GetAlign() != text::HoriOrientation::LEFT_AND_WIDTH?
+ m_pTableData->GetWidth() : m_pTableData->GetSpace();
+
+ for( sal_uInt16 i = 0; i < m_nNoOfCols; i++ )
+ {
+ if (m_pTableData->GetColumns()[i].nWidth < m_nMinWidth)
+ m_nMinWidth = m_pTableData->GetColumns()[i].nWidth;
+ }
+ sal_Int64 nMinTwips = m_aFieldArr[0].NormalizePercent( m_nMinWidth );
+ sal_Int64 nMaxTwips = m_aFieldArr[0].NormalizePercent( m_nTableWidth );
+ for( sal_uInt16 i = 0; (i < m_nMetFields) && (i < m_nNoOfVisibleCols); i++ )
+ {
+ m_aFieldArr[i].set_value( m_aFieldArr[i].NormalizePercent(
+ GetVisibleWidth(i) ), FieldUnit::TWIP );
+ m_aFieldArr[i].set_min(nMinTwips, FieldUnit::TWIP);
+ m_aFieldArr[i].set_max(nMaxTwips, FieldUnit::TWIP);
+ m_aFieldArr[i].set_sensitive(true);
+ m_aTextArr[i]->set_sensitive(true);
+ }
+
+ if (m_nNoOfVisibleCols > m_nMetFields)
+ {
+ m_xUpBtn->set_sensitive(true);
+ }
+
+ for( sal_uInt16 i = m_nNoOfVisibleCols; i < m_nMetFields; ++i )
+ {
+ m_aFieldArr[i].set_text(OUString());
+ m_aTextArr[i]->set_sensitive(false);
+ }
+ }
+ ActivatePage(rSet);
+}
+
+void SwTableColumnPage::Init(bool bWeb)
+{
+ FieldUnit aMetric = ::GetDfltMetric(bWeb);
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SwTableColumnPage, ValueChangedHdl);
+ for (sal_uInt16 i = 0; i < MET_FIELDS; ++i)
+ {
+ m_aValueTable[i] = i;
+ m_aFieldArr[i].SetMetric(aMetric);
+ m_aFieldArr[i].connect_value_changed(aLk);
+ }
+ SetFieldUnit(*m_xSpaceED, aMetric);
+
+ Link<weld::Button&,void> aClickLk = LINK(this, SwTableColumnPage, AutoClickHdl);
+ m_xUpBtn->connect_clicked(aClickLk);
+ m_xDownBtn->connect_clicked(aClickLk);
+
+ Link<weld::Toggleable&,void> aToggleLk = LINK(this, SwTableColumnPage, ModeHdl);
+ m_xModifyTableCB->connect_toggled(aToggleLk);
+ m_xProportionalCB->connect_toggled(aToggleLk);
+}
+
+IMPL_LINK(SwTableColumnPage, AutoClickHdl, weld::Button&, rControl, void)
+{
+ //move display window
+ if (&rControl == m_xDownBtn.get())
+ {
+ if(m_aValueTable[0] > 0)
+ {
+ for(sal_uInt16 & rn : m_aValueTable)
+ rn -= 1;
+ }
+ }
+ if (&rControl == m_xUpBtn.get())
+ {
+ if( m_aValueTable[ m_nMetFields -1 ] < m_nNoOfVisibleCols -1 )
+ {
+ for(sal_uInt16 & rn : m_aValueTable)
+ rn += 1;
+ }
+ }
+ for( sal_uInt16 i = 0; (i < m_nNoOfVisibleCols ) && ( i < m_nMetFields); i++ )
+ {
+ OUString sEntry('~');
+ OUString sIndex = OUString::number( m_aValueTable[i] + 1 );
+ sEntry += sIndex;
+ m_aTextArr[i]->set_label(sEntry);
+ }
+
+ m_xDownBtn->set_sensitive(m_aValueTable[0] > 0);
+ m_xUpBtn->set_sensitive(m_aValueTable[ m_nMetFields -1 ] < m_nNoOfVisibleCols -1 );
+ UpdateCols(0);
+}
+
+IMPL_LINK(SwTableColumnPage, ValueChangedHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ m_bModified = true;
+ ModifyHdl(&rEdit);
+}
+
+IMPL_LINK(SwTableColumnPage, ModeHdl, weld::Toggleable&, rBox, void)
+{
+ const bool bCheck = rBox.get_active();
+ if (&rBox == m_xProportionalCB.get())
+ {
+ if (bCheck)
+ m_xModifyTableCB->set_active(true);
+ m_xModifyTableCB->set_sensitive(!bCheck && m_bModifyTable);
+ }
+}
+
+bool SwTableColumnPage::FillItemSet( SfxItemSet* )
+{
+ for (SwPercentField & i : m_aFieldArr)
+ {
+ if (i.has_focus())
+ {
+ ModifyHdl(i.get());
+ break;
+ }
+ }
+
+ if (m_bModified)
+ {
+ m_pTableData->SetColsChanged();
+ }
+ return m_bModified;
+}
+
+void SwTableColumnPage::ModifyHdl(const weld::MetricSpinButton* pField)
+{
+ SwPercentField *pEdit = nullptr;
+ sal_uInt16 i;
+
+ for( i = 0; i < m_nMetFields; i++)
+ {
+ if (pField == m_aFieldArr[i].get())
+ {
+ pEdit = &m_aFieldArr[i];
+ break;
+ }
+ }
+
+ if (m_nMetFields <= i || !pEdit)
+ {
+ OSL_ENSURE(false, "cannot happen.");
+ return;
+ }
+
+ SetVisibleWidth(m_aValueTable[i], pEdit->DenormalizePercent(pEdit->get_value(FieldUnit::TWIP)));
+
+ UpdateCols( m_aValueTable[i] );
+}
+
+void SwTableColumnPage::UpdateCols( sal_uInt16 nCurrentPos )
+{
+ SwTwips nSum = 0;
+
+ for( sal_uInt16 i = 0; i < m_nNoOfCols; i++ )
+ {
+ nSum += (m_pTableData->GetColumns())[i].nWidth;
+ }
+ SwTwips nDiff = nSum - m_nTableWidth;
+
+ bool bModifyTableChecked = m_xModifyTableCB->get_active();
+ bool bProp = m_xProportionalCB->get_active();
+
+ if (!bModifyTableChecked && !bProp)
+ {
+ //The table width is constant, the difference is balanced with the other columns
+ sal_uInt16 nLoopCount = 0;
+ while( nDiff )
+ {
+ if( ++nCurrentPos == m_nNoOfVisibleCols)
+ {
+ nCurrentPos = 0;
+ ++nLoopCount;
+ //#i101353# in small tables it might not be possible to balance column width
+ if( nLoopCount > 1 )
+ break;
+ }
+ if( nDiff < 0 )
+ {
+ SetVisibleWidth(nCurrentPos, GetVisibleWidth(nCurrentPos) -nDiff);
+ nDiff = 0;
+ }
+ else if( GetVisibleWidth(nCurrentPos) >= nDiff + m_nMinWidth )
+ {
+ SetVisibleWidth(nCurrentPos, GetVisibleWidth(nCurrentPos) -nDiff);
+ nDiff = 0;
+ }
+ if( nDiff > 0 && GetVisibleWidth(nCurrentPos) > m_nMinWidth )
+ {
+ if( nDiff >= (GetVisibleWidth(nCurrentPos) - m_nMinWidth) )
+ {
+ nDiff -= (GetVisibleWidth(nCurrentPos) - m_nMinWidth);
+ SetVisibleWidth(nCurrentPos, m_nMinWidth);
+ }
+ else
+ {
+ nDiff = 0;
+ SetVisibleWidth(nCurrentPos, GetVisibleWidth(nCurrentPos) -nDiff);
+ }
+ OSL_ENSURE(nDiff >= 0, "nDiff < 0 cannot be here!");
+ }
+ }
+ }
+ else if (bModifyTableChecked && !bProp)
+ {
+ //Difference is balanced by the width of the table,
+ //other columns remain unchanged.
+ OSL_ENSURE(nDiff <= m_pTableData->GetSpace() - m_nTableWidth, "wrong maximum" );
+ SwTwips nActSpace = m_pTableData->GetSpace() - m_nTableWidth;
+ if(nDiff > nActSpace)
+ {
+ m_nTableWidth = m_pTableData->GetSpace();
+ SetVisibleWidth(nCurrentPos, GetVisibleWidth(nCurrentPos) - nDiff + nActSpace );
+ }
+ else
+ {
+ m_nTableWidth += nDiff;
+ }
+ }
+ else if (bModifyTableChecked && bProp)
+ {
+ //All columns will be changed proportionally with,
+ //the table width is adjusted accordingly.
+ const double fOrigColWidth = std::max(SwTwips(1), GetVisibleWidth(nCurrentPos) - nDiff);
+ const double fMaxWidth = std::max(m_pTableData->GetSpace(), m_nTableWidth);
+ const double fMaxPercent = fMaxWidth / m_nTableWidth;
+ const double fPercentChange = std::min(fMaxPercent, GetVisibleWidth(nCurrentPos)/fOrigColWidth);
+ SwTwips nNewTableSize = 0;
+ for( sal_uInt16 i = 0; i < m_nNoOfVisibleCols; i++ )
+ {
+ SwTwips nNewColWidth = round( fPercentChange * (i == nCurrentPos ? fOrigColWidth : GetVisibleWidth(i)) );
+ if ( nNewColWidth < MINLAY )
+ nNewColWidth = MINLAY;
+ SetVisibleWidth(i, nNewColWidth);
+ nNewTableSize += nNewColWidth;
+ }
+ m_nTableWidth = nNewTableSize;
+ }
+
+ if (!m_bPercentMode)
+ {
+ m_xSpaceED->set_value(m_xSpaceED->normalize(m_pTableData->GetSpace() - m_nTableWidth), FieldUnit::TWIP);
+ m_xSpaceSFT->set_label(m_xSpaceED->get_text());
+ }
+ else
+ m_xSpaceSFT->set_label(OUString());
+
+ for( sal_uInt16 i = 0; ( i < m_nNoOfVisibleCols ) && ( i < m_nMetFields ); i++)
+ {
+ m_aFieldArr[i].set_value(m_aFieldArr[i].NormalizePercent(
+ GetVisibleWidth(m_aValueTable[i]) ), FieldUnit::TWIP);
+ }
+}
+
+void SwTableColumnPage::ActivatePage( const SfxItemSet& )
+{
+ m_bPercentMode = m_pTableData->GetWidthPercent() != 0;
+ for( sal_uInt16 i = 0; (i < m_nMetFields) && (i < m_nNoOfVisibleCols); i++ )
+ {
+ m_aFieldArr[i].SetRefValue(m_pTableData->GetWidth());
+ m_aFieldArr[i].ShowPercent( m_bPercentMode );
+ }
+
+ const sal_uInt16 nTableAlign = m_pTableData->GetAlign();
+ if((text::HoriOrientation::FULL != nTableAlign && m_nTableWidth != m_pTableData->GetWidth()) ||
+ (text::HoriOrientation::FULL == nTableAlign && m_nTableWidth != m_pTableData->GetSpace()))
+ {
+ m_nTableWidth = text::HoriOrientation::FULL == nTableAlign ?
+ m_pTableData->GetSpace() :
+ m_pTableData->GetWidth();
+ UpdateCols(0);
+ }
+ m_bModifyTable = true;
+ if (m_pTableData->GetWidthPercent() ||
+ text::HoriOrientation::FULL == nTableAlign ||
+ m_pTableData->IsLineSelected() )
+ m_bModifyTable = false;
+ if (m_bPercentMode)
+ {
+ m_xModifyTableCB->set_active(false);
+ m_xProportionalCB->set_active(false);
+ }
+ else if (!m_bModifyTable)
+ {
+ m_xProportionalCB->set_active(false);
+ m_xModifyTableCB->set_active(false);
+ }
+ m_xSpaceFT->set_sensitive(!m_bPercentMode);
+ m_xSpaceSFT->set_sensitive(!m_bPercentMode);
+ m_xModifyTableCB->set_sensitive( !m_bPercentMode && m_bModifyTable );
+ m_xProportionalCB->set_sensitive(!m_bPercentMode && m_bModifyTable );
+
+ m_xSpaceED->set_value(m_xSpaceED->normalize(
+ m_pTableData->GetSpace() - m_nTableWidth), FieldUnit::TWIP);
+ m_xSpaceSFT->set_label(m_xSpaceED->get_text());
+
+}
+
+DeactivateRC SwTableColumnPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ if(text::HoriOrientation::FULL != m_pTableData->GetAlign() && m_pTableData->GetWidth() != m_nTableWidth)
+ {
+ m_pTableData->SetWidth(m_nTableWidth);
+ SwTwips nDiff = m_pTableData->GetSpace() - m_pTableData->GetWidth() -
+ m_pTableData->GetLeftSpace() - m_pTableData->GetRightSpace();
+ switch( m_pTableData->GetAlign() )
+ {
+ case text::HoriOrientation::RIGHT:
+ m_pTableData->SetLeftSpace(m_pTableData->GetLeftSpace() + nDiff);
+ break;
+ case text::HoriOrientation::LEFT:
+ m_pTableData->SetRightSpace(m_pTableData->GetRightSpace() + nDiff);
+ break;
+ case text::HoriOrientation::NONE:
+ {
+ SwTwips nDiff2 = nDiff/2;
+ if( nDiff > 0 ||
+ (-nDiff2 < m_pTableData->GetRightSpace() && - nDiff2 < m_pTableData->GetLeftSpace()))
+ {
+ m_pTableData->SetRightSpace(m_pTableData->GetRightSpace() + nDiff2);
+ m_pTableData->SetLeftSpace(m_pTableData->GetLeftSpace() + nDiff2);
+ }
+ else
+ {
+ if(m_pTableData->GetRightSpace() > m_pTableData->GetLeftSpace())
+ {
+ m_pTableData->SetLeftSpace(0);
+ m_pTableData->SetRightSpace(m_pTableData->GetSpace() - m_pTableData->GetWidth());
+ }
+ else
+ {
+ m_pTableData->SetRightSpace(0);
+ m_pTableData->SetLeftSpace(m_pTableData->GetSpace() - m_pTableData->GetWidth());
+ }
+ }
+ }
+ break;
+ case text::HoriOrientation::CENTER:
+ m_pTableData->SetRightSpace(m_pTableData->GetRightSpace() + nDiff/2);
+ m_pTableData->SetLeftSpace(m_pTableData->GetLeftSpace() + nDiff/2);
+ break;
+ case text::HoriOrientation::LEFT_AND_WIDTH :
+ if(nDiff > m_pTableData->GetRightSpace())
+ {
+ m_pTableData->SetLeftSpace(m_pTableData->GetSpace() - m_pTableData->GetWidth());
+ }
+ m_pTableData->SetRightSpace(
+ m_pTableData->GetSpace() - m_pTableData->GetWidth() - m_pTableData->GetLeftSpace());
+ break;
+ }
+ m_pTableData->SetWidthChanged();
+ }
+ _pSet->Put(SwPtrItem( FN_TABLE_REP, m_pTableData ));
+ }
+ return DeactivateRC::LeavePage;
+}
+
+SwTwips SwTableColumnPage::GetVisibleWidth(sal_uInt16 nPos)
+{
+ sal_uInt16 i=0;
+
+ while( nPos )
+ {
+ if(m_pTableData->GetColumns()[i].bVisible)
+ nPos--;
+ i++;
+ }
+ SwTwips nReturn = m_pTableData->GetColumns()[i].nWidth;
+ OSL_ENSURE(i < m_nNoOfCols, "Array index out of range");
+ while(!m_pTableData->GetColumns()[i].bVisible && (i + 1) < m_nNoOfCols)
+ nReturn += m_pTableData->GetColumns()[++i].nWidth;
+
+ return nReturn;
+}
+
+void SwTableColumnPage::SetVisibleWidth(sal_uInt16 nPos, SwTwips nNewWidth)
+{
+ sal_uInt16 i=0;
+ while( nPos )
+ {
+ if(m_pTableData->GetColumns()[i].bVisible)
+ nPos--;
+ i++;
+ }
+ OSL_ENSURE(i < m_nNoOfCols, "Array index out of range");
+ m_pTableData->GetColumns()[i].nWidth = nNewWidth;
+ while(!m_pTableData->GetColumns()[i].bVisible && (i + 1) < m_nNoOfCols)
+ m_pTableData->GetColumns()[++i].nWidth = 0;
+
+}
+
+SwTableTabDlg::SwTableTabDlg(weld::Window* pParent, const SfxItemSet* pItemSet, SwWrtShell* pSh)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/tableproperties.ui", "TablePropertiesDialog", pItemSet)
+ , m_pShell(pSh)
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ AddTabPage("table", &SwFormatTablePage::Create, nullptr);
+ AddTabPage("textflow", &SwTextFlowPage::Create, nullptr);
+ AddTabPage("columns", &SwTableColumnPage::Create, nullptr);
+ AddTabPage("background", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG), nullptr);
+ AddTabPage("borders", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BORDER), nullptr);
+}
+
+void SwTableTabDlg::PageCreated(const OUString& rId, SfxTabPage& rPage)
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ if (rId == "background")
+ {
+ SvxBackgroundTabFlags const nFlagType = SvxBackgroundTabFlags::SHOW_TBLCTL;
+ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(nFlagType)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "borders")
+ {
+ aSet.Put (SfxUInt16Item(SID_SWMODE_TYPE, static_cast<sal_uInt16>(SwBorderModes::TABLE)));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "textflow")
+ {
+ static_cast<SwTextFlowPage&>(rPage).SetShell(m_pShell);
+ const FrameTypeFlags eType = m_pShell->GetFrameType(nullptr,true);
+ if( !(FrameTypeFlags::BODY & eType) )
+ static_cast<SwTextFlowPage&>(rPage).DisablePageBreak();
+ }
+}
+
+SwTextFlowPage::SwTextFlowPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "modules/swriter/ui/tabletextflowpage.ui", "TableTextFlowPage", &rSet)
+ , m_pShell(nullptr)
+ , m_bPageBreak(true)
+ , m_bHtmlMode(false)
+ , m_xPgBrkCB(m_xBuilder->weld_check_button("break"))
+ , m_xPgBrkRB(m_xBuilder->weld_radio_button("page"))
+ , m_xColBrkRB(m_xBuilder->weld_radio_button("column"))
+ , m_xPgBrkBeforeRB(m_xBuilder->weld_radio_button("before"))
+ , m_xPgBrkAfterRB(m_xBuilder->weld_radio_button("after"))
+ , m_xPageCollCB(m_xBuilder->weld_check_button("pagestyle"))
+ , m_xPageCollLB(m_xBuilder->weld_combo_box("pagestylelb"))
+ , m_xPageNoCB(m_xBuilder->weld_check_button("pagenoft"))
+ , m_xPageNoNF(m_xBuilder->weld_spin_button("pagenonf"))
+ , m_xSplitCB(m_xBuilder->weld_check_button("split"))
+ , m_xSplitRowCB(m_xBuilder->weld_check_button("splitrow"))
+ , m_xKeepCB(m_xBuilder->weld_check_button("keep"))
+ , m_xHeadLineCB(m_xBuilder->weld_check_button("headline"))
+ , m_xRepeatHeaderCombo(m_xBuilder->weld_widget("repeatheader"))
+ , m_xRepeatHeaderNF(m_xBuilder->weld_spin_button("repeatheadernf"))
+ , m_xTextDirectionLB(m_xBuilder->weld_combo_box("textorientation"))
+ , m_xVertOrientLB(m_xBuilder->weld_combo_box("vertorient"))
+{
+ m_xPgBrkCB->connect_toggled(LINK(this, SwTextFlowPage, PageBreakHdl_Impl));
+ m_xPgBrkBeforeRB->connect_toggled(
+ LINK(this, SwTextFlowPage, PageBreakPosHdl_Impl));
+ m_xPgBrkAfterRB->connect_toggled(
+ LINK(this, SwTextFlowPage, PageBreakPosHdl_Impl));
+ m_xPageCollCB->connect_toggled(
+ LINK(this, SwTextFlowPage, ApplyCollClickHdl_Impl));
+ m_xColBrkRB->connect_toggled(
+ LINK(this, SwTextFlowPage, PageBreakTypeHdl_Impl));
+ m_xPgBrkRB->connect_toggled(
+ LINK(this, SwTextFlowPage, PageBreakTypeHdl_Impl));
+ m_xPageNoCB->connect_toggled(
+ LINK(this, SwTextFlowPage, PageNoClickHdl_Impl));
+ m_xSplitCB->connect_toggled(
+ LINK(this, SwTextFlowPage, SplitHdl_Impl));
+ m_xHeadLineCB->connect_toggled(LINK(this, SwTextFlowPage, HeadLineCBClickHdl));
+
+ const SfxUInt16Item *pModeItem = rSet.GetItemIfSet( SID_HTML_MODE, false );
+ if(pModeItem && pModeItem->GetValue() & HTMLMODE_ON)
+ {
+ m_xKeepCB->hide();
+ m_xSplitCB->hide();
+ m_xSplitRowCB->hide();
+ }
+
+ HeadLineCBClickHdl(*m_xHeadLineCB);
+}
+
+SwTextFlowPage::~SwTextFlowPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SwTextFlowPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SwTextFlowPage>(pPage, pController, *rAttrSet);
+}
+
+bool SwTextFlowPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+
+ //Repeat Heading
+ if (m_xHeadLineCB->get_state_changed_from_saved() ||
+ m_xRepeatHeaderNF->get_value_changed_from_saved() )
+ {
+ bModified |= nullptr != rSet->Put(
+ SfxUInt16Item(FN_PARAM_TABLE_HEADLINE, m_xHeadLineCB->get_active() ? sal_uInt16(m_xRepeatHeaderNF->get_value()) : 0));
+ }
+ if (m_xKeepCB->get_state_changed_from_saved())
+ bModified |= nullptr != rSet->Put( SvxFormatKeepItem( m_xKeepCB->get_active(), RES_KEEP));
+
+ if (m_xSplitCB->get_state_changed_from_saved())
+ bModified |= nullptr != rSet->Put( SwFormatLayoutSplit( m_xSplitCB->get_active()));
+
+ if (m_xSplitRowCB->get_state_changed_from_saved())
+ bModified |= nullptr != rSet->Put( SwFormatRowSplit( m_xSplitRowCB->get_active()));
+
+ const SvxFormatBreakItem* pBreak = GetOldItem( *rSet, RES_BREAK );
+ const SwFormatPageDesc* pDesc = GetOldItem( *rSet, RES_PAGEDESC );
+
+ bool bState = m_xPageCollCB->get_active();
+
+ //If we have a page style, then there's no break
+ bool bPageItemPut = false;
+ if ( bState != (m_xPageCollCB->get_saved_state() == TRISTATE_TRUE)
+ || (bState && m_xPageCollLB->get_value_changed_from_saved())
+ || (m_xPageNoCB->get_sensitive() && m_xPageNoCB->get_state_changed_from_saved())
+ || (m_xPageNoNF->get_sensitive() && m_xPageNoNF->get_value_changed_from_saved()))
+ {
+ OUString sPage;
+
+ if ( bState )
+ {
+ sPage = m_xPageCollLB->get_active_text();
+ }
+ sal_uInt16 nPgNum = o3tl::narrowing<sal_uInt16>(m_xPageNoNF->get_value());
+ bool const usePageNo(bState && m_xPageNoCB->get_active());
+ std::optional<sal_uInt16> const oPageNum(
+ usePageNo ? nPgNum : std::optional<sal_Int16>());
+ if (!pDesc || !pDesc->GetPageDesc()
+ || (pDesc->GetPageDesc()->GetName() != sPage)
+ || (pDesc->GetNumOffset() != oPageNum))
+ {
+ SwFormatPageDesc aFormat( m_pShell->FindPageDescByName( sPage, true ) );
+ aFormat.SetNumOffset(oPageNum);
+ bModified |= nullptr != rSet->Put( aFormat );
+ bPageItemPut = bState;
+ }
+ }
+ bool bIsChecked = m_xPgBrkCB->get_active();
+ if ( !bPageItemPut &&
+ ( bState != (m_xPageCollCB->get_saved_state() == TRISTATE_TRUE) ||
+ bIsChecked != (m_xPgBrkCB->get_saved_state() == TRISTATE_TRUE) ||
+ m_xPgBrkBeforeRB->get_state_changed_from_saved() ||
+ m_xPgBrkRB->get_state_changed_from_saved() ))
+ {
+ SvxFormatBreakItem aBreak( GetItemSet().Get( RES_BREAK ) );
+
+ if(bIsChecked)
+ {
+ bool bBefore = m_xPgBrkBeforeRB->get_active();
+
+ if (m_xPgBrkRB->get_active())
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::PageBefore );
+ else
+ aBreak.SetValue( SvxBreak::PageAfter );
+ }
+ else
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::ColumnBefore );
+ else
+ aBreak.SetValue( SvxBreak::ColumnAfter );
+ }
+ }
+ else
+ {
+ aBreak.SetValue( SvxBreak::NONE );
+ }
+
+ if ( !pBreak || !( *pBreak == aBreak ) )
+ {
+ bModified |= nullptr != rSet->Put( aBreak );
+ }
+ }
+
+ if (m_xTextDirectionLB->get_value_changed_from_saved())
+ {
+ OUString sId = m_xTextDirectionLB->get_active_id();
+ bModified |= nullptr != rSet->Put(SvxFrameDirectionItem(static_cast<SvxFrameDirection>(sId.toUInt32()), FN_TABLE_BOX_TEXTORIENTATION));
+ }
+
+ if (m_xVertOrientLB->get_value_changed_from_saved())
+ {
+ sal_uInt16 nOrient = USHRT_MAX;
+ switch (m_xVertOrientLB->get_active())
+ {
+ case 0 : nOrient = text::VertOrientation::NONE; break;
+ case 1 : nOrient = text::VertOrientation::CENTER; break;
+ case 2 : nOrient = text::VertOrientation::BOTTOM; break;
+ }
+ if (nOrient != USHRT_MAX)
+ bModified |= nullptr != rSet->Put(SfxUInt16Item(FN_TABLE_SET_VERT_ALIGN, nOrient));
+ }
+
+ return bModified;
+
+}
+
+void SwTextFlowPage::Reset( const SfxItemSet* rSet )
+{
+ bool bFlowAllowed = !m_bHtmlMode || officecfg::Office::Common::Filter::HTML::Export::PrintLayout::get();
+ if(bFlowAllowed)
+ {
+ //Inserting of the existing page templates in the list box
+ const size_t nCount = m_pShell->GetPageDescCnt();
+
+ for( size_t i = 0; i < nCount; ++i)
+ {
+ const SwPageDesc &rPageDesc = m_pShell->GetPageDesc(i);
+ m_xPageCollLB->append_text(rPageDesc.GetName());
+ }
+
+ OUString aFormatName;
+ for (sal_uInt16 i = RES_POOLPAGE_BEGIN; i < RES_POOLPAGE_END; ++i)
+ {
+ aFormatName = SwStyleNameMapper::GetUIName(i, aFormatName);
+ if (m_xPageCollLB->find_text(aFormatName) == -1)
+ m_xPageCollLB->append_text(aFormatName);
+ }
+
+ if(const SvxFormatKeepItem* pKeepItem = rSet->GetItemIfSet( RES_KEEP, false ))
+ {
+ m_xKeepCB->set_active( pKeepItem->GetValue() );
+ m_xKeepCB->save_state();
+ }
+ if(const SwFormatLayoutSplit* pSplitItem = rSet->GetItemIfSet( RES_LAYOUT_SPLIT, false ))
+ {
+ m_xSplitCB->set_active( pSplitItem->GetValue() );
+ }
+ else
+ m_xSplitCB->set_active(true);
+
+ m_xSplitCB->save_state();
+ SplitHdl_Impl(*m_xSplitCB);
+
+ if(const SwFormatRowSplit* pSplitItem = rSet->GetItemIfSet( RES_ROW_SPLIT, false ))
+ {
+ m_xSplitRowCB->set_active( pSplitItem->GetValue() );
+ }
+ else
+ m_xSplitRowCB->set_state(TRISTATE_INDET);
+ m_xSplitRowCB->save_state();
+
+ if(m_bPageBreak)
+ {
+ if(const SwFormatPageDesc* pPageDescItem = rSet->GetItemIfSet( RES_PAGEDESC, false ))
+ {
+ OUString sPageDesc;
+ const SwPageDesc* pDesc = pPageDescItem->GetPageDesc();
+
+ ::std::optional<sal_uInt16> oNumOffset = pPageDescItem->GetNumOffset();
+ if (oNumOffset)
+ {
+ m_xPageNoCB->set_active(true);
+ m_xPageNoNF->set_sensitive(true);
+ m_xPageNoNF->set_value(*oNumOffset);
+ }
+ else
+ {
+ m_xPageNoCB->set_active(false);
+ m_xPageNoNF->set_sensitive(false);
+ }
+
+ if(pDesc)
+ sPageDesc = pDesc->GetName();
+ if (!sPageDesc.isEmpty() && m_xPageCollLB->find_text(sPageDesc) != -1)
+ {
+ m_xPageCollLB->set_active_text(sPageDesc);
+ m_xPageCollCB->set_active(true);
+
+ m_xPgBrkCB->set_sensitive(true);
+ m_xPgBrkRB->set_sensitive(true);
+ m_xColBrkRB->set_sensitive(true);
+ m_xPgBrkBeforeRB->set_sensitive(true);
+ m_xPgBrkAfterRB->set_sensitive(true);
+ m_xPageCollCB->set_sensitive(true);
+
+ m_xPgBrkCB->set_active(true);
+ m_xColBrkRB->set_active( false );
+ m_xPgBrkBeforeRB->set_active(true);
+ m_xPgBrkAfterRB->set_active( false );
+ }
+ else
+ {
+ m_xPageCollLB->set_active(-1);
+ m_xPageCollCB->set_active(false);
+ }
+ }
+
+ if(const SvxFormatBreakItem* pPageBreak = rSet->GetItemIfSet( RES_BREAK, false ))
+ {
+ SvxBreak eBreak = pPageBreak->GetBreak();
+
+ if ( eBreak != SvxBreak::NONE )
+ {
+ m_xPgBrkCB->set_active(true);
+ m_xPageCollCB->set_sensitive(false);
+ m_xPageCollLB->set_sensitive(false);
+ m_xPageNoCB->set_sensitive(false);
+ m_xPageNoNF->set_sensitive(false);
+ }
+ switch ( eBreak )
+ {
+ case SvxBreak::PageBefore:
+ m_xPgBrkRB->set_active(true);
+ m_xColBrkRB->set_active( false );
+ m_xPgBrkBeforeRB->set_active(true);
+ m_xPgBrkAfterRB->set_active( false );
+ break;
+ case SvxBreak::PageAfter:
+ m_xPgBrkRB->set_active(true);
+ m_xColBrkRB->set_active( false );
+ m_xPgBrkBeforeRB->set_active( false );
+ m_xPgBrkAfterRB->set_active(true);
+ break;
+ case SvxBreak::ColumnBefore:
+ m_xPgBrkRB->set_active( false );
+ m_xColBrkRB->set_active(true);
+ m_xPgBrkBeforeRB->set_active(true);
+ m_xPgBrkAfterRB->set_active( false );
+ break;
+ case SvxBreak::ColumnAfter:
+ m_xPgBrkRB->set_active( false );
+ m_xColBrkRB->set_active(true);
+ m_xPgBrkBeforeRB->set_active( false );
+ m_xPgBrkAfterRB->set_active(true);
+ break;
+ default:; //prevent warning
+ }
+
+ }
+ if (m_xPgBrkBeforeRB->get_active())
+ PageBreakPosHdl_Impl(*m_xPgBrkBeforeRB);
+ else if (m_xPgBrkAfterRB->get_active())
+ PageBreakPosHdl_Impl(*m_xPgBrkAfterRB);
+ PageBreakHdl_Impl(*m_xPgBrkCB);
+ }
+ }
+ else
+ {
+ m_xPgBrkRB->set_sensitive(false);
+ m_xColBrkRB->set_sensitive(false);
+ m_xPgBrkBeforeRB->set_sensitive(false);
+ m_xPgBrkAfterRB->set_sensitive(false);
+ m_xKeepCB->set_sensitive(false);
+ m_xSplitCB->set_sensitive(false);
+ m_xPgBrkCB->set_sensitive(false);
+ m_xPageCollCB->set_sensitive(false);
+ m_xPageCollLB->set_sensitive(false);
+ }
+
+ if(const SfxUInt16Item* pHeadlineItem = rSet->GetItemIfSet( FN_PARAM_TABLE_HEADLINE, false ))
+ {
+ sal_uInt16 nRep = pHeadlineItem->GetValue();
+ m_xHeadLineCB->set_active(nRep > 0);
+ m_xHeadLineCB->save_state();
+ m_xRepeatHeaderNF->set_value(nRep);
+ m_xRepeatHeaderNF->set_min(1);
+ m_xRepeatHeaderNF->save_value();
+ }
+ if ( rSet->GetItemState(FN_TABLE_BOX_TEXTORIENTATION) > SfxItemState::DEFAULT )
+ {
+ SvxFrameDirection nDirection = rSet->Get(FN_TABLE_BOX_TEXTORIENTATION).GetValue();
+ m_xTextDirectionLB->set_active_id(OUString::number(static_cast<sal_uInt32>(nDirection)));
+ }
+
+ if ( rSet->GetItemState(FN_TABLE_SET_VERT_ALIGN) > SfxItemState::DEFAULT )
+ {
+ sal_uInt16 nVert = rSet->Get(FN_TABLE_SET_VERT_ALIGN).GetValue();
+ sal_uInt16 nPos = 0;
+ switch(nVert)
+ {
+ case text::VertOrientation::NONE: nPos = 0; break;
+ case text::VertOrientation::CENTER: nPos = 1; break;
+ case text::VertOrientation::BOTTOM: nPos = 2; break;
+ }
+ m_xVertOrientLB->set_active(nPos);
+ }
+
+ m_xPageCollCB->save_state();
+ m_xPageCollLB->save_value();
+ m_xPgBrkCB->save_state();
+ m_xPgBrkRB->save_state();
+ m_xColBrkRB->save_state();
+ m_xPgBrkBeforeRB->save_state();
+ m_xPgBrkAfterRB->save_state();
+ m_xPageNoCB->save_state();
+ m_xPageNoNF->save_value();
+ m_xTextDirectionLB->save_value();
+ m_xVertOrientLB->save_value();
+
+ HeadLineCBClickHdl(*m_xHeadLineCB);
+}
+
+void SwTextFlowPage::SetShell(SwWrtShell* pSh)
+{
+ m_pShell = pSh;
+ m_bHtmlMode = 0 != (::GetHtmlMode(m_pShell->GetView().GetDocShell()) & HTMLMODE_ON);
+ if(m_bHtmlMode)
+ {
+ m_xPageNoNF->set_sensitive(false);
+ m_xPageNoCB->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SwTextFlowPage, PageBreakHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xPgBrkCB->get_active())
+ {
+ m_xPgBrkRB->set_sensitive(true);
+ m_xColBrkRB->set_sensitive(true);
+ m_xPgBrkBeforeRB->set_sensitive(true);
+ m_xPgBrkAfterRB->set_sensitive(true);
+
+ if (m_xPgBrkRB->get_active() && m_xPgBrkBeforeRB->get_active())
+ {
+ m_xPageCollCB->set_sensitive(true);
+
+ bool bEnable = m_xPageCollCB->get_active() && m_xPageCollLB->get_count();
+ m_xPageCollLB->set_sensitive(bEnable);
+ if (!m_bHtmlMode)
+ {
+ m_xPageNoCB->set_sensitive(bEnable);
+ m_xPageNoNF->set_sensitive(bEnable && m_xPageNoCB->get_active());
+ }
+ }
+ }
+ else
+ {
+ m_xPageCollCB->set_active(false);
+ m_xPageCollCB->set_sensitive(false);
+ m_xPageCollLB->set_sensitive(false);
+ m_xPageNoCB->set_sensitive(false);
+ m_xPageNoNF->set_sensitive(false);
+ m_xPgBrkRB->set_sensitive(false);
+ m_xColBrkRB->set_sensitive(false);
+ m_xPgBrkBeforeRB->set_sensitive(false);
+ m_xPgBrkAfterRB->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SwTextFlowPage, ApplyCollClickHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnable = false;
+ if (m_xPageCollCB->get_active() && m_xPageCollLB->get_count())
+ {
+ bEnable = true;
+ m_xPageCollLB->set_active(0);
+ }
+ else
+ {
+ m_xPageCollLB->set_active(-1);
+ }
+ m_xPageCollLB->set_sensitive(bEnable);
+ if (!m_bHtmlMode)
+ {
+ m_xPageNoCB->set_sensitive(bEnable);
+ m_xPageNoNF->set_sensitive(bEnable && m_xPageNoCB->get_active());
+ }
+}
+
+IMPL_LINK_NOARG(SwTextFlowPage, PageBreakPosHdl_Impl, weld::Toggleable&, void)
+{
+ if (!m_xPgBrkCB->get_active())
+ return;
+
+ if (m_xPgBrkBeforeRB->get_active() && m_xPgBrkRB->get_active())
+ {
+ m_xPageCollCB->set_sensitive(true);
+
+ bool bEnable = m_xPageCollCB->get_active() && m_xPageCollLB->get_count();
+
+ m_xPageCollLB->set_sensitive(bEnable);
+ if (!m_bHtmlMode)
+ {
+ m_xPageNoCB->set_sensitive(bEnable);
+ m_xPageNoNF->set_sensitive(bEnable && m_xPageNoCB->get_active());
+ }
+ }
+ else if (m_xPgBrkAfterRB->get_active())
+ {
+ m_xPageCollCB->set_active(false);
+ m_xPageCollCB->set_sensitive(false);
+ m_xPageCollLB->set_sensitive(false);
+ m_xPageNoCB->set_sensitive(false);
+ m_xPageNoNF->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SwTextFlowPage, PageBreakTypeHdl_Impl, weld::Toggleable&, void)
+{
+ if (m_xColBrkRB->get_active() || m_xPgBrkAfterRB->get_active())
+ {
+ m_xPageCollCB->set_active(false);
+ m_xPageCollCB->set_sensitive(false);
+ m_xPageCollLB->set_sensitive(false);
+ m_xPageNoCB->set_sensitive(false);
+ m_xPageNoNF->set_sensitive(false);
+ }
+ else if (m_xPgBrkBeforeRB->get_active())
+ PageBreakPosHdl_Impl(*m_xPgBrkBeforeRB);
+}
+
+IMPL_LINK_NOARG(SwTextFlowPage, PageNoClickHdl_Impl, weld::Toggleable&, void)
+{
+ m_xPageNoNF->set_sensitive(m_xPageNoCB->get_active());
+}
+
+IMPL_LINK(SwTextFlowPage, SplitHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ m_xSplitRowCB->set_sensitive(rBox.get_active());
+}
+
+IMPL_LINK_NOARG(SwTextFlowPage, HeadLineCBClickHdl, weld::Toggleable&, void)
+{
+ m_xRepeatHeaderCombo->set_sensitive(m_xHeadLineCB->get_active());
+}
+
+void SwTextFlowPage::DisablePageBreak()
+{
+ m_bPageBreak = false;
+ m_xPgBrkCB->set_sensitive(false);
+ m_xPgBrkRB->set_sensitive(false);
+ m_xColBrkRB->set_sensitive(false);
+ m_xPgBrkBeforeRB->set_sensitive(false);
+ m_xPgBrkAfterRB->set_sensitive(false);
+ m_xPageCollCB->set_sensitive(false);
+ m_xPageCollLB->set_sensitive(false);
+ m_xPageNoCB->set_sensitive(false);
+ m_xPageNoNF->set_sensitive(false);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/table/tautofmt.cxx b/sw/source/ui/table/tautofmt.cxx
new file mode 100644
index 0000000000..8dbc965e80
--- /dev/null
+++ b/sw/source/ui/table/tautofmt.cxx
@@ -0,0 +1,408 @@
+/* -*- 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 <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sal/log.hxx>
+#include <strings.hrc>
+#include <shellres.hxx>
+#include <tautofmt.hxx>
+
+namespace {
+
+class SwStringInputDlg : public SfxDialogController
+{
+private:
+ std::unique_ptr<weld::Label> m_xLabel;
+ std::unique_ptr<weld::Entry> m_xEdInput; // Edit obtains the focus.
+
+public:
+ SwStringInputDlg(weld::Window* pParent, const OUString& rTitle,
+ const OUString& rEditTitle, const OUString& rDefault)
+ : SfxDialogController(pParent, "modules/swriter/ui/stringinput.ui",
+ "StringInputDialog")
+ , m_xLabel(m_xBuilder->weld_label("name"))
+ , m_xEdInput(m_xBuilder->weld_entry("edit"))
+ {
+ m_xLabel->set_label(rEditTitle);
+ m_xDialog->set_title(rTitle);
+ m_xEdInput->set_text(rDefault);
+ m_xEdInput->select_region(0, -1);
+ }
+
+ OUString GetInputString() const
+ {
+ return m_xEdInput->get_text();
+ }
+};
+
+}
+
+// AutoFormat-Dialogue:
+SwAutoFormatDlg::SwAutoFormatDlg(weld::Window* pParent, SwWrtShell* pWrtShell,
+ bool bAutoFormat, const SwTableAutoFormat* pSelFormat)
+ : SfxDialogController(pParent, "modules/swriter/ui/autoformattable.ui",
+ "AutoFormatTableDialog")
+ , m_aStrTitle(SwResId(STR_ADD_AUTOFORMAT_TITLE))
+ , m_aStrLabel(SwResId(STR_ADD_AUTOFORMAT_LABEL))
+ , m_aStrClose(SwResId(STR_BTN_AUTOFORMAT_CLOSE))
+ , m_aStrDelTitle(SwResId(STR_DEL_AUTOFORMAT_TITLE))
+ , m_aStrDelMsg(SwResId(STR_DEL_AUTOFORMAT_MSG))
+ , m_aStrRenameTitle(SwResId(STR_RENAME_AUTOFORMAT_TITLE))
+ , m_aStrInvalidFormat(SwResId(STR_INVALID_AUTOFORMAT_NAME))
+ , m_pShell(pWrtShell)
+ , m_nIndex(0)
+ , m_nDfltStylePos(0)
+ , m_bCoreDataChanged(false)
+ , m_bSetAutoFormat(bAutoFormat)
+ , m_xTableTable(new SwTableAutoFormatTable)
+ , m_xLbFormat(m_xBuilder->weld_tree_view("formatlb"))
+ , m_xBtnNumFormat(m_xBuilder->weld_check_button("numformatcb"))
+ , m_xBtnBorder(m_xBuilder->weld_check_button("bordercb"))
+ , m_xBtnFont(m_xBuilder->weld_check_button("fontcb"))
+ , m_xBtnPattern(m_xBuilder->weld_check_button("patterncb"))
+ , m_xBtnAlignment(m_xBuilder->weld_check_button("alignmentcb"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnRemove(m_xBuilder->weld_button("remove"))
+ , m_xBtnRename(m_xBuilder->weld_button("rename"))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aWndPreview))
+{
+ m_aWndPreview.DetectRTL(pWrtShell);
+ m_xTableTable->Load();
+
+ const int nWidth = m_xLbFormat->get_approximate_digit_width() * 32;
+ const int nHeight = m_xLbFormat->get_height_rows(8);
+ m_xLbFormat->set_size_request(nWidth, nHeight);
+ m_xWndPreview->set_size_request(nWidth, nHeight);
+
+ Init(pSelFormat);
+}
+
+SwAutoFormatDlg::~SwAutoFormatDlg()
+{
+ try
+ {
+ if (m_bCoreDataChanged)
+ m_xTableTable->Save();
+ }
+ catch (...)
+ {
+ }
+ m_xTableTable.reset();
+}
+
+void SwAutoFormatDlg::Init( const SwTableAutoFormat* pSelFormat )
+{
+ Link<weld::Toggleable&, void> aLk(LINK(this, SwAutoFormatDlg, CheckHdl));
+ m_xBtnBorder->connect_toggled(aLk);
+ m_xBtnFont->connect_toggled(aLk);
+ m_xBtnPattern->connect_toggled(aLk);
+ m_xBtnAlignment->connect_toggled(aLk);
+ m_xBtnNumFormat->connect_toggled(aLk);
+
+ m_xBtnAdd->connect_clicked(LINK(this, SwAutoFormatDlg, AddHdl));
+ m_xBtnRemove->connect_clicked(LINK(this, SwAutoFormatDlg, RemoveHdl));
+ m_xBtnRename->connect_clicked(LINK(this, SwAutoFormatDlg, RenameHdl));
+ m_xLbFormat->connect_changed(LINK(this, SwAutoFormatDlg, SelFormatHdl));
+
+ m_xBtnAdd->set_sensitive(m_bSetAutoFormat);
+
+ m_nIndex = 0;
+ if( !m_bSetAutoFormat )
+ {
+ // Then the list to be expanded by the entry "- none -".
+ m_xLbFormat->append_text(SwViewShell::GetShellRes()->aStrNone);
+ m_nDfltStylePos = 1;
+ m_nIndex = 255;
+ }
+
+ for (sal_uInt8 i = 0, nCount = static_cast<sal_uInt8>(m_xTableTable->size());
+ i < nCount; i++)
+ {
+ SwTableAutoFormat const& rFormat = (*m_xTableTable)[ i ];
+ m_xLbFormat->append_text(rFormat.GetName());
+ if (pSelFormat && rFormat.GetName() == pSelFormat->GetName())
+ m_nIndex = i;
+ }
+
+ m_xLbFormat->select(255 != m_nIndex ? (m_nDfltStylePos + m_nIndex) : 0);
+ SelFormatHdl(*m_xLbFormat);
+}
+
+void SwAutoFormatDlg::UpdateChecks( const SwTableAutoFormat& rFormat, bool bEnable )
+{
+ m_xBtnNumFormat->set_sensitive(bEnable);
+ m_xBtnNumFormat->set_active(rFormat.IsValueFormat());
+
+ m_xBtnBorder->set_sensitive(bEnable);
+ m_xBtnBorder->set_active(rFormat.IsFrame());
+
+ m_xBtnFont->set_sensitive(bEnable);
+ m_xBtnFont->set_active(rFormat.IsFont());
+
+ m_xBtnPattern->set_sensitive(bEnable);
+ m_xBtnPattern->set_active(rFormat.IsBackground());
+
+ m_xBtnAlignment->set_sensitive(bEnable);
+ m_xBtnAlignment->set_active(rFormat.IsJustify());
+}
+
+std::unique_ptr<SwTableAutoFormat> SwAutoFormatDlg::FillAutoFormatOfIndex() const
+{
+ if( 255 != m_nIndex )
+ {
+ return std::make_unique<SwTableAutoFormat>( (*m_xTableTable)[ m_nIndex ] );
+ }
+
+ return nullptr;
+}
+
+// Handler:
+IMPL_LINK(SwAutoFormatDlg, CheckHdl, weld::Toggleable&, rBtn, void)
+{
+ if (m_nIndex == 255)
+ return;
+
+ SwTableAutoFormat& rData = (*m_xTableTable)[m_nIndex];
+ bool bCheck = rBtn.get_active(), bDataChgd = true;
+
+ if (&rBtn == m_xBtnNumFormat.get())
+ rData.SetValueFormat( bCheck );
+ else if (&rBtn == m_xBtnBorder.get())
+ rData.SetFrame( bCheck );
+ else if (&rBtn == m_xBtnFont.get())
+ rData.SetFont( bCheck );
+ else if (&rBtn == m_xBtnPattern.get())
+ rData.SetBackground( bCheck );
+ else if (&rBtn == m_xBtnAlignment.get())
+ rData.SetJustify( bCheck );
+ else
+ bDataChgd = false;
+
+ if( bDataChgd )
+ {
+ if( !m_bCoreDataChanged )
+ {
+ m_xBtnCancel->set_label(m_aStrClose);
+ m_bCoreDataChanged = true;
+ }
+
+ m_aWndPreview.NotifyChange(rData);
+ }
+}
+
+IMPL_LINK_NOARG(SwAutoFormatDlg, AddHdl, weld::Button&, void)
+{
+ bool bOk = false, bFormatInserted = false;
+ while( !bOk )
+ {
+ SwStringInputDlg aDlg(m_xDialog.get(), m_aStrTitle, m_aStrLabel, OUString());
+ if (RET_OK == aDlg.run())
+ {
+ const OUString aFormatName(aDlg.GetInputString());
+
+ if ( !aFormatName.isEmpty() )
+ {
+ size_t n;
+ for( n = 0; n < m_xTableTable->size(); ++n )
+ if( (*m_xTableTable)[n].GetName() == aFormatName )
+ break;
+
+ if( n >= m_xTableTable->size() )
+ {
+ // Format with the name does not already exist, so take up.
+ std::unique_ptr<SwTableAutoFormat> pNewData(
+ new SwTableAutoFormat(aFormatName));
+ bool bGetOk = m_pShell->GetTableAutoFormat( *pNewData );
+ SAL_WARN_IF(!bGetOk, "sw.ui", "GetTableAutoFormat failed for: " << aFormatName);
+
+ // Insert sorted!!
+ for( n = 1; n < m_xTableTable->size(); ++n )
+ if( (*m_xTableTable)[ n ].GetName() > aFormatName )
+ break;
+
+ m_xTableTable->InsertAutoFormat(n, std::move(pNewData));
+ m_xLbFormat->insert_text(m_nDfltStylePos + n, aFormatName);
+ m_xLbFormat->select(m_nDfltStylePos + n);
+ bFormatInserted = true;
+ m_xBtnAdd->set_sensitive(false);
+ if ( !m_bCoreDataChanged )
+ {
+ m_xBtnCancel->set_label(m_aStrClose);
+ m_bCoreDataChanged = true;
+ }
+
+ SelFormatHdl(*m_xLbFormat);
+ bOk = true;
+ }
+ }
+
+ if( !bFormatInserted )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Error, VclButtonsType::OkCancel, m_aStrInvalidFormat));
+ bOk = RET_CANCEL == xBox->run();
+ }
+ }
+ else
+ bOk = true;
+ }
+}
+
+IMPL_LINK_NOARG(SwAutoFormatDlg, RemoveHdl, weld::Button&, void)
+{
+ OUString aMessage = m_aStrDelMsg + "\n\n" +
+ m_xLbFormat->get_selected_text() + "\n";
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Question,
+ VclButtonsType::OkCancel, m_aStrDelTitle));
+ xBox->set_secondary_text(aMessage);
+
+ if (xBox->run() == RET_OK)
+ {
+ sal_uInt8 nIndex = m_nIndex;
+
+ m_xLbFormat->remove(m_nDfltStylePos + nIndex);
+ m_xLbFormat->select(m_nDfltStylePos + nIndex - 1);
+
+ m_xTableTable->EraseAutoFormat(nIndex);
+ m_nIndex = nIndex - 1;
+
+ if( !m_nIndex )
+ {
+ m_xBtnRemove->set_sensitive(false);
+ m_xBtnRename->set_sensitive(false);
+ }
+
+ if( !m_bCoreDataChanged )
+ {
+ m_xBtnCancel->set_label(m_aStrClose);
+ m_bCoreDataChanged = true;
+ }
+ }
+
+ SelFormatHdl(*m_xLbFormat);
+}
+
+IMPL_LINK_NOARG(SwAutoFormatDlg, RenameHdl, weld::Button&, void)
+{
+ bool bOk = false;
+ while( !bOk )
+ {
+ SwStringInputDlg aDlg(m_xDialog.get(), m_aStrRenameTitle, m_aStrLabel, m_xLbFormat->get_selected_text());
+ if (aDlg.run() == RET_OK)
+ {
+ bool bFormatRenamed = false;
+ const OUString aFormatName(aDlg.GetInputString());
+
+ if ( !aFormatName.isEmpty() )
+ {
+ size_t n;
+ for( n = 0; n < m_xTableTable->size(); ++n )
+ if ((*m_xTableTable)[n].GetName() == aFormatName)
+ break;
+
+ if( n >= m_xTableTable->size() )
+ {
+ sal_uInt8 nIndex = m_nIndex;
+
+ // no format with this name exists, so rename it
+ m_xLbFormat->remove(m_nDfltStylePos + nIndex);
+ std::unique_ptr<SwTableAutoFormat> p(
+ m_xTableTable->ReleaseAutoFormat(nIndex));
+
+ p->SetName( aFormatName );
+
+ // keep all arrays sorted!
+ for( n = 1; n < m_xTableTable->size(); ++n )
+ if ((*m_xTableTable)[n].GetName() > aFormatName)
+ {
+ break;
+ }
+
+ m_xTableTable->InsertAutoFormat( n, std::move(p) );
+ m_xLbFormat->insert_text(m_nDfltStylePos + n, aFormatName);
+ m_xLbFormat->select(m_nDfltStylePos + n);
+
+ if ( !m_bCoreDataChanged )
+ {
+ m_xBtnCancel->set_label(m_aStrClose);
+ m_bCoreDataChanged = true;
+ }
+
+ SelFormatHdl(*m_xLbFormat);
+ bOk = true;
+ bFormatRenamed = true;
+ }
+ }
+
+ if( !bFormatRenamed )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Error, VclButtonsType::OkCancel, m_aStrInvalidFormat));
+ bOk = RET_CANCEL == xBox->run();
+ }
+ }
+ else
+ bOk = true;
+ }
+}
+
+IMPL_LINK_NOARG(SwAutoFormatDlg, SelFormatHdl, weld::TreeView&, void)
+{
+ bool bBtnEnable = false;
+ sal_uInt8 nOldIdx = m_nIndex;
+ int nSelPos = m_xLbFormat->get_selected_index();
+ if (nSelPos >= m_nDfltStylePos)
+ {
+ m_nIndex = nSelPos - m_nDfltStylePos;
+ m_aWndPreview.NotifyChange((*m_xTableTable)[m_nIndex]);
+ bBtnEnable = 0 != m_nIndex;
+ UpdateChecks( (*m_xTableTable)[m_nIndex], true );
+ }
+ else
+ {
+ m_nIndex = 255;
+
+ SwTableAutoFormat aTmp( SwViewShell::GetShellRes()->aStrNone );
+ aTmp.SetFont( false );
+ aTmp.SetJustify( false );
+ aTmp.SetFrame( false );
+ aTmp.SetBackground( false );
+ aTmp.SetValueFormat( false );
+ aTmp.SetWidthHeight( false );
+
+ if (nOldIdx != m_nIndex)
+ m_aWndPreview.NotifyChange(aTmp);
+ UpdateChecks( aTmp, false );
+ }
+
+ m_xBtnRemove->set_sensitive(bBtnEnable);
+ m_xBtnRename->set_sensitive(bBtnEnable);
+}
+
+short SwAutoFormatDlg::run()
+{
+ short nRet = SfxDialogController::run();
+ if (nRet == RET_OK && m_bSetAutoFormat)
+ m_pShell->SetTableStyle((*m_xTableTable)[m_nIndex]);
+ return nRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/uno/swdetect.cxx b/sw/source/ui/uno/swdetect.cxx
new file mode 100644
index 0000000000..83b7162ae2
--- /dev/null
+++ b/sw/source/ui/uno/swdetect.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 "swdetect.hxx"
+
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <sfx2/docfile.hxx>
+#include <sot/storage.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/mediadescriptor.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using utl::MediaDescriptor;
+
+SwFilterDetect::SwFilterDetect()
+{
+}
+
+SwFilterDetect::~SwFilterDetect()
+{
+}
+
+OUString SAL_CALL SwFilterDetect::detect( Sequence< PropertyValue >& lDescriptor )
+{
+ MediaDescriptor aMediaDesc( lDescriptor );
+ OUString aTypeName = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_TYPENAME, OUString() );
+ uno::Reference< io::XInputStream > xInStream ( aMediaDesc[MediaDescriptor::PROP_INPUTSTREAM], uno::UNO_QUERY );
+ if ( !xInStream.is() )
+ return OUString();
+
+ SfxMedium aMedium;
+ aMedium.UseInteractionHandler( false );
+ aMedium.setStreamToLoadFrom( xInStream, true );
+
+ SvStream *pInStrm = aMedium.GetInStream();
+ if ( !pInStrm || pInStrm->GetError() )
+ return OUString();
+
+ bool bIsDetected = false;
+
+ if ( aTypeName == "writer_Rich_Text_Format" )
+ {
+ pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ bIsDetected = ( read_uInt8s_ToOString( *pInStrm, 5 ) == "{\\rtf" );
+ }
+ else if ( aTypeName == "writer_MS_WinWord_5" )
+ {
+ pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ const sal_uInt8 nBufSize = 3;
+ sal_uInt8 nBuffer[ nBufSize ];
+ if (pInStrm->ReadBytes(nBuffer, nBufSize) < nBufSize)
+ return OUString();
+
+ bIsDetected = (nBuffer[0] == 0x9B && nBuffer[1] == 0xA5 && nBuffer[2] == 0x21) // WinWord 1
+ || (nBuffer[0] == 0x9C && nBuffer[1] == 0xA5 && nBuffer[2] == 0x21) // PMWord 1
+ || (nBuffer[0] == 0xDB && nBuffer[1] == 0xA5 && nBuffer[2] == 0x2D) // WinWord 2
+ || (nBuffer[0] == 0xDC && nBuffer[1] == 0xA5 && nBuffer[2] == 0x65); // WinWord 6.0/95, as a single stream file
+ }
+ else
+ {
+ // Do not attempt to create an SotStorage on a
+ // 0-length stream as that would create the compound
+ // document header on the stream and effectively write to
+ // disk!
+ pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ if ( pInStrm->remainingSize() == 0 )
+ return OUString();
+
+ try
+ {
+ tools::SvRef<SotStorage> aStorage = new SotStorage ( pInStrm, false );
+ if ( !aStorage->GetError() )
+ {
+ bIsDetected = aStorage->IsContained( "WordDocument" );
+ if ( bIsDetected && aTypeName.startsWith( "writer_MS_Word_97" ) )
+ {
+ bIsDetected = ( aStorage->IsContained("0Table") || aStorage->IsContained("1Table") );
+
+ // If we are checking the template type, and the document is not a .dot, don't
+ // mis-detect it.
+ if ( bIsDetected && aTypeName == "writer_MS_Word_97_Vorlage" )
+ {
+ // It is common practice to rename a .doc to .dot to make it a template.
+ // Since we have detected a.doc-ish format, always accept .dot-named-files
+ // as valid templates to avoid flagging this as an invalid .dot format..
+ INetURLObject aParser(aMediaDesc.getUnpackedValueOrDefault(
+ utl::MediaDescriptor::PROP_URL, OUString()));
+
+ // Super ugly hack, but we don't want to use the whole WW8Fib thing here in
+ // the swd library, apparently. We know (do we?) that the "aBits1" byte, as
+ // the variable is called in WW8Fib::WW8Fib(SvStream&,sal_uInt8,sal_uInt32),
+ // is at offset 10 in the WordDocument stream. The fDot bit is bit 0x01 of
+ // that byte.
+ if (aParser.getExtension().toAsciiLowerCase() != "dot")
+ {
+ tools::SvRef<SotStorageStream> xWordDocument
+ = aStorage->OpenSotStream("WordDocument", StreamMode::STD_READ);
+ xWordDocument->Seek(10);
+ if (xWordDocument->Tell() == 10)
+ {
+ sal_uInt8 aBits1;
+ xWordDocument->ReadUChar(aBits1);
+ // Check fDot bit
+ bIsDetected = ((aBits1 & 0x01) == 0x01);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ bIsDetected = false;
+ }
+ }
+
+ if ( bIsDetected )
+ return aTypeName;
+
+ return OUString();
+}
+
+/* XServiceInfo */
+OUString SAL_CALL SwFilterDetect::getImplementationName()
+{
+ return "com.sun.star.comp.writer.FormatDetector";
+}
+
+/* XServiceInfo */
+sal_Bool SAL_CALL SwFilterDetect::supportsService( const OUString& sServiceName )
+{
+ return cppu::supportsService(this, sServiceName);
+}
+
+/* XServiceInfo */
+Sequence< OUString > SAL_CALL SwFilterDetect::getSupportedServiceNames()
+{
+ return { "com.sun.star.frame.ExtendedTypeDetection", "com.sun.star.text.FormatDetector", "com.sun.star.text.W4WFormatDetector" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_writer_FormatDetector_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new SwFilterDetect());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/uno/swdetect.hxx b/sw/source/ui/uno/swdetect.hxx
new file mode 100644
index 0000000000..a72521004a
--- /dev/null
+++ b/sw/source/ui/uno/swdetect.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_UNO_SWDETECT_HXX
+#define INCLUDED_SW_SOURCE_UI_UNO_SWDETECT_HXX
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+namespace com::sun::star::beans { struct PropertyValue; }
+
+class SfxMedium;
+class SfxFilter;
+class SfxMedium;
+
+class SwFilterDetect : public ::cppu::WeakImplHelper< css::document::XExtendedFilterDetection, css::lang::XServiceInfo >
+{
+public:
+ SwFilterDetect();
+ virtual ~SwFilterDetect() override;
+
+ /* XServiceInfo */
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& sServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XExtendedFilterDetect
+ virtual OUString SAL_CALL detect( css::uno::Sequence< css::beans::PropertyValue >& lDescriptor ) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/utlui/swrenamexnameddlg.cxx b/sw/source/ui/utlui/swrenamexnameddlg.cxx
new file mode 100644
index 0000000000..4bcf29d3c3
--- /dev/null
+++ b/sw/source/ui/utlui/swrenamexnameddlg.cxx
@@ -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 .
+ */
+
+#include <osl/diagnose.h>
+
+#include <swrenamexnameddlg.hxx>
+
+using namespace ::com::sun::star;
+
+SwRenameXNamedDlg::SwRenameXNamedDlg(weld::Widget* pParent,
+ uno::Reference< container::XNamed > & xN,
+ uno::Reference< container::XNameAccess > & xNA )
+ : GenericDialogController(pParent, "modules/swriter/ui/renameobjectdialog.ui", "RenameObjectDialog")
+ , m_xNamed(xN)
+ , m_xNameAccess(xNA)
+ , m_xNewNameED(m_xBuilder->weld_entry("entry"))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+{
+ m_xNewNameED->connect_insert_text(LINK(this, SwRenameXNamedDlg, TextFilterHdl));
+
+ OUString sTmp(m_xDialog->get_title());
+ m_xNewNameED->set_text(m_xNamed->getName());
+ m_xNewNameED->select_region(0, -1);
+ sTmp += m_xNamed->getName();
+ m_xDialog->set_title(sTmp);
+
+ m_xOk->connect_clicked(LINK(this, SwRenameXNamedDlg, OkHdl));
+ m_xNewNameED->connect_changed(LINK(this, SwRenameXNamedDlg, ModifyHdl));
+ m_xOk->set_sensitive(false);
+}
+
+IMPL_LINK(SwRenameXNamedDlg, TextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = m_aTextFilter.filter(rTest);
+ return true;
+}
+
+IMPL_LINK_NOARG(SwRenameXNamedDlg, OkHdl, weld::Button&, void)
+{
+ try
+ {
+ m_xNamed->setName(m_xNewNameED->get_text());
+ }
+ catch (const uno::RuntimeException&)
+ {
+ OSL_FAIL("name wasn't changed");
+ }
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK(SwRenameXNamedDlg, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ OUString sTmp(rEdit.get_text());
+
+ m_xOk->set_sensitive(!sTmp.isEmpty()
+ && !m_xNameAccess->hasByName(sTmp)
+ && (!m_xSecondAccess.is() || !m_xSecondAccess->hasByName(sTmp))
+ && (!m_xThirdAccess.is() || !m_xThirdAccess->hasByName(sTmp))
+ );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaaddin.cxx b/sw/source/ui/vba/vbaaddin.cxx
new file mode 100644
index 0000000000..8fdfb00480
--- /dev/null
+++ b/sw/source/ui/vba/vbaaddin.cxx
@@ -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 .
+ */
+#include "vbaaddin.hxx"
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaAddin::SwVbaAddin( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, OUString aFileURL ) :
+ SwVbaAddin_BASE( rParent, rContext ), msFileURL(std::move( aFileURL )), mbInstalled( true )
+{
+}
+
+SwVbaAddin::~SwVbaAddin()
+{
+}
+
+OUString SAL_CALL SwVbaAddin::getName()
+{
+ OUString sName;
+ INetURLObject aURL( msFileURL );
+ ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName );
+ return sName;
+}
+
+void SAL_CALL
+SwVbaAddin::setName( const OUString& )
+{
+ throw uno::RuntimeException(" Fail to set name" );
+}
+
+OUString SAL_CALL SwVbaAddin::getPath()
+{
+ INetURLObject aURL( msFileURL );
+ aURL.CutLastName();
+ return aURL.GetURLPath();
+}
+
+sal_Bool SAL_CALL SwVbaAddin::getAutoload()
+{
+ return true;
+}
+
+sal_Bool SAL_CALL SwVbaAddin::getInstalled()
+{
+ return mbInstalled;
+}
+
+void SAL_CALL SwVbaAddin::setInstalled( sal_Bool _installed )
+{
+ if( bool(_installed) != mbInstalled )
+ {
+ mbInstalled = _installed;
+ // TODO: should call AutoExec and AutoExit etc.
+ }
+}
+
+OUString
+SwVbaAddin::getServiceImplName()
+{
+ return "SwVbaAddin";
+}
+
+uno::Sequence< OUString >
+SwVbaAddin::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Addin"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaaddin.hxx b/sw/source/ui/vba/vbaaddin.hxx
new file mode 100644
index 0000000000..f177e7935d
--- /dev/null
+++ b/sw/source/ui/vba/vbaaddin.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAADDIN_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAADDIN_HXX
+
+#include <ooo/vba/word/XAddin.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XAddin> SwVbaAddin_BASE;
+
+class SwVbaAddin : public SwVbaAddin_BASE
+{
+private:
+ OUString msFileURL;
+ bool mbInstalled;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaAddin(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext, OUString aFileURL);
+ virtual ~SwVbaAddin() override;
+
+ // Attributes
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName(const OUString& _name) override;
+ virtual OUString SAL_CALL getPath() override;
+ virtual sal_Bool SAL_CALL getAutoload() override;
+ virtual sal_Bool SAL_CALL getInstalled() override;
+ virtual void SAL_CALL setInstalled(sal_Bool _installed) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAADDIN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaaddins.cxx b/sw/source/ui/vba/vbaaddins.cxx
new file mode 100644
index 0000000000..6fd6e42f86
--- /dev/null
+++ b/sw/source/ui/vba/vbaaddins.cxx
@@ -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 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 "vbaaddins.hxx"
+#include "vbaaddin.hxx"
+#include <unotools/pathoptions.hxx>
+#include <sal/log.hxx>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static uno::Reference< container::XIndexAccess > lcl_getAddinCollection( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext )
+{
+ XNamedObjectCollectionHelper< word::XAddin >::XNamedVec aAddins;
+
+ // first get the autoload addins in the directory STARTUP
+ uno::Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager(), uno::UNO_SET_THROW );
+ uno::Reference<ucb::XSimpleFileAccess3> xSFA(ucb::SimpleFileAccess::create(xContext));
+ SvtPathOptions aPathOpt;
+ // FIXME: temporary the STARTUP path is located in $OO/basic3.1/program/addin
+ const OUString& aAddinPath = aPathOpt.GetAddinPath();
+ SAL_INFO("sw.vba", "lcl_getAddinCollection: " << aAddinPath );
+ if( xSFA->isFolder( aAddinPath ) )
+ {
+ const uno::Sequence< OUString > sEntries = xSFA->getFolderContents( aAddinPath, false );
+ for( const OUString& sUrl : sEntries )
+ {
+ if( !xSFA->isFolder( sUrl ) && sUrl.endsWithIgnoreAsciiCase( ".dot" ) )
+ {
+ aAddins.push_back( uno::Reference< word::XAddin >( new SwVbaAddin( xParent, xContext, sUrl ) ) );
+ }
+ }
+ }
+
+ // TODO: second get the customize addins in the org.openoffice.Office.Writer/GlobalTemplateList
+
+ uno::Reference< container::XIndexAccess > xAddinsAccess( new XNamedObjectCollectionHelper< word::XAddin >( std::move(aAddins) ) );
+ return xAddinsAccess;
+}
+
+SwVbaAddins::SwVbaAddins( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext ): SwVbaAddins_BASE( xParent, xContext, lcl_getAddinCollection( xParent,xContext ) )
+{
+}
+// XEnumerationAccess
+uno::Type
+SwVbaAddins::getElementType()
+{
+ return cppu::UnoType<word::XAddin>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaAddins::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xEnumerationAccess->createEnumeration();
+}
+
+uno::Any
+SwVbaAddins::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaAddins::getServiceImplName()
+{
+ return "SwVbaAddins";
+}
+
+css::uno::Sequence<OUString>
+SwVbaAddins::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Addins"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaaddins.hxx b/sw/source/ui/vba/vbaaddins.hxx
new file mode 100644
index 0000000000..0072b36d5a
--- /dev/null
+++ b/sw/source/ui/vba/vbaaddins.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAADDINS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAADDINS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XAddins.hpp>
+
+typedef CollTestImplHelper<ooo::vba::word::XAddins> SwVbaAddins_BASE;
+
+class SwVbaAddins : public SwVbaAddins_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaAddins(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext);
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // SwVbaAddins_BASE
+ virtual css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAADDINS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaapplication.cxx b/sw/source/ui/vba/vbaapplication.cxx
new file mode 100644
index 0000000000..d3f290db28
--- /dev/null
+++ b/sw/source/ui/vba/vbaapplication.cxx
@@ -0,0 +1,529 @@
+/* -*- 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 <com/sun/star/task/XStatusIndicatorSupplier.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+
+#include "vbaapplication.hxx"
+#include "vbadocument.hxx"
+#include "vbafilterpropsfromformat.hxx"
+#include <sal/log.hxx>
+#include <osl/file.hxx>
+#include <vcl/svapp.hxx>
+#include <vbahelper/vbahelper.hxx>
+#include "vbawindow.hxx"
+#include "vbasystem.hxx"
+#include "vbaoptions.hxx"
+#include "vbaselection.hxx"
+#include "vbadocuments.hxx"
+#include "vbaaddins.hxx"
+#include "vbamailmerge.hxx"
+#include "vbadialogs.hxx"
+#include "vbawordbasic.hxx"
+#include <ooo/vba/XConnectionPoint.hpp>
+#include <ooo/vba/word/WdEnableCancelKey.hpp>
+#include <ooo/vba/word/WdWindowState.hpp>
+#include <ooo/vba/word/XApplicationOutgoing.hpp>
+#include <ooo/vba/word/XBookmarks.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <cppu/unotype.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <swdll.hxx>
+#include <swmodule.hxx>
+#include "vbalistgalleries.hxx"
+#include <tools/urlobj.hxx>
+
+using namespace ::ooo;
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class SwVbaApplicationOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
+{
+private:
+ SwVbaApplication* mpApp;
+
+public:
+ SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp );
+
+ // XConnectionPoint
+ sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
+ void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
+};
+
+}
+
+SwVbaApplication::SwVbaApplication( uno::Reference<uno::XComponentContext >& xContext ):
+ SwVbaApplication_BASE( xContext )
+{
+}
+
+SwVbaApplication::~SwVbaApplication()
+{
+}
+
+sal_uInt32
+SwVbaApplication::AddSink( const uno::Reference< XSink >& xSink )
+{
+ {
+ SolarMutexGuard aGuard;
+ SwGlobals::ensure();
+ }
+ // No harm in potentially calling this several times
+ SW_MOD()->RegisterAutomationApplicationEventsCaller( uno::Reference< XSinkCaller >(this) );
+ mvSinks.push_back(xSink);
+ return mvSinks.size();
+}
+
+void
+SwVbaApplication::RemoveSink( sal_uInt32 nNumber )
+{
+ if (nNumber < 1 || nNumber > mvSinks.size())
+ return;
+
+ mvSinks[nNumber-1] = uno::Reference< XSink >();
+}
+
+OUString SAL_CALL
+SwVbaApplication::getName()
+{
+ return "Microsoft Word";
+}
+
+uno::Reference< word::XDocument > SAL_CALL
+SwVbaApplication::getActiveDocument()
+{
+ return new SwVbaDocument( this, mxContext, getCurrentDocument() );
+}
+
+rtl::Reference<SwVbaWindow>
+SwVbaApplication::getActiveSwVbaWindow()
+{
+ // #FIXME so far can't determine Parent
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
+ return new SwVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel, xController );
+}
+
+uno::Reference< css::uno::XComponentContext > const &
+SwVbaApplication::getContext() const
+{
+ return mxContext;
+}
+
+uno::Reference< word::XWindow > SAL_CALL
+SwVbaApplication::getActiveWindow()
+{
+ return getActiveSwVbaWindow();
+}
+
+uno::Reference<word::XSystem > SAL_CALL
+SwVbaApplication::getSystem()
+{
+ return uno::Reference< word::XSystem >( new SwVbaSystem( mxContext ) );
+}
+
+uno::Reference<word::XOptions > SAL_CALL
+SwVbaApplication::getOptions()
+{
+ return uno::Reference< word::XOptions >( new SwVbaOptions( mxContext ) );
+}
+
+uno::Any SAL_CALL
+SwVbaApplication::CommandBars( const uno::Any& aIndex )
+{
+ try
+ {
+ return VbaApplicationBase::CommandBars( aIndex );
+ }
+ catch (const uno::RuntimeException&)
+ {
+ return uno::Any();
+ }
+}
+
+uno::Reference< word::XSelection > SAL_CALL
+SwVbaApplication::getSelection()
+{
+ return new SwVbaSelection( this, mxContext, getCurrentDocument() );
+}
+
+uno::Reference< word::XWordBasic > SAL_CALL
+SwVbaApplication::getWordBasic()
+{
+ uno::Reference< word::XWordBasic > xWB( new SwWordBasic( this ) );
+ return xWB;
+}
+
+uno::Any SAL_CALL
+SwVbaApplication::Documents( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaDocuments( this, mxContext ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaApplication::Addins( const uno::Any& index )
+{
+ static uno::Reference< XCollection > xCol( new SwVbaAddins( this, mxContext ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaApplication::Dialogs( const uno::Any& index )
+{
+ uno::Reference< word::XDialogs > xCol( new SwVbaDialogs( this, mxContext, getCurrentDocument() ));
+ if ( index.hasValue() )
+ return xCol->Item( index );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaApplication::ListGalleries( const uno::Any& index )
+{
+ uno::Reference< text::XTextDocument > xTextDoc( getCurrentDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaListGalleries( this, mxContext, xTextDoc ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+sal_Bool SAL_CALL SwVbaApplication::getDisplayAutoCompleteTips()
+{
+ return SvxAutoCorrCfg::Get().IsAutoTextTip();
+}
+
+void SAL_CALL SwVbaApplication::setDisplayAutoCompleteTips( sal_Bool _displayAutoCompleteTips )
+{
+ SvxAutoCorrCfg::Get().SetAutoTextTip( _displayAutoCompleteTips );
+}
+
+sal_Int32 SAL_CALL SwVbaApplication::getEnableCancelKey()
+{
+ // the default value is wdCancelInterrupt in Word
+ return word::WdEnableCancelKey::wdCancelInterrupt;
+}
+
+void SAL_CALL SwVbaApplication::setEnableCancelKey( sal_Int32/* _enableCancelKey */)
+{
+ // seems not supported in Writer
+}
+
+sal_Int32 SAL_CALL SwVbaApplication::getWindowState()
+{
+ auto xWindow = getActiveWindow();
+ if (xWindow.is())
+ {
+ uno::Any aState = xWindow->getWindowState();
+ sal_Int32 nState;
+ if (aState >>= nState)
+ return nState;
+ }
+
+ return word::WdWindowState::wdWindowStateNormal; // ?
+}
+
+void SAL_CALL SwVbaApplication::setWindowState( sal_Int32 _windowstate )
+{
+ try
+ {
+ auto xWindow = getActiveWindow();
+ if (xWindow.is())
+ {
+ uno::Any aState;
+ aState <<= _windowstate;
+ xWindow->setWindowState( aState );
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ }
+}
+
+sal_Int32 SAL_CALL SwVbaApplication::getWidth()
+{
+ auto pWindow = getActiveSwVbaWindow();
+ return pWindow->getWidth();
+}
+
+void SAL_CALL SwVbaApplication::setWidth( sal_Int32 _width )
+{
+ auto pWindow = getActiveSwVbaWindow();
+ pWindow->setWidth( _width );
+}
+
+sal_Int32 SAL_CALL SwVbaApplication::getHeight()
+{
+ auto pWindow = getActiveSwVbaWindow();
+ return pWindow->getHeight();
+}
+
+void SAL_CALL SwVbaApplication::setHeight( sal_Int32 _height )
+{
+ auto pWindow = getActiveSwVbaWindow();
+ pWindow->setHeight( _height );
+}
+
+sal_Int32 SAL_CALL SwVbaApplication::getLeft()
+{
+ auto pWindow = getActiveSwVbaWindow();
+ return pWindow->getLeft();
+}
+
+void SAL_CALL SwVbaApplication::setLeft( sal_Int32 _left )
+{
+ auto pWindow = getActiveSwVbaWindow();
+ pWindow->setLeft( _left );
+}
+
+sal_Int32 SAL_CALL SwVbaApplication::getTop()
+{
+ auto pWindow = getActiveSwVbaWindow();
+ return pWindow->getTop();
+}
+
+void SAL_CALL SwVbaApplication::setTop( sal_Int32 _top )
+{
+ auto pWindow = getActiveSwVbaWindow();
+ pWindow->setTop( _top );
+}
+
+OUString SAL_CALL SwVbaApplication::getStatusBar()
+{
+ return "";
+}
+
+uno::Any SAL_CALL SwVbaApplication::getCustomizationContext()
+{
+ return uno::Any(); // ???
+}
+
+void SAL_CALL SwVbaApplication::setCustomizationContext(const uno::Any& /*_customizationcontext*/)
+{
+ // ???
+}
+
+void SAL_CALL SwVbaApplication::setStatusBar( const OUString& _statusbar )
+{
+ // ScVbaAppSettings::setStatusBar() also uses the XStatusIndicator to show this, so maybe that is OK?
+ uno::Reference< frame::XModel > xModel = getCurrentDocument();
+ if (xModel.is())
+ {
+ uno::Reference< task::XStatusIndicatorSupplier > xStatusIndicatorSupplier( xModel->getCurrentController(), uno::UNO_QUERY );
+ if (xStatusIndicatorSupplier.is())
+ {
+ uno::Reference< task::XStatusIndicator > xStatusIndicator = xStatusIndicatorSupplier->getStatusIndicator();
+ if (xStatusIndicator.is())
+ xStatusIndicator->start( _statusbar, 100 );
+ }
+ }
+
+ // Yes, we intentionally use the "extensions.olebridge" tag here even if this is sw. We
+ // interpret setting the StatusBar property as a request from an Automation client to display
+ // the string in LibreOffice's debug output, and all other generic Automation support debug
+ // output (in extensions/source/ole) uses that tag. If the check for "cross-module" or mixed log
+ // areas in compilerplugins/clang/sallogareas.cxx is re-activated, this will have to be added as
+ // a special case.
+
+ SAL_INFO("extensions.olebridge", "Client debug output: " << _statusbar);
+}
+
+float SAL_CALL SwVbaApplication::CentimetersToPoints( float Centimeters )
+{
+ return o3tl::convert(Centimeters, o3tl::Length::cm, o3tl::Length::pt);
+}
+
+float SAL_CALL SwVbaApplication::PointsToCentimeters( float Points )
+{
+ return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::cm);
+}
+
+float SAL_CALL SwVbaApplication::PixelsToPoints( float Pixels, ::sal_Bool fVertical )
+{
+ //Set up xDevice
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
+ uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
+ uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
+ css::uno::Reference< css::awt::XDevice > xDevice( xWindow, css::uno::UNO_QUERY );
+
+ return ooo::vba::PixelsToPoints(xDevice, Pixels, fVertical);
+}
+
+float SAL_CALL SwVbaApplication::PointsToPixels( float Pixels, ::sal_Bool fVertical )
+{
+ uno::Reference< frame::XModel > xModel( getCurrentDocument(), uno::UNO_SET_THROW );
+ uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW );
+ uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
+ uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
+ css::uno::Reference< css::awt::XDevice > xDevice( xWindow, css::uno::UNO_QUERY );
+
+ return ooo::vba::PointsToPixels(xDevice, Pixels, fVertical);
+}
+
+float SAL_CALL SwVbaApplication::InchesToPoints( float Inches )
+{
+ return o3tl::convert(Inches, o3tl::Length::in, o3tl::Length::pt);
+}
+
+float SAL_CALL SwVbaApplication::PointsToInches( float Points )
+{
+ return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::in);
+}
+
+float SAL_CALL SwVbaApplication::MillimetersToPoints( float Millimeters )
+{
+ return o3tl::convert(Millimeters, o3tl::Length::mm, o3tl::Length::pt);
+}
+
+float SAL_CALL SwVbaApplication::PointsToMillimeters( float Points )
+{
+ return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::mm);
+}
+
+float SAL_CALL SwVbaApplication::PicasToPoints( float Picas )
+{
+ return o3tl::convert(Picas, o3tl::Length::pc, o3tl::Length::pt);
+}
+
+float SAL_CALL SwVbaApplication::PointsToPicas( float Points )
+{
+ return o3tl::convert(Points, o3tl::Length::pt, o3tl::Length::pc);
+}
+
+void SAL_CALL SwVbaApplication::ShowMe()
+{
+ // Method no longer supported in word - deprecated
+}
+
+void SAL_CALL SwVbaApplication::Resize( sal_Int32 Width, sal_Int32 Height )
+{
+ // Have to do it like this as the Width and Height are hidden away in the ooo::vba::XWindowBase
+ // which ooo::vba::word::XApplication does not inherit from. SwVbaWindow, however, does inherit
+ // from XWindowBase. Ugh.
+ auto pWindow = getActiveSwVbaWindow();
+ pWindow->setWidth( Width );
+ pWindow->setHeight( Height );
+}
+
+void SAL_CALL SwVbaApplication::Move( sal_Int32 Left, sal_Int32 Top )
+{
+ // See comment in Resize().
+ auto pWindow = getActiveSwVbaWindow();
+ pWindow->setLeft( Left );
+ pWindow->setTop( Top );
+}
+
+// XInterfaceWithIID
+
+OUString SAL_CALL
+SwVbaApplication::getIID()
+{
+ return "{82154421-0FBF-11d4-8313-005004526AB4}";
+}
+
+// XConnectable
+
+OUString SAL_CALL
+SwVbaApplication::GetIIDForClassItselfNotCoclass()
+{
+ return "{82154423-0FBF-11D4-8313-005004526AB4}";
+}
+
+TypeAndIID SAL_CALL
+SwVbaApplication::GetConnectionPoint()
+{
+ TypeAndIID aResult =
+ { cppu::UnoType<word::XApplicationOutgoing>::get(),
+ "{82154422-0FBF-11D4-8313-005004526AB4}"
+ };
+
+ return aResult;
+}
+
+uno::Reference<XConnectionPoint> SAL_CALL
+SwVbaApplication::FindConnectionPoint()
+{
+ uno::Reference<XConnectionPoint> xCP(new SwVbaApplicationOutgoingConnectionPoint(this));
+ return xCP;
+}
+
+OUString
+SwVbaApplication::getServiceImplName()
+{
+ return "SwVbaApplication";
+}
+
+uno::Sequence< OUString >
+SwVbaApplication::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Application"
+ };
+ return aServiceNames;
+}
+
+uno::Reference< frame::XModel >
+SwVbaApplication::getCurrentDocument()
+{
+ return getCurrentWordDoc( mxContext );
+}
+
+// XSinkCaller
+
+void SAL_CALL
+SwVbaApplication::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
+{
+ for (auto& i : mvSinks)
+ {
+ if (i.is())
+ i->Call(Method, Arguments);
+ }
+}
+
+// SwVbaApplicationOutgoingConnectionPoint
+
+SwVbaApplicationOutgoingConnectionPoint::SwVbaApplicationOutgoingConnectionPoint( SwVbaApplication* pApp ) :
+ mpApp(pApp)
+{
+}
+
+// XConnectionPoint
+sal_uInt32 SAL_CALL
+SwVbaApplicationOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
+{
+ return mpApp->AddSink(Sink);
+}
+
+void SAL_CALL
+SwVbaApplicationOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
+{
+ mpApp->RemoveSink( Cookie );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaapplication.hxx b/sw/source/ui/vba/vbaapplication.hxx
new file mode 100644
index 0000000000..90b4322835
--- /dev/null
+++ b/sw/source/ui/vba/vbaapplication.hxx
@@ -0,0 +1,129 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX
+
+#include <vector>
+
+#include <ooo/vba/XSink.hpp>
+#include <ooo/vba/XSinkCaller.hpp>
+#include <ooo/vba/word/XApplication.hpp>
+#include <ooo/vba/word/XDocument.hpp>
+#include <ooo/vba/word/XWindow.hpp>
+#include <ooo/vba/word/XSystem.hpp>
+#include <ooo/vba/word/XOptions.hpp>
+#include <ooo/vba/word/XSelection.hpp>
+#include <vbahelper/vbaapplicationbase.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/ref.hxx>
+
+#include "vbawindow.hxx"
+
+typedef cppu::ImplInheritanceHelper< VbaApplicationBase, ooo::vba::word::XApplication, ooo::vba::XSinkCaller > SwVbaApplication_BASE;
+
+// This class is currently not a singleton. One instance is created per document with (potential?)
+// StarBasic code in it, I think, and a shared one for all Automation clients connected to the
+// ooo::vba::word::Application (Writer.Application) service. (Of course it probably is not common to
+// have several Automation clients at once.)
+
+// Should it be a true singleton? Hard to say. Anyway, it is actually the SwVbaGlobals class that
+// should be a singleton in that case, I think.
+
+class SwVbaApplication : public SwVbaApplication_BASE
+{
+ std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks;
+
+public:
+ explicit SwVbaApplication( css::uno::Reference< css::uno::XComponentContext >& xContext );
+ virtual ~SwVbaApplication() override;
+
+ sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink );
+ void RemoveSink( sal_uInt32 nNumber );
+
+ rtl::Reference<SwVbaWindow> getActiveSwVbaWindow();
+ css::uno::Reference< css::uno::XComponentContext > const & getContext() const;
+
+ // XApplication
+ virtual OUString SAL_CALL getName() override;
+ virtual css::uno::Reference< ooo::vba::word::XSystem > SAL_CALL getSystem() override;
+ virtual css::uno::Reference< ov::word::XDocument > SAL_CALL getActiveDocument() override;
+ virtual css::uno::Reference< ov::word::XWindow > SAL_CALL getActiveWindow() override;
+ virtual css::uno::Reference< ooo::vba::word::XOptions > SAL_CALL getOptions() override;
+ virtual css::uno::Reference< ooo::vba::word::XSelection > SAL_CALL getSelection() override;
+ virtual css::uno::Reference< ooo::vba::word::XWordBasic > SAL_CALL getWordBasic() override;
+ virtual css::uno::Any SAL_CALL CommandBars( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Documents( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Addins( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Dialogs( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL ListGalleries( const css::uno::Any& aIndex ) override;
+ virtual sal_Bool SAL_CALL getDisplayAutoCompleteTips() override;
+ virtual void SAL_CALL setDisplayAutoCompleteTips( sal_Bool _displayAutoCompleteTips ) override;
+ virtual sal_Int32 SAL_CALL getEnableCancelKey() override;
+ virtual void SAL_CALL setEnableCancelKey( sal_Int32 _enableCancelKey ) override;
+ virtual sal_Int32 SAL_CALL getWindowState() override;
+ virtual void SAL_CALL setWindowState( sal_Int32 _windowstate ) override;
+ virtual sal_Int32 SAL_CALL getWidth() override;
+ virtual void SAL_CALL setWidth( sal_Int32 _width ) override;
+ virtual sal_Int32 SAL_CALL getHeight() override;
+ virtual void SAL_CALL setHeight( sal_Int32 _height ) override;
+ virtual sal_Int32 SAL_CALL getLeft() override;
+ virtual void SAL_CALL setLeft( sal_Int32 _left ) override;
+ virtual sal_Int32 SAL_CALL getTop() override;
+ virtual void SAL_CALL setTop( sal_Int32 _top ) override;
+ virtual OUString SAL_CALL getStatusBar() override;
+ virtual void SAL_CALL setStatusBar( const OUString& _statusbar ) override;
+ virtual css::uno::Any SAL_CALL getCustomizationContext() override;
+ virtual void SAL_CALL setCustomizationContext( const css::uno::Any& _customizationcontext ) override;
+ virtual float SAL_CALL CentimetersToPoints( float Centimeters ) override;
+ virtual float SAL_CALL PointsToCentimeters( float Points ) override;
+ virtual float SAL_CALL PixelsToPoints( float Pixels, ::sal_Bool fVertical ) override;
+ virtual float SAL_CALL PointsToPixels( float Pixels, ::sal_Bool fVertical ) override;
+ virtual float SAL_CALL InchesToPoints( float Inches ) override;
+ virtual float SAL_CALL PointsToInches( float Points ) override;
+ virtual float SAL_CALL MillimetersToPoints( float Millimeters ) override;
+ virtual float SAL_CALL PointsToMillimeters( float Points ) override;
+ virtual float SAL_CALL PicasToPoints( float Picas ) override;
+ virtual float SAL_CALL PointsToPicas( float Points ) override;
+
+
+
+ virtual void SAL_CALL ShowMe() override;
+ virtual void SAL_CALL Resize( sal_Int32 Width, sal_Int32 Height ) override;
+ virtual void SAL_CALL Move( sal_Int32 Left, sal_Int32 Top ) override;
+
+ // XInterfaceWithIID
+ virtual OUString SAL_CALL getIID() override;
+
+ // XConnectable
+ virtual OUString SAL_CALL GetIIDForClassItselfNotCoclass() override;
+ virtual ov::TypeAndIID SAL_CALL GetConnectionPoint() override;
+ virtual css::uno::Reference<ov::XConnectionPoint> SAL_CALL FindConnectionPoint() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XSinkCaller
+ virtual void SAL_CALL CallSinks( const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments ) override;
+
+ virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAAPPLICATION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaautotextentry.cxx b/sw/source/ui/vba/vbaautotextentry.cxx
new file mode 100644
index 0000000000..dd1f17f16f
--- /dev/null
+++ b/sw/source/ui/vba/vbaautotextentry.cxx
@@ -0,0 +1,132 @@
+/* -*- 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 "vbaautotextentry.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/text/XParagraphCursor.hpp>
+#include "wordvbahelper.hxx"
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaAutoTextEntry::SwVbaAutoTextEntry( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XAutoTextEntry > xEntry ) :
+ SwVbaAutoTextEntry_BASE( rParent, rContext ), mxEntry(std::move( xEntry ))
+{
+}
+
+SwVbaAutoTextEntry::~SwVbaAutoTextEntry()
+{
+}
+
+uno::Reference< word::XRange > SAL_CALL SwVbaAutoTextEntry::Insert( const uno::Reference< word::XRange >& _where, const uno::Any& _richtext )
+{
+ SwVbaRange* pWhere = dynamic_cast<SwVbaRange*>( _where.get() );
+ if( pWhere )
+ {
+ uno::Reference< text::XTextRange > xTextRange = pWhere->getXTextRange();
+ xTextRange->setString( "x" ); // set marker
+ uno::Reference< text::XTextRange > xEndMarker = xTextRange->getEnd();
+ xEndMarker->setString( "x" ); // set marker
+ uno::Reference< text::XText > xText = pWhere->getXText();
+ mxEntry->applyTo( xEndMarker->getStart() );
+ uno::Reference< text::XTextCursor > xTC = xText->createTextCursorByRange( xTextRange->getStart() );
+ xTC->goRight( 1, true );
+ xTC->setString( "" ); // remove marker
+ // remove the blank paragraph if it is a rich text
+ bool bRich = false;
+ _richtext >>= bRich;
+ if( bRich )
+ {
+ // check if it is a blank paragraph
+ uno::Reference< text::XParagraphCursor > xParaCursor( xTC, uno::UNO_QUERY_THROW );
+ if( xParaCursor->isStartOfParagraph() && xParaCursor->isEndOfParagraph() )
+ {
+ //remove the blank paragraph
+ uno::Reference< frame::XModel > xModel( getCurrentWordDoc( mxContext ), uno::UNO_SET_THROW );
+ uno::Reference< text::XTextViewCursor > xTVCursor = word::getXTextViewCursor( xModel );
+ uno::Reference< text::XTextRange > xCurrentRange( xTC->getEnd(), uno::UNO_SET_THROW );
+ xTVCursor->gotoRange( xCurrentRange, false );
+ dispatchRequests( xModel,".uno:Delete" );
+ xTVCursor->gotoRange( xEndMarker->getEnd(), false );
+ }
+ }
+ xEndMarker->setString( "" ); // remove marker
+ xTC = xText->createTextCursorByRange( xEndMarker->getEnd() );
+ pWhere->setXTextCursor( xTC );
+ }
+ return uno::Reference< word::XRange >( pWhere );
+}
+
+OUString
+SwVbaAutoTextEntry::getServiceImplName()
+{
+ return "SwVbaAutoTextEntry";
+}
+
+uno::Sequence< OUString >
+SwVbaAutoTextEntry::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.AutoTextEntry"
+ };
+ return aServiceNames;
+}
+
+SwVbaAutoTextEntries::SwVbaAutoTextEntries( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ) : SwVbaAutoTextEntries_BASE( xParent, xContext, xIndexAccess )
+{
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaAutoTextEntries::getElementType()
+{
+ return cppu::UnoType<word::XAutoTextEntry>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaAutoTextEntries::createEnumeration()
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+uno::Any
+SwVbaAutoTextEntries::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< text::XAutoTextEntry > xEntry( aSource, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XAutoTextEntry >( new SwVbaAutoTextEntry( this, mxContext, xEntry ) ) );
+}
+
+OUString
+SwVbaAutoTextEntries::getServiceImplName()
+{
+ return "SwVbaAutoTextEntries";
+}
+
+css::uno::Sequence<OUString>
+SwVbaAutoTextEntries::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.AutoTextEntries"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaautotextentry.hxx b/sw/source/ui/vba/vbaautotextentry.hxx
new file mode 100644
index 0000000000..9a8ab4ad1d
--- /dev/null
+++ b/sw/source/ui/vba/vbaautotextentry.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAAUTOTEXTENTRY_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAAUTOTEXTENTRY_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XAutoTextEntries.hpp>
+#include <ooo/vba/word/XAutoTextEntry.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <ooo/vba/word/XRange.hpp>
+#include <com/sun/star/text/XAutoTextEntry.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XAutoTextEntry > SwVbaAutoTextEntry_BASE;
+
+class SwVbaAutoTextEntry : public SwVbaAutoTextEntry_BASE
+{
+private:
+ css::uno::Reference< css::text::XAutoTextEntry > mxEntry;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaAutoTextEntry( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XAutoTextEntry > xEntry );
+ virtual ~SwVbaAutoTextEntry() override;
+
+ // XAutoTextEntry
+ virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL Insert( const css::uno::Reference< ooo::vba::word::XRange >& _where, const css::uno::Any& _richtext ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+typedef CollTestImplHelper< ooo::vba::word::XAutoTextEntries > SwVbaAutoTextEntries_BASE;
+
+class SwVbaAutoTextEntries : public SwVbaAutoTextEntries_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaAutoTextEntries( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaAutoTextEntries_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAAUTOTEXTENTRY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbabookmark.cxx b/sw/source/ui/vba/vbabookmark.cxx
new file mode 100644
index 0000000000..aecc0760bc
--- /dev/null
+++ b/sw/source/ui/vba/vbabookmark.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 "vbabookmark.hxx"
+#include <com/sun/star/text/XBookmarksSupplier.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <utility>
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaBookmark::SwVbaBookmark( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,
+ css::uno::Reference< frame::XModel > xModel, OUString aBookmarkName ) :
+ SwVbaBookmark_BASE( rParent, rContext ), mxModel(std::move( xModel )), maBookmarkName(std::move( aBookmarkName )), mbValid( true )
+{
+ uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( mxModel, uno::UNO_QUERY_THROW );
+ mxBookmark.set( xBookmarksSupplier->getBookmarks()->getByName( maBookmarkName ), uno::UNO_QUERY_THROW );
+}
+
+SwVbaBookmark::~SwVbaBookmark()
+{
+}
+
+void SwVbaBookmark::checkVality()
+{
+ if( !mbValid )
+ throw uno::RuntimeException("The bookmark is not valid" );
+}
+
+void SAL_CALL SwVbaBookmark::Delete()
+{
+ checkVality();
+ uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW );
+ xTextDocument->getText()->removeTextContent( mxBookmark );
+ mbValid = false;
+}
+
+void SAL_CALL SwVbaBookmark::Select()
+{
+ checkVality();
+ uno::Reference< view::XSelectionSupplier > xSelectSupp( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelectSupp->select( uno::Any( mxBookmark ) );
+}
+
+OUString SAL_CALL SwVbaBookmark::getName()
+{
+ return maBookmarkName;
+}
+
+void SAL_CALL SwVbaBookmark::setName( const OUString& _name )
+{
+ uno::Reference< container::XNamed > xNamed( mxBookmark, uno::UNO_QUERY_THROW );
+ xNamed->setName( _name );
+}
+
+uno::Any SAL_CALL SwVbaBookmark::Range()
+{
+ uno::Reference< text::XTextContent > xTextContent( mxBookmark, uno::UNO_SET_THROW );
+ uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xTextRange( xTextContent->getAnchor(), uno::UNO_SET_THROW );
+ return uno::Any( uno::Reference< word::XRange>( new SwVbaRange( this, mxContext, xTextDocument, xTextRange->getStart(), xTextRange->getEnd(), xTextRange->getText() ) ) );
+}
+
+OUString
+SwVbaBookmark::getServiceImplName()
+{
+ return "SwVbaBookmark";
+}
+
+uno::Sequence< OUString >
+SwVbaBookmark::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Bookmark"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbabookmark.hxx b/sw/source/ui/vba/vbabookmark.hxx
new file mode 100644
index 0000000000..24524df618
--- /dev/null
+++ b/sw/source/ui/vba/vbabookmark.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARK_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARK_HXX
+
+#include <ooo/vba/word/XBookmark.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextContent.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XBookmark> SwVbaBookmark_BASE;
+
+class SwVbaBookmark : public SwVbaBookmark_BASE
+{
+private:
+ css::uno::Reference<css::frame::XModel> mxModel;
+ css::uno::Reference<css::text::XTextContent> mxBookmark;
+ OUString maBookmarkName;
+ bool mbValid;
+
+private:
+ /// @throws css::uno::RuntimeException
+ void checkVality();
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaBookmark(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ css::uno::Reference<css::frame::XModel> xModel, OUString aName);
+ virtual ~SwVbaBookmark() override;
+
+ // Methods
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName(const OUString&) override;
+ virtual void SAL_CALL Delete() override;
+ virtual void SAL_CALL Select() override;
+ virtual css::uno::Any SAL_CALL Range() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARK_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbabookmarks.cxx b/sw/source/ui/vba/vbabookmarks.cxx
new file mode 100644
index 0000000000..6755413796
--- /dev/null
+++ b/sw/source/ui/vba/vbabookmarks.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 "vbabookmarks.hxx"
+#include "vbabookmark.hxx"
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <ooo/vba/word/WdBookmarkSortBy.hpp>
+#include "vbarange.hxx"
+#include "wordvbahelper.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class BookmarksEnumeration : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > mxModel;
+public:
+ /// @throws uno::RuntimeException
+ BookmarksEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Reference< frame::XModel > xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel(std::move( xModel )) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< container::XNamed > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ OUString aName = xNamed->getName();
+ return uno::Any( uno::Reference< word::XBookmark > ( new SwVbaBookmark( m_xParent, m_xContext, mxModel, aName ) ) );
+ }
+
+};
+
+// Bookmarks use case-insensitive name lookup in MS Word.
+class BookmarkCollectionHelper : public ::cppu::WeakImplHelper< container::XNameAccess,
+ container::XIndexAccess >
+{
+private:
+ uno::Reference< container::XNameAccess > mxNameAccess;
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ uno::Any m_cachePos;
+public:
+ /// @throws uno::RuntimeException
+ explicit BookmarkCollectionHelper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess ))
+ {
+ mxNameAccess.set( mxIndexAccess, uno::UNO_QUERY_THROW );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return mxIndexAccess->getElementType(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return mxIndexAccess->hasElements(); }
+ // XNameAccess
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName(aName) )
+ throw container::NoSuchElementException();
+ return m_cachePos;
+ }
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ return mxNameAccess->getElementNames();
+ }
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ if( mxNameAccess->hasByName( aName ) )
+ {
+ m_cachePos = mxNameAccess->getByName( aName );
+ return true;
+ }
+ else
+ {
+ for( sal_Int32 nIndex = 0; nIndex < mxIndexAccess->getCount(); nIndex++ )
+ {
+ uno::Reference< container::XNamed > xNamed( mxIndexAccess->getByIndex( nIndex ), uno::UNO_QUERY_THROW );
+ OUString aBookmarkName = xNamed->getName();
+ if( aName.equalsIgnoreAsciiCase( aBookmarkName ) )
+ {
+ m_cachePos <<= xNamed;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return mxIndexAccess->getCount();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ return mxIndexAccess->getByIndex( Index );
+ }
+};
+
+}
+
+SwVbaBookmarks::SwVbaBookmarks( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xBookmarks, uno::Reference< frame::XModel > xModel ): SwVbaBookmarks_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new BookmarkCollectionHelper( xBookmarks ) ) ), mxModel(std::move( xModel ))
+{
+ mxBookmarksSupplier.set( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW );
+}
+// XEnumerationAccess
+uno::Type
+SwVbaBookmarks::getElementType()
+{
+ return cppu::UnoType<word::XBookmark>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaBookmarks::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new BookmarksEnumeration( getParent(), mxContext,xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+SwVbaBookmarks::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< container::XNamed > xNamed( aSource, uno::UNO_QUERY_THROW );
+ OUString aName = xNamed->getName();
+ return uno::Any( uno::Reference< word::XBookmark > ( new SwVbaBookmark( getParent(), mxContext, mxModel, aName ) ) );
+}
+
+void SwVbaBookmarks::removeBookmarkByName( const OUString& rName )
+{
+ uno::Reference< text::XTextContent > xBookmark( m_xNameAccess->getByName( rName ), uno::UNO_QUERY_THROW );
+ word::getXTextViewCursor( mxModel )->getText()->removeTextContent( xBookmark );
+}
+
+void SwVbaBookmarks::addBookmarkByName( const uno::Reference< frame::XModel >& xModel, const OUString& rName, const uno::Reference< text::XTextRange >& rTextRange )
+{
+ uno::Reference< lang::XMultiServiceFactory > xDocMSF( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextContent > xBookmark( xDocMSF->createInstance("com.sun.star.text.Bookmark"), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNamed > xNamed( xBookmark, uno::UNO_QUERY_THROW );
+ xNamed->setName( rName );
+ rTextRange->getText()->insertTextContent( rTextRange, xBookmark, false );
+}
+
+uno::Any SAL_CALL
+SwVbaBookmarks::Add( const OUString& rName, const uno::Any& rRange )
+{
+ uno::Reference< text::XTextRange > xTextRange;
+ uno::Reference< word::XRange > xRange;
+ if( rRange >>= xRange )
+ {
+ SwVbaRange* pRange = dynamic_cast< SwVbaRange* >( xRange.get() );
+ if( pRange )
+ xTextRange = pRange->getXTextRange();
+ }
+ else
+ {
+ // FIXME: insert the bookmark into current view cursor
+ xTextRange.set( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW );
+ }
+
+ // remove the exist bookmark
+ if( m_xNameAccess->hasByName( rName ) )
+ removeBookmarkByName( rName );
+
+ addBookmarkByName( mxModel, rName, xTextRange );
+
+ return uno::Any( uno::Reference< word::XBookmark >( new SwVbaBookmark( getParent(), mxContext, mxModel, rName ) ) );
+}
+
+sal_Int32 SAL_CALL
+SwVbaBookmarks::getDefaultSorting()
+{
+ return word::WdBookmarkSortBy::wdSortByName;
+}
+
+void SAL_CALL
+SwVbaBookmarks::setDefaultSorting( sal_Int32/* _type*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL
+SwVbaBookmarks::getShowHidden()
+{
+ return true;
+}
+
+void SAL_CALL
+SwVbaBookmarks::setShowHidden( sal_Bool /*_hidden*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL
+SwVbaBookmarks::Exists( const OUString& rName )
+{
+ bool bExist = m_xNameAccess->hasByName( rName );
+ return bExist;
+}
+
+OUString
+SwVbaBookmarks::getServiceImplName()
+{
+ return "SwVbaBookmarks";
+}
+
+css::uno::Sequence<OUString>
+SwVbaBookmarks::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Bookmarks"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbabookmarks.hxx b/sw/source/ui/vba/vbabookmarks.hxx
new file mode 100644
index 0000000000..1b264fb6b7
--- /dev/null
+++ b/sw/source/ui/vba/vbabookmarks.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARKS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARKS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XBookmarks.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XBookmarksSupplier.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XBookmarks > SwVbaBookmarks_BASE;
+
+class SwVbaBookmarks : public SwVbaBookmarks_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::text::XBookmarksSupplier > mxBookmarksSupplier;
+
+private:
+ /// @throws css::uno::RuntimeException
+ void removeBookmarkByName( const OUString& rName );
+
+public:
+ SwVbaBookmarks( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xBookmarks, css::uno::Reference< css::frame::XModel > xModel );
+
+ /// @throws css::uno::RuntimeException
+ static void addBookmarkByName( const css::uno::Reference< css::frame::XModel >& xModel, const OUString& rName, const css::uno::Reference< css::text::XTextRange >& rTextRange );
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaBookmarks_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XBookmarks
+ virtual sal_Int32 SAL_CALL getDefaultSorting() override;
+ virtual void SAL_CALL setDefaultSorting( sal_Int32 _type ) override;
+ virtual sal_Bool SAL_CALL getShowHidden() override;
+ virtual void SAL_CALL setShowHidden( sal_Bool _hidden ) override;
+
+ virtual css::uno::Any SAL_CALL Add( const OUString& rName, const css::uno::Any& rRange ) override;
+ virtual sal_Bool SAL_CALL Exists( const OUString& rName ) override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBABOOKMARKS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaborders.cxx b/sw/source/ui/vba/vbaborders.cxx
new file mode 100644
index 0000000000..9e780fe210
--- /dev/null
+++ b/sw/source/ui/vba/vbaborders.cxx
@@ -0,0 +1,366 @@
+/* -*- 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 "vbaborders.hxx"
+#include <ooo/vba/word/XBorder.hpp>
+#include <ooo/vba/word/WdBorderType.hpp>
+#include <ooo/vba/word/WdLineStyle.hpp>
+#include <sal/macros.h>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/TableBorder.hpp>
+#include <utility>
+#include "vbapalette.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+typedef ::cppu::WeakImplHelper<container::XIndexAccess > RangeBorders_Base;
+typedef InheritedHelperInterfaceWeakImpl<word::XBorder > SwVbaBorder_Base;
+
+// #TODO sort these indexes to match the order in which Word iterates over the
+// borders, the enumeration will match the order in this list
+const sal_Int16 supportedIndexTable[] = { word::WdBorderType::wdBorderBottom, word::WdBorderType::wdBorderDiagonalDown, word::WdBorderType::wdBorderDiagonalUp, word::WdBorderType::wdBorderHorizontal, word::WdBorderType::wdBorderLeft, word::WdBorderType::wdBorderRight, word::WdBorderType::wdBorderTop, word::WdBorderType::wdBorderVertical };
+
+// Equiv widths in 1/100 mm
+const sal_Int32 OOLineHairline = 2;
+
+namespace {
+
+class SwVbaBorder : public SwVbaBorder_Base
+{
+private:
+ uno::Reference< beans::XPropertySet > m_xProps;
+ sal_Int32 m_LineType;
+ void setBorderLine( table::BorderLine const & rBorderLine )
+ {
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( "TableBorder" ) >>= aTableBorder;
+
+ switch ( m_LineType )
+ {
+ case word::WdBorderType::wdBorderLeft:
+ aTableBorder.IsLeftLineValid = true;
+ aTableBorder.LeftLine= rBorderLine;
+ break;
+ case word::WdBorderType::wdBorderTop:
+ aTableBorder.IsTopLineValid = true;
+ aTableBorder.TopLine = rBorderLine;
+ break;
+
+ case word::WdBorderType::wdBorderBottom:
+ aTableBorder.IsBottomLineValid = true;
+ aTableBorder.BottomLine = rBorderLine;
+ break;
+ case word::WdBorderType::wdBorderRight:
+ aTableBorder.IsRightLineValid = true;
+ aTableBorder.RightLine = rBorderLine;
+ break;
+ case word::WdBorderType::wdBorderVertical:
+ aTableBorder.IsVerticalLineValid = true;
+ aTableBorder.VerticalLine = rBorderLine;
+ break;
+ case word::WdBorderType::wdBorderHorizontal:
+ aTableBorder.IsHorizontalLineValid = true;
+ aTableBorder.HorizontalLine = rBorderLine;
+ break;
+ case word::WdBorderType::wdBorderDiagonalDown:
+ case word::WdBorderType::wdBorderDiagonalUp:
+ // #TODO have to ignore at the moment, would be
+ // nice to investigate what we can do here
+ break;
+ default:
+ return;
+ }
+ m_xProps->setPropertyValue( "TableBorder", uno::Any(aTableBorder) );
+ }
+
+ bool getBorderLine( table::BorderLine& rBorderLine )
+ {
+ table::TableBorder aTableBorder;
+ m_xProps->getPropertyValue( "TableBorder" ) >>= aTableBorder;
+ switch ( m_LineType )
+ {
+ case word::WdBorderType::wdBorderLeft:
+ if ( aTableBorder.IsLeftLineValid )
+ rBorderLine = aTableBorder.LeftLine;
+ break;
+ case word::WdBorderType::wdBorderTop:
+ if ( aTableBorder.IsTopLineValid )
+ rBorderLine = aTableBorder.TopLine;
+ break;
+ case word::WdBorderType::wdBorderBottom:
+ if ( aTableBorder.IsBottomLineValid )
+ rBorderLine = aTableBorder.BottomLine;
+ break;
+ case word::WdBorderType::wdBorderRight:
+ if ( aTableBorder.IsRightLineValid )
+ rBorderLine = aTableBorder.RightLine;
+ break;
+ case word::WdBorderType::wdBorderVertical:
+ if ( aTableBorder.IsVerticalLineValid )
+ rBorderLine = aTableBorder.VerticalLine;
+ break;
+ case word::WdBorderType::wdBorderHorizontal:
+ if ( aTableBorder.IsHorizontalLineValid )
+ rBorderLine = aTableBorder.HorizontalLine;
+ break;
+
+ case word::WdBorderType::wdBorderDiagonalDown:
+ case word::WdBorderType::wdBorderDiagonalUp:
+ // #TODO have to ignore at the moment, would be
+ // nice to investigate what we can do here
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+protected:
+ virtual OUString getServiceImplName() override
+ {
+ return "SwVbaBorder";
+ }
+
+ virtual css::uno::Sequence<OUString> getServiceNames() override
+ {
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Border"
+ };
+ return aServiceNames;
+ }
+public:
+ SwVbaBorder( const uno::Reference< beans::XPropertySet > & xProps, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 lineType ) : SwVbaBorder_Base( uno::Reference< XHelperInterface >( xProps, uno::UNO_QUERY ), xContext ), m_xProps( xProps ), m_LineType( lineType ) {}
+
+ uno::Any SAL_CALL getLineStyle() override
+ {
+ sal_Int32 nLineStyle = word::WdLineStyle::wdLineStyleNone;
+ table::BorderLine aBorderLine;
+ if ( getBorderLine( aBorderLine ) )
+ {
+ if( aBorderLine.InnerLineWidth !=0 && aBorderLine.OuterLineWidth !=0 )
+ {
+ nLineStyle = word::WdLineStyle::wdLineStyleDouble;
+ }
+ else if( aBorderLine.InnerLineWidth !=0 || aBorderLine.OuterLineWidth !=0 )
+ {
+ nLineStyle = word::WdLineStyle::wdLineStyleSingle;
+ }
+ else
+ {
+ nLineStyle = word::WdLineStyle::wdLineStyleNone;
+ }
+ }
+ return uno::Any( nLineStyle );
+ }
+ void SAL_CALL setLineStyle( const uno::Any& _linestyle ) override
+ {
+ // Urk no choice but to silently ignore we don't support this attribute
+ // #TODO would be nice to support the word line styles
+ sal_Int32 nLineStyle = 0;
+ _linestyle >>= nLineStyle;
+ table::BorderLine aBorderLine;
+ if ( !getBorderLine( aBorderLine ) )
+ throw uno::RuntimeException("Method failed" );
+
+ switch ( nLineStyle )
+ {
+ case word::WdLineStyle::wdLineStyleNone:
+ {
+ aBorderLine.InnerLineWidth = 0;
+ aBorderLine.OuterLineWidth = 0;
+ break;
+ }
+ case word::WdLineStyle::wdLineStyleDashDot:
+ case word::WdLineStyle::wdLineStyleDashDotDot:
+ case word::WdLineStyle::wdLineStyleDashDotStroked:
+ case word::WdLineStyle::wdLineStyleDashLargeGap:
+ case word::WdLineStyle::wdLineStyleDashSmallGap:
+ case word::WdLineStyle::wdLineStyleDot:
+ case word::WdLineStyle::wdLineStyleDouble:
+ case word::WdLineStyle::wdLineStyleDoubleWavy:
+ case word::WdLineStyle::wdLineStyleEmboss3D:
+ case word::WdLineStyle::wdLineStyleEngrave3D:
+ case word::WdLineStyle::wdLineStyleInset:
+ case word::WdLineStyle::wdLineStyleOutset:
+ case word::WdLineStyle::wdLineStyleSingle:
+ case word::WdLineStyle::wdLineStyleSingleWavy:
+ case word::WdLineStyle::wdLineStyleThickThinLargeGap:
+ case word::WdLineStyle::wdLineStyleThickThinMedGap:
+ case word::WdLineStyle::wdLineStyleThickThinSmallGap:
+ case word::WdLineStyle::wdLineStyleThinThickLargeGap:
+ case word::WdLineStyle::wdLineStyleThinThickMedGap:
+ case word::WdLineStyle::wdLineStyleThinThickSmallGap:
+ case word::WdLineStyle::wdLineStyleThinThickThinLargeGap:
+ case word::WdLineStyle::wdLineStyleThinThickThinMedGap:
+ case word::WdLineStyle::wdLineStyleThinThickThinSmallGap:
+ case word::WdLineStyle::wdLineStyleTriple:
+ {
+ aBorderLine.InnerLineWidth = 0;
+ aBorderLine.OuterLineWidth = OOLineHairline;
+ break;
+ }
+ default:
+ throw uno::RuntimeException("Bad param" );
+ }
+ setBorderLine( aBorderLine );
+
+ }
+};
+
+class RangeBorders : public RangeBorders_Base
+{
+private:
+ uno::Reference< table::XCellRange > m_xRange;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ VbaPalette m_Palette;
+ sal_Int32 getTableIndex( sal_Int32 nConst )
+ {
+ // okay return position of the index in the table
+ sal_Int32 nIndexes = getCount();
+ sal_Int32 realIndex = 0;
+ const sal_Int16* pTableEntry = supportedIndexTable;
+ for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry )
+ {
+ if ( *pTableEntry == nConst )
+ return realIndex;
+ }
+ return getCount(); // error condition
+ }
+public:
+ RangeBorders( uno::Reference< table::XCellRange > xRange, uno::Reference< uno::XComponentContext > xContext, VbaPalette aPalette ) : m_xRange(std::move( xRange )), m_xContext(std::move( xContext )), m_Palette(std::move( aPalette ))
+ {
+ }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return SAL_N_ELEMENTS( supportedIndexTable );
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+
+ sal_Int32 nIndex = getTableIndex( Index );
+ if ( nIndex >= 0 && nIndex < getCount() )
+ {
+ uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XBorder >( new SwVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ] )) );
+ }
+ throw lang::IndexOutOfBoundsException();
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XBorder>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+};
+
+}
+
+static uno::Reference< container::XIndexAccess >
+rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, VbaPalette const & rPalette )
+{
+ return new RangeBorders( xRange, xContext, rPalette );
+}
+
+namespace {
+
+class RangeBorderEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 m_nIndex;
+public:
+ explicit RangeBorderEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : m_xIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( m_nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+// for Table borders
+SwVbaBorders::SwVbaBorders( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< table::XCellRange >& xRange, VbaPalette const & rPalette ): SwVbaBorders_BASE( xParent, xContext, rangeToBorderIndexAccess( xRange ,xContext, rPalette ) )
+{
+ m_xProps.set( xRange, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< container::XEnumeration >
+SwVbaBorders::createEnumeration()
+{
+ return new RangeBorderEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+SwVbaBorders::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource; // it's already a Border object
+}
+
+uno::Type
+SwVbaBorders::getElementType()
+{
+ return cppu::UnoType<word::XBorders>::get();
+}
+
+uno::Any
+SwVbaBorders::getItemByIntIndex( const sal_Int32 nIndex )
+{
+ return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) );
+}
+
+sal_Bool SAL_CALL SwVbaBorders::getShadow()
+{
+ // always return False for table border in MS Word
+ return false;
+}
+
+void SAL_CALL SwVbaBorders::setShadow( sal_Bool /*_shadow*/ )
+{
+ // not support in Table border in Word
+ // TODO:
+}
+
+OUString
+SwVbaBorders::getServiceImplName()
+{
+ return "SwVbaBorders";
+}
+
+uno::Sequence< OUString >
+SwVbaBorders::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Borders"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaborders.hxx b/sw/source/ui/vba/vbaborders.hxx
new file mode 100644
index 0000000000..a4ca819f67
--- /dev/null
+++ b/sw/source/ui/vba/vbaborders.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBABORDERS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBABORDERS_HXX
+
+#include <ooo/vba/word/XBorders.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::word::XBorders > SwVbaBorders_BASE;
+class VbaPalette;
+class SwVbaBorders : public SwVbaBorders_BASE
+{
+ // XEnumerationAccess
+ virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex ) override;
+ css::uno::Reference< css::beans::XPropertySet > m_xProps;
+public:
+ SwVbaBorders( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::table::XCellRange >& xRange, VbaPalette const & rPalette );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ virtual sal_Bool SAL_CALL getShadow() override;
+ virtual void SAL_CALL setShadow( sal_Bool _shadow ) override;
+
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBABORDERS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacell.cxx b/sw/source/ui/vba/vbacell.cxx
new file mode 100644
index 0000000000..a24dd3dd1c
--- /dev/null
+++ b/sw/source/ui/vba/vbacell.cxx
@@ -0,0 +1,102 @@
+/* -*- 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 "vbacell.hxx"
+#include "vbatablehelper.hxx"
+#include "vbarow.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaCell::SwVbaCell( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextTable > xTextTable, sal_Int32 nColumn, sal_Int32 nRow ) :
+ SwVbaCell_BASE( rParent, rContext ), mxTextTable(std::move( xTextTable )), mnColumn( nColumn ), mnRow( nRow )
+{
+}
+
+SwVbaCell::~SwVbaCell()
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaCell::getWidth()
+{
+ SwVbaTableHelper aTableHelper( mxTextTable );
+ return aTableHelper.GetColWidth( mnColumn, mnRow );
+}
+
+void SAL_CALL SwVbaCell::setWidth( ::sal_Int32 _width )
+{
+ SwVbaTableHelper aTableHelper( mxTextTable );
+ aTableHelper.SetColWidth( _width, mnColumn, mnRow, true );
+}
+
+uno::Any SAL_CALL SwVbaCell::getHeight()
+{
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) );
+ return xRow->getHeight();
+}
+
+void SAL_CALL SwVbaCell::setHeight( const uno::Any& _height )
+{
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) );
+ xRow->setHeight( _height );
+}
+
+::sal_Int32 SAL_CALL SwVbaCell::getHeightRule()
+{
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) );
+ return xRow->getHeightRule();
+}
+
+void SAL_CALL SwVbaCell::setHeightRule( ::sal_Int32 _heightrule )
+{
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnRow ) );
+ xRow->setHeightRule( _heightrule );
+}
+
+void SAL_CALL SwVbaCell::SetWidth( float width, sal_Int32 /*rulestyle*/ )
+{
+ // FIXME: handle the argument: rulestyle
+ setWidth( static_cast<sal_Int32>(width) );
+}
+
+void SAL_CALL SwVbaCell::SetHeight( float height, sal_Int32 heightrule )
+{
+ // FIXME: handle the argument: heightrule
+ setHeightRule( heightrule );
+ setHeight( uno::Any( height ) );
+}
+
+OUString
+SwVbaCell::getServiceImplName()
+{
+ return "SwVbaCell";
+}
+
+uno::Sequence< OUString >
+SwVbaCell::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Cell"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacell.hxx b/sw/source/ui/vba/vbacell.hxx
new file mode 100644
index 0000000000..8ca9f0adad
--- /dev/null
+++ b/sw/source/ui/vba/vbacell.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACELL_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBACELL_HXX
+
+#include <ooo/vba/word/XCell.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextTable.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XCell > SwVbaCell_BASE;
+
+class SwVbaCell : public SwVbaCell_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ sal_Int32 mnColumn;
+ sal_Int32 mnRow;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaCell( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nColumn, sal_Int32 nRow );
+ virtual ~SwVbaCell() override;
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getWidth() override;
+ virtual void SAL_CALL setWidth( ::sal_Int32 _width ) override;
+ virtual css::uno::Any SAL_CALL getHeight() override;
+ virtual void SAL_CALL setHeight( const css::uno::Any& _height ) override;
+ virtual ::sal_Int32 SAL_CALL getHeightRule() override;
+ virtual void SAL_CALL setHeightRule( ::sal_Int32 _heightrule ) override;
+
+ // Methods
+ virtual void SAL_CALL SetWidth( float width, sal_Int32 rulestyle ) override;
+ virtual void SAL_CALL SetHeight( float height, sal_Int32 heightrule ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACELL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacells.cxx b/sw/source/ui/vba/vbacells.cxx
new file mode 100644
index 0000000000..e30c2ed370
--- /dev/null
+++ b/sw/source/ui/vba/vbacells.cxx
@@ -0,0 +1,214 @@
+/* -*- 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 "vbacells.hxx"
+#include "vbacell.hxx"
+#include "vbarow.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class CellsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ sal_Int32 mnIndex;
+
+public:
+ explicit CellsEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )), mnIndex( 0 )
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mnIndex < mxIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if( mnIndex < mxIndexAccess->getCount() )
+ {
+ return mxIndexAccess->getByIndex( mnIndex++ );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class CellCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< css::text::XTextTable > mxTextTable;
+ sal_Int32 mnLeft;
+ sal_Int32 mnTop;
+ sal_Int32 mnRight;
+ sal_Int32 mnBottom;
+
+public:
+ /// @throws css::uno::RuntimeException
+ CellCollectionHelper( css::uno::Reference< ov::XHelperInterface > xParent, css::uno::Reference< css::uno::XComponentContext > xContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ): mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxTextTable(std::move( xTextTable )), mnLeft( nLeft ), mnTop( nTop ), mnRight( nRight ), mnBottom( nBottom )
+ {
+ }
+
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ return ( mnRight - mnLeft + 1 ) * ( mnBottom - mnTop + 1 );
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw css::lang::IndexOutOfBoundsException();
+
+ for( sal_Int32 row = mnTop; row <= mnBottom; row++ )
+ {
+ for( sal_Int32 col = mnLeft; col <= mnRight; col++ )
+ {
+ if( Index == ( ( row - mnTop ) * ( mnRight - mnLeft + 1 ) + ( col - mnLeft ) ) )
+ return uno::Any( uno::Reference< word::XCell >( new SwVbaCell( mxParent, mxContext, mxTextTable, col, row ) ) );
+ }
+ }
+ throw css::lang::IndexOutOfBoundsException();
+
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XCell>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new CellsEnumWrapper( this );
+ }
+};
+
+}
+
+SwVbaCells::SwVbaCells( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< text::XTextTable >& xTextTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) : SwVbaCells_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new CellCollectionHelper( xParent, xContext, xTextTable, nLeft, nTop, nRight, nBottom ) ) ), mxTextTable( xTextTable ), mnTop( nTop ), mnBottom( nBottom )
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaCells::getWidth()
+{
+ uno::Reference< word::XCell > xCell( m_xIndexAccess->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ return xCell->getWidth();
+}
+
+void SAL_CALL SwVbaCells::setWidth( ::sal_Int32 _width )
+{
+ sal_Int32 nIndex = 0;
+ while( nIndex < m_xIndexAccess->getCount() )
+ {
+ uno::Reference< word::XCell > xCell( m_xIndexAccess->getByIndex( nIndex++ ), uno::UNO_QUERY_THROW );
+ xCell->setWidth( _width );
+ }
+}
+
+uno::Any SAL_CALL SwVbaCells::getHeight()
+{
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnTop ) );
+ return xRow->getHeight();
+}
+
+void SAL_CALL SwVbaCells::setHeight( const uno::Any& _height )
+{
+ for( sal_Int32 row = mnTop; row <= mnBottom; row++ )
+ {
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, row ) );
+ xRow->setHeight( _height );
+ }
+}
+
+::sal_Int32 SAL_CALL SwVbaCells::getHeightRule()
+{
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, mnTop ) );
+ return xRow->getHeightRule();
+}
+
+void SAL_CALL SwVbaCells::setHeightRule( ::sal_Int32 _heightrule )
+{
+ for( sal_Int32 row = mnTop; row <= mnBottom; row++ )
+ {
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, row ) );
+ xRow->setHeightRule( _heightrule );
+ }
+}
+
+void SAL_CALL SwVbaCells::SetWidth( float width, sal_Int32 rulestyle )
+{
+ sal_Int32 nIndex = 0;
+ while( nIndex < m_xIndexAccess->getCount() )
+ {
+ uno::Reference< word::XCell > xCell( m_xIndexAccess->getByIndex( nIndex++ ), uno::UNO_QUERY_THROW );
+ xCell->SetWidth( width, rulestyle );
+ }
+}
+
+void SAL_CALL SwVbaCells::SetHeight( float height, sal_Int32 heightrule )
+{
+ for( sal_Int32 row = mnTop; row <= mnBottom; row++ )
+ {
+ uno::Reference< word::XRow > xRow( new SwVbaRow( getParent(), mxContext, mxTextTable, row ) );
+ xRow->SetHeight( height, heightrule );
+ }
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaCells::getElementType()
+{
+ return cppu::UnoType<word::XCell>::get();
+}
+
+uno::Reference< container::XEnumeration >
+SwVbaCells::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xEnumAccess->createEnumeration();
+}
+
+uno::Any
+SwVbaCells::createCollectionObject( const uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaCells::getServiceImplName()
+{
+ return "SwVbaCells";
+}
+
+uno::Sequence<OUString>
+SwVbaCells::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Cells"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacells.hxx b/sw/source/ui/vba/vbacells.hxx
new file mode 100644
index 0000000000..e9de9f532f
--- /dev/null
+++ b/sw/source/ui/vba/vbacells.hxx
@@ -0,0 +1,63 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACELLS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBACELLS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XCells.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XCells > SwVbaCells_BASE;
+
+class SwVbaCells : public SwVbaCells_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ sal_Int32 mnTop;
+ sal_Int32 mnBottom;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaCells( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::text::XTextTable >& xTextTable, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom );
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getWidth() override;
+ virtual void SAL_CALL setWidth( ::sal_Int32 _width ) override;
+ virtual css::uno::Any SAL_CALL getHeight() override;
+ virtual void SAL_CALL setHeight( const css::uno::Any& _height ) override;
+ virtual ::sal_Int32 SAL_CALL getHeightRule() override;
+ virtual void SAL_CALL setHeightRule( ::sal_Int32 _heightrule ) override;
+
+ // Methods
+ virtual void SAL_CALL SetWidth( float width, sal_Int32 rulestyle ) override;
+ virtual void SAL_CALL SetHeight( float height, sal_Int32 heightrule ) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaCells_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACELLS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacolumn.cxx b/sw/source/ui/vba/vbacolumn.cxx
new file mode 100644
index 0000000000..c4411bfab4
--- /dev/null
+++ b/sw/source/ui/vba/vbacolumn.cxx
@@ -0,0 +1,91 @@
+/* -*- 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 "vbacolumn.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include "vbatablehelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaColumn::SwVbaColumn( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextTable > xTextTable, sal_Int32 nIndex ) :
+ SwVbaColumn_BASE( rParent, rContext ), mxTextTable(std::move( xTextTable )), mnIndex( nIndex )
+{
+}
+
+SwVbaColumn::~SwVbaColumn()
+{
+}
+
+sal_Int32 SAL_CALL
+SwVbaColumn::getWidth( )
+{
+ SwVbaTableHelper aTableHelper( mxTextTable );
+ return aTableHelper.GetColWidth( mnIndex );
+}
+
+void SAL_CALL
+SwVbaColumn::setWidth( sal_Int32 _width )
+{
+
+ SwVbaTableHelper aTableHelper( mxTextTable );
+ aTableHelper.SetColWidth( _width, mnIndex );
+}
+
+void SAL_CALL
+SwVbaColumn::Select( )
+{
+ SelectColumn( getCurrentWordDoc(mxContext), mxTextTable, mnIndex, mnIndex );
+}
+
+void SwVbaColumn::SelectColumn( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextTable >& xTextTable, sal_Int32 nStartColumn, sal_Int32 nEndColumn )
+{
+ OUString sStartCol = SwVbaTableHelper::getColumnStr( nStartColumn );
+ OUString aRangeName = sStartCol + OUString::number( 1 );
+ OUString sEndCol = SwVbaTableHelper::getColumnStr( nEndColumn );
+ sal_Int32 nRowCount = xTextTable->getRows()->getCount();
+ aRangeName += ":" + sEndCol + OUString::number(nRowCount);
+
+ uno::Reference< table::XCellRange > xCellRange( xTextTable, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xSelRange = xCellRange->getCellRangeByName( aRangeName );
+
+ uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelection->select( uno::Any( xSelRange ) );
+}
+
+OUString
+SwVbaColumn::getServiceImplName()
+{
+ return "SwVbaColumn";
+}
+
+uno::Sequence< OUString >
+SwVbaColumn::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Column"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacolumn.hxx b/sw/source/ui/vba/vbacolumn.hxx
new file mode 100644
index 0000000000..4fe34de54a
--- /dev/null
+++ b/sw/source/ui/vba/vbacolumn.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMN_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMN_HXX
+
+#include <ooo/vba/word/XColumn.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextTable.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XColumn > SwVbaColumn_BASE;
+
+class SwVbaColumn : public SwVbaColumn_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ sal_Int32 mnIndex;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaColumn( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nIndex );
+ virtual ~SwVbaColumn() override;
+
+ // Methods
+ virtual sal_Int32 SAL_CALL getWidth() override;
+ virtual void SAL_CALL setWidth( sal_Int32 _width ) override;
+ virtual void SAL_CALL Select( ) override;
+
+ /// @throws css::uno::RuntimeException
+ static void SelectColumn( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextTable >& xTextTable, sal_Int32 nStartColumn, sal_Int32 nEndColumn );
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacolumns.cxx b/sw/source/ui/vba/vbacolumns.cxx
new file mode 100644
index 0000000000..ffaf662029
--- /dev/null
+++ b/sw/source/ui/vba/vbacolumns.cxx
@@ -0,0 +1,149 @@
+/* -*- 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 "vbacolumns.hxx"
+#include "vbacolumn.hxx"
+#include "vbatablehelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class ColumnsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::WeakReference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< text::XTextTable > mxTextTable;
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ sal_Int32 mnIndex;
+
+public:
+ ColumnsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< text::XTextTable > xTextTable ) : mxParent( xParent ), mxContext(std::move( xContext )), mxTextTable(std::move( xTextTable )), mnIndex( 0 )
+ {
+ mxIndexAccess = mxTextTable->getColumns();
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mnIndex < mxIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if( mnIndex < mxIndexAccess->getCount() )
+ {
+ return uno::Any( uno::Reference< word::XColumn > ( new SwVbaColumn( mxParent, mxContext, mxTextTable, mnIndex++ ) ) );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaColumns::SwVbaColumns( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableColumns >& xTableColumns ) : SwVbaColumns_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableColumns, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable ))
+{
+ mnStartColumnIndex = 0;
+ SwVbaTableHelper aTableHelper( mxTextTable );
+ mnEndColumnIndex = aTableHelper.getTabColumnsMaxCount( ) - 1;
+}
+
+SwVbaColumns::SwVbaColumns( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableColumns >& xTableColumns, sal_Int32 nStartCol, sal_Int32 nEndCol ) : SwVbaColumns_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableColumns, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )), mnStartColumnIndex( nStartCol ), mnEndColumnIndex( nEndCol )
+{
+ if( mnEndColumnIndex < mnStartColumnIndex )
+ throw uno::RuntimeException();
+}
+
+uno::Reference< word::XColumn > SwVbaColumns::getColumnAtIndex( sal_Int32 index )
+{
+ return uno::Reference< word::XColumn >( new SwVbaColumn( this, mxContext, mxTextTable, index ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaColumns::getWidth()
+{
+ return getColumnAtIndex( mnStartColumnIndex )->getWidth();
+}
+
+void SAL_CALL SwVbaColumns::setWidth( ::sal_Int32 _width )
+{
+ for( sal_Int32 index = mnStartColumnIndex; index <= mnEndColumnIndex; index++ )
+ {
+ getColumnAtIndex( index )->setWidth( _width );
+ }
+}
+
+void SAL_CALL SwVbaColumns::Select( )
+{
+ SwVbaColumn::SelectColumn( getCurrentWordDoc(mxContext), mxTextTable, mnStartColumnIndex, mnEndColumnIndex );
+}
+
+::sal_Int32 SAL_CALL SwVbaColumns::getCount()
+{
+ return ( mnEndColumnIndex - mnStartColumnIndex + 1 );
+}
+
+uno::Any SAL_CALL SwVbaColumns::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ )
+{
+ sal_Int32 nIndex = 0;
+ if( Index1 >>= nIndex )
+ {
+ if( nIndex <= 0 || nIndex > getCount() )
+ {
+ throw lang::IndexOutOfBoundsException("Index out of bounds" );
+ }
+ return uno::Any( uno::Reference< word::XColumn >( new SwVbaColumn( this, mxContext, mxTextTable, nIndex - 1 ) ) );
+ }
+ throw uno::RuntimeException("Index out of bounds" );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaColumns::getElementType()
+{
+ return cppu::UnoType<word::XColumn>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaColumns::createEnumeration()
+{
+ return new ColumnsEnumWrapper( this, mxContext, mxTextTable );
+}
+
+uno::Any
+SwVbaColumns::createCollectionObject( const uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaColumns::getServiceImplName()
+{
+ return "SwVbaColumns";
+}
+
+uno::Sequence<OUString>
+SwVbaColumns::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Columns"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacolumns.hxx b/sw/source/ui/vba/vbacolumns.hxx
new file mode 100644
index 0000000000..712dc03f0b
--- /dev/null
+++ b/sw/source/ui/vba/vbacolumns.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMNS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMNS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XColumns.hpp>
+#include <ooo/vba/word/XColumn.hpp>
+#include <com/sun/star/table/XTableColumns.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XColumns > SwVbaColumns_BASE;
+
+class SwVbaColumns : public SwVbaColumns_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ sal_Int32 mnStartColumnIndex;
+ sal_Int32 mnEndColumnIndex;
+
+private:
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< ooo::vba::word::XColumn > getColumnAtIndex( sal_Int32 index );
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaColumns( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableColumns >& xTableColumns );
+ /// @throws css::uno::RuntimeException
+ SwVbaColumns( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableColumns >& xTableColumns, sal_Int32 nStartCol, sal_Int32 nEndCol );
+
+ virtual sal_Int32 SAL_CALL getWidth( ) override;
+ virtual void SAL_CALL setWidth( sal_Int32 _width ) override;
+ virtual void SAL_CALL Select( ) override;
+
+ //XCollection
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaColumns_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBACOLUMNS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrol.cxx b/sw/source/ui/vba/vbacontentcontrol.cxx
new file mode 100644
index 0000000000..dc4e4afc23
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrol.cxx
@@ -0,0 +1,753 @@
+/* -*- 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 <ooo/vba/word/WdColor.hpp>
+#include <ooo/vba/word/WdCalendarType.hpp>
+#include <ooo/vba/word/WdContentControlType.hpp>
+#include <ooo/vba/word/WdLanguageID.hpp>
+
+#include <sal/log.hxx>
+
+#include <ndtxt.hxx>
+#include <unotextrange.hxx>
+
+#include "vbacontentcontrol.hxx"
+#include "vbacontentcontrollistentries.hxx"
+#include "vbarange.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/**
+ * Content controls are the modern version of FormFields, providing inline functionality similar
+ * to that of ActiveX form controls. Individual content controls may contain contents
+ * such as dates, lists, or paragraphs of formatted text.
+ *
+ * Not all functions are applicable to each type of control, so use getType verification liberally.
+ */
+SwVbaContentControl::SwVbaContentControl(const uno::Reference<XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext,
+ const uno::Reference<text::XTextDocument>& xTextDocument,
+ std::shared_ptr<SwContentControl> pContentControl)
+ : SwVbaContentControl_BASE(rParent, rContext)
+ , mxTextDocument(xTextDocument)
+ , m_pCC(pContentControl)
+{
+ assert(m_pCC && "SwVbaContentControl created without a shared_ptr. Why would you do that?");
+}
+
+SwVbaContentControl::~SwVbaContentControl() {}
+
+sal_Bool SwVbaContentControl::getAllowInsertDeleteSection()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getAllowInsertDeleteSection stub");
+ return false;
+}
+
+void SwVbaContentControl::setAllowInsertDeleteSection(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setAllowInsertDeleteSection stub");
+}
+
+sal_Int32 SwVbaContentControl::getAppearance()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getAppearance stub");
+ // wdContentControlBoundingBox / wdContentControlHidden / wdContentControlTags
+ return 0;
+}
+
+void SwVbaContentControl::setAppearance(sal_Int32 nSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setAppearance[" << nSet << "] stub");
+}
+
+OUString SwVbaContentControl::getBuildingBlockCategory()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getBuildingBlockCategory stub");
+ return OUString();
+}
+
+void SwVbaContentControl::setBuildingBlockCategory(const OUString& sSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setBuildingBlockCategory[" << sSet << "] stub");
+}
+
+sal_Int32 SwVbaContentControl::getBuildingBlockType()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getBuildingBlockType stub");
+ // returns a WdBuildingBlockTypes that represents the type of building block
+ return 0;
+}
+
+void SwVbaContentControl::setBuildingBlockType(sal_Int32 nSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setBuildingBlockType[" << nSet << "] stub");
+}
+
+sal_Bool SwVbaContentControl::getChecked() { return m_pCC->GetCheckbox() && m_pCC->GetChecked(); }
+
+void SwVbaContentControl::setChecked(sal_Bool bSet)
+{
+ // Word 2010: if locked, then the checked status is changed, but not the underlying text.
+ // Do we really want to do that? That is pretty bizarre behaviour...
+ // For now, just implement what seems to be a more logical response.
+ // TODO: test with modern versions.
+ if (getLockContents())
+ return;
+
+ if (m_pCC->GetCheckbox() && m_pCC->GetChecked() != static_cast<bool>(bSet))
+ {
+ m_pCC->SetChecked(bSet);
+ m_pCC->SetShowingPlaceHolder(false);
+ if (m_pCC->GetTextAttr())
+ m_pCC->GetTextAttr()->Invalidate();
+ }
+}
+
+sal_Int32 SwVbaContentControl::getColor()
+{
+ //This is just an assumed implementation - I have no testing environment to confirm.
+ OUString sColor = m_pCC->GetColor();
+ if (sColor == "wdColorAutomatic")
+ return word::WdColor::wdColorAutomatic;
+ if (sColor == "wdColorBlack")
+ return word::WdColor::wdColorBlack;
+ if (sColor == "wdColorBlue")
+ return word::WdColor::wdColorBlue;
+ if (sColor == "wdColorBlueGray")
+ return word::WdColor::wdColorBlueGray;
+ if (sColor == "wdColorBrightGreen")
+ return word::WdColor::wdColorBrightGreen;
+ if (sColor == "wdColorBrown")
+ return word::WdColor::wdColorBrown;
+ if (sColor == "wdColorDarkBlue")
+ return word::WdColor::wdColorDarkBlue;
+ if (sColor == "wdColorDarkGreen")
+ return word::WdColor::wdColorDarkGreen;
+ if (sColor == "wdColorDarkRed")
+ return word::WdColor::wdColorDarkRed;
+ if (sColor == "wdColorDarkTeal")
+ return word::WdColor::wdColorDarkTeal;
+ if (sColor == "wdColorDarkYellow")
+ return word::WdColor::wdColorDarkYellow;
+ if (sColor == "wdColorGold")
+ return word::WdColor::wdColorGold;
+ if (sColor == "wdColorGray05")
+ return word::WdColor::wdColorGray05;
+ if (sColor == "wdColorGray10")
+ return word::WdColor::wdColorGray10;
+ if (sColor == "wdColorGray125")
+ return word::WdColor::wdColorGray125;
+ if (sColor == "wdColorGray15")
+ return word::WdColor::wdColorGray15;
+ if (sColor == "wdColorGray20")
+ return word::WdColor::wdColorGray20;
+ if (sColor == "wdColorGray25")
+ return word::WdColor::wdColorGray25;
+ if (sColor == "wdColorGray30")
+ return word::WdColor::wdColorGray30;
+ if (sColor == "wdColorGray35")
+ return word::WdColor::wdColorGray35;
+ if (sColor == "wdColorGray375")
+ return word::WdColor::wdColorGray375;
+ if (sColor == "wdColorGray40")
+ return word::WdColor::wdColorGray40;
+ if (sColor == "wdColorGray45")
+ return word::WdColor::wdColorGray45;
+ if (sColor == "wdColorGray50")
+ return word::WdColor::wdColorGray50;
+ if (sColor == "wdColorGray55")
+ return word::WdColor::wdColorGray55;
+ if (sColor == "wdColorGray60")
+ return word::WdColor::wdColorGray60;
+ if (sColor == "wdColorGray625")
+ return word::WdColor::wdColorGray625;
+ if (sColor == "wdColorGray65")
+ return word::WdColor::wdColorGray65;
+ if (sColor == "wdColorGray70")
+ return word::WdColor::wdColorGray70;
+ if (sColor == "wdColorGray75")
+ return word::WdColor::wdColorGray75;
+ if (sColor == "wdColorGray80")
+ return word::WdColor::wdColorGray80;
+ if (sColor == "wdColorGray85")
+ return word::WdColor::wdColorGray85;
+ if (sColor == "wdColorGray875")
+ return word::WdColor::wdColorGray875;
+ if (sColor == "wdColorGray90")
+ return word::WdColor::wdColorGray90;
+ if (sColor == "wdColorGray95")
+ return word::WdColor::wdColorGray95;
+ if (sColor == "wdColorGreen")
+ return word::WdColor::wdColorGreen;
+ if (sColor == "wdColorIndigo")
+ return word::WdColor::wdColorIndigo;
+ if (sColor == "wdColorLavender")
+ return word::WdColor::wdColorLavender;
+ if (sColor == "wdColorLightBlue")
+ return word::WdColor::wdColorLightBlue;
+ if (sColor == "wdColorLightGreen")
+ return word::WdColor::wdColorLightGreen;
+ if (sColor == "wdColorLightOrange")
+ return word::WdColor::wdColorLightOrange;
+ if (sColor == "wdColorLightTurquoise")
+ return word::WdColor::wdColorLightTurquoise;
+ if (sColor == "wdColorLightYellow")
+ return word::WdColor::wdColorLightYellow;
+ if (sColor == "wdColorLime")
+ return word::WdColor::wdColorLime;
+ if (sColor == "wdColorOliveGreen")
+ return word::WdColor::wdColorOliveGreen;
+ if (sColor == "wdColorOrange")
+ return word::WdColor::wdColorOrange;
+ if (sColor == "wdColorPaleBlue")
+ return word::WdColor::wdColorPaleBlue;
+ if (sColor == "wdColorPink")
+ return word::WdColor::wdColorPink;
+ if (sColor == "wdColorPlum")
+ return word::WdColor::wdColorPlum;
+ if (sColor == "wdColorRed")
+ return word::WdColor::wdColorRed;
+ if (sColor == "wdColorRose")
+ return word::WdColor::wdColorRose;
+ if (sColor == "wdColorSeaGreen")
+ return word::WdColor::wdColorSeaGreen;
+ if (sColor == "wdColorSkyBlue")
+ return word::WdColor::wdColorSkyBlue;
+ if (sColor == "wdColorTan")
+ return word::WdColor::wdColorTan;
+ if (sColor == "wdColorTeal")
+ return word::WdColor::wdColorTeal;
+ if (sColor == "wdColorTurquoise")
+ return word::WdColor::wdColorTurquoise;
+ if (sColor == "wdColorViolet")
+ return word::WdColor::wdColorViolet;
+ if (sColor == "wdColorWhite")
+ return word::WdColor::wdColorWhite;
+ if (sColor == "wdColorYellow")
+ return word::WdColor::wdColorYellow;
+
+ return word::WdColor::wdColorBlack;
+}
+
+void SwVbaContentControl::setColor(sal_Int32 nWdColor)
+{
+ switch (nWdColor)
+ {
+ case word::WdColor::wdColorAqua:
+ m_pCC->SetColor("wdColorAqua");
+ break;
+ case word::WdColor::wdColorAutomatic:
+ m_pCC->SetColor("wdColorAutomatic");
+ break;
+ case word::WdColor::wdColorBlack:
+ m_pCC->SetColor("wdColorBlack");
+ break;
+ case word::WdColor::wdColorBlue:
+ m_pCC->SetColor("wdColorBlue");
+ break;
+ case word::WdColor::wdColorBlueGray:
+ m_pCC->SetColor("wdColorBlueGray");
+ break;
+ case word::WdColor::wdColorBrightGreen:
+ m_pCC->SetColor("wdColorBrightGreen");
+ break;
+ case word::WdColor::wdColorBrown:
+ m_pCC->SetColor("wdColorBrown");
+ break;
+ case word::WdColor::wdColorDarkBlue:
+ m_pCC->SetColor("wdColorDarkBlue");
+ break;
+ case word::WdColor::wdColorDarkGreen:
+ m_pCC->SetColor("wdColorDarkGreen");
+ break;
+ case word::WdColor::wdColorDarkRed:
+ m_pCC->SetColor("wdColorDarkRed");
+ break;
+ case word::WdColor::wdColorDarkTeal:
+ m_pCC->SetColor("wdColorDarkTeal");
+ break;
+ case word::WdColor::wdColorDarkYellow:
+ m_pCC->SetColor("wdColorDarkYellow");
+ break;
+ case word::WdColor::wdColorGold:
+ m_pCC->SetColor("wdColorGold");
+ break;
+ case word::WdColor::wdColorGray05:
+ m_pCC->SetColor("wdColorGray05");
+ break;
+ case word::WdColor::wdColorGray10:
+ m_pCC->SetColor("wdColorGray10");
+ break;
+ case word::WdColor::wdColorGray125:
+ m_pCC->SetColor("wdColorGray125");
+ break;
+ case word::WdColor::wdColorGray15:
+ m_pCC->SetColor("wdColorGray15");
+ break;
+ case word::WdColor::wdColorGray20:
+ m_pCC->SetColor("wdColorGray20");
+ break;
+ case word::WdColor::wdColorGray25:
+ m_pCC->SetColor("wdColorGray25");
+ break;
+ case word::WdColor::wdColorGray30:
+ m_pCC->SetColor("wdColorGray30");
+ break;
+ case word::WdColor::wdColorGray35:
+ m_pCC->SetColor("wdColorGray35");
+ break;
+ case word::WdColor::wdColorGray375:
+ m_pCC->SetColor("wdColorGray375");
+ break;
+ case word::WdColor::wdColorGray40:
+ m_pCC->SetColor("wdColorGray40");
+ break;
+ case word::WdColor::wdColorGray45:
+ m_pCC->SetColor("wdColorGray45");
+ break;
+ case word::WdColor::wdColorGray50:
+ m_pCC->SetColor("wdColorGray50");
+ break;
+ case word::WdColor::wdColorGray55:
+ m_pCC->SetColor("wdColorGray55");
+ break;
+ case word::WdColor::wdColorGray60:
+ m_pCC->SetColor("wdColorGray60");
+ break;
+ case word::WdColor::wdColorGray625:
+ m_pCC->SetColor("wdColorGray625");
+ break;
+ case word::WdColor::wdColorGray65:
+ m_pCC->SetColor("wdColorGray65");
+ break;
+ case word::WdColor::wdColorGray70:
+ m_pCC->SetColor("wdColorGray70");
+ break;
+ case word::WdColor::wdColorGray75:
+ m_pCC->SetColor("wdColorGray75");
+ break;
+ case word::WdColor::wdColorGray80:
+ m_pCC->SetColor("wdColorGray80");
+ break;
+ case word::WdColor::wdColorGray85:
+ m_pCC->SetColor("wdColorGray85");
+ break;
+ case word::WdColor::wdColorGray875:
+ m_pCC->SetColor("wdColorGray875");
+ break;
+ case word::WdColor::wdColorGray90:
+ m_pCC->SetColor("wdColorGray90");
+ break;
+ case word::WdColor::wdColorGray95:
+ m_pCC->SetColor("wdColorGray95");
+ break;
+ case word::WdColor::wdColorGreen:
+ m_pCC->SetColor("wdColorGreen");
+ break;
+ case word::WdColor::wdColorIndigo:
+ m_pCC->SetColor("wdColorIndigo");
+ break;
+ case word::WdColor::wdColorLavender:
+ m_pCC->SetColor("wdColorLavender");
+ break;
+ case word::WdColor::wdColorLightBlue:
+ m_pCC->SetColor("wdColorLightBlue");
+ break;
+ case word::WdColor::wdColorLightGreen:
+ m_pCC->SetColor("wdColorLightGreen");
+ break;
+ case word::WdColor::wdColorLightOrange:
+ m_pCC->SetColor("wdColorLightOrange");
+ break;
+ case word::WdColor::wdColorLightTurquoise:
+ m_pCC->SetColor("wdColorLightTurquoise");
+ break;
+ case word::WdColor::wdColorLightYellow:
+ m_pCC->SetColor("wdColorLightYellow");
+ break;
+ case word::WdColor::wdColorLime:
+ m_pCC->SetColor("wdColorLime");
+ break;
+ case word::WdColor::wdColorOliveGreen:
+ m_pCC->SetColor("wdColorOliveGreen");
+ break;
+ case word::WdColor::wdColorOrange:
+ m_pCC->SetColor("wdColorOrange");
+ break;
+ case word::WdColor::wdColorPaleBlue:
+ m_pCC->SetColor("wdColorPaleBlue");
+ break;
+ case word::WdColor::wdColorPink:
+ m_pCC->SetColor("wdColorPink");
+ break;
+ case word::WdColor::wdColorPlum:
+ m_pCC->SetColor("wdColorPlum");
+ break;
+ case word::WdColor::wdColorRed:
+ m_pCC->SetColor("wdColorRed");
+ break;
+ case word::WdColor::wdColorRose:
+ m_pCC->SetColor("wdColorRose");
+ break;
+ case word::WdColor::wdColorSeaGreen:
+ m_pCC->SetColor("wdColorSeaGreen");
+ break;
+ case word::WdColor::wdColorSkyBlue:
+ m_pCC->SetColor("wdColorSkyBlue");
+ break;
+ case word::WdColor::wdColorTan:
+ m_pCC->SetColor("wdColorTan");
+ break;
+ case word::WdColor::wdColorTeal:
+ m_pCC->SetColor("wdColorTeal");
+ break;
+ case word::WdColor::wdColorTurquoise:
+ m_pCC->SetColor("wdColorTurquoise");
+ break;
+ case word::WdColor::wdColorViolet:
+ m_pCC->SetColor("wdColorViolet");
+ break;
+ case word::WdColor::wdColorWhite:
+ m_pCC->SetColor("wdColorWhite");
+ break;
+ default:;
+ }
+}
+
+sal_Int32 SwVbaContentControl::getDateCalendarType()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getDateCalendarType stub");
+ // returns a WdCalendarTypes that represents the type of building block
+ return word::WdCalendarType::wdCalendarWestern;
+}
+
+void SwVbaContentControl::setDateCalendarType(sal_Int32 nSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setDateCalendarType[" << nSet << "] stub");
+}
+
+OUString SwVbaContentControl::getDateDisplayFormat() { return m_pCC->GetDateFormat(); }
+
+void SwVbaContentControl::setDateDisplayFormat(const OUString& sSet) { m_pCC->SetDateFormat(sSet); }
+
+sal_Int32 SwVbaContentControl::getDateStorageFormat()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getDateStorageFormat stub");
+ // returns a WdContentControlDateStorageFormat when bound to the XML data store.
+ return 0;
+}
+
+void SwVbaContentControl::setDateStorageFormat(sal_Int32 nSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setDateStorageFormat[" << nSet << "] stub");
+}
+
+sal_Int32 SwVbaContentControl::getDateDisplayLocale()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getDateDisplayLocale stub");
+ // returns a WdLanguageID that represents the language format for a date content control.
+ return word::WdLanguageID::wdEnglishUS;
+}
+
+uno::Any SwVbaContentControl::getDropdownListEntries()
+{
+ if (!m_pCC->GetDropDown() && !m_pCC->GetComboBox())
+ return uno::Any();
+
+ return uno::Any(
+ uno::Reference<XCollection>(new SwVbaContentControlListEntries(this, mxContext, m_pCC)));
+}
+
+OUString SwVbaContentControl::getID()
+{
+ // This signed integer is treated in VBA as if it was an unsigned int.
+ return OUString::number(static_cast<sal_uInt32>(m_pCC->GetId()));
+}
+
+sal_Int32 SwVbaContentControl::getLevel()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getLevel stub");
+ // returns a WdContentControlLevel
+ return 0;
+}
+
+sal_Bool SwVbaContentControl::getLockContentControl()
+{
+ std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/true);
+ return oLock.has_value() && *oLock;
+}
+
+void SwVbaContentControl::setLockContentControl(sal_Bool bSet)
+{
+ std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/false);
+ m_pCC->SetLock(/*bContents=*/oLock.has_value() && *oLock, /*bControl=*/bSet);
+}
+
+sal_Bool SwVbaContentControl::getLockContents()
+{
+ // If the theoretical design model says it is locked, then report as locked.
+ std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/false);
+ if (oLock.has_value() && *oLock)
+ return true;
+
+ // Now check the real implementation.
+ // Checkbox/DropDown/Picture are normally locked - but not in this sense. Report as unlocked.
+ if (m_pCC->GetType() == SwContentControlType::CHECKBOX
+ || m_pCC->GetType() == SwContentControlType::DROP_DOWN_LIST
+ || m_pCC->GetType() == SwContentControlType::PICTURE)
+ {
+ return false;
+ }
+
+ return m_pCC->GetReadWrite();
+}
+
+void SwVbaContentControl::setLockContents(sal_Bool bSet)
+{
+ // Set the lock both theoretically and actually.
+ std::optional<bool> oLock = m_pCC->GetLock(/*bControl=*/true);
+ m_pCC->SetLock(/*bContents=*/bSet, /*bControl=*/oLock.has_value() && *oLock);
+
+ // Checkbox/DropDown/Picture are normally locked in LO implementation - don't unlock them.
+ if (m_pCC->GetType() == SwContentControlType::CHECKBOX
+ || m_pCC->GetType() == SwContentControlType::DROP_DOWN_LIST
+ || m_pCC->GetType() == SwContentControlType::PICTURE)
+ {
+ return;
+ }
+ m_pCC->SetReadWrite(bSet);
+}
+
+sal_Bool SwVbaContentControl::getMultiLine()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getMultiLine stub");
+ return false;
+}
+
+void SwVbaContentControl::setMultiLine(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setMultiLine stub");
+}
+
+OUString SwVbaContentControl::getPlaceholderText()
+{
+ // return m_pCC->GetPlaceholderDocPart(); // This is not correct. Much more complex than this...
+ SAL_INFO("sw.vba", "SwVbaContentControl::getPlaceholderText stub");
+ return OUString();
+}
+
+sal_Bool SwVbaContentControl::getShowingPlaceholderText() { return m_pCC->GetShowingPlaceHolder(); }
+
+uno::Reference<word::XRange> SwVbaContentControl::getRange()
+{
+ uno::Reference<word::XRange> xRet;
+ SwTextNode* pTextNode = m_pCC->GetTextNode();
+ if (pTextNode && m_pCC->GetTextAttr())
+ {
+ // Don't select the text attribute itself at the start.
+ SwPosition aStart(*pTextNode, m_pCC->GetTextAttr()->GetStart() + 1);
+ // Don't select the CH_TXTATR_BREAKWORD itself at the end.
+ SwPosition aEnd(*pTextNode, *m_pCC->GetTextAttr()->End() - 1);
+ uno::Reference<text::XTextRange> xText(
+ SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), aStart, &aEnd));
+ if (xText.is())
+ xRet = new SwVbaRange(mxParent, mxContext, mxTextDocument, xText->getStart(),
+ xText->getEnd());
+ }
+ return xRet;
+}
+
+OUString SwVbaContentControl::getRepeatingSectionItemTitle()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getRepeatingSectionItemTitle stub");
+ return OUString();
+}
+
+void SwVbaContentControl::setRepeatingSectionItemTitle(const OUString& rSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setRepeatingSectionItemTitle[" << rSet << "] stub");
+}
+
+OUString SwVbaContentControl::getTag() { return m_pCC->GetTag(); }
+
+void SwVbaContentControl::setTag(const OUString& rSet) { return m_pCC->SetTag(rSet); }
+
+sal_Bool SwVbaContentControl::getTemporary()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::getTemporary stub");
+ // Is content control removed when user edits (one time use)? Not implemented in LO.
+ return false;
+}
+
+void SwVbaContentControl::setTemporary(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setTemporary stub");
+}
+
+OUString SwVbaContentControl::getTitle() { return m_pCC->GetAlias(); }
+
+void SwVbaContentControl::setTitle(const OUString& rSet) { return m_pCC->SetAlias(rSet); }
+
+sal_Int32 SwVbaContentControl::getType()
+{
+ SwContentControlType eType = m_pCC->GetType();
+ sal_Int32 eVbaType = word::WdContentControlType::wdContentControlRichText;
+
+ switch (eType)
+ {
+ case SwContentControlType::CHECKBOX:
+ eVbaType = word::WdContentControlType::wdContentControlCheckbox;
+ break;
+ case SwContentControlType::DROP_DOWN_LIST:
+ eVbaType = word::WdContentControlType::wdContentControlDropdownList;
+ break;
+ case SwContentControlType::PICTURE:
+ eVbaType = word::WdContentControlType::wdContentControlPicture;
+ break;
+ case SwContentControlType::DATE:
+ eVbaType = word::WdContentControlType::wdContentControlDate;
+ break;
+ case SwContentControlType::PLAIN_TEXT:
+ eVbaType = word::WdContentControlType::wdContentControlText;
+ break;
+ case SwContentControlType::COMBO_BOX:
+ eVbaType = word::WdContentControlType::wdContentControlComboBox;
+ break;
+ case SwContentControlType::RICH_TEXT:
+ default:;
+ }
+ return eVbaType;
+}
+
+void SwVbaContentControl::setType(sal_Int32 nSet)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::setType[" << nSet << "] stub");
+ // SwContentControlType eType = SwContentControlType::RICH_TEXT;
+ // switch(nSet)
+ // {
+ // case word::WdContentControlType::wdContentControlCheckbox:
+ // eType = SwContentControlType::CHECKBOX;
+ // break;
+ // case word::WdContentControlType::wdContentControlDropdownList:
+ // eType = SwContentControlType::DROP_DOWN_LIST;
+ // break;
+ // case word::WdContentControlType::wdContentControlPicture:
+ // eType = SwContentControlType::PICTURE;
+ // break;
+ // case word::WdContentControlType::wdContentControlDate:
+ // eType = SwContentControlType::DATE;
+ // break;
+ // case word::WdContentControlType::wdContentControlText:
+ // eType = SwContentControlType::PLAIN_TEXT;
+ // break;
+ // case word::WdContentControlType::wdContentControlComboBox:
+ // eType = SwContentControlType::COMBO_BOX;
+ // break;
+ // case word::WdContentControlType::wdContentControlRichText:
+ // default:;
+ // }
+ // m_pCC->SetType(eType);
+}
+
+void SwVbaContentControl::Copy()
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::Copy[" << getID() << "] stub");
+}
+
+void SwVbaContentControl::Cut()
+{
+ if (getLockContentControl() || !m_pCC->GetTextAttr())
+ return;
+
+ SAL_INFO("sw.vba",
+ "SwVbaContentControl::Cut[" << getID() << "], but missing sending to clipboard");
+
+ m_pCC->GetTextAttr()->Delete(/*bSaveContents=*/getLockContents());
+}
+
+void SwVbaContentControl::Delete(const uno::Any& DeleteContents)
+{
+ if (getLockContentControl() || !m_pCC->GetTextAttr())
+ return;
+
+ bool bDeleteContents = false;
+ DeleteContents >>= bDeleteContents;
+
+ m_pCC->GetTextAttr()->Delete(/*bSaveContents=*/!bDeleteContents || getLockContents());
+}
+
+void SwVbaContentControl::SetCheckedSymbol(sal_Int32 Character, const uno::Any& Font)
+{
+ if (!m_pCC->GetTextAttr())
+ return;
+
+ SAL_INFO_IF(Font.hasValue(), "sw.vba", "SetCheckedSymbol Font[" << Font << "] stub");
+ if (Character < 31 || Character > SAL_MAX_UINT16)
+ return; // unsupported character. Would such a thing exist in VBA?
+
+ m_pCC->SetCheckedState(OUString(static_cast<sal_Unicode>(Character)));
+
+ if (m_pCC->GetCheckbox() && m_pCC->GetChecked() && !m_pCC->GetShowingPlaceHolder())
+ m_pCC->GetTextAttr()->Invalidate();
+}
+
+void SwVbaContentControl::SetUnCheckedSymbol(sal_Int32 Character, const uno::Any& Font)
+{
+ if (!m_pCC->GetTextAttr())
+ return;
+
+ SAL_INFO_IF(Font.hasValue(), "sw.vba", "SetUnCheckedSymbol Font[" << Font << "] stub");
+ if (Character < 31 || Character > SAL_MAX_UINT16)
+ return; // unsupported character. Would such a thing exist in VBA?
+
+ m_pCC->SetUncheckedState(OUString(static_cast<sal_Unicode>(Character)));
+
+ if (m_pCC->GetCheckbox() && !m_pCC->GetChecked() && !m_pCC->GetShowingPlaceHolder())
+ m_pCC->GetTextAttr()->Invalidate();
+}
+
+void SwVbaContentControl::SetPlaceholderText(const uno::Any& BuildingBlock, const uno::Any& Range,
+ const uno::Any& Text)
+{
+ SAL_INFO("sw.vba", "SwVbaContentControl::SetPlaceholderText stub");
+ if (BuildingBlock.hasValue())
+ {
+ // Set placeholder text to the building block - whatever that is.
+ }
+ else if (Range.hasValue())
+ {
+ // Set placeholder text to the contents of the Range, however you do that.
+ }
+ else if (Text.hasValue())
+ {
+ // Set placeholder text to the provided string
+ }
+ else
+ {
+ // Remove placeholder text.
+ m_pCC->SetPlaceholderDocPart("");
+ }
+ if (m_pCC->GetShowingPlaceHolder() && !getLockContents() && m_pCC->GetTextAttr())
+ {
+ //replace the text and ensure showing placeholder is still set
+ }
+}
+
+void SwVbaContentControl::Ungroup() { SAL_INFO("sw.vba", "SwVbaContentControl::UnGroup stub"); }
+
+OUString SwVbaContentControl::getServiceImplName() { return "SwVbaContentControl"; }
+
+uno::Sequence<OUString> SwVbaContentControl::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ContentControl" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrol.hxx b/sw/source/ui/vba/vbacontentcontrol.hxx
new file mode 100644
index 0000000000..9f98b92468
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrol.hxx
@@ -0,0 +1,142 @@
+/* -*- 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/text/XTextDocument.hpp>
+#include <ooo/vba/word/XContentControl.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <textcontentcontrol.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XContentControl> SwVbaContentControl_BASE;
+
+class SwVbaContentControl : public SwVbaContentControl_BASE
+{
+private:
+ css::uno::Reference<css::text::XTextDocument> mxTextDocument;
+ std::shared_ptr<SwContentControl> m_pCC;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaContentControl(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ const css::uno::Reference<css::text::XTextDocument>& xTextDocument,
+ std::shared_ptr<SwContentControl> pContentControl);
+ ~SwVbaContentControl() override;
+
+ // XContentControl Properties
+ sal_Bool SAL_CALL getAllowInsertDeleteSection() override;
+ void SAL_CALL setAllowInsertDeleteSection(sal_Bool bSet) override;
+
+ sal_Int32 SAL_CALL getAppearance() override;
+ void SAL_CALL setAppearance(sal_Int32 nSet) override;
+
+ OUString SAL_CALL getBuildingBlockCategory() override;
+ void SAL_CALL setBuildingBlockCategory(const OUString& sSet) override;
+
+ sal_Int32 SAL_CALL getBuildingBlockType() override;
+ void SAL_CALL setBuildingBlockType(sal_Int32 nSet) override;
+
+ sal_Bool SAL_CALL getChecked() override;
+ void SAL_CALL setChecked(sal_Bool bSet) override;
+
+ // returns or sets a WdColor (@since after 2010 I assume)
+ sal_Int32 SAL_CALL getColor() override;
+ void SAL_CALL setColor(sal_Int32 nSet) override;
+
+ sal_Int32 SAL_CALL getDateCalendarType() override;
+ void SAL_CALL setDateCalendarType(sal_Int32 nSet) override;
+
+ OUString SAL_CALL getDateDisplayFormat() override;
+ void SAL_CALL setDateDisplayFormat(const OUString& sSet) override;
+
+ sal_Int32 SAL_CALL getDateDisplayLocale() override;
+
+ sal_Int32 SAL_CALL getDateStorageFormat() override;
+ void SAL_CALL setDateStorageFormat(sal_Int32 nSet) override;
+
+ css::uno::Any SAL_CALL getDropdownListEntries() override;
+
+ // This is an integer used as a unique identifier string
+ OUString SAL_CALL getID() override;
+
+ sal_Int32 SAL_CALL getLevel() override;
+
+ // returns or sets if the user can delete the control
+ sal_Bool SAL_CALL getLockContentControl() override;
+ void SAL_CALL setLockContentControl(sal_Bool bSet) override;
+
+ // returns or sets if the user can edit the contents (i.e. read-only flag)
+ sal_Bool SAL_CALL getLockContents() override;
+ void SAL_CALL setLockContents(sal_Bool bSet) override;
+
+ sal_Bool SAL_CALL getMultiLine() override;
+ void SAL_CALL setMultiLine(sal_Bool bSet) override;
+
+ // WRONG- THIS SHOULD RETURN XBUILDINGBLOCK
+ OUString SAL_CALL getPlaceholderText() override;
+
+ sal_Bool SAL_CALL getShowingPlaceholderText() override;
+
+ OUString SAL_CALL getRepeatingSectionItemTitle() override;
+ void SAL_CALL setRepeatingSectionItemTitle(const OUString& rSet) override;
+
+ css::uno::Reference<ooo::vba::word::XRange> SAL_CALL getRange() override;
+
+ OUString SAL_CALL getTag() override;
+ void SAL_CALL setTag(const OUString& rSet) override;
+
+ // returns or sets if the control is removed after accepting user change (i.e. control -> text)
+ sal_Bool SAL_CALL getTemporary() override;
+ void SAL_CALL setTemporary(sal_Bool bSet) override;
+
+ OUString SAL_CALL getTitle() override;
+ void SAL_CALL setTitle(const OUString& rSet) override;
+
+ // returns or sets a WdContentControlType that represents the type for a content control.
+ sal_Int32 SAL_CALL getType() override;
+ void SAL_CALL setType(sal_Int32 nSet) override;
+
+ // XContentControl Methods
+
+ // Copies the content control from the active document to the Clipboard.
+ // Retrieve from the clipboard using the Paste method of the Selection object
+ // or of the Range object, or use the Paste function from within Microsoft Word.
+ void SAL_CALL Copy() override;
+
+ // Removes the control from the active document and moves it to the Clipboard.
+ void SAL_CALL Cut() override;
+
+ // Specifies whether to delete the contents of the content control. The default value is False.
+ // True removes both the content control and its contents.
+ // False removes the control but leaves the contents of the content control in the document.
+ void SAL_CALL Delete(const css::uno::Any& bDeleteContents) override;
+
+ // Set the Unicode character used to display the checked state.
+ void SAL_CALL SetCheckedSymbol(sal_Int32 Character, const css::uno::Any& sFont) override;
+
+ // Set the Unicode character used to display the unchecked state.
+ void SAL_CALL SetUnCheckedSymbol(sal_Int32 Character, const css::uno::Any& sFont) override;
+
+ // Sets the placeholder text that displays until a user enters their own text.
+ // Only one of the parameters is used when specifying placeholder text.
+ // If more than one parameter is provided, use the text specified in the first parameter.
+ // If all parameters are omitted, the placeholder text is blank.
+ void SAL_CALL SetPlaceholderText(const css::uno::Any& BuildingBlock, const css::uno::Any& Range,
+ const css::uno::Any& sText) override;
+
+ void SAL_CALL Ungroup() override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentries.cxx b/sw/source/ui/vba/vbacontentcontrollistentries.cxx
new file mode 100644
index 0000000000..552397e156
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentries.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 "vbacontentcontrollistentries.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace
+{
+class ContentControlListEntriesEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess> mxIndexAccess;
+ sal_Int32 mnIndex;
+
+public:
+ explicit ContentControlListEntriesEnumWrapper(
+ uno::Reference<container::XIndexAccess> xIndexAccess)
+ : mxIndexAccess(xIndexAccess)
+ , mnIndex(0)
+ {
+ }
+
+ virtual sal_Bool SAL_CALL hasMoreElements() override
+ {
+ return (mnIndex < mxIndexAccess->getCount());
+ }
+
+ virtual uno::Any SAL_CALL nextElement() override
+ {
+ if (mnIndex < mxIndexAccess->getCount())
+ {
+ return mxIndexAccess->getByIndex(mnIndex++);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class ContentControlListEntryCollectionHelper
+ : public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess>
+{
+private:
+ uno::Reference<XHelperInterface> mxParent;
+ uno::Reference<uno::XComponentContext> mxContext;
+ std::shared_ptr<SwContentControl> m_pCC;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ContentControlListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
+ uno::Reference<uno::XComponentContext> xContext,
+ std::shared_ptr<SwContentControl> pCC)
+ : mxParent(xParent)
+ , mxContext(xContext)
+ , m_pCC(pCC)
+ {
+ }
+
+ sal_Int32 SAL_CALL getCount() override { return m_pCC->GetListItems().size(); }
+
+ uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
+ {
+ if (Index < 0 || Index >= getCount())
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any(uno::Reference<word::XContentControlListEntry>(
+ new SwVbaContentControlListEntry(mxParent, mxContext, m_pCC, Index)));
+ }
+
+ uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<word::XContentControlListEntry>::get();
+ }
+
+ sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
+
+ // XEnumerationAccess
+ uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
+ {
+ return new ContentControlListEntriesEnumWrapper(this);
+ }
+};
+}
+
+/**
+ * DropDownLists and ComboBoxes contain a list of name/value pairs to choose from.
+ * Use of DropDownListEntries from any other control is invalid.
+ */
+SwVbaContentControlListEntries::SwVbaContentControlListEntries(
+ const uno::Reference<XHelperInterface>& xParent,
+ const uno::Reference<uno::XComponentContext>& xContext, std::shared_ptr<SwContentControl> pCC)
+ : SwVbaContentControlListEntries_BASE(
+ xParent, xContext,
+ uno::Reference<container::XIndexAccess>(
+ new ContentControlListEntryCollectionHelper(xParent, xContext, pCC)))
+ , m_pCC(pCC)
+{
+}
+
+uno::Reference<word::XContentControlListEntry>
+SwVbaContentControlListEntries::Add(const OUString& rName, const uno::Any& rValue,
+ const uno::Any& rIndex)
+{
+ // No duplicate Names allowed in VBA
+ for (auto& rListItem : m_pCC->GetListItems())
+ {
+ if (rListItem.ToString() == rName)
+ return uno::Reference<word::XContentControlListEntry>();
+ }
+
+ sal_Int32 nZIndex = SAL_MAX_INT32;
+ rIndex >>= nZIndex;
+ // rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice.
+ assert(nZIndex > 0);
+ --nZIndex;
+ nZIndex = std::min(static_cast<size_t>(nZIndex), m_pCC->GetListItems().size());
+
+ OUString sValue;
+ rValue >>= sValue;
+ if (m_pCC->AddListItem(nZIndex, rName, sValue))
+ {
+ return uno::Reference<word::XContentControlListEntry>(
+ new SwVbaContentControlListEntry(mxParent, mxContext, m_pCC, nZIndex));
+ }
+
+ return uno::Reference<word::XContentControlListEntry>();
+}
+
+void SwVbaContentControlListEntries::Clear() { m_pCC->ClearListItems(); }
+
+sal_Int32 SwVbaContentControlListEntries::getCount() { return m_pCC->GetListItems().size(); }
+
+// XEnumerationAccess
+uno::Type SwVbaContentControlListEntries::getElementType()
+{
+ return cppu::UnoType<word::XContentControlListEntry>::get();
+}
+
+uno::Reference<container::XEnumeration> SwVbaContentControlListEntries::createEnumeration()
+{
+ return new ContentControlListEntriesEnumWrapper(m_xIndexAccess);
+}
+
+// SwVbaContentControlListEntries_BASE
+uno::Any SwVbaContentControlListEntries::createCollectionObject(const uno::Any& aSource)
+{
+ return aSource;
+}
+
+OUString SwVbaContentControlListEntries::getServiceImplName()
+{
+ return "SwVbaContentControlListEntries";
+}
+
+uno::Sequence<OUString> SwVbaContentControlListEntries::getServiceNames()
+{
+ static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ContentControlListEntries" };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentries.hxx b/sw/source/ui/vba/vbacontentcontrollistentries.hxx
new file mode 100644
index 0000000000..dc32203179
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentries.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 <ooo/vba/word/XContentControlListEntries.hpp>
+#include <ooo/vba/word/XContentControlListEntry.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+#include <textcontentcontrol.hxx>
+
+#include "vbacontentcontrollistentries.hxx"
+#include "vbacontentcontrollistentry.hxx"
+
+typedef CollTestImplHelper<ooo::vba::word::XContentControlListEntries>
+ SwVbaContentControlListEntries_BASE;
+
+class SwVbaContentControlListEntries : public SwVbaContentControlListEntries_BASE
+{
+private:
+ std::shared_ptr<SwContentControl> m_pCC;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaContentControlListEntries(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ std::shared_ptr<SwContentControl> pCC);
+
+ // XContentControlListEntries
+ css::uno::Reference<ooo::vba::word::XContentControlListEntry> SAL_CALL
+ Add(const OUString& rName, const css::uno::Any& rValue, const css::uno::Any& rIndex) override;
+ void SAL_CALL Clear() override;
+ sal_Int32 SAL_CALL getCount() override;
+
+ // XEnumerationAccess
+ css::uno::Type SAL_CALL getElementType() override;
+ css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // SwVbaContentControlListEntries_BASE
+ css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.cxx b/sw/source/ui/vba/vbacontentcontrollistentry.cxx
new file mode 100644
index 0000000000..73f5e9d0a2
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentry.cxx
@@ -0,0 +1,161 @@
+/* -*- 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 "vbacontentcontrollistentry.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaContentControlListEntry::SwVbaContentControlListEntry(
+ const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext, std::shared_ptr<SwContentControl> pCC,
+ size_t nZIndex)
+ : SwVbaContentControlListEntry_BASE(rParent, rContext)
+ , m_pCC(pCC)
+ , m_nZIndex(nZIndex)
+{
+}
+
+SwVbaContentControlListEntry::~SwVbaContentControlListEntry() {}
+
+sal_Int32 SwVbaContentControlListEntry::getIndex() { return m_nZIndex + 1; }
+
+void SwVbaContentControlListEntry::setIndex(sal_Int32 nSet)
+{
+ if (nSet < 1 || static_cast<size_t>(nSet) == m_nZIndex + 1)
+ return;
+
+ // Given a one-based index to set to
+ size_t nIndex = std::min(static_cast<size_t>(nSet), m_pCC->GetListItems().size());
+ // change to zero-based index
+ --nIndex;
+ while (nIndex < m_nZIndex)
+ MoveUp();
+ while (m_nZIndex < nIndex)
+ MoveDown();
+}
+
+OUString SwVbaContentControlListEntry::getText()
+{
+ assert(m_nZIndex < m_pCC->GetListItems().size());
+ const SwContentControlListItem& rListItem = m_pCC->GetListItems()[m_nZIndex];
+ return rListItem.ToString();
+}
+
+void SwVbaContentControlListEntry::setText(const OUString& rSet)
+{
+ std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems();
+ assert(m_nZIndex < vListItems.size());
+
+ // prevent duplicates
+ for (size_t i = 0; i < vListItems.size(); ++i)
+ {
+ if (vListItems[i].ToString() == rSet)
+ return;
+ }
+
+ const std::optional<size_t> oSel(m_pCC->GetSelectedListItem(/*bCheckDocModel=*/true));
+ const bool bNeedsInvalidation = m_pCC->GetDropDown() && oSel && *oSel == m_nZIndex;
+
+ vListItems[m_nZIndex].m_aDisplayText = rSet;
+ m_pCC->SetListItems(vListItems);
+
+ if (bNeedsInvalidation)
+ {
+ m_pCC->SetSelectedListItem(m_nZIndex);
+ if (m_pCC->GetTextAttr())
+ m_pCC->GetTextAttr()->Invalidate();
+ }
+}
+
+OUString SwVbaContentControlListEntry::getValue()
+{
+ assert(m_nZIndex < m_pCC->GetListItems().size());
+ const SwContentControlListItem& rListItem = m_pCC->GetListItems()[m_nZIndex];
+
+ return rListItem.m_aValue;
+}
+
+void SwVbaContentControlListEntry::setValue(const OUString& rSet)
+{
+ assert(m_nZIndex < m_pCC->GetListItems().size());
+ std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems();
+
+ // LO may pull the display text from Value. Ensure changing Value doesn't alter display text.
+ if (vListItems[m_nZIndex].m_aDisplayText.isEmpty())
+ vListItems[m_nZIndex].m_aDisplayText = vListItems[m_nZIndex].ToString();
+
+ vListItems[m_nZIndex].m_aValue = rSet;
+ m_pCC->SetListItems(vListItems);
+}
+
+void SwVbaContentControlListEntry::Delete() { m_pCC->DeleteListItem(m_nZIndex); }
+
+void SwVbaContentControlListEntry::MoveDown()
+{
+ // if already at last position, can't move down
+ if (m_nZIndex >= m_pCC->GetListItems().size() - 1)
+ return;
+
+ const std::optional<size_t> oSelected = m_pCC->GetSelectedListItem(/*bCheckDocModel=*/false);
+ if (oSelected)
+ {
+ if (*oSelected == m_nZIndex)
+ m_pCC->SetSelectedListItem(m_nZIndex + 1);
+ else if (*oSelected == m_nZIndex + 1)
+ m_pCC->SetSelectedListItem(*oSelected - 1);
+ }
+ std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems();
+ std::swap(vListItems[m_nZIndex], vListItems[m_nZIndex + 1]);
+ m_pCC->SetListItems(vListItems);
+ ++m_nZIndex;
+}
+
+void SwVbaContentControlListEntry::MoveUp()
+{
+ // if already at position 0, can't move up
+ if (!m_nZIndex || m_nZIndex >= m_pCC->GetListItems().size())
+ return;
+
+ const std::optional<size_t> oSelected = m_pCC->GetSelectedListItem(/*bCheckDocModel=*/false);
+ if (oSelected)
+ {
+ if (*oSelected == m_nZIndex)
+ m_pCC->SetSelectedListItem(m_nZIndex - 1);
+ else if (*oSelected == m_nZIndex - 1)
+ m_pCC->SetSelectedListItem(*oSelected + 1);
+ }
+ std::vector<SwContentControlListItem> vListItems = m_pCC->GetListItems();
+ std::swap(vListItems[m_nZIndex], vListItems[m_nZIndex - 1]);
+ m_pCC->SetListItems(vListItems);
+ --m_nZIndex;
+}
+
+void SwVbaContentControlListEntry::Select()
+{
+ assert(m_nZIndex < m_pCC->GetListItems().size());
+ m_pCC->SetSelectedListItem(m_nZIndex);
+ m_pCC->SetShowingPlaceHolder(false);
+ if (m_pCC->GetTextAttr())
+ m_pCC->GetTextAttr()->Invalidate();
+}
+
+// XHelperInterface
+OUString SwVbaContentControlListEntry::getServiceImplName()
+{
+ return "SwVbaContentControlListEntry";
+}
+
+uno::Sequence<OUString> SwVbaContentControlListEntry::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ContentControlListEntry" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrollistentry.hxx b/sw/source/ui/vba/vbacontentcontrollistentry.hxx
new file mode 100644
index 0000000000..bb55eade34
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrollistentry.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/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XContentControlListEntry.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <textcontentcontrol.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XContentControlListEntry>
+ SwVbaContentControlListEntry_BASE;
+
+class SwVbaContentControlListEntry : public SwVbaContentControlListEntry_BASE
+{
+private:
+ std::shared_ptr<SwContentControl> m_pCC;
+ // All LO and internal UNO functions are 0-based. Convert to 1-based when sending to VBA
+ size_t m_nZIndex;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaContentControlListEntry(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ std::shared_ptr<SwContentControl> pCC, size_t nZIndex);
+ ~SwVbaContentControlListEntry() override;
+
+ // XContentControlListEntry
+ sal_Int32 SAL_CALL getIndex() override;
+ void SAL_CALL setIndex(sal_Int32 nSet) override;
+
+ OUString SAL_CALL getText() override;
+ void SAL_CALL setText(const OUString& sSet) override;
+
+ OUString SAL_CALL getValue() override;
+ void SAL_CALL setValue(const OUString& sSet) override;
+
+ void SAL_CALL Delete() override;
+ void SAL_CALL MoveDown() override;
+ void SAL_CALL MoveUp() override;
+ void SAL_CALL Select() override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrols.cxx b/sw/source/ui/vba/vbacontentcontrols.cxx
new file mode 100644
index 0000000000..37199e2cec
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrols.cxx
@@ -0,0 +1,268 @@
+/* -*- 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 <comphelper/sequence.hxx>
+#include <sal/log.hxx>
+
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <textcontentcontrol.hxx>
+
+#include "vbacontentcontrol.hxx"
+#include "vbacontentcontrols.hxx"
+#include "wordvbahelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+// Helper function to access the content controls
+// @param rIndex
+// [in] negative indexes indicate the need to search by name, otherwise get by index,
+// using SAL_MAX_INT32 to indicate the need to just get the total count.
+// [out] rIndex indicates the found index, or the total number of content controls
+static std::shared_ptr<SwContentControl>
+lcl_getContentControl(std::u16string_view sName, std::u16string_view sTag,
+ std::u16string_view sTitle, sal_Int32& rIndex,
+ const uno::Reference<text::XTextDocument>& xTextDocument,
+ uno::Sequence<OUString>* pElementNames = nullptr)
+{
+ SwDoc* pDoc = word::getDocShell(xTextDocument)->GetDoc();
+ if (!pDoc)
+ return nullptr;
+
+ assert(sTag.empty() || sTitle.empty()); // only one grouping at a time is allowed
+
+ std::shared_ptr<SwContentControl> pControl;
+ std::vector<OUString> vElementNames;
+ SwContentControlManager& rManager = pDoc->GetContentControlManager();
+ const size_t nLen = rManager.GetCount();
+ if (!pElementNames && rIndex > 0 && sName.empty() && sTag.empty() && sTitle.empty())
+ {
+ size_t i = static_cast<size_t>(rIndex);
+ // This is the normal get-by-index/getCount mode - no need for fancy filtering.
+ if (i < nLen)
+ pControl = rManager.Get(i)->GetContentControl().GetContentControl();
+ else
+ rIndex = nLen;
+ }
+ else
+ {
+ // loop through everything collecting names, filtering by Tag/Title
+ sal_Int32 nCounter = 0;
+ for (size_t i = 0; i < nLen; ++i)
+ {
+ pControl = rManager.Get(i)->GetContentControl().GetContentControl();
+ if (!sTag.empty() && sTag != pControl->GetTag())
+ {
+ pControl = nullptr;
+ continue;
+ }
+ if (!sTitle.empty() && sTitle != pControl->GetAlias())
+ {
+ pControl = nullptr;
+ continue;
+ }
+
+ // When treated as a name, consider the integer ID to be unsigned
+ const OUString sID = OUString::number(static_cast<sal_uInt32>(pControl->GetId()));
+ if (!sName.empty() && sName != sID)
+ {
+ pControl = nullptr;
+ continue;
+ }
+
+ if (pElementNames)
+ vElementNames.push_back(sID);
+
+ if (rIndex == nCounter || !sName.empty())
+ break;
+
+ pControl = nullptr;
+ ++nCounter;
+ }
+ rIndex = nCounter;
+ }
+ if (pElementNames)
+ *pElementNames = comphelper::containerToSequence(vElementNames);
+ return pControl;
+}
+
+namespace
+{
+class ContentControlsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess> mxIndexAccess;
+ sal_Int32 mnIndex;
+
+public:
+ explicit ContentControlsEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess)
+ : mxIndexAccess(std::move(xIndexAccess))
+ , mnIndex(0)
+ {
+ }
+
+ sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); }
+
+ uno::Any SAL_CALL nextElement() override
+ {
+ if (mnIndex < mxIndexAccess->getCount())
+ {
+ return mxIndexAccess->getByIndex(mnIndex++);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class ContentControlCollectionHelper
+ : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess,
+ container::XEnumerationAccess>
+{
+private:
+ uno::Reference<XHelperInterface> mxParent;
+ uno::Reference<uno::XComponentContext> mxContext;
+ uno::Reference<text::XTextDocument> mxTextDocument;
+ const OUString m_sTag;
+ const OUString m_sTitle;
+ std::shared_ptr<SwContentControl> m_pCache;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ContentControlCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
+ uno::Reference<uno::XComponentContext> xContext,
+ uno::Reference<text::XTextDocument> xTextDocument,
+ const OUString& rTag, const OUString& rTitle)
+
+ : mxParent(std::move(xParent))
+ , mxContext(std::move(xContext))
+ , mxTextDocument(std::move(xTextDocument))
+ , m_sTag(rTag)
+ , m_sTitle(rTitle)
+ {
+ }
+
+ // XIndexAccess
+ sal_Int32 SAL_CALL getCount() override
+ {
+ sal_Int32 nCount = SAL_MAX_INT32;
+ lcl_getContentControl(u"", m_sTag, m_sTitle, nCount, mxTextDocument);
+ return nCount == SAL_MAX_INT32 || nCount < 0 ? 0 : nCount;
+ }
+
+ uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
+ {
+ m_pCache = lcl_getContentControl(u"", m_sTag, m_sTitle, Index, mxTextDocument);
+ if (!m_pCache)
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any(uno::Reference<word::XContentControl>(
+ new SwVbaContentControl(mxParent, mxContext, mxTextDocument, m_pCache)));
+ }
+
+ // XNameAccess
+ uno::Sequence<OUString> SAL_CALL getElementNames() override
+ {
+ sal_Int32 nCount = SAL_MAX_INT32;
+ uno::Sequence<OUString> aSeq;
+ lcl_getContentControl(u"", m_sTag, m_sTitle, nCount, mxTextDocument, &aSeq);
+ return aSeq;
+ }
+
+ uno::Any SAL_CALL getByName(const OUString& aName) override
+ {
+ if (!hasByName(aName))
+ throw container::NoSuchElementException();
+
+ return uno::Any(uno::Reference<word::XContentControl>(
+ new SwVbaContentControl(mxParent, mxContext, mxTextDocument, m_pCache)));
+ }
+
+ sal_Bool SAL_CALL hasByName(const OUString& aName) override
+ {
+ sal_Int32 nCount = -1;
+ m_pCache = lcl_getContentControl(aName, m_sTag, m_sTitle, nCount, mxTextDocument);
+ return m_pCache != nullptr;
+ }
+
+ // XElementAccess
+ uno::Type SAL_CALL getElementType() override
+ {
+ return cppu::UnoType<word::XContentControl>::get();
+ }
+
+ sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
+
+ // XEnumerationAccess
+ uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
+ {
+ return new ContentControlsEnumWrapper(this);
+ }
+};
+}
+
+/**
+ * Content Controls can be accessed and filtered in many different ways.
+ * Surprisingly however, there is no clear, descriptive "by name" access.
+ * Instead, each content control (probably) has a unique _signed-integer_ identifier,
+ * which can be passed to Item() as a float or _unsigned-integer_ string
+ * (to differentiate it from getByIndex).
+ *
+ * Index access can be filtered by Tag, Title, Range, and XML link.
+ * TODO: add filtering for Range, SelectLinkedControls, SelectUnlinkedControls
+ */
+SwVbaContentControls::SwVbaContentControls(const uno::Reference<XHelperInterface>& xParent,
+ const uno::Reference<uno::XComponentContext>& xContext,
+ const uno::Reference<text::XTextDocument>& xTextDocument,
+ const OUString& rTag, const OUString& rTitle)
+ : SwVbaContentControls_BASE(
+ xParent, xContext,
+ uno::Reference<container::XIndexAccess>(
+ new ContentControlCollectionHelper(xParent, xContext, xTextDocument, rTag, rTitle)))
+{
+}
+
+// uno::Reference<ooo::vba::word::XContentControl> SwVbaContentControls::Add(const uno::Any& Range,
+// sal_Int32 Type)
+// {
+// sw::mark::IFieldmark* pFieldmark = nullptr;
+// switch (Type)
+// {
+// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox:
+// break;
+// case ooo::vba::word::WdFieldType::wdFieldFormDropDown:
+// break;
+// case ooo::vba::word::WdFieldType::wdFieldFormTextInput:
+// default:;
+// }
+//
+// return uno::Reference<ooo::vba::word::XContentControl>(
+// new SwVbaContentControl(mxParent, mxContext, m_xTextDocument, pFieldmark));
+// }
+
+// XEnumerationAccess
+uno::Type SwVbaContentControls::getElementType()
+{
+ return cppu::UnoType<word::XContentControl>::get();
+}
+
+uno::Reference<container::XEnumeration> SwVbaContentControls::createEnumeration()
+{
+ return new ContentControlsEnumWrapper(m_xIndexAccess);
+}
+
+uno::Any SwVbaContentControls::createCollectionObject(const uno::Any& aSource) { return aSource; }
+
+OUString SwVbaContentControls::getServiceImplName() { return "SwVbaContentControls"; }
+
+uno::Sequence<OUString> SwVbaContentControls::getServiceNames()
+{
+ static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ContentControls" };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbacontentcontrols.hxx b/sw/source/ui/vba/vbacontentcontrols.hxx
new file mode 100644
index 0000000000..20ff65ae89
--- /dev/null
+++ b/sw/source/ui/vba/vbacontentcontrols.hxx
@@ -0,0 +1,40 @@
+/* -*- 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/text/XTextDocument.hpp>
+#include <ooo/vba/word/XContentControls.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper<ooo::vba::word::XContentControls> SwVbaContentControls_BASE;
+
+class SwVbaContentControls : public SwVbaContentControls_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaContentControls(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::text::XTextDocument>& xTextDocument,
+ const OUString& rTag, const OUString& rTitle);
+
+ // XContentControls
+ //css::uno::Reference<ooo::vba::word::XContentControl> SAL_CALL Add(const css::uno::Any& Type, const css::uno::Any& Range) override;
+
+ // XEnumerationAccess
+ css::uno::Type SAL_CALL getElementType() override;
+ css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // SwVbaContentControls_BASE
+ css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadialog.cxx b/sw/source/ui/vba/vbadialog.cxx
new file mode 100644
index 0000000000..f6af8f113e
--- /dev/null
+++ b/sw/source/ui/vba/vbadialog.cxx
@@ -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 .
+ */
+#include "vbadialog.hxx"
+#include <ooo/vba/word/WdWordDialog.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+struct WordDialogTable
+{
+ sal_Int32 wdDialog;
+ const char* ooDialog;
+};
+
+}
+
+const WordDialogTable aWordDialogTable[] =
+{
+ { word::WdWordDialog::wdDialogFileNew, ".uno:NewDoc" },
+ { word::WdWordDialog::wdDialogFileOpen, ".uno:Open" },
+ { word::WdWordDialog::wdDialogFilePrint, ".uno:Print" },
+ { word::WdWordDialog::wdDialogFileSaveAs, ".uno:SaveAs" },
+ { 0, nullptr }
+};
+
+OUString
+SwVbaDialog::mapIndexToName( sal_Int32 nIndex )
+{
+ for (const WordDialogTable & rTable : aWordDialogTable)
+ {
+ if( nIndex == rTable.wdDialog )
+ {
+ return OUString::createFromAscii( rTable.ooDialog );
+ }
+ }
+ return OUString();
+}
+
+OUString
+SwVbaDialog::getServiceImplName()
+{
+ return "SwVbaDialog";
+}
+
+uno::Sequence< OUString >
+SwVbaDialog::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Dialog"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadialog.hxx b/sw/source/ui/vba/vbadialog.hxx
new file mode 100644
index 0000000000..df4443446f
--- /dev/null
+++ b/sw/source/ui/vba/vbadialog.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADIALOG_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBADIALOG_HXX
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/word/XDialog.hpp>
+#include <vbahelper/vbadialogbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaDialogBase, ov::word::XDialog > SwVbaDialog_BASE;
+
+class SwVbaDialog : public SwVbaDialog_BASE
+{
+public:
+ SwVbaDialog( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, sal_Int32 nIndex ):SwVbaDialog_BASE( xParent, xContext, xModel, nIndex ) {}
+
+ // Methods
+ virtual OUString mapIndexToName( sal_Int32 nIndex ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadialogs.cxx b/sw/source/ui/vba/vbadialogs.cxx
new file mode 100644
index 0000000000..2b26a4cfaa
--- /dev/null
+++ b/sw/source/ui/vba/vbadialogs.cxx
@@ -0,0 +1,51 @@
+/* -*- 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 <ooo/vba/word/XDialog.hpp>
+#include "vbadialogs.hxx"
+#include "vbadialog.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+uno::Any
+SwVbaDialogs::Item( const uno::Any &aItem )
+{
+ sal_Int32 nIndex = 0;
+ aItem >>= nIndex;
+ uno::Reference< word::XDialog > aDialog( new SwVbaDialog( uno::Reference< XHelperInterface >( Application(),uno::UNO_QUERY_THROW ), mxContext, m_xModel, nIndex ) );
+ return uno::Any( aDialog );
+}
+
+OUString
+SwVbaDialogs::getServiceImplName()
+{
+ return "SwVbaDialogs";
+}
+
+uno::Sequence< OUString >
+SwVbaDialogs::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Dialogs"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadialogs.hxx b/sw/source/ui/vba/vbadialogs.hxx
new file mode 100644
index 0000000000..3703868f1b
--- /dev/null
+++ b/sw/source/ui/vba/vbadialogs.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADIALOGS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBADIALOGS_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <ooo/vba/word/XDialogs.hpp>
+#include <vbahelper/vbadialogsbase.hxx>
+#include <cppuhelper/implbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaDialogsBase, ov::word::XDialogs > SwVbaDialogs_BASE;
+
+class SwVbaDialogs : public SwVbaDialogs_BASE
+{
+public:
+ SwVbaDialogs( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel >& xModel ): SwVbaDialogs_BASE( xParent, xContext, xModel ) {}
+
+ // XCollection
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADIALOGS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadocument.cxx b/sw/source/ui/vba/vbadocument.cxx
new file mode 100644
index 0000000000..c898546450
--- /dev/null
+++ b/sw/source/ui/vba/vbadocument.cxx
@@ -0,0 +1,795 @@
+/* -*- 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 "vbafilterpropsfromformat.hxx"
+#include "vbacontentcontrols.hxx"
+#include "vbadocument.hxx"
+#include "vbaformfields.hxx"
+#include "vbarange.hxx"
+#include "vbarangehelper.hxx"
+#include "vbadocumentproperties.hxx"
+#include "vbabookmarks.hxx"
+#include "vbamailmerge.hxx"
+#include "vbavariables.hxx"
+#include "vbawindow.hxx"
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <cppu/unotype.hxx>
+
+#include <com/sun/star/text/XBookmarksSupplier.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/document/XRedlinesSupplier.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <ooo/vba/XControlProvider.hpp>
+#include <ooo/vba/word/WdProtectionType.hpp>
+#include <ooo/vba/word/WdSaveFormat.hpp>
+#include <ooo/vba/word/XDocumentOutgoing.hpp>
+
+#include "wordvbahelper.hxx"
+#include <doc.hxx>
+#include <docsh.hxx>
+#include "vbatemplate.hxx"
+#include "vbaparagraph.hxx"
+#include "vbastyles.hxx"
+#include "vbatables.hxx"
+#include "vbafield.hxx"
+#include "vbapagesetup.hxx"
+#include "vbasections.hxx"
+#include "vbatablesofcontents.hxx"
+#include <vbahelper/vbashapes.hxx>
+#include <vbahelper/vbahelper.hxx>
+#include "vbarevisions.hxx"
+#include "vbaframes.hxx"
+#include <basic/sberrors.hxx>
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class SwVbaDocumentOutgoingConnectionPoint : public cppu::WeakImplHelper<XConnectionPoint>
+{
+private:
+ SwVbaDocument* mpDoc;
+
+public:
+ SwVbaDocumentOutgoingConnectionPoint( SwVbaDocument* pDoc );
+
+ // XConnectionPoint
+ sal_uInt32 SAL_CALL Advise(const uno::Reference< XSink >& Sink ) override;
+ void SAL_CALL Unadvise( sal_uInt32 Cookie ) override;
+};
+
+}
+
+SwVbaDocument::SwVbaDocument( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > const & xModel ): SwVbaDocument_BASE( xParent, xContext, xModel )
+{
+ Initialize();
+}
+SwVbaDocument::SwVbaDocument( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& xContext ) : SwVbaDocument_BASE( aArgs, xContext )
+{
+ Initialize();
+}
+
+SwVbaDocument::~SwVbaDocument()
+{
+}
+
+void SwVbaDocument::Initialize()
+{
+ mxTextDocument.set( getModel(), uno::UNO_QUERY_THROW );
+ SwDocShell& rDocSh = *word::getDocShell(mxModel);
+ rDocSh.RegisterAutomationDocumentObject(this);
+ rDocSh.GetDoc()->SetVbaEventProcessor();
+}
+
+sal_uInt32
+SwVbaDocument::AddSink( const uno::Reference< XSink >& xSink )
+{
+ word::getDocShell( mxModel )->RegisterAutomationDocumentEventsCaller( uno::Reference< XSinkCaller >(this) );
+ mvSinks.push_back(xSink);
+ return mvSinks.size();
+}
+
+void
+SwVbaDocument::RemoveSink( sal_uInt32 nNumber )
+{
+ if (nNumber < 1 || nNumber > mvSinks.size())
+ return;
+
+ mvSinks[nNumber-1] = uno::Reference< XSink >();
+}
+
+uno::Reference< word::XRange > SAL_CALL
+SwVbaDocument::getContent()
+{
+ uno::Reference< text::XTextRange > xStart = mxTextDocument->getText()->getStart();
+ uno::Reference< text::XTextRange > xEnd;
+ return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxTextDocument, xStart, xEnd ) );
+}
+
+uno::Reference< word::XRange > SAL_CALL
+SwVbaDocument::Range( const uno::Any& rStart, const uno::Any& rEnd )
+{
+ if( !rStart.hasValue() && !rEnd.hasValue() )
+ return getContent();
+
+ sal_Int32 nStart = 0;
+ sal_Int32 nEnd = 0;
+ rStart >>= nStart;
+ rEnd >>= nEnd;
+
+ uno::Reference< text::XTextRange > xStart;
+ uno::Reference< text::XTextRange > xEnd;
+
+ if( nStart > nEnd)
+ throw uno::RuntimeException();
+
+ if( nEnd != 0)
+ {
+ if( nEnd == nStart )
+ {
+ xStart = mxTextDocument->getText()->getEnd();
+ xEnd = mxTextDocument->getText()->getEnd();
+ }
+ else
+ {
+ xEnd = SwVbaRangeHelper::getRangeByPosition( mxTextDocument->getText(), nEnd );
+
+ if( nStart != 0 )
+ xStart = SwVbaRangeHelper::getRangeByPosition( mxTextDocument->getText(), nStart );
+ else
+ xStart = mxTextDocument->getText()->getStart();
+ }
+ }
+ else
+ {
+ xStart = mxTextDocument->getText()->getEnd();
+ xEnd = mxTextDocument->getText()->getEnd();
+ }
+
+ if( !xStart.is() && !xEnd.is() )
+ {
+ try
+ {
+ // FIXME
+ xStart = mxTextDocument->getText()->getStart();
+ xEnd = mxTextDocument->getText()->getEnd();
+ }
+ catch(const uno::Exception&)
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_METHOD_FAILED, {});
+ }
+ }
+ return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxTextDocument, xStart, xEnd ) );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::BuiltInDocumentProperties( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaBuiltinDocumentProperties( mxParent, mxContext, getModel() ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::CustomDocumentProperties( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaCustomDocumentProperties( mxParent, mxContext, getModel() ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Bookmarks( const uno::Any& rIndex )
+{
+ uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( getModel(),uno::UNO_QUERY_THROW );
+ uno::Reference<container::XIndexAccess > xBookmarks( xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xBookmarksVba( new SwVbaBookmarks( this, mxContext, xBookmarks, getModel() ) );
+ if ( rIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ return uno::Any( xBookmarksVba );
+
+ return xBookmarksVba->Item( rIndex, uno::Any() );
+}
+
+uno::Any SwVbaDocument::ContentControls(const uno::Any& index)
+{
+ uno::Reference<XCollection> xContentControls(
+ new SwVbaContentControls(this, mxContext, mxTextDocument, "", ""));
+ if (index.hasValue())
+ {
+ try
+ {
+ return xContentControls->Item(index, uno::Any());
+ }
+ catch (lang::IndexOutOfBoundsException&)
+ {
+ // Hack: Instead of an index, it might be a float that was mistakenly treated as a long,
+ // which can happen with any valid positive integer when specified as a double like
+ // ActiveDocument.ContentControls(1841581653#).
+ if (index.getValueTypeClass() == css::uno::TypeClass_LONG)
+ {
+ sal_Int32 nLong(0);
+ index >>= nLong;
+ return xContentControls->Item(uno::Any(static_cast<double>(nLong)), uno::Any());
+ }
+ }
+ }
+
+ return uno::Any(xContentControls);
+}
+
+uno::Any SwVbaDocument::SelectContentControlsByTag(const uno::Any& index)
+{
+ OUString sTag;
+ index >>= sTag;
+ return uno::Any(uno::Reference<XCollection>(
+ new SwVbaContentControls(this, mxContext, mxTextDocument, sTag, "")));
+}
+
+uno::Any SwVbaDocument::SelectContentControlsByTitle(const uno::Any& index)
+{
+ OUString sTitle;
+ index >>= sTitle;
+ return uno::Any(uno::Reference<XCollection>(
+ new SwVbaContentControls(this, mxContext, mxTextDocument, "", sTitle)));
+}
+
+uno::Reference<word::XWindow> SwVbaDocument::getActiveWindow()
+{
+ // copied from vbaapplication which has a #FIXME so far can't determine Parent
+ return new SwVbaWindow(uno::Reference< XHelperInterface >(), mxContext, mxModel,
+ mxModel->getCurrentController());
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Variables( const uno::Any& rIndex )
+{
+ uno::Reference< css::document::XDocumentPropertiesSupplier > xDocumentPropertiesSupplier( getModel(),uno::UNO_QUERY_THROW );
+ uno::Reference< css::document::XDocumentProperties > xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
+ uno::Reference< beans::XPropertyAccess > xUserDefined( xDocumentProperties->getUserDefinedProperties(), uno::UNO_QUERY_THROW );
+
+ uno::Reference< XCollection > xVariables( new SwVbaVariables( this, mxContext, xUserDefined ) );
+ if ( rIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ return uno::Any( xVariables );
+
+ return xVariables->Item( rIndex, uno::Any() );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Paragraphs( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaParagraphs( mxParent, mxContext, mxTextDocument ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Styles( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaStyles( mxParent, mxContext, getModel() ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Fields( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, getModel() ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Shapes( const uno::Any& index )
+{
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( getModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new ScVbaShapes( this, mxContext, xIndexAccess, xModel ) );
+
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+void SAL_CALL
+SwVbaDocument::Select()
+{
+ auto xRange = getContent();
+ if ( xRange )
+ xRange->Select();
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Sections( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaSections( mxParent, mxContext, getModel() ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::TablesOfContents( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaTablesOfContents( this, mxContext, mxTextDocument ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL SwVbaDocument::FormFields(const uno::Any& index)
+{
+ uno::Reference<XCollection> xCol(new SwVbaFormFields(this, mxContext, mxTextDocument));
+ if (index.hasValue())
+ return xCol->Item(index, uno::Any());
+ return uno::Any(xCol);
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::PageSetup( )
+{
+ uno::Reference< beans::XPropertySet > xPageProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XPageSetup >( new SwVbaPageSetup( this, mxContext, mxModel, xPageProps ) ) );
+}
+
+OUString
+SwVbaDocument::getServiceImplName()
+{
+ return "SwVbaDocument";
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::getAttachedTemplate()
+{
+ uno::Reference< word::XTemplate > xTemplate;
+ uno::Reference<css::document::XDocumentPropertiesSupplier> const xDocPropSupp(
+ getModel(), uno::UNO_QUERY_THROW);
+ uno::Reference< css::document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_SET_THROW );
+ OUString sTemplateUrl = xDocProps->getTemplateURL();
+
+ xTemplate = new SwVbaTemplate( this, mxContext, sTemplateUrl );
+ return uno::Any( xTemplate );
+}
+
+void SAL_CALL
+SwVbaDocument::setAttachedTemplate( const css::uno::Any& _attachedtemplate )
+{
+ OUString sTemplate;
+ if( !( _attachedtemplate >>= sTemplate ) )
+ {
+ throw uno::RuntimeException();
+ }
+ OUString aURL;
+ INetURLObject aObj;
+ aObj.SetURL( sTemplate );
+ bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
+ if ( bIsURL )
+ aURL = sTemplate;
+ else
+ osl::FileBase::getFileURLFromSystemPath( sTemplate, aURL );
+
+ uno::Reference<css::document::XDocumentPropertiesSupplier> const xDocPropSupp(
+ getModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< css::document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_SET_THROW );
+ xDocProps->setTemplateURL( aURL );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Tables( const css::uno::Any& aIndex )
+{
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xColl( new SwVbaTables( mxParent, mxContext, xModel ) );
+
+ if ( aIndex.hasValue() )
+ return xColl->Item( aIndex, uno::Any() );
+ return uno::Any( xColl );
+}
+
+void SAL_CALL SwVbaDocument::Activate()
+{
+ VbaDocumentBase::Activate();
+}
+
+::sal_Int32 SAL_CALL SwVbaDocument::getProtectionType()
+{
+ //TODO
+ return word::WdProtectionType::wdNoProtection;
+}
+
+void SAL_CALL SwVbaDocument::setProtectionType( ::sal_Int32 /*_protectiontype*/ )
+{
+ //TODO
+}
+
+sal_Bool SAL_CALL SwVbaDocument::getUpdateStylesOnOpen()
+{
+ //TODO
+ return false;
+}
+
+void SAL_CALL SwVbaDocument::setUpdateStylesOnOpen( sal_Bool /*_updatestylesonopen*/ )
+{
+ //TODO
+}
+
+sal_Bool SAL_CALL SwVbaDocument::getAutoHyphenation()
+{
+ // check this property only in default paragraph style
+ bool IsAutoHyphenation = false;
+ uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW );
+ xParaProps->getPropertyValue("ParaIsHyphenation") >>= IsAutoHyphenation;
+ return IsAutoHyphenation;
+}
+
+void SAL_CALL SwVbaDocument::setAutoHyphenation( sal_Bool _autohyphenation )
+{
+ //TODO
+ uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW );
+ xParaProps->setPropertyValue("ParaIsHyphenation", uno::Any( _autohyphenation ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaDocument::getHyphenationZone()
+{
+ //TODO
+ return 0;
+}
+
+void SAL_CALL SwVbaDocument::setHyphenationZone( ::sal_Int32 /*_hyphenationzone*/ )
+{
+ //TODO
+}
+
+::sal_Int32 SAL_CALL SwVbaDocument::getConsecutiveHyphensLimit()
+{
+ //TODO
+ sal_Int16 nHyphensLimit = 0;
+ uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW );
+ xParaProps->getPropertyValue("ParaHyphenationMaxHyphens") >>= nHyphensLimit;
+ return nHyphensLimit;
+}
+
+void SAL_CALL SwVbaDocument::setConsecutiveHyphensLimit( ::sal_Int32 _consecutivehyphenslimit )
+{
+ sal_Int16 nHyphensLimit = static_cast< sal_Int16 >( _consecutivehyphenslimit );
+ uno::Reference< beans::XPropertySet > xParaProps( word::getDefaultParagraphStyle( getModel() ), uno::UNO_QUERY_THROW );
+ xParaProps->setPropertyValue("ParaHyphenationMaxHyphens", uno::Any( nHyphensLimit ) );
+}
+
+uno::Reference< ooo::vba::word::XMailMerge > SAL_CALL SwVbaDocument::getMailMerge()
+{
+ return SwVbaMailMerge::get(mxParent, mxContext);
+}
+
+void SAL_CALL SwVbaDocument::Protect( ::sal_Int32 /*Type*/, const uno::Any& /*NOReset*/, const uno::Any& /*Password*/, const uno::Any& /*UseIRM*/, const uno::Any& /*EnforceStyleLock*/ )
+{
+ // Seems not support in Writer
+ // VbaDocumentBase::Protect( Password );
+}
+
+void SAL_CALL SwVbaDocument::PrintOut( const uno::Any& /*Background*/, const uno::Any& /*Append*/, const uno::Any& /*Range*/, const uno::Any& /*OutputFileName*/, const uno::Any& /*From*/, const uno::Any& /*To*/, const uno::Any& /*Item*/, const uno::Any& /*Copies*/, const uno::Any& /*Pages*/, const uno::Any& /*PageType*/, const uno::Any& /*PrintToFile*/, const uno::Any& /*Collate*/, const uno::Any& /*FileName*/, const uno::Any& /*ActivePrinterMacGX*/, const uno::Any& /*ManualDuplexPrint*/, const uno::Any& /*PrintZoomColumn*/, const uno::Any& /*PrintZoomRow*/, const uno::Any& /*PrintZoomPaperWidth*/, const uno::Any& /*PrintZoomPaperHeight*/ )
+{
+ //TODO
+}
+
+void SAL_CALL SwVbaDocument::PrintPreview( )
+{
+ dispatchRequests( mxModel,".uno:PrintPreview" );
+}
+
+void SAL_CALL SwVbaDocument::ClosePrintPreview( )
+{
+ dispatchRequests( mxModel,".uno:ClosePreview" );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Revisions( const uno::Any& index )
+{
+ uno::Reference< css::document::XRedlinesSupplier > xRedlinesSupp( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xRedlines( xRedlinesSupp->getRedlines(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaRevisions( this, mxContext, getModel(), xRedlines ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::Frames( const uno::Any& index )
+{
+ uno::Reference< text::XTextFramesSupplier > xTextFramesSupp( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xFrames( xTextFramesSupp->getTextFrames(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaFrames( this, mxContext, xFrames, getModel() ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+void SAL_CALL
+SwVbaDocument::SaveAs2000( const uno::Any& FileName, const uno::Any& FileFormat, const uno::Any& /*LockComments*/, const uno::Any& /*Password*/, const uno::Any& /*AddToRecentFiles*/, const uno::Any& /*WritePassword*/, const uno::Any& /*ReadOnlyRecommended*/, const uno::Any& /*EmbedTrueTypeFonts*/, const uno::Any& /*SaveNativePictureFormat*/, const uno::Any& /*SaveFormsData*/, const uno::Any& /*SaveAsAOCELetter*/ )
+{
+ SAL_INFO("sw.vba", "Document.SaveAs2000(FileName:=" << FileName << ",FileFormat:=" << FileFormat << ")");
+
+ // Based on ScVbaWorkbook::SaveAs.
+ OUString sFileName;
+ FileName >>= sFileName;
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath( sFileName, sURL );
+
+ // Detect if there is no path then we need to use the current folder.
+ INetURLObject aURL( sURL );
+ sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+ if( sURL.isEmpty() )
+ {
+ // Need to add cur dir ( of this document ) or else the 'Work' dir
+ sURL = getModel()->getURL();
+
+ if ( sURL.isEmpty() )
+ {
+ // Not path available from 'this' document. Need to add the 'document'/work directory then.
+ // Based on SwVbaOptions::getValueEvent()
+ uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() );
+ OUString sPathUrl;
+ xPathSettings->getPropertyValue( "Work" ) >>= sPathUrl;
+ // Path could be a multipath, Microsoft doesn't support this feature in Word currently.
+ // Only the last path is from interest.
+ sal_Int32 nIndex = sPathUrl.lastIndexOf( ';' );
+ if( nIndex != -1 )
+ {
+ sPathUrl = sPathUrl.copy( nIndex + 1 );
+ }
+
+ aURL.SetURL( sPathUrl );
+ }
+ else
+ {
+ aURL.SetURL( sURL );
+ aURL.Append( sFileName );
+ }
+ sURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+
+ }
+
+ sal_Int32 nFileFormat = word::WdSaveFormat::wdFormatDocument;
+ FileFormat >>= nFileFormat;
+
+ uno::Sequence storeProps{ comphelper::makePropertyValue("FilterName", uno::Any()) };
+
+ setFilterPropsFromFormat( nFileFormat, storeProps );
+
+ uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
+ xStor->storeAsURL( sURL, storeProps );
+}
+
+void SAL_CALL
+SwVbaDocument::SaveAs( const uno::Any& FileName, const uno::Any& FileFormat, const uno::Any& LockComments, const uno::Any& Password, const uno::Any& AddToRecentFiles, const uno::Any& WritePassword, const uno::Any& ReadOnlyRecommended, const uno::Any& EmbedTrueTypeFonts, const uno::Any& SaveNativePictureFormat, const uno::Any& SaveFormsData, const uno::Any& SaveAsAOCELetter, const uno::Any& /*Encoding*/, const uno::Any& /*InsertLineBreaks*/, const uno::Any& /*AllowSubstitutions*/, const uno::Any& /*LineEnding*/, const uno::Any& /*AddBiDiMarks*/ )
+{
+ return SaveAs2000( FileName, FileFormat, LockComments, Password, AddToRecentFiles, WritePassword, ReadOnlyRecommended, EmbedTrueTypeFonts, SaveNativePictureFormat, SaveFormsData, SaveAsAOCELetter );
+}
+
+void SAL_CALL
+SwVbaDocument::Close( const uno::Any& SaveChanges, const uno::Any& /*OriginalFormat*/, const uno::Any& /*RouteDocument*/ )
+{
+ VbaDocumentBase::Close( SaveChanges, uno::Any(), uno::Any() );
+}
+
+void SAL_CALL
+SwVbaDocument::SavePreviewPngAs( const uno::Any& FileName )
+{
+ OUString sFileName;
+ FileName >>= sFileName;
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath( sFileName, sURL );
+
+ uno::Sequence storeProps{ comphelper::makePropertyValue("FilterName",
+ OUString("writer_png_Export")) };
+
+ uno::Reference< frame::XStorable > xStor( getModel(), uno::UNO_QUERY_THROW );
+ xStor->storeToURL( sURL, storeProps );
+}
+
+uno::Any
+SwVbaDocument::getControlShape( std::u16string_view sName )
+{
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+
+ sal_Int32 nCount = xIndexAccess->getCount();
+ for( int index = 0; index < nCount; index++ )
+ {
+ uno::Any aUnoObj = xIndexAccess->getByIndex( index );
+ // It seems there are some drawing objects that can not query into Control shapes?
+ uno::Reference< drawing::XControlShape > xControlShape( aUnoObj, uno::UNO_QUERY );
+ if( xControlShape.is() )
+ {
+ uno::Reference< container::XNamed > xNamed( xControlShape->getControl(), uno::UNO_QUERY_THROW );
+ if( sName == xNamed->getName() )
+ {
+ return aUnoObj;
+ }
+ }
+ }
+ return uno::Any();
+}
+
+uno::Reference< beans::XIntrospectionAccess > SAL_CALL
+SwVbaDocument::getIntrospection( )
+{
+ return uno::Reference< beans::XIntrospectionAccess >();
+}
+
+uno::Any SAL_CALL
+SwVbaDocument::invoke( const OUString& aFunctionName, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ )
+{
+ SAL_INFO("sw.vba", "** will barf " << aFunctionName );
+ throw uno::RuntimeException(); // unsupported operation
+}
+
+void SAL_CALL
+SwVbaDocument::setValue( const OUString& /*aPropertyName*/, const uno::Any& /*aValue*/ )
+{
+ throw uno::RuntimeException(); // unsupported operation
+}
+uno::Any SAL_CALL
+SwVbaDocument::getValue( const OUString& aPropertyName )
+{
+ uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW );
+
+ uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW );
+ uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext("ooo.vba.ControlProvider", mxContext ), uno::UNO_QUERY_THROW );
+ uno::Reference< msforms::XControl > xControl( xControlProvider->createControl( xControlShape, getModel() ) );
+ return uno::Any( xControl );
+}
+
+sal_Bool SAL_CALL
+SwVbaDocument::hasMethod( const OUString& /*aName*/ )
+{
+ return false;
+}
+
+sal_Bool SAL_CALL
+SwVbaDocument::hasProperty( const OUString& aName )
+{
+ uno::Reference< container::XNameAccess > xFormControls( getFormControls() );
+ if ( xFormControls.is() )
+ return xFormControls->hasByName( aName );
+ return false;
+}
+
+uno::Reference< container::XNameAccess >
+SwVbaDocument::getFormControls() const
+{
+ uno::Reference< container::XNameAccess > xFormControls;
+ try
+ {
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< form::XFormsSupplier > xFormSupplier( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xFormSupplier->getForms(), uno::UNO_QUERY_THROW );
+ // get the www-standard container ( maybe we should access the
+ // 'www-standard' by name rather than index, this seems an
+ // implementation detail
+ xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW );
+ }
+ catch(const uno::Exception&)
+ {
+ }
+ return xFormControls;
+}
+
+// XInterfaceWithIID
+
+OUString SAL_CALL
+SwVbaDocument::getIID()
+{
+ return "{82154424-0FBF-11d4-8313-005004526AB4}";
+}
+
+// XConnectable
+
+OUString SAL_CALL
+SwVbaDocument::GetIIDForClassItselfNotCoclass()
+{
+ return "{82154428-0FBF-11D4-8313-005004526AB4}";
+}
+
+TypeAndIID SAL_CALL
+SwVbaDocument::GetConnectionPoint()
+{
+ TypeAndIID aResult =
+ { cppu::UnoType<word::XDocumentOutgoing>::get(),
+ "{82154429-0FBF-11D4-8313-005004526AB4}"
+ };
+
+ return aResult;
+}
+
+// XSinkCaller
+
+void SAL_CALL
+SwVbaDocument::CallSinks( const OUString& Method, uno::Sequence< uno::Any >& Arguments )
+{
+ for (auto& i : mvSinks)
+ {
+ if (i.is())
+ i->Call(Method, Arguments);
+ }
+}
+
+uno::Reference<XConnectionPoint> SAL_CALL
+SwVbaDocument::FindConnectionPoint()
+{
+ uno::Reference<XConnectionPoint> xCP(new SwVbaDocumentOutgoingConnectionPoint(this));
+ return xCP;
+}
+
+// SwVbaApplicationOutgoingConnectionPoint
+
+SwVbaDocumentOutgoingConnectionPoint::SwVbaDocumentOutgoingConnectionPoint( SwVbaDocument* pDoc ) :
+ mpDoc(pDoc)
+{
+}
+
+// XConnectionPoint
+
+sal_uInt32 SAL_CALL
+SwVbaDocumentOutgoingConnectionPoint::Advise( const uno::Reference< XSink >& Sink )
+{
+ return mpDoc->AddSink(Sink);
+}
+
+void SAL_CALL
+SwVbaDocumentOutgoingConnectionPoint::Unadvise( sal_uInt32 Cookie )
+{
+ mpDoc->RemoveSink( Cookie );
+}
+
+uno::Sequence< OUString >
+SwVbaDocument::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Document"
+ };
+ return aServiceNames;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Writer_SwVbaDocument_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new SwVbaDocument(args, context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadocument.hxx b/sw/source/ui/vba/vbadocument.hxx
new file mode 100644
index 0000000000..069215513c
--- /dev/null
+++ b/sw/source/ui/vba/vbadocument.hxx
@@ -0,0 +1,125 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENT_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENT_HXX
+
+#include <ooo/vba/XSink.hpp>
+#include <ooo/vba/XSinkCaller.hpp>
+#include <ooo/vba/word/XDocument.hpp>
+#include <vbahelper/vbadocumentbase.hxx>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <vector>
+
+typedef cppu::ImplInheritanceHelper< VbaDocumentBase, ooo::vba::word::XDocument, ooo::vba::XSinkCaller > SwVbaDocument_BASE;
+
+class SwVbaDocument : public SwVbaDocument_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+
+ std::vector<css::uno::Reference< ooo::vba::XSink >> mvSinks;
+
+ void Initialize();
+ css::uno::Any getControlShape( std::u16string_view sName );
+ css::uno::Reference< css::container::XNameAccess > getFormControls() const;
+
+public:
+ SwVbaDocument( const css::uno::Reference< ooo::vba::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& m_xContext, css::uno::Reference< css::frame::XModel > const & xModel );
+ SwVbaDocument( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
+ virtual ~SwVbaDocument() override;
+
+ sal_uInt32 AddSink( const css::uno::Reference< ooo::vba::XSink >& xSink );
+ void RemoveSink( sal_uInt32 nNumber );
+
+ // XDocument
+ virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL getContent() override;
+ virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL Range( const css::uno::Any& rStart, const css::uno::Any& rEnd ) override;
+ virtual css::uno::Any SAL_CALL BuiltInDocumentProperties( const css::uno::Any& index ) override;
+ virtual css::uno::Any SAL_CALL CustomDocumentProperties( const css::uno::Any& index ) override;
+ virtual css::uno::Any SAL_CALL Bookmarks( const css::uno::Any& rIndex ) override;
+ css::uno::Any SAL_CALL ContentControls(const css::uno::Any& index) override;
+ css::uno::Any SAL_CALL SelectContentControlsByTag(const css::uno::Any& index) override;
+ css::uno::Any SAL_CALL SelectContentControlsByTitle(const css::uno::Any& index) override;
+ css::uno::Reference<ov::word::XWindow> SAL_CALL getActiveWindow() override;
+ virtual css::uno::Any SAL_CALL Variables( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL getAttachedTemplate() override;
+ virtual void SAL_CALL setAttachedTemplate( const css::uno::Any& _attachedtemplate ) override;
+ virtual css::uno::Any SAL_CALL Paragraphs( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL Styles( const css::uno::Any& rIndex ) override;
+ virtual css::uno::Any SAL_CALL Tables( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Fields( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL Select() override;
+ virtual css::uno::Any SAL_CALL Sections( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL Activate() override;
+ virtual css::uno::Any SAL_CALL PageSetup() override;
+ virtual css::uno::Any SAL_CALL TablesOfContents( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL FormFields( const css::uno::Any& aIndex ) override;
+ virtual ::sal_Int32 SAL_CALL getProtectionType() override;
+ virtual void SAL_CALL setProtectionType( ::sal_Int32 _protectiontype ) override;
+ virtual sal_Bool SAL_CALL getUpdateStylesOnOpen() override;
+ virtual void SAL_CALL setUpdateStylesOnOpen( sal_Bool _updatestylesonopen ) override;
+ virtual sal_Bool SAL_CALL getAutoHyphenation() override;
+ virtual void SAL_CALL setAutoHyphenation( sal_Bool _autohyphenation ) override;
+ virtual ::sal_Int32 SAL_CALL getHyphenationZone() override;
+ virtual void SAL_CALL setHyphenationZone( ::sal_Int32 _hyphenationzone ) override;
+ virtual ::sal_Int32 SAL_CALL getConsecutiveHyphensLimit() override;
+ virtual void SAL_CALL setConsecutiveHyphensLimit( ::sal_Int32 _consecutivehyphenslimit ) override;
+ virtual css::uno::Reference< ooo::vba::word::XMailMerge > SAL_CALL getMailMerge() override;
+
+ using VbaDocumentBase::Protect;
+ virtual void SAL_CALL Protect( ::sal_Int32 Type, const css::uno::Any& NOReset, const css::uno::Any& Password, const css::uno::Any& UseIRM, const css::uno::Any& EnforceStyleLock ) override;
+ virtual void SAL_CALL PrintOut( const css::uno::Any& Background, const css::uno::Any& Append, const css::uno::Any& Range, const css::uno::Any& OutputFileName, const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Item, const css::uno::Any& Copies, const css::uno::Any& Pages, const css::uno::Any& PageType, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& FileName, const css::uno::Any& ActivePrinterMacGX, const css::uno::Any& ManualDuplexPrint, const css::uno::Any& PrintZoomColumn, const css::uno::Any& PrintZoomRow, const css::uno::Any& PrintZoomPaperWidth, const css::uno::Any& PrintZoomPaperHeight ) override;
+ virtual void SAL_CALL PrintPreview( ) override;
+ virtual void SAL_CALL ClosePrintPreview( ) override;
+ virtual css::uno::Any SAL_CALL Revisions( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Frames( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL SaveAs2000( const css::uno::Any& FileName, const css::uno::Any& FileFormat, const css::uno::Any& LockComments, const css::uno::Any& Password, const css::uno::Any& AddToRecentFiles, const css::uno::Any& WritePassword, const css::uno::Any& ReadOnlyRecommended, const css::uno::Any& EmbedTrueTypeFonts, const css::uno::Any& SaveNativePictureFormat, const css::uno::Any& SaveFormsData, const css::uno::Any& SaveAsAOCELetter ) override;
+ virtual void SAL_CALL SaveAs( const css::uno::Any& FileName, const css::uno::Any& FileFormat, const css::uno::Any& LockComments, const css::uno::Any& Password, const css::uno::Any& AddToRecentFiles, const css::uno::Any& WritePassword, const css::uno::Any& ReadOnlyRecommended, const css::uno::Any& EmbedTrueTypeFonts, const css::uno::Any& SaveNativePictureFormat, const css::uno::Any& SaveFormsData, const css::uno::Any& SaveAsAOCELetter, const css::uno::Any& Encoding, const css::uno::Any& InsertLineBreaks, const css::uno::Any& AllowSubstitutions, const css::uno::Any& LineEnding, const css::uno::Any& AddBiDiMarks ) override;
+ virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& OriginalFormat, const css::uno::Any& RouteDocument ) override;
+ virtual void SAL_CALL SavePreviewPngAs( const css::uno::Any& FileName ) override;
+
+ // XInvocation
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection( ) override;
+ virtual css::uno::Any SAL_CALL invoke( const OUString& aFunctionName, const css::uno::Sequence< css::uno::Any >& aParams, css::uno::Sequence< ::sal_Int16 >& aOutParamIndex, css::uno::Sequence< css::uno::Any >& aOutParam ) override;
+ virtual void SAL_CALL setValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getValue( const OUString& aPropertyName ) override;
+ virtual sal_Bool SAL_CALL hasMethod( const OUString& aName ) override;
+ virtual sal_Bool SAL_CALL hasProperty( const OUString& aName ) override;
+
+ // XInterfaceWithIID
+ virtual OUString SAL_CALL getIID() override;
+
+ // XConnectable
+ virtual OUString SAL_CALL GetIIDForClassItselfNotCoclass() override;
+ virtual ov::TypeAndIID SAL_CALL GetConnectionPoint() override;
+ virtual css::uno::Reference<ov::XConnectionPoint> SAL_CALL FindConnectionPoint() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XSinkCaller
+ virtual void SAL_CALL CallSinks( const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments ) override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadocumentproperties.cxx b/sw/source/ui/vba/vbadocumentproperties.cxx
new file mode 100644
index 0000000000..6d5f06830f
--- /dev/null
+++ b/sw/source/ui/vba/vbadocumentproperties.cxx
@@ -0,0 +1,921 @@
+/* -*- 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 "vbadocumentproperties.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <sal/log.hxx>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <ooo/vba/word/WdBuiltInProperty.hpp>
+#include <ooo/vba/office/MsoDocProperties.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <memory>
+#include "wordvbahelper.hxx"
+#include <fesh.hxx>
+#include <docsh.hxx>
+#include <utility>
+using namespace ::ooo::vba;
+using namespace css;
+
+/// @throws lang::IllegalArgumentException
+static sal_Int8 lcl_toMSOPropType( const uno::Type& aType )
+{
+ sal_Int16 msoType = office::MsoDocProperties::msoPropertyTypeString;
+
+ switch ( aType.getTypeClass() )
+ {
+ case uno::TypeClass_BOOLEAN:
+ msoType = office::MsoDocProperties::msoPropertyTypeBoolean;
+ break;
+ case uno::TypeClass_FLOAT:
+ msoType = office::MsoDocProperties::msoPropertyTypeFloat;
+ break;
+ case uno::TypeClass_STRUCT: // Assume date
+ msoType = office::MsoDocProperties::msoPropertyTypeDate;
+ break;
+ case uno::TypeClass_BYTE:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_HYPER:
+ msoType = office::MsoDocProperties::msoPropertyTypeNumber;
+ break;
+ default:
+ throw lang::IllegalArgumentException();
+ }
+ return msoType;
+}
+
+namespace {
+
+class PropertGetSetHelper
+{
+protected:
+ uno::Reference< frame::XModel > m_xModel;
+ uno::Reference<document::XDocumentProperties> m_xDocProps;
+public:
+ explicit PropertGetSetHelper( uno::Reference< frame::XModel > xModel ):m_xModel(std::move( xModel ))
+ {
+ uno::Reference<document::XDocumentPropertiesSupplier> const
+ xDocPropSupp(m_xModel, uno::UNO_QUERY_THROW);
+ m_xDocProps.set(xDocPropSupp->getDocumentProperties(),
+ uno::UNO_SET_THROW);
+ }
+ virtual ~PropertGetSetHelper() {}
+ virtual uno::Any getPropertyValue( const OUString& rPropName ) = 0;
+ virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) = 0;
+ uno::Reference< beans::XPropertySet > getUserDefinedProperties() {
+ return uno::Reference<beans::XPropertySet>(
+ m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ }
+
+};
+
+class BuiltinPropertyGetSetHelper : public PropertGetSetHelper
+{
+public:
+ explicit BuiltinPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel )
+ {
+ }
+ virtual uno::Any getPropertyValue( const OUString& rPropName ) override
+ {
+ if ( rPropName == "EditingDuration" )
+ {
+ sal_Int32 const nSecs = m_xDocProps->getEditingDuration();
+ return uno::Any( nSecs/60 ); // minutes
+ }
+ else if ("Title" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getTitle());
+ }
+ else if ("Subject" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getSubject());
+ }
+ else if ("Author" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getAuthor());
+ }
+ else if ("Keywords" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getKeywords());
+ }
+ else if ("Description" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getDescription());
+ }
+ else if ("Template" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getTemplateName());
+ }
+ else if ("ModifiedBy" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getModifiedBy());
+ }
+ else if ("Generator" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getGenerator());
+ }
+ else if ("PrintDate" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getPrintDate());
+ }
+ else if ("CreationDate" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getCreationDate());
+ }
+ else if ("ModifyDate" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getModificationDate());
+ }
+ else if ("AutoloadURL" == rPropName)
+ {
+ return uno::Any(m_xDocProps->getAutoloadURL());
+ }
+ else
+ {
+ // fall back to user-defined properties
+ return getUserDefinedProperties()->getPropertyValue(rPropName);
+ }
+ }
+ virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
+ {
+ if ("EditingDuration" == rPropName)
+ {
+ sal_Int32 nMins = 0;
+ if (aValue >>= nMins)
+ {
+ m_xDocProps->setEditingDuration(nMins * 60); // convert minutes
+ }
+ }
+ else if ("Title" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setTitle(str);
+ }
+ }
+ else if ("Subject" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setSubject(str);
+ }
+ }
+ else if ("Author" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setAuthor(str);
+ }
+ }
+ else if ("Keywords" == rPropName)
+ {
+ uno::Sequence<OUString> keywords;
+ if (aValue >>= keywords)
+ {
+ m_xDocProps->setKeywords(keywords);
+ }
+ }
+ else if ("Description" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setDescription(str);
+ }
+ }
+ else if ("Template" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setTemplateName(str);
+ }
+ }
+ else if ("ModifiedBy" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setModifiedBy(str);
+ }
+ }
+ else if ("Generator" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ return m_xDocProps->setGenerator(str);
+ }
+ }
+ else if ("PrintDate" == rPropName)
+ {
+ util::DateTime dt;
+ if (aValue >>= dt)
+ {
+ m_xDocProps->setPrintDate(dt);
+ }
+ }
+ else if ("CreationDate" == rPropName)
+ {
+ util::DateTime dt;
+ if (aValue >>= dt)
+ {
+ m_xDocProps->setCreationDate(dt);
+ }
+ }
+ else if ("ModifyDate" == rPropName)
+ {
+ util::DateTime dt;
+ if (aValue >>= dt)
+ {
+ m_xDocProps->setModificationDate(dt);
+ }
+ }
+ else if ("AutoloadURL" == rPropName)
+ {
+ OUString str;
+ if (aValue >>= str)
+ {
+ m_xDocProps->setAutoloadURL(str);
+ }
+ }
+ else
+ {
+ // fall back to user-defined properties
+ getUserDefinedProperties()->setPropertyValue(rPropName, aValue);
+ }
+ }
+};
+
+class CustomPropertyGetSetHelper : public BuiltinPropertyGetSetHelper
+{
+public:
+ explicit CustomPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :BuiltinPropertyGetSetHelper( xModel )
+ {
+ }
+ virtual uno::Any getPropertyValue( const OUString& rPropName ) override
+ {
+ return getUserDefinedProperties()->getPropertyValue(rPropName);
+ }
+ virtual void setPropertyValue(
+ const OUString& rPropName, const uno::Any& rValue) override
+ {
+ return getUserDefinedProperties()->setPropertyValue(rPropName, rValue);
+ }
+};
+
+class StatisticPropertyGetSetHelper : public PropertGetSetHelper
+{
+ SwDocShell* mpDocShell;
+ uno::Reference< beans::XPropertySet > mxModelProps;
+public:
+ explicit StatisticPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel ) , mpDocShell( nullptr )
+ {
+ mxModelProps.set( m_xModel, uno::UNO_QUERY_THROW );
+ mpDocShell = word::getDocShell( xModel );
+ }
+ virtual uno::Any getPropertyValue( const OUString& rPropName ) override
+ {
+ try
+ {
+ // Characters, ParagraphCount & WordCount are available from
+ // the model ( and additionally these also update the statics object )
+ return mxModelProps->getPropertyValue( rPropName );
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("sw.vba", "");
+ }
+ uno::Any aReturn;
+ if ( rPropName == "LineCount" ) // special processing needed
+ {
+ if ( mpDocShell )
+ {
+ if (SwFEShell* pFEShell = mpDocShell->GetFEShell())
+ aReturn <<= pFEShell->GetLineCount();
+ }
+ }
+ else
+ {
+ uno::Sequence< beans::NamedValue > const stats(
+ m_xDocProps->getDocumentStatistics());
+
+ auto pStat = std::find_if(stats.begin(), stats.end(),
+ [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; });
+ if (pStat == stats.end())
+ throw uno::RuntimeException(); // bad Property
+
+ aReturn = pStat->Value;
+ }
+ return aReturn;
+ }
+
+ virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
+ {
+ uno::Sequence< beans::NamedValue > stats(
+ m_xDocProps->getDocumentStatistics());
+
+ auto [begin, end] = asNonConstRange(stats);
+ auto pStat = std::find_if(begin, end,
+ [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; });
+ if (pStat != end)
+ {
+ pStat->Value = aValue;
+ m_xDocProps->setDocumentStatistics(stats);
+ }
+ }
+};
+
+class DocPropInfo
+{
+public:
+ OUString msMSODesc;
+ OUString msOOOPropName;
+ std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
+
+ static DocPropInfo createDocPropInfo( const OUString& sDesc, const OUString& sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
+ {
+ DocPropInfo aItem;
+ aItem.msMSODesc = sDesc;
+ aItem.msOOOPropName = sPropName;
+ aItem.mpPropGetSetHelper = rHelper;
+ return aItem;
+ }
+
+ static DocPropInfo createDocPropInfo( const char* sDesc, const char* sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
+ {
+ return createDocPropInfo( OUString::createFromAscii( sDesc ), OUString::createFromAscii( sPropName ), rHelper );
+ }
+ uno::Any getValue()
+ {
+ if ( mpPropGetSetHelper )
+ return mpPropGetSetHelper->getPropertyValue( msOOOPropName );
+ return uno::Any();
+ }
+ void setValue( const uno::Any& rValue )
+ {
+ if ( mpPropGetSetHelper )
+ mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue );
+ }
+ uno::Reference< beans::XPropertySet > getUserDefinedProperties()
+ {
+ uno::Reference< beans::XPropertySet > xProps;
+ if ( mpPropGetSetHelper )
+ return mpPropGetSetHelper->getUserDefinedProperties();
+ return xProps;
+ }
+};
+
+}
+
+typedef std::unordered_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo;
+
+namespace {
+
+class BuiltInIndexHelper
+{
+ MSOIndexToOODocPropInfo m_docPropInfoMap;
+
+public:
+ explicit BuiltInIndexHelper( const uno::Reference< frame::XModel >& xModel )
+ {
+ auto aStandardHelper = std::make_shared<BuiltinPropertyGetSetHelper>( xModel );
+ auto aUsingStatsHelper = std::make_shared<StatisticPropertyGetSetHelper>( xModel );
+
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper ); // Not sure if this is correct
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper ); // special handling required ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper ); // special handling require ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper ); // special handling required ?
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper ); // doesn't seem to exist
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper ); // hacked in
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper ); // doesn't seem to exist
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper ); // hacked in
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper ); // hacked in
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyBytes ] = DocPropInfo::createDocPropInfo( "Number of bytes", "", aStandardHelper ); // doesn't seem to exist - size on disk exists ( for an already saved document ) perhaps it will do ( or we need something else )
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper ); // special handling
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper ); // special handling
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper ); // doesn't seem to exist
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper ); // doesn't seem to exist
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper ); // doesn't seem to exist
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper ); // doesn't seem to exist
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper );
+ m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper ); // doesn't seem to be supported
+ }
+
+ MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; }
+};
+
+}
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::XDocumentProperty > SwVbaDocumentProperty_BASE;
+
+namespace {
+
+class SwVbaBuiltInDocumentProperty : public SwVbaDocumentProperty_BASE
+{
+protected:
+ DocPropInfo mPropInfo;
+public:
+ SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, DocPropInfo rInfo );
+ // XDocumentProperty
+ virtual void SAL_CALL Delete( ) override;
+ virtual OUString SAL_CALL getName( ) override;
+ virtual void SAL_CALL setName( const OUString& Name ) override;
+ virtual ::sal_Int8 SAL_CALL getType( ) override;
+ virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
+ virtual sal_Bool SAL_CALL getLinkToContent( ) override;
+ virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
+ virtual uno::Any SAL_CALL getValue( ) override;
+ virtual void SAL_CALL setValue( const uno::Any& Value ) override;
+ virtual OUString SAL_CALL getLinkSource( ) override;
+ virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
+ //XDefaultProperty
+ virtual OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; }
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual uno::Sequence<OUString> getServiceNames() override;
+};
+
+class SwVbaCustomDocumentProperty : public SwVbaBuiltInDocumentProperty
+{
+public:
+
+ SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
+
+ virtual sal_Bool SAL_CALL getLinkToContent( ) override;
+ virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
+
+ virtual OUString SAL_CALL getLinkSource( ) override;
+ virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL setName( const OUString& Name ) override;
+ virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
+
+};
+
+}
+
+SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo )
+{
+}
+
+sal_Bool
+SwVbaCustomDocumentProperty::getLinkToContent( )
+{
+ // #FIXME we need to store the link content somewhere
+ return false;
+}
+
+void
+SwVbaCustomDocumentProperty::setLinkToContent( sal_Bool /*bLinkContent*/ )
+{
+}
+
+OUString
+SwVbaCustomDocumentProperty::getLinkSource( )
+{
+ // #FIXME we need to store the link content somewhere
+ return OUString();
+}
+
+void
+SwVbaCustomDocumentProperty::setLinkSource( const OUString& /*rsLinkContent*/ )
+{
+ // #FIXME we need to store the link source somewhere
+}
+
+void SAL_CALL
+SwVbaCustomDocumentProperty::setName( const OUString& /*Name*/ )
+{
+ // setName on existing property ?
+ // #FIXME
+ // do we need to delete existing property and create a new one?
+}
+
+void SAL_CALL
+SwVbaCustomDocumentProperty::setType( ::sal_Int8 /*Type*/ )
+{
+ // setType, do we need to do a conversion?
+ // #FIXME the underlying value needs to be changed to the new type
+}
+
+void SAL_CALL
+SwVbaCustomDocumentProperty::Delete( )
+{
+ uno::Reference< beans::XPropertyContainer > xContainer(
+ mPropInfo.getUserDefinedProperties(), uno::UNO_QUERY_THROW);
+ xContainer->removeProperty( getName() );
+}
+
+SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, DocPropInfo rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo(std::move( rInfo ))
+{
+}
+
+void SAL_CALL
+SwVbaBuiltInDocumentProperty::Delete( )
+{
+ // not valid for Builtin
+ throw uno::RuntimeException();
+}
+
+OUString SAL_CALL
+SwVbaBuiltInDocumentProperty::getName( )
+{
+ return mPropInfo.msMSODesc;
+}
+
+void SAL_CALL
+SwVbaBuiltInDocumentProperty::setName( const OUString& )
+{
+ // not valid for Builtin
+ throw uno::RuntimeException();
+}
+
+::sal_Int8 SAL_CALL
+SwVbaBuiltInDocumentProperty::getType( )
+{
+ return lcl_toMSOPropType( getValue().getValueType() );
+}
+
+void SAL_CALL
+SwVbaBuiltInDocumentProperty::setType( ::sal_Int8 /*Type*/ )
+{
+ // not valid for Builtin
+ throw uno::RuntimeException();
+}
+
+sal_Bool SAL_CALL
+SwVbaBuiltInDocumentProperty::getLinkToContent( )
+{
+ return false; // built-in always false
+}
+
+void SAL_CALL
+SwVbaBuiltInDocumentProperty::setLinkToContent( sal_Bool /*LinkToContent*/ )
+{
+ // not valid for Builtin
+ throw uno::RuntimeException();
+}
+
+uno::Any SAL_CALL
+SwVbaBuiltInDocumentProperty::getValue( )
+{
+ uno::Any aRet = mPropInfo.getValue();
+ if ( !aRet.hasValue() )
+ throw uno::RuntimeException();
+ return aRet;
+}
+
+void SAL_CALL
+SwVbaBuiltInDocumentProperty::setValue( const uno::Any& Value )
+{
+ mPropInfo.setValue( Value );
+}
+
+OUString SAL_CALL
+SwVbaBuiltInDocumentProperty::getLinkSource( )
+{
+ // not valid for Builtin
+ throw uno::RuntimeException();
+}
+
+void SAL_CALL
+SwVbaBuiltInDocumentProperty::setLinkSource( const OUString& /*LinkSource*/ )
+{
+ // not valid for Builtin
+ throw uno::RuntimeException();
+}
+
+OUString
+SwVbaBuiltInDocumentProperty::getServiceImplName()
+{
+ return "SwVbaBuiltinDocumentProperty";
+}
+
+uno::Sequence<OUString>
+SwVbaBuiltInDocumentProperty::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.DocumentProperty"
+ };
+ return aServiceNames;
+}
+typedef ::cppu::WeakImplHelper< css::container::XIndexAccess
+ ,css::container::XNameAccess
+ ,css::container::XEnumerationAccess
+ > PropertiesImpl_BASE;
+
+typedef std::unordered_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps;
+
+namespace {
+
+class DocPropEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration >
+{
+ DocProps mDocProps;
+ DocProps::iterator mIt;
+public:
+
+ explicit DocPropEnumeration( DocProps&& rProps ) : mDocProps( std::move(rProps) ), mIt( mDocProps.begin() ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return mIt != mDocProps.end();
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ return uno::Any( mIt++->second );
+ }
+};
+
+}
+
+typedef std::unordered_map< OUString, uno::Reference< XDocumentProperty > > DocPropsByName;
+
+namespace {
+
+class BuiltInPropertiesImpl : public PropertiesImpl_BASE
+{
+protected:
+
+ uno::Reference< frame::XModel > m_xModel;
+
+ DocProps mDocProps;
+ DocPropsByName mNamedDocProps;
+
+ public:
+ BuiltInPropertiesImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, uno::Reference< frame::XModel > xModel ) : m_xModel(std::move( xModel ))
+ {
+ BuiltInIndexHelper builtIns( m_xModel );
+ for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index )
+ {
+ mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] );
+ mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ];
+ }
+ }
+// XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return mDocProps.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ // correct the correct by the base class for 1 based indices
+ DocProps::iterator it = mDocProps.find( ++Index );
+ if ( it == mDocProps.end() )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( it->second );
+ }
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+ DocPropsByName::iterator it = mNamedDocProps.find( aName );
+ return uno::Any( it->second );
+
+ }
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ uno::Sequence< OUString > aNames( getCount() );
+ OUString* pName = aNames.getArray();
+ for (const auto& rEntry : mNamedDocProps)
+ {
+ *pName = rEntry.first;
+ ++pName;
+ }
+ return aNames;
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ DocPropsByName::iterator it = mNamedDocProps.find( aName );
+ if ( it == mNamedDocProps.end() )
+ return false;
+ return true;
+ }
+// XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<XDocumentProperty>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return !mDocProps.empty();
+ }
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new DocPropEnumeration( std::unordered_map(mDocProps) );
+ }
+};
+
+}
+
+SwVbaBuiltinDocumentProperties::SwVbaBuiltinDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaDocumentproperties_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new BuiltInPropertiesImpl( xParent, xContext, xModel ) ) )
+{
+}
+
+uno::Reference< XDocumentProperty > SAL_CALL
+SwVbaBuiltinDocumentProperties::Add( const OUString& /*Name*/, sal_Bool /*LinkToContent*/, ::sal_Int8 /*Type*/, const uno::Any& /*value*/, const uno::Any& /*LinkSource*/ )
+{
+ throw uno::RuntimeException( "not supported for Builtin properties" );
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+SwVbaBuiltinDocumentProperties::getElementType()
+{
+ return cppu::UnoType<XDocumentProperty>::get();
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwVbaBuiltinDocumentProperties::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xEnumAccess->createEnumeration();
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any
+SwVbaBuiltinDocumentProperties::createCollectionObject( const uno::Any& aSource )
+{
+ // pass through
+ return aSource;
+}
+
+// XHelperInterface
+OUString
+SwVbaBuiltinDocumentProperties::getServiceImplName()
+{
+ return "SwVbaBuiltinDocumentProperties";
+}
+
+uno::Sequence<OUString>
+SwVbaBuiltinDocumentProperties::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.DocumentProperties"
+ };
+ return aServiceNames;
+}
+
+namespace {
+
+class CustomPropertiesImpl : public PropertiesImpl_BASE
+{
+ uno::Reference< XHelperInterface > m_xParent;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< frame::XModel > m_xModel;
+ uno::Reference< beans::XPropertySet > mxUserDefinedProp;
+ std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
+public:
+ CustomPropertiesImpl( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel ) : m_xParent(std::move( xParent )), m_xContext(std::move( xContext )), m_xModel(std::move( xModel ))
+ {
+ // suck in the document( custom ) properties
+ mpPropGetSetHelper = std::make_shared<CustomPropertyGetSetHelper>( m_xModel );
+ mxUserDefinedProp.set(mpPropGetSetHelper->getUserDefinedProperties(),
+ uno::UNO_SET_THROW);
+ };
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength();
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
+ if ( Index >= aProps.getLength() )
+ throw lang::IndexOutOfBoundsException();
+ // How to determine type e.g Date? ( com.sun.star.util.DateTime )
+ DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper );
+ return uno::Any( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
+ }
+
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName( aName ) )
+ throw container::NoSuchElementException();
+
+ DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper );
+ return uno::Any( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
+ }
+
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ const uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
+ uno::Sequence< OUString > aNames( aProps.getLength() );
+ std::transform(aProps.begin(), aProps.end(), aNames.getArray(),
+ [](const beans::Property& rProp) -> OUString { return rProp.Name; });
+ return aNames;
+ }
+
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ SAL_INFO("sw.vba", "hasByName(" << aName << ") returns " << mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) );
+ return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName );
+ }
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<XDocumentProperty>::get();
+ }
+
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return getCount() > 0;
+ }
+
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ // create a map of properties ( the key doesn't matter )
+ SAL_INFO("sw.vba", "Creating an enumeration");
+ sal_Int32 key = 0;
+ sal_Int32 nElem = getCount();
+ DocProps simpleDocPropSnapShot;
+ for ( ; key < nElem; ++key )
+ simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW );
+ SAL_INFO("sw.vba", "After creating the enumeration");
+ return new DocPropEnumeration( std::move(simpleDocPropSnapShot) );
+ }
+
+ void addProp( const OUString& Name, const uno::Any& Value )
+ {
+ uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW );
+ // TODO fixme, perform the necessary Type Value conversions
+ xContainer->addProperty( Name, sal_Int16(128), Value );
+ }
+
+};
+
+}
+
+SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel )
+{
+ // replace the m_xIndexAccess implementation ( we need a virtual init )
+ m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) );
+ m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< XDocumentProperty > SAL_CALL
+SwVbaCustomDocumentProperties::Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 /*Type*/, const uno::Any& Value, const uno::Any& LinkSource )
+{
+ CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() );
+ uno::Reference< XDocumentProperty > xDocProp;
+ if ( pCustomProps )
+ {
+ OUString sLinkSource;
+ pCustomProps->addProp( Name, Value );
+
+ xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW );
+ xDocProp->setLinkToContent( LinkToContent );
+
+ if ( LinkSource >>= sLinkSource )
+ xDocProp->setLinkSource( sLinkSource );
+ }
+ return xDocProp;
+}
+
+// XHelperInterface
+OUString
+SwVbaCustomDocumentProperties::getServiceImplName()
+{
+ return "SwVbaCustomDocumentProperties";
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadocumentproperties.hxx b/sw/source/ui/vba/vbadocumentproperties.hxx
new file mode 100644
index 0000000000..740353e829
--- /dev/null
+++ b/sw/source/ui/vba/vbadocumentproperties.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTPROPERTIES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTPROPERTIES_HXX
+
+#include <ooo/vba/XDocumentProperties.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::XDocumentProperties > SwVbaDocumentproperties_BASE;
+
+class SwVbaBuiltinDocumentProperties : public SwVbaDocumentproperties_BASE
+{
+public:
+ SwVbaBuiltinDocumentProperties( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xDocument );
+
+ // XDocumentProperties
+ virtual css::uno::Reference< ::ooo::vba::XDocumentProperty > SAL_CALL Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 Type, const css::uno::Any& Value, const css::uno::Any& LinkSource ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+class SwVbaCustomDocumentProperties : public SwVbaBuiltinDocumentProperties
+{
+public:
+ SwVbaCustomDocumentProperties( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xDocument );
+// XDocumentProperties
+ virtual css::uno::Reference< ::ooo::vba::XDocumentProperty > SAL_CALL Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 Type, const css::uno::Any& Value, const css::uno::Any& LinkSource ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+};
+
+#endif /* SW_VBA_DOCUMENTPROPERTY_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadocuments.cxx b/sw/source/ui/vba/vbadocuments.cxx
new file mode 100644
index 0000000000..ca5f298555
--- /dev/null
+++ b/sw/source/ui/vba/vbadocuments.cxx
@@ -0,0 +1,161 @@
+/* -*- 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/XTextDocument.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+
+#include <tools/urlobj.hxx>
+#include <rtl/ref.hxx>
+
+#include "vbadocument.hxx"
+#include "vbadocuments.hxx"
+
+#include <osl/file.hxx>
+#include <utility>
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static uno::Any
+getDocument( uno::Reference< uno::XComponentContext > const & xContext, const uno::Reference< text::XTextDocument > &xDoc, const uno::Any& aApplication )
+{
+ // FIXME: fine as long as SwVbaDocument is stateless ...
+ if( !xDoc.is() )
+ return uno::Any();
+
+ rtl::Reference<SwVbaDocument> pWb = new SwVbaDocument( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xDoc );
+ return uno::Any( uno::Reference< word::XDocument > (pWb) );
+}
+
+namespace {
+
+class DocumentEnumImpl : public EnumerationHelperImpl
+{
+ uno::Any m_aApplication;
+public:
+ /// @throws uno::RuntimeException
+ DocumentEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Any aApplication ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication(std::move( aApplication )) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< text::XTextDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return getDocument( m_xContext, xDoc, m_aApplication );
+ }
+};
+
+}
+
+SwVbaDocuments::SwVbaDocuments( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : SwVbaDocuments_BASE( xParent, xContext, VbaDocumentsBase::WORD_DOCUMENT )
+{
+}
+// XEnumerationAccess
+uno::Type
+SwVbaDocuments::getElementType()
+{
+ return cppu::UnoType<word::XDocument>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaDocuments::createEnumeration()
+{
+ // #FIXME it's possible the DocumentEnumImpl here doesn't reflect
+ // the state of this object (although it should) would be
+ // safer to create an enumeration based on this objects state
+ // rather than one effectively based of the desktop component
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new DocumentEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() );
+}
+
+uno::Any
+SwVbaDocuments::createCollectionObject( const uno::Any& aSource )
+{
+ uno::Reference< text::XTextDocument > xDoc( aSource, uno::UNO_QUERY_THROW );
+ return getDocument( mxContext, xDoc, Application() );
+}
+
+uno::Any SAL_CALL
+SwVbaDocuments::Add( const uno::Any& Template, const uno::Any& /*NewTemplate*/, const uno::Any& /*DocumentType*/, const uno::Any& /*Visible*/ )
+{
+ OUString sFileName;
+ if( Template.hasValue() && ( Template >>= sFileName ) )
+ {
+ return Open( sFileName, uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any());
+ }
+ uno::Reference <text::XTextDocument> xTextDoc( createDocument() , uno::UNO_QUERY_THROW );
+ return getDocument( mxContext, xTextDoc, Application() );
+}
+
+// #TODO# #FIXME# can any of the unused params below be used?
+// #TODO# #FIXME# surely we should actually close the document here
+void SAL_CALL
+SwVbaDocuments::Close( const uno::Any& /*SaveChanges*/, const uno::Any& /*OriginalFormat*/, const uno::Any& /*RouteDocument*/ )
+{
+}
+
+// #TODO# #FIXME# can any of the unused params below be used?
+uno::Any SAL_CALL
+SwVbaDocuments::Open( const OUString& Filename, const uno::Any& /*ConfirmConversions*/, const uno::Any& ReadOnly, const uno::Any& /*AddToRecentFiles*/, const uno::Any& /*PasswordDocument*/, const uno::Any& /*PasswordTemplate*/, const uno::Any& /*Revert*/, const uno::Any& /*WritePasswordDocument*/, const uno::Any& /*WritePasswordTemplate*/, const uno::Any& /*Format*/, const uno::Any& /*Encoding*/, const uno::Any& /*Visible*/, const uno::Any& /*OpenAndRepair*/, const uno::Any& /*DocumentDirection*/, const uno::Any& /*NoEncodingDialog*/, const uno::Any& /*XMLTransform*/ )
+{
+ SAL_INFO("sw.vba", "Documents.Open(Filename:=" << Filename << ",ReadOnly:=" << ReadOnly << ")");
+
+ // we need to detect if this is a URL, if not then assume it's a file path
+ OUString aURL;
+ INetURLObject aObj;
+ aObj.SetURL( Filename );
+ bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
+ if ( bIsURL )
+ aURL = Filename;
+ else
+ osl::FileBase::getFileURLFromSystemPath( Filename, aURL );
+
+ uno::Reference <text::XTextDocument> xSpreadDoc( openDocument( Filename, ReadOnly, {}), uno::UNO_QUERY_THROW );
+ uno::Any aRet = getDocument( mxContext, xSpreadDoc, Application() );
+ uno::Reference< word::XDocument > xDocument( aRet, uno::UNO_QUERY );
+ if ( xDocument.is() )
+ xDocument->Activate();
+ return aRet;
+}
+
+uno::Any SAL_CALL
+SwVbaDocuments::OpenNoRepairDialog( const OUString& Filename, const uno::Any& ConfirmConversions, const uno::Any& ReadOnly, const uno::Any& AddToRecentFiles, const uno::Any& PasswordDocument, const uno::Any& PasswordTemplate, const uno::Any& Revert, const uno::Any& WritePasswordDocument, const uno::Any& WritePasswordTemplate, const uno::Any& Format, const uno::Any& Encoding, const uno::Any& Visible, const uno::Any& OpenAndRepair, const uno::Any& DocumentDirection, const uno::Any& NoEncodingDialog, const uno::Any& XMLTransform )
+{
+ return Open( Filename, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog, XMLTransform );
+}
+
+uno::Any SAL_CALL
+SwVbaDocuments::OpenOld( const OUString& FileName, const uno::Any& ConfirmConversions, const uno::Any& ReadOnly, const uno::Any& AddToRecentFiles, const uno::Any& PasswordDocument, const uno::Any& PasswordTemplate, const uno::Any& Revert, const uno::Any& WritePasswordDocument, const uno::Any& WritePasswordTemplate, const uno::Any& Format )
+{
+ return Open( FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any() );
+}
+
+OUString
+SwVbaDocuments::getServiceImplName()
+{
+ return "SwVbaDocuments";
+}
+
+uno::Sequence<OUString>
+SwVbaDocuments::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Documents"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbadocuments.hxx b/sw/source/ui/vba/vbadocuments.hxx
new file mode 100644
index 0000000000..2b6261adba
--- /dev/null
+++ b/sw/source/ui/vba/vbadocuments.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTS_HXX
+
+#include <ooo/vba/word/XDocuments.hpp>
+#include <vbahelper/vbadocumentsbase.hxx>
+#include <cppuhelper/implbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaDocumentsBase, ov::word::XDocuments > SwVbaDocuments_BASE;
+
+class SwVbaDocuments : public SwVbaDocuments_BASE
+{
+public:
+ SwVbaDocuments( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaDocuments_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Template, const css::uno::Any& NewTemplate, const css::uno::Any& DocumentType, const css::uno::Any& Visible ) override;
+ virtual css::uno::Any SAL_CALL Open( const OUString& Filename, const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Format, const css::uno::Any& Encoding, const css::uno::Any& Visible, const css::uno::Any& OpenAndRepair, const css::uno::Any& DocumentDirection, const css::uno::Any& NoEncodingDialog, const css::uno::Any& XMLTransform ) override;
+ virtual css::uno::Any SAL_CALL OpenNoRepairDialog( const OUString& Filename, const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Format, const css::uno::Any& Encoding, const css::uno::Any& Visible, const css::uno::Any& OpenAndRepair, const css::uno::Any& DocumentDirection, const css::uno::Any& NoEncodingDialog, const css::uno::Any& XMLTransform ) override;
+ virtual css::uno::Any SAL_CALL OpenOld( const OUString& FileName, const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly, const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Format ) override;
+ virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& OriginalFormat, const css::uno::Any& RouteDocument ) override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBADOCUMENTS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaeventshelper.cxx b/sw/source/ui/vba/vbaeventshelper.cxx
new file mode 100644
index 0000000000..d928eaba16
--- /dev/null
+++ b/sw/source/ui/vba/vbaeventshelper.cxx
@@ -0,0 +1,94 @@
+/* -*- 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 "vbaeventshelper.hxx"
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <cppuhelper/supportsservice.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::script::vba::VBAEventId;
+
+SwVbaEventsHelper::SwVbaEventsHelper( uno::Sequence< css::uno::Any > const& aArgs, uno::Reference< uno::XComponentContext > const& /*xContext*/ ) :
+ VbaEventsHelperBase( aArgs )
+{
+ using namespace ::com::sun::star::script::ModuleType;
+ registerEventHandler( DOCUMENT_NEW, DOCUMENT, "Document_New" );
+ registerEventHandler( AUTO_NEW, NORMAL, "AutoNew" );
+ registerEventHandler( DOCUMENT_OPEN, DOCUMENT, "Document_Open" );
+ registerEventHandler( AUTO_OPEN, NORMAL, "AutoOpen" );
+ registerEventHandler( DOCUMENT_CLOSE, DOCUMENT, "Document_Close" );
+ registerEventHandler( AUTO_CLOSE, NORMAL, "AutoClose" );
+}
+
+SwVbaEventsHelper::~SwVbaEventsHelper()
+{
+}
+
+bool SwVbaEventsHelper::implPrepareEvent(EventQueue& /*rEventQueue*/,
+ const EventHandlerInfo& /*rInfo*/, const uno::Sequence<uno::Any>& /*rArgs*/)
+{
+ return true;
+}
+
+uno::Sequence< uno::Any > SwVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& /*rInfo*/,
+ const uno::Sequence< uno::Any >& /*rArgs*/ )
+{
+ // no event handler expects any arguments
+ return uno::Sequence< uno::Any >();
+}
+
+void SwVbaEventsHelper::implPostProcessEvent( EventQueue& /*rEventQueue*/,
+ const EventHandlerInfo& /*rInfo*/, bool /*bCancel*/ )
+{
+ // nothing to do after any event
+}
+
+OUString SwVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& /*rInfo*/,
+ const uno::Sequence< uno::Any >& /*rArgs*/ ) const
+{
+ // TODO: get actual codename from document
+ return "ThisDocument";
+}
+
+ // XServiceInfo
+OUString SwVbaEventsHelper::getImplementationName()
+{
+ return "SwVbaEventsHelper";
+}
+sal_Bool SwVbaEventsHelper::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+css::uno::Sequence< OUString > SwVbaEventsHelper::getSupportedServiceNames()
+{
+ return { "com.sun.star.script.vba.VBATextEventProcessor" };
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Writer_SwVbaEventsHelper_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new SwVbaEventsHelper(args, context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaeventshelper.hxx b/sw/source/ui/vba/vbaeventshelper.hxx
new file mode 100644
index 0000000000..31a6b2808e
--- /dev/null
+++ b/sw/source/ui/vba/vbaeventshelper.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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAEVENTSHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAEVENTSHELPER_HXX
+
+#include <vbahelper/vbaeventshelperbase.hxx>
+
+class SwVbaEventsHelper : public VbaEventsHelperBase
+{
+public:
+ SwVbaEventsHelper(
+ const css::uno::Sequence< css::uno::Any >& rArgs,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+ virtual ~SwVbaEventsHelper() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+protected:
+ virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) override;
+ virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) override;
+ virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bCancel ) override;
+ virtual OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbafield.cxx b/sw/source/ui/vba/vbafield.cxx
new file mode 100644
index 0000000000..ded84a6d8b
--- /dev/null
+++ b/sw/source/ui/vba/vbafield.cxx
@@ -0,0 +1,538 @@
+/* -*- 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 "vbafield.hxx"
+#include "vbarange.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
+#include <com/sun/star/text/FilenameDisplayFormat.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/util/XUpdatable.hpp>
+#include <ooo/vba/word/WdFieldType.hpp>
+#include <basic/sberrors.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <sal/log.hxx>
+#include <tools/long.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaField::SwVbaField( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< css::text::XTextField >& xTextField) : SwVbaField_BASE( rParent, rContext )
+{
+ mxTextField.set( xTextField, uno::UNO_SET_THROW );
+}
+
+sal_Bool SAL_CALL SwVbaField::Update()
+{
+ uno::Reference< util::XUpdatable > xUpdatable( mxTextField, uno::UNO_QUERY );
+ if( xUpdatable.is() )
+ {
+ xUpdatable->update();
+ return true;
+ }
+ return false;
+}
+
+// XHelperInterface
+OUString
+SwVbaField::getServiceImplName()
+{
+ return "SwVbaField";
+}
+
+uno::Sequence<OUString>
+SwVbaField::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Field"
+ };
+ return aServiceNames;
+}
+
+namespace {
+
+// FIXME? copy and paste code
+// the codes are copied from ww8par5.cxx
+class SwVbaReadFieldParams
+{
+private:
+ OUString m_aData;
+ sal_Int32 m_nLen, m_nFnd, m_nNext, m_nSavPtr;
+ OUString m_aFieldName;
+public:
+ explicit SwVbaReadFieldParams( const OUString& rData );
+
+ tools::Long SkipToNextToken();
+
+ sal_Int32 FindNextStringPiece( sal_Int32 _nStart );
+
+ OUString GetResult() const;
+ const OUString& GetFieldName()const { return m_aFieldName; }
+};
+
+}
+
+SwVbaReadFieldParams::SwVbaReadFieldParams( const OUString& _rData )
+ : m_aData( _rData ), m_nLen( _rData.getLength() ), m_nNext( 0 )
+{
+ // First search for an opening parenthesis or a space or a quotation mark
+ // or a backslash, so that the field command
+ // (thus INCLUDEPICTURE or ...) is ignored.
+ while( (m_nLen > m_nNext) && (m_aData[ m_nNext ] == ' ') )
+ ++m_nNext;
+
+ sal_Unicode c;
+ while( m_nLen > m_nNext
+ && (c = m_aData[ m_nNext ]) != ' '
+ && c != '"'
+ && c != '\\'
+ && c != 132
+ && c != 0x201c )
+ ++m_nNext;
+
+ m_nFnd = m_nNext;
+ m_nSavPtr = m_nNext;
+ m_aFieldName = m_aData.copy( 0, m_nFnd );
+}
+
+OUString SwVbaReadFieldParams::GetResult() const
+{
+ return (-1 == m_nFnd)
+ ? OUString()
+ : m_aData.copy( m_nFnd, (m_nSavPtr - m_nFnd) );
+}
+
+// ret: -2: NOT a '\' parameter but normal Text
+tools::Long SwVbaReadFieldParams::SkipToNextToken()
+{
+ tools::Long nRet = -1; // end
+ if (
+ (-1 != m_nNext) && (m_nLen > m_nNext) &&
+ -1 != (m_nFnd = FindNextStringPiece(m_nNext))
+ )
+ {
+ m_nSavPtr = m_nNext;
+
+ if ('\\' == m_aData[m_nFnd] && '\\' != m_aData[m_nFnd + 1])
+ {
+ nRet = m_aData[++m_nFnd];
+ m_nNext = ++m_nFnd; // and set behind
+ }
+ else
+ {
+ nRet = -2;
+ if (
+ (-1 != m_nSavPtr ) &&
+ (
+ ('"' == m_aData[m_nSavPtr - 1]) ||
+ (0x201d == m_aData[m_nSavPtr - 1])
+ )
+ )
+ {
+ --m_nSavPtr;
+ }
+ }
+ }
+ return nRet;
+}
+
+// FindNextPara is searching for the next Backslash-Parameter or the next string
+// until blank or the next "\" or until the closing quotation mark
+// or until the string end of pStr.
+
+// Output ppNext (if ppNext != 0) beginning of the search for the next parameter or 0
+
+// Return value: 0 if String-End reached, otherwise begin of the parameter or the string
+
+sal_Int32 SwVbaReadFieldParams::FindNextStringPiece(const sal_Int32 nStart)
+{
+ sal_Int32 n = ( -1 == nStart ) ? m_nFnd : nStart; // Start
+ sal_Int32 n2; // End
+
+ m_nNext = -1; // Default for not found
+
+ while( (m_nLen > n) && (m_aData[ n ] == ' ') )
+ ++n;
+
+ if( m_nLen == n )
+ return -1; // String End reached!
+
+ if( (m_aData[ n ] == '"') // quotation marks are in front of parenthesis?
+ || (m_aData[ n ] == 0x201c)
+ || (m_aData[ n ] == 132) )
+ {
+ n++; // ignore quotation marks
+ n2 = n; // From here search for the end
+ while( (m_nLen > n2)
+ && (m_aData[ n2 ] != '"')
+ && (m_aData[ n2 ] != 0x201d)
+ && (m_aData[ n2 ] != 147) )
+ n2++; // Search for the end of the parenthesis
+ }
+ else // no quotation marks
+ {
+ n2 = n; // from here search for the end
+ while( (m_nLen > n2) && (m_aData[ n2 ] != ' ') ) // Search for the end of the parenthesis
+ {
+ if( m_aData[ n2 ] == '\\' )
+ {
+ if( m_aData[ n2+1 ] == '\\' )
+ n2 += 2; // double-backslash -> OK
+ else
+ {
+ if( n2 > n )
+ n2--;
+ break; // single-backslash -> End
+ }
+ }
+ else
+ n2++; // no backslash -> OK
+ }
+ }
+ if( m_nLen > n2 )
+ {
+ if(m_aData[ n2 ] != ' ') n2++;
+ m_nNext = n2;
+ }
+ return n;
+}
+
+// SwVbaFields
+
+static uno::Any lcl_createField( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel, const uno::Any& aSource )
+{
+ uno::Reference< text::XTextField > xTextField( aSource, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextDocument > xTextDocument( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< word::XField > xField( new SwVbaField( xParent, xContext, xTextField ) );
+ return uno::Any( xField );
+}
+
+namespace {
+
+class FieldEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration >
+{
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+ uno::Reference< container::XEnumeration > mxEnumeration;
+public:
+ FieldEnumeration( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, uno::Reference< container::XEnumeration > xEnumeration ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )), mxEnumeration(std::move( xEnumeration ))
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return mxEnumeration->hasMoreElements();
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ return lcl_createField( mxParent, mxContext, mxModel, mxEnumeration->nextElement() );
+ }
+};
+
+class FieldCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+ uno::Reference< container::XEnumerationAccess > mxEnumerationAccess;
+public:
+ /// @throws css::uno::RuntimeException
+ FieldCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, const uno::Reference< frame::XModel >& xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel( xModel )
+ {
+ uno::Reference< text::XTextFieldsSupplier > xSupp( xModel, uno::UNO_QUERY_THROW );
+ mxEnumerationAccess.set( xSupp->getTextFields(), uno::UNO_SET_THROW );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return mxEnumerationAccess->getElementType(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return mxEnumerationAccess->hasElements(); }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
+ sal_Int32 nCount = 0;
+ while( xEnumeration->hasMoreElements() )
+ {
+ ++nCount;
+ xEnumeration->nextElement();
+ }
+ return nCount;
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
+ sal_Int32 nCount = 0;
+ while( xEnumeration->hasMoreElements() )
+ {
+ if( nCount == Index )
+ {
+ return xEnumeration->nextElement();
+ }
+ ++nCount;
+ }
+ throw lang::IndexOutOfBoundsException();
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ uno::Reference< container::XEnumeration > xEnumeration = mxEnumerationAccess->createEnumeration();
+ return uno::Reference< container::XEnumeration >( new FieldEnumeration( mxParent, mxContext, mxModel, xEnumeration ) );
+ }
+};
+
+}
+
+SwVbaFields::SwVbaFields( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaFields_BASE( xParent, xContext , uno::Reference< container::XIndexAccess >( new FieldCollectionHelper( xParent, xContext, xModel ) ) ), mxModel( xModel )
+{
+ mxMSF.set( mxModel, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< word::XField > SAL_CALL
+SwVbaFields::Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& Type, const css::uno::Any& Text, const css::uno::Any& /*PreserveFormatting*/ )
+{
+ sal_Int32 nType = word::WdFieldType::wdFieldEmpty;
+ Type >>= nType;
+ OUString sText;
+ Text >>= sText;
+
+ OUString sFieldName;
+ if( ( nType == word::WdFieldType::wdFieldEmpty ) && !sText.isEmpty() )
+ {
+ SwVbaReadFieldParams aReadParam(sText);
+ sFieldName = aReadParam.GetFieldName();
+ SAL_INFO("sw.vba", "the field name is " << sFieldName );
+ }
+
+ uno::Reference< text::XTextContent > xTextField;
+ if( nType == word::WdFieldType::wdFieldFileName || sFieldName.equalsIgnoreAsciiCase("FILENAME") )
+ {
+ xTextField.set( Create_Field_FileName( sText ), uno::UNO_QUERY_THROW );
+ }
+ else if( nType == word::WdFieldType::wdFieldDocProperty || sFieldName.equalsIgnoreAsciiCase("DOCPROPERTY") )
+ {
+ xTextField.set( Create_Field_DocProperty( sText ), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+
+ SwVbaRange& rVbaRange = dynamic_cast<SwVbaRange&>(*Range);
+ uno::Reference< text::XTextRange > xTextRange = rVbaRange.getXTextRange();
+ uno::Reference< text::XText > xText = xTextRange->getText();
+ xText->insertTextContent( xTextRange, xTextField, true );
+ return uno::Reference< word::XField >( new SwVbaField( mxParent, mxContext, uno::Reference< text::XTextField >( xTextField, uno::UNO_QUERY_THROW ) ) );
+}
+
+uno::Reference< text::XTextField > SwVbaFields::Create_Field_FileName( const OUString& _text )
+{
+ uno::Reference< text::XTextField > xTextField( mxMSF->createInstance("com.sun.star.text.TextField.FileName"), uno::UNO_QUERY_THROW );
+ sal_Int16 nFileFormat = text::FilenameDisplayFormat::NAME_AND_EXT;
+ if( !_text.isEmpty() )
+ {
+ tools::Long nRet;
+ SwVbaReadFieldParams aReadParam( _text );
+ while (-1 != (nRet = aReadParam.SkipToNextToken()))
+ {
+ switch (nRet)
+ {
+ case 'p':
+ nFileFormat = text::FilenameDisplayFormat::FULL;
+ break;
+ case '*':
+ //Skip over MERGEFORMAT
+ aReadParam.SkipToNextToken();
+ break;
+ default:
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ break;
+ }
+ }
+ }
+
+ uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW );
+ xProps->setPropertyValue("FileFormat", uno::Any( nFileFormat ) );
+
+ return xTextField;
+}
+
+namespace {
+
+struct DocPropertyTable
+{
+ const char* sDocPropertyName;
+ const char* sFieldService;
+};
+
+}
+
+const DocPropertyTable aDocPropertyTables[] =
+{
+ { "Author", "com.sun.star.text.textfield.docinfo.CreateAuthor" },
+ { "Bytes", nullptr },
+ { "Category", nullptr },
+ { "Characters",nullptr },
+ { "CharactersWithSpaces", nullptr },
+ { "Comments", "com.sun.star.text.textfield.docinfo.Description" },
+ { "Company", nullptr },
+ { "CreateTime", "com.sun.star.text.textfield.docinfo.CreateDateTime" },
+ { "HyperlinkBase", nullptr },
+ { "Keywords", "com.sun.star.text.textfield.docinfo.Keywords" },
+ { "LastPrinted", "com.sun.star.text.textfield.docinfo.PrintDateTime" },
+ { "LastSavedBy", "com.sun.star.text.textfield.docinfo.ChangeAuthor" },
+ { "LastSavedTime", "com.sun.star.text.textfield.docinfo.ChangeDateTime" },
+ { "Lines", nullptr },
+ { "Manager", nullptr },
+ { "NameofApplication", nullptr },
+ { "ODMADocID", nullptr },
+ { "Pages", "com.sun.star.text.textfield.PageCount" },
+ { "Paragraphs", "com.sun.star.text.textfield.ParagraphCount" },
+ { "RevisionNumber", "com.sun.star.text.textfield.docinfo.Revision" },
+ { "Security", nullptr },
+ { "Subject", "com.sun.star.text.textfield.docinfo.Subject" },
+ { "Template", "com.sun.star.text.textfield.TemplateName" },
+ { "Title", "com.sun.star.text.textfield.docinfo.Title" },
+ { "TotalEditingTime", "com.sun.star.text.textfield.docinfo.EditTime" },
+ { "Words", "com.sun.star.text.textfield.WordCount" },
+ { nullptr, nullptr }
+};
+
+uno::Reference< text::XTextField > SwVbaFields::Create_Field_DocProperty( const OUString& _text )
+{
+ OUString aDocProperty;
+ SwVbaReadFieldParams aReadParam( _text );
+ tools::Long nRet;
+ while( -1 != ( nRet = aReadParam.SkipToNextToken() ))
+ {
+ switch( nRet )
+ {
+ case -2:
+ if( aDocProperty.isEmpty() )
+ aDocProperty = aReadParam.GetResult();
+ break;
+ case '*':
+ //Skip over MERGEFORMAT
+ aReadParam.SkipToNextToken();
+ break;
+ }
+ }
+ aDocProperty = aDocProperty.replaceAll("\"", "");
+ SAL_INFO("sw.vba", "SwVbaFields::Create_Field_DocProperty, the document property name is " << aDocProperty );
+ if( aDocProperty.isEmpty() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ bool bCustom = true;
+ OUString sFieldService;
+ // find the build in document properties
+ for( const DocPropertyTable* pTable = aDocPropertyTables; pTable->sDocPropertyName != nullptr; pTable++ )
+ {
+ if( aDocProperty.equalsIgnoreAsciiCaseAscii( pTable->sDocPropertyName ) )
+ {
+ if( pTable->sFieldService != nullptr )
+ sFieldService = OUString::createFromAscii(pTable->sFieldService);
+ bCustom = false;
+ break;
+ }
+ }
+
+ if( bCustom )
+ {
+ sFieldService = "com.sun.star.text.textfield.docinfo.Custom";
+ }
+ else if( sFieldService.isEmpty() )
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+
+ uno::Reference< text::XTextField > xTextField( mxMSF->createInstance( sFieldService ), uno::UNO_QUERY_THROW );
+
+ if( bCustom )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xTextField, uno::UNO_QUERY_THROW );
+ xProps->setPropertyValue("Name", uno::Any( aDocProperty ) );
+ }
+
+ return xTextField;
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwVbaFields::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xEnumerationAccess->createEnumeration();
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any
+SwVbaFields::createCollectionObject( const uno::Any& aSource )
+{
+ return lcl_createField( mxParent, mxContext, mxModel, aSource );
+}
+
+sal_Int32 SAL_CALL SwVbaFields::Update()
+{
+ sal_Int32 nUpdate = 1;
+ try
+ {
+ uno::Reference< text::XTextFieldsSupplier > xSupp( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< util::XRefreshable > xRef( xSupp->getTextFields(), uno::UNO_QUERY_THROW );
+ xRef->refresh();
+ nUpdate = 0;
+ }
+ catch(const uno::Exception&)
+ {
+ nUpdate = 1;
+ }
+ return nUpdate;
+}
+
+// XHelperInterface
+OUString
+SwVbaFields::getServiceImplName()
+{
+ return "SwVbaFields";
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+SwVbaFields::getElementType()
+{
+ return cppu::UnoType<word::XField>::get();
+}
+
+uno::Sequence<OUString>
+SwVbaFields::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Fields"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbafield.hxx b/sw/source/ui/vba/vbafield.hxx
new file mode 100644
index 0000000000..292be2edb7
--- /dev/null
+++ b/sw/source/ui/vba/vbafield.hxx
@@ -0,0 +1,74 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFIELD_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAFIELD_HXX
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <ooo/vba/word/XField.hpp>
+#include <ooo/vba/word/XFields.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XField > SwVbaField_BASE;
+
+class SwVbaField : public SwVbaField_BASE
+{
+ css::uno::Reference< css::text::XTextField > mxTextField;
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaField( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< css::text::XTextField >& xTextField);
+
+ virtual sal_Bool SAL_CALL Update() override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+typedef CollTestImplHelper< ov::word::XFields > SwVbaFields_BASE;
+
+class SwVbaFields : public SwVbaFields_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF;
+private:
+ /// @throws css::uno::RuntimeException
+ /// @throws css::script::BasicErrorException
+ css::uno::Reference< css::text::XTextField > Create_Field_FileName(const OUString& rText);
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XTextField > Create_Field_DocProperty( const OUString& _text );
+
+public:
+ SwVbaFields( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+ // XFields
+ virtual css::uno::Reference< ::ooo::vba::word::XField > SAL_CALL Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& Type, const css::uno::Any& Text, const css::uno::Any& PreserveFormatting ) override;
+ virtual sal_Int32 SAL_CALL Update() override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbafilterpropsfromformat.hxx b/sw/source/ui/vba/vbafilterpropsfromformat.hxx
new file mode 100644
index 0000000000..cde1da0b4d
--- /dev/null
+++ b/sw/source/ui/vba/vbafilterpropsfromformat.hxx
@@ -0,0 +1,75 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFILTERPROPSFROMFORMAT_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAFILTERPROPSFROMFORMAT_HXX
+
+#include <sal/config.h>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <rtl/ustring.hxx>
+#include <ooo/vba/word/WdSaveFormat.hpp>
+
+namespace
+{
+inline bool setFilterPropsFromFormat(sal_Int32 nFormat,
+ css::uno::Sequence<css::beans::PropertyValue>& rProps)
+{
+ auto[begin, end] = asNonConstRange(rProps);
+ auto pProp = std::find_if(begin, end, [](const css::beans::PropertyValue& rProp) {
+ return rProp.Name == "FilterName";
+ });
+ if (pProp != end)
+ {
+ switch (nFormat)
+ {
+ case ooo::vba::word::WdSaveFormat::wdFormatDocument:
+ pProp->Value <<= OUString("MS Word 97");
+ break;
+ // Just save all the text formats as "Text"
+ case ooo::vba::word::WdSaveFormat::wdFormatDOSText:
+ case ooo::vba::word::WdSaveFormat::wdFormatDOSTextLineBreaks:
+ case ooo::vba::word::WdSaveFormat::wdFormatEncodedText:
+ case ooo::vba::word::WdSaveFormat::wdFormatText:
+ case ooo::vba::word::WdSaveFormat::wdFormatTextLineBreaks:
+ pProp->Value <<= OUString("Text");
+ break;
+ case ooo::vba::word::WdSaveFormat::wdFormatFilteredHTML:
+ case ooo::vba::word::WdSaveFormat::wdFormatHTML:
+ pProp->Value <<= OUString("HTML");
+ break;
+ case ooo::vba::word::WdSaveFormat::wdFormatRTF:
+ pProp->Value <<= OUString("Rich Text Format");
+ break;
+ case ooo::vba::word::WdSaveFormat::wdFormatTemplate:
+ pProp->Value <<= OUString("MS Word 97 Vorlage");
+ break;
+
+ // Default to "MS Word 97"
+ default:
+ pProp->Value <<= OUString("MS Word 97");
+ break;
+ }
+ return true;
+ }
+ return false;
+}
+}
+
+#endif
diff --git a/sw/source/ui/vba/vbafind.cxx b/sw/source/ui/vba/vbafind.cxx
new file mode 100644
index 0000000000..892e062f3c
--- /dev/null
+++ b/sw/source/ui/vba/vbafind.cxx
@@ -0,0 +1,431 @@
+/* -*- 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 "vbafind.hxx"
+#include "vbareplacement.hxx"
+#include <ooo/vba/word/WdFindWrap.hpp>
+#include <ooo/vba/word/WdReplace.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <doc.hxx>
+#include <docsh.hxx>
+#include "wordvbahelper.hxx"
+#include <rtl/ref.hxx>
+#include <sal/log.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaFind::SwVbaFind( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel ) :
+ SwVbaFind_BASE( rParent, rContext ), mxModel( std::move(xModel) ), mbReplace( false ), mnReplaceType( word::WdReplace::wdReplaceOne ), mnWrap( word::WdFindWrap::wdFindStop )
+{
+ mxReplaceable.set( mxModel, uno::UNO_QUERY_THROW );
+ mxPropertyReplace.set( mxReplaceable->createReplaceDescriptor(), uno::UNO_QUERY_THROW );
+ mxTVC = word::getXTextViewCursor( mxModel );
+ mxSelSupp.set( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
+}
+
+SwVbaFind::~SwVbaFind()
+{
+}
+
+uno::Reference< word::XFind > SwVbaFind::GetOrCreateFind(const uno::Reference< ooo::vba::XHelperInterface >& rParent,
+ const uno::Reference< uno::XComponentContext >& rContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< text::XTextRange >& xTextRange)
+{
+ rtl::Reference< SwVbaFind > xFind;
+ SwDoc* pDoc = word::getDocShell( xModel )->GetDoc();
+ if( pDoc )
+ xFind = dynamic_cast<SwVbaFind *>( pDoc->getVbaFind().get() );
+ if ( !xFind )
+ {
+ xFind = new SwVbaFind( rParent, rContext, xModel );
+ if ( pDoc )
+ pDoc->setVbaFind( xFind );
+ }
+ xFind->mxTextRange = xTextRange;
+
+ return xFind;
+}
+
+
+bool SwVbaFind::InRange( const uno::Reference< text::XTextRange >& xCurrentRange )
+{
+ uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW );
+ return xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) >= 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) <= 0;
+}
+
+bool SwVbaFind::InEqualRange( const uno::Reference< text::XTextRange >& xCurrentRange )
+{
+ uno::Reference< text::XTextRangeCompare > xTRC( mxTextRange->getText(), uno::UNO_QUERY_THROW );
+ return xTRC->compareRegionStarts( mxTextRange, xCurrentRange ) == 0 && xTRC->compareRegionEnds( mxTextRange, xCurrentRange ) == 0;
+}
+
+void SwVbaFind::SetReplaceWith( const OUString& rText )
+{
+ mxPropertyReplace->setReplaceString( rText );
+ mbReplace = true;
+}
+
+OUString SwVbaFind::GetReplaceWith()
+{
+ return mxPropertyReplace->getReplaceString();
+}
+void SwVbaFind::SetReplace( sal_Int32 type )
+{
+ mnReplaceType = type;
+ mbReplace = true;
+}
+uno::Reference< text::XTextRange > SwVbaFind::FindOneElement()
+{
+ uno::Reference< text::XTextRange > xFoundOne;
+ if( !mxTVC->getString().isEmpty() )
+ {
+ if( getForward() )
+ {
+ xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
+ }
+ else
+ {
+ xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
+ }
+
+ if( xFoundOne.is() && InEqualRange( xFoundOne ) )
+ {
+ xFoundOne.set( mxReplaceable->findNext( xFoundOne, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
+ }
+ else if( xFoundOne.is() && !InRange( xFoundOne ) )
+ {
+ xFoundOne.clear();
+ }
+ }
+ else
+ {
+ xFoundOne.set( mxReplaceable->findNext( mxTextRange, uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
+ }
+
+ if( !xFoundOne.is() && ( getWrap() == word::WdFindWrap::wdFindContinue || getWrap() == word::WdFindWrap::wdFindAsk ) )
+ {
+ if( getForward() )
+ {
+ mxTVC->gotoStart(false);
+ xFoundOne.set( mxReplaceable->findNext( mxTextRange->getStart(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
+ }
+ else
+ {
+ mxTVC->gotoEnd( false );
+ xFoundOne.set( mxReplaceable->findNext( mxTextRange->getEnd(), uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) ), uno::UNO_QUERY );
+
+ }
+ }
+ return xFoundOne;
+}
+
+bool SwVbaFind::SearchReplace()
+{
+ bool result = false;
+
+ // TODO: map wildcards in area to OOo wildcards
+
+ if( mbReplace )
+ {
+ switch( mnReplaceType )
+ {
+ case word::WdReplace::wdReplaceNone:
+ {
+ result = true;
+ break;
+ }
+ case word::WdReplace::wdReplaceOne:
+ {
+ uno::Reference< text::XTextRange > xFindOne = FindOneElement();
+ if( xFindOne.is() )
+ {
+ xFindOne->setString( GetReplaceWith() );
+ result = mxSelSupp->select( uno::Any( xFindOne ) );
+ }
+ break;
+ }
+ case word::WdReplace::wdReplaceAll:
+ {
+ uno::Reference< container::XIndexAccess > xIndexAccess = mxReplaceable->findAll( uno::Reference< util::XSearchDescriptor >( mxPropertyReplace, uno::UNO_QUERY_THROW ) );
+ if( xIndexAccess->getCount() > 0 )
+ {
+ for( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ )
+ {
+ uno::Reference< text::XTextRange > xTextRange( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW );
+ if( mnWrap == word::WdFindWrap::wdFindContinue || mnWrap == word::WdFindWrap::wdFindAsk || InRange( xTextRange ) )
+ {
+ xTextRange->setString( GetReplaceWith() );
+ result = true;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ result = false;
+ }
+ }
+ }
+ else
+ {
+ uno::Reference< text::XTextRange > xFindOne = FindOneElement();
+ if( xFindOne.is() )
+ result = mxSelSupp->select( uno::Any( xFindOne ) );
+ }
+
+ return result;
+}
+
+OUString SAL_CALL SwVbaFind::getText()
+{
+ return mxPropertyReplace->getSearchString();
+}
+
+void SAL_CALL SwVbaFind::setText( const OUString& _text )
+{
+ mxPropertyReplace->setSearchString( _text );
+}
+
+uno::Any SAL_CALL SwVbaFind::getReplacement()
+{
+ return uno::Any( uno::Reference< word::XReplacement >( new SwVbaReplacement( this, mxContext, mxPropertyReplace ) ) );
+}
+
+void SAL_CALL SwVbaFind::setReplacement( const uno::Any& /*_replacement */ )
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+sal_Bool SAL_CALL SwVbaFind::getForward()
+{
+ bool bBackward = false;
+ mxPropertyReplace->getPropertyValue("SearchBackwards") >>= bBackward;
+ return !bBackward;
+}
+
+void SAL_CALL SwVbaFind::setForward( sal_Bool _forward )
+{
+ bool bBackward = !_forward;
+ mxPropertyReplace->setPropertyValue("SearchBackwards", uno::Any( bBackward ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaFind::getWrap()
+{
+ // seems not supported in Writer
+ return mnWrap;
+}
+
+void SAL_CALL SwVbaFind::setWrap( ::sal_Int32 _wrap )
+{
+ // seems not supported in Writer
+ mnWrap = _wrap;
+}
+
+sal_Bool SAL_CALL SwVbaFind::getFormat()
+{
+ return mxPropertyReplace->getValueSearch();
+}
+
+void SAL_CALL SwVbaFind::setFormat( sal_Bool _format )
+{
+ mxPropertyReplace->setValueSearch( _format );
+}
+
+sal_Bool SAL_CALL SwVbaFind::getMatchCase()
+{
+ bool value = false;
+ mxPropertyReplace->getPropertyValue("SearchCaseSensitive") >>= value;
+ return value;
+}
+
+void SAL_CALL SwVbaFind::setMatchCase( sal_Bool _matchcase )
+{
+ mxPropertyReplace->setPropertyValue("SearchCaseSensitive", uno::Any( _matchcase ) );
+}
+
+sal_Bool SAL_CALL SwVbaFind::getMatchWholeWord()
+{
+ bool value = false;
+ mxPropertyReplace->getPropertyValue("SearchWords") >>= value;
+ return value;
+}
+
+void SAL_CALL SwVbaFind::setMatchWholeWord( sal_Bool _matchwholeword )
+{
+ mxPropertyReplace->setPropertyValue("SearchWords", uno::Any( _matchwholeword ) );
+}
+
+sal_Bool SAL_CALL SwVbaFind::getMatchWildcards()
+{
+ bool value = false;
+ mxPropertyReplace->getPropertyValue("SearchRegularExpression") >>= value;
+ return value;
+}
+
+void SAL_CALL SwVbaFind::setMatchWildcards( sal_Bool _matchwildcards )
+{
+ mxPropertyReplace->setPropertyValue("SearchRegularExpression", uno::Any( _matchwildcards ) );
+}
+
+sal_Bool SAL_CALL SwVbaFind::getMatchSoundsLike()
+{
+ bool value = false;
+ mxPropertyReplace->getPropertyValue("SearchSimilarity") >>= value;
+ return value;
+}
+
+void SAL_CALL SwVbaFind::setMatchSoundsLike( sal_Bool _matchsoundslike )
+{
+ // seems not accurate
+ mxPropertyReplace->setPropertyValue("SearchSimilarity", uno::Any( _matchsoundslike ) );
+}
+
+sal_Bool SAL_CALL SwVbaFind::getMatchAllWordForms()
+{
+ bool value = false;
+ mxPropertyReplace->getPropertyValue("SearchSimilarity") >>= value;
+ if( value )
+ mxPropertyReplace->getPropertyValue("SearchSimilarityRelax") >>= value;
+ return value;
+}
+
+void SAL_CALL SwVbaFind::setMatchAllWordForms( sal_Bool _matchallwordforms )
+{
+ // seems not accurate
+ mxPropertyReplace->setPropertyValue("SearchSimilarity", uno::Any( _matchallwordforms ) );
+ mxPropertyReplace->setPropertyValue("SearchSimilarityRelax", uno::Any( _matchallwordforms ) );
+}
+
+uno::Any SAL_CALL SwVbaFind::getStyle()
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+void SAL_CALL SwVbaFind::setStyle( const uno::Any& /*_style */ )
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+sal_Bool SAL_CALL
+SwVbaFind::Execute( const uno::Any& FindText, const uno::Any& MatchCase, const uno::Any& MatchWholeWord, const uno::Any& MatchWildcards, const uno::Any& MatchSoundsLike, const uno::Any& MatchAllWordForms, const uno::Any& Forward, const uno::Any& Wrap, const uno::Any& Format, const uno::Any& ReplaceWith, const uno::Any& Replace, const uno::Any& /*MatchKashida*/, const uno::Any& /*MatchDiacritics*/, const uno::Any& /*MatchAlefHamza*/, const uno::Any& /*MatchControl*/, const uno::Any& /*MatchPrefix*/, const uno::Any& /*MatchSuffix*/, const uno::Any& /*MatchPhrase*/, const uno::Any& /*IgnoreSpace*/, const uno::Any& /*IgnorePunct*/ )
+{
+ bool result = false;
+ if( FindText.hasValue() )
+ {
+ OUString sText;
+ FindText >>= sText;
+ setText( sText );
+ }
+
+ bool bValue = false;
+ if( MatchCase.hasValue() )
+ {
+ MatchCase >>= bValue;
+ setMatchCase( bValue );
+ }
+
+ if( MatchWholeWord.hasValue() )
+ {
+ MatchWholeWord >>= bValue;
+ setMatchWholeWord( bValue );
+ }
+
+ if( MatchWildcards.hasValue() )
+ {
+ MatchWildcards >>= bValue;
+ setMatchWildcards( bValue );
+ }
+
+ if( MatchSoundsLike.hasValue() )
+ {
+ MatchSoundsLike >>= bValue;
+ setMatchSoundsLike( bValue );
+ }
+
+ if( MatchAllWordForms.hasValue() )
+ {
+ MatchAllWordForms >>= bValue;
+ setMatchAllWordForms( bValue );
+ }
+
+ if( Forward.hasValue() )
+ {
+ Forward >>= bValue;
+ setForward( bValue );
+ }
+
+ if( Wrap.hasValue() )
+ {
+ sal_Int32 nWrapType = 0;
+ Wrap >>= nWrapType;
+ setWrap( nWrapType );
+ }
+
+ if( Format.hasValue() )
+ {
+ Format >>= bValue;
+ setFormat( bValue );
+ }
+
+ if( ReplaceWith.hasValue() )
+ {
+ OUString sValue;
+ ReplaceWith >>= sValue;
+ SetReplaceWith( sValue );
+ }
+
+ if( Replace.hasValue() )
+ {
+ sal_Int32 nValue(0);
+ Replace >>= nValue;
+ SetReplace( nValue );
+ }
+
+ result = SearchReplace();
+
+ return result;
+}
+
+void SAL_CALL
+SwVbaFind::ClearFormatting( )
+{
+ uno::Sequence< beans::PropertyValue > aSearchAttribs;
+ mxPropertyReplace->setSearchAttributes( aSearchAttribs );
+}
+
+OUString
+SwVbaFind::getServiceImplName()
+{
+ return "SwVbaFind";
+}
+
+uno::Sequence< OUString >
+SwVbaFind::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Find"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbafind.hxx b/sw/source/ui/vba/vbafind.hxx
new file mode 100644
index 0000000000..110a084bd2
--- /dev/null
+++ b/sw/source/ui/vba/vbafind.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFIND_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAFIND_HXX
+
+#include <ooo/vba/word/XFind.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/util/XReplaceable.hpp>
+#include <com/sun/star/util/XPropertyReplace.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XFind > SwVbaFind_BASE;
+
+class SwVbaFind : public SwVbaFind_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::text::XTextRange > mxTextRange;
+ css::uno::Reference< css::util::XReplaceable > mxReplaceable;
+ css::uno::Reference< css::util::XPropertyReplace> mxPropertyReplace;
+ css::uno::Reference< css::text::XTextViewCursor> mxTVC;
+ css::uno::Reference< css::view::XSelectionSupplier> mxSelSupp;
+ bool mbReplace;
+ sal_Int32 mnReplaceType;
+ sal_Int32 mnWrap;
+
+private:
+ /// @throws css::uno::RuntimeException
+ bool InRange( const css::uno::Reference< css::text::XTextRange >& xCurrentRange );
+ /// @throws css::uno::RuntimeException
+ bool InEqualRange( const css::uno::Reference< css::text::XTextRange >& xCurrentRange );
+ void SetReplace( sal_Int32 type );
+ /// @throws css::uno::RuntimeException
+ void SetReplaceWith( const OUString& rText );
+ /// @throws css::uno::RuntimeException
+ OUString GetReplaceWith();
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XTextRange > FindOneElement();
+ /// @throws css::uno::RuntimeException
+ bool SearchReplace();
+
+ /// @throws css::uno::RuntimeException
+ SwVbaFind( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel );
+public:
+ static css::uno::Reference< ooo::vba::word::XFind > GetOrCreateFind(const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< com::sun::star::uno::XComponentContext >& rContext, const css::uno::Reference< com::sun::star::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextRange >& xTextRange);
+ virtual ~SwVbaFind() override;
+
+ // Attributes
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& _text ) override;
+ virtual css::uno::Any SAL_CALL getReplacement() override;
+ virtual void SAL_CALL setReplacement( const css::uno::Any& _replacement ) override;
+ virtual sal_Bool SAL_CALL getForward() override;
+ virtual void SAL_CALL setForward( sal_Bool _forward ) override;
+ virtual ::sal_Int32 SAL_CALL getWrap() override;
+ virtual void SAL_CALL setWrap( ::sal_Int32 _wrap ) override;
+ virtual sal_Bool SAL_CALL getFormat() override;
+ virtual void SAL_CALL setFormat( sal_Bool _format ) override;
+ virtual sal_Bool SAL_CALL getMatchCase() override;
+ virtual void SAL_CALL setMatchCase( sal_Bool _matchcase ) override;
+ virtual sal_Bool SAL_CALL getMatchWholeWord() override;
+ virtual void SAL_CALL setMatchWholeWord( sal_Bool _matchwholeword ) override;
+ virtual sal_Bool SAL_CALL getMatchWildcards() override;
+ virtual void SAL_CALL setMatchWildcards( sal_Bool _matchwildcards ) override;
+ virtual sal_Bool SAL_CALL getMatchSoundsLike() override;
+ virtual void SAL_CALL setMatchSoundsLike( sal_Bool _matchsoundslike ) override;
+ virtual sal_Bool SAL_CALL getMatchAllWordForms() override;
+ virtual void SAL_CALL setMatchAllWordForms( sal_Bool _matchallwordforms ) override;
+ virtual css::uno::Any SAL_CALL getStyle() override;
+ virtual void SAL_CALL setStyle( const css::uno::Any& _style ) override;
+
+ // Methods
+ virtual sal_Bool SAL_CALL Execute( const css::uno::Any& FindText, const css::uno::Any& MatchCase, const css::uno::Any& MatchWholeWord, const css::uno::Any& MatchWildcards, const css::uno::Any& MatchSoundsLike, const css::uno::Any& MatchAllWordForms, const css::uno::Any& Forward, const css::uno::Any& Wrap, const css::uno::Any& Format, const css::uno::Any& ReplaceWith, const css::uno::Any& Replace, const css::uno::Any& MatchKashida, const css::uno::Any& MatchDiacritics, const css::uno::Any& MatchAlefHamza, const css::uno::Any& MatchControl, const css::uno::Any& MatchPrefix, const css::uno::Any& MatchSuffix, const css::uno::Any& MatchPhrase, const css::uno::Any& IgnoreSpace, const css::uno::Any& IgnorePunct ) override;
+ virtual void SAL_CALL ClearFormatting( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFIND_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbafont.cxx b/sw/source/ui/vba/vbafont.cxx
new file mode 100644
index 0000000000..91a31ec664
--- /dev/null
+++ b/sw/source/ui/vba/vbafont.cxx
@@ -0,0 +1,235 @@
+/* -*- 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 "vbafont.hxx"
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <ooo/vba/word/WdUnderline.hpp>
+#include <sal/macros.h>
+#include <unordered_map>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const uno::Any aLongAnyTrue( sal_Int16(-1) );
+const uno::Any aLongAnyFalse( sal_Int16( 0 ) );
+
+namespace {
+
+struct MapPair
+{
+ sal_Int32 nMSOConst;
+ sal_Int32 nOOOConst;
+};
+
+}
+
+MapPair const UnderLineTable[] = {
+ { word::WdUnderline::wdUnderlineNone, css::awt::FontUnderline::NONE },
+ { word::WdUnderline::wdUnderlineSingle, css::awt::FontUnderline::SINGLE },
+ { word::WdUnderline::wdUnderlineWords, css::awt::FontUnderline::SINGLE },
+ { word::WdUnderline::wdUnderlineDouble, css::awt::FontUnderline::DOUBLE },
+ { word::WdUnderline::wdUnderlineDotted, css::awt::FontUnderline::DOTTED },
+ { word::WdUnderline::wdUnderlineThick, css::awt::FontUnderline::BOLDDASH },
+ { word::WdUnderline::wdUnderlineDash, css::awt::FontUnderline::DASH },
+ { word::WdUnderline::wdUnderlineDotDash, css::awt::FontUnderline::DASHDOT },
+ { word::WdUnderline::wdUnderlineDotDotDash, css::awt::FontUnderline::DASHDOTDOT },
+ { word::WdUnderline::wdUnderlineWavy, css::awt::FontUnderline::WAVE },
+ { word::WdUnderline::wdUnderlineDottedHeavy, css::awt::FontUnderline::BOLDDOTTED },
+ { word::WdUnderline::wdUnderlineDashHeavy, css::awt::FontUnderline::BOLDDASH },
+ { word::WdUnderline::wdUnderlineDotDashHeavy, css::awt::FontUnderline::BOLDDASHDOT },
+ { word::WdUnderline::wdUnderlineDotDotDashHeavy, css::awt::FontUnderline::BOLDDASHDOTDOT },
+ { word::WdUnderline::wdUnderlineWavyHeavy, css::awt::FontUnderline::BOLDWAVE },
+ { word::WdUnderline::wdUnderlineDashLong, css::awt::FontUnderline::LONGDASH },
+ { word::WdUnderline::wdUnderlineWavyDouble, css::awt::FontUnderline::DOUBLEWAVE },
+ { word::WdUnderline::wdUnderlineDashLongHeavy, css::awt::FontUnderline::BOLDLONGDASH },
+};
+
+typedef std::unordered_map< sal_Int32, sal_Int32 > ConstToConst;
+
+namespace {
+
+class UnderLineMapper
+{
+ ConstToConst m_MSO2OOO;
+ ConstToConst m_OOO2MSO;
+private:
+ UnderLineMapper()
+ {
+ for ( auto const & index: UnderLineTable )
+ {
+ m_MSO2OOO[ index.nMSOConst ] = index.nOOOConst;
+ m_OOO2MSO[ index.nOOOConst ] = index.nMSOConst;
+ }
+ }
+public:
+ static OUString propName()
+ {
+ return "CharUnderline";
+ }
+
+ static UnderLineMapper& instance()
+ {
+ static UnderLineMapper theMapper;
+ return theMapper;
+ }
+
+ /// @throws lang::IllegalArgumentException
+ sal_Int32 getOOOFromMSO( sal_Int32 nMSOConst )
+ {
+ ConstToConst::iterator it = m_MSO2OOO.find( nMSOConst );
+ if ( it == m_MSO2OOO.end() )
+ throw lang::IllegalArgumentException();
+ return it->second;
+ }
+ /// @throws lang::IllegalArgumentException
+ sal_Int32 getMSOFromOOO( sal_Int32 nOOOConst )
+ {
+ ConstToConst::iterator it = m_OOO2MSO.find( nOOOConst );
+ if ( it == m_OOO2MSO.end() )
+ throw lang::IllegalArgumentException();
+ return it->second;
+ }
+};
+
+}
+
+SwVbaFont::SwVbaFont( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xPalette, uno::Reference< css::beans::XPropertySet > const & xPropertySet )
+ : SwVbaFont_BASE( xParent, xContext, xPalette, xPropertySet, Component::WORD )
+{
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getUnderline()
+{
+ sal_Int32 nOOVal = 0;
+ mxFont->getPropertyValue( UnderLineMapper::propName() ) >>= nOOVal;
+ return uno::Any( UnderLineMapper::instance().getMSOFromOOO( nOOVal ) );
+}
+
+void SAL_CALL
+SwVbaFont::setUnderline( const uno::Any& _underline )
+{
+ sal_Int32 nMSOVal = 0;
+
+ if ( _underline >>= nMSOVal )
+ {
+ sal_Int32 nOOVal = UnderLineMapper::instance().getOOOFromMSO( nMSOVal );
+ mxFont->setPropertyValue( UnderLineMapper::propName(), uno::Any( nOOVal ) );
+ }
+}
+
+OUString
+SwVbaFont::getServiceImplName()
+{
+ return "SwVbaFont";
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getColorIndex()
+{
+ sal_Int32 nColor = 0;
+
+ getColor() >>= nColor;
+ sal_Int32 nElems = mxPalette->getCount();
+ sal_Int32 nIndex = 0;
+ for ( sal_Int32 count=0; count<nElems; ++count )
+ {
+ sal_Int32 nPaletteColor = 0;
+ mxPalette->getByIndex( count ) >>= nPaletteColor;
+ if ( nPaletteColor == nColor )
+ {
+ nIndex = count;
+ break;
+ }
+ }
+ return uno::Any( nIndex );
+}
+uno::Any SAL_CALL
+SwVbaFont::getSubscript()
+{
+ bool bRes = false;
+ SwVbaFont_BASE::getSubscript() >>= bRes;
+ if ( bRes )
+ return aLongAnyTrue;
+ return aLongAnyFalse;
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getSuperscript()
+{
+ bool bRes = false;
+ SwVbaFont_BASE::getSuperscript() >>= bRes;
+ if ( bRes )
+ return aLongAnyTrue;
+ return aLongAnyFalse;
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getBold()
+{
+ bool bRes = false;
+ SwVbaFont_BASE::getBold() >>= bRes;
+ if ( bRes )
+ return aLongAnyTrue;
+ return aLongAnyFalse;
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getItalic()
+{
+ bool bRes = false;
+ SwVbaFont_BASE::getItalic() >>= bRes;
+ if ( bRes )
+ return aLongAnyTrue;
+ return aLongAnyFalse;
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getStrikethrough()
+{
+ bool bRes = false;
+ SwVbaFont_BASE::getStrikethrough() >>= bRes;
+ if ( bRes )
+ return aLongAnyTrue;
+ return aLongAnyFalse;
+}
+
+uno::Any SAL_CALL
+SwVbaFont::getShadow()
+{
+ bool bRes = false;
+ SwVbaFont_BASE::getShadow() >>= bRes;
+ if ( bRes )
+ return aLongAnyTrue;
+ return aLongAnyFalse;
+}
+
+uno::Sequence< OUString >
+SwVbaFont::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Font"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbafont.hxx b/sw/source/ui/vba/vbafont.hxx
new file mode 100644
index 0000000000..61bfc0f526
--- /dev/null
+++ b/sw/source/ui/vba/vbafont.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 <vbahelper/vbafontbase.hxx>
+#include <ooo/vba/word/XFont.hpp>
+#include <cppuhelper/implbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaFontBase, ov::word::XFont > SwVbaFont_BASE;
+
+class SwVbaFont : public SwVbaFont_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFont( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xPalette, css::uno::Reference< css::beans::XPropertySet > const & xPropertySet );
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getColorIndex() override;
+ virtual css::uno::Any SAL_CALL getUnderline() override;
+ virtual void SAL_CALL setUnderline( const css::uno::Any& _underline ) override;
+ virtual css::uno::Any SAL_CALL getSubscript() override;
+ virtual css::uno::Any SAL_CALL getSuperscript() override;
+
+ virtual css::uno::Any SAL_CALL getBold() override;
+ virtual css::uno::Any SAL_CALL getItalic() override;
+ virtual css::uno::Any SAL_CALL getStrikethrough() override;
+ virtual css::uno::Any SAL_CALL getShadow() override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfield.cxx b/sw/source/ui/vba/vbaformfield.cxx
new file mode 100644
index 0000000000..cb1351fa74
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfield.cxx
@@ -0,0 +1,255 @@
+/* -*- 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 <ooo/vba/word/WdFieldType.hpp>
+
+#include <sal/log.hxx>
+
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <unotextrange.hxx>
+
+#include "vbaformfield.hxx"
+#include "vbaformfieldcheckbox.hxx"
+#include "vbaformfielddropdown.hxx"
+#include "vbaformfieldtextinput.hxx"
+#include "vbarange.hxx"
+#include "wordvbahelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/**
+ * FormFields are inline text objects that are only found in MS Word.
+ * They cannot be created in Excel or in Calc.
+ *
+ * There are three specific kinds of FormFields: CheckBox, DropDown, and TextInput.
+ */
+SwVbaFormField::SwVbaFormField(const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext,
+ const uno::Reference<text::XTextDocument>& xTextDocument,
+ sw::mark::IFieldmark& rFormField)
+ : SwVbaFormField_BASE(rParent, rContext)
+ , m_xTextDocument(xTextDocument)
+ , m_rFormField(rFormField)
+{
+}
+
+SwVbaFormField::~SwVbaFormField() {}
+
+uno::Any SwVbaFormField::CheckBox()
+{
+ return uno::Any(uno::Reference<word::XCheckBox>(
+ new SwVbaFormFieldCheckBox(mxParent, mxContext, m_rFormField)));
+}
+
+uno::Any SwVbaFormField::DropDown()
+{
+ return uno::Any(uno::Reference<word::XDropDown>(
+ new SwVbaFormFieldDropDown(mxParent, mxContext, m_rFormField)));
+}
+
+uno::Any SwVbaFormField::TextInput()
+{
+ return uno::Any(uno::Reference<word::XTextInput>(
+ new SwVbaFormFieldTextInput(mxParent, mxContext, m_rFormField)));
+}
+
+uno::Any SwVbaFormField::Previous()
+{
+ SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc();
+ if (!pDoc)
+ return uno::Any();
+
+ const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ if (!pMarkAccess)
+ return uno::Any();
+
+ sw::mark::IFieldmark* pFieldMark = pMarkAccess->getFieldmarkBefore(m_rFormField.GetMarkPos(),
+ /*bLoop=*/false);
+
+ // DateFields are a LO specialty, and do not exist natively in MS documents. Ignore if added...
+ auto pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark);
+ while (pDateField)
+ {
+ pFieldMark = pMarkAccess->getFieldmarkBefore(pDateField->GetMarkPos(), /*bLoop=*/false);
+ pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark);
+ }
+
+ if (!pFieldMark)
+ return uno::Any();
+
+ return uno::Any(uno::Reference<word::XFormField>(
+ new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldMark)));
+}
+
+uno::Any SwVbaFormField::Next()
+{
+ SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc();
+ if (!pDoc)
+ return uno::Any();
+
+ const IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ if (!pMarkAccess)
+ return uno::Any();
+
+ sw::mark::IFieldmark* pFieldMark = pMarkAccess->getFieldmarkAfter(m_rFormField.GetMarkPos(),
+ /*bLoop=*/false);
+
+ // DateFields are a LO specialty, and do not exist natively in MS documents. Ignore if added...
+ auto pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark);
+ while (pDateField)
+ {
+ pFieldMark = pMarkAccess->getFieldmarkAfter(pDateField->GetMarkPos(), /*bLoop=*/false);
+ pDateField = dynamic_cast<sw::mark::IDateFieldmark*>(pFieldMark);
+ }
+
+ if (!pFieldMark)
+ return uno::Any();
+
+ return uno::Any(uno::Reference<word::XFormField>(
+ new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldMark)));
+}
+
+uno::Reference<word::XRange> SwVbaFormField::Range()
+{
+ uno::Reference<word::XRange> xRet;
+ SwDoc* pDoc = word::getDocShell(m_xTextDocument)->GetDoc();
+ if (pDoc)
+ {
+ rtl::Reference<SwXTextRange> xText(SwXTextRange::CreateXTextRange(
+ *pDoc, m_rFormField.GetMarkStart(), &m_rFormField.GetMarkEnd()));
+ if (xText.is())
+ xRet = new SwVbaRange(mxParent, mxContext, m_xTextDocument, xText->getStart(),
+ xText->getEnd());
+ }
+ return xRet;
+}
+
+OUString SwVbaFormField::getDefaultPropertyName() { return "Type"; }
+
+sal_Int32 SwVbaFormField::getType()
+{
+ IDocumentMarkAccess::MarkType aType = IDocumentMarkAccess::GetType(m_rFormField);
+ if (aType == IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK)
+ return ooo::vba::word::WdFieldType::wdFieldFormCheckBox;
+ else if (aType == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK)
+ return ooo::vba::word::WdFieldType::wdFieldFormTextInput;
+ return ooo::vba::word::WdFieldType::wdFieldFormDropDown;
+}
+
+sal_Bool SwVbaFormField::getCalculateOnExit()
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::getCalculateOnExit stub");
+ return false;
+}
+
+void SwVbaFormField::setCalculateOnExit(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::setCalculateOnExit stub");
+}
+
+sal_Bool SwVbaFormField::getEnabled()
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::getEnabled stub");
+ return true;
+}
+
+void SwVbaFormField::setEnabled(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::setEnabled stub");
+}
+
+OUString SwVbaFormField::getEntryMacro()
+{
+ OUString sMacro;
+ (*m_rFormField.GetParameters())["EntryMacro"] >>= sMacro;
+ return sMacro;
+}
+
+void SwVbaFormField::setEntryMacro(const OUString& rSet)
+{
+ (*m_rFormField.GetParameters())["EntryMacro"] <<= rSet;
+}
+
+OUString SwVbaFormField::getExitMacro()
+{
+ OUString sMacro;
+ (*m_rFormField.GetParameters())["ExitMacro"] >>= sMacro;
+ return sMacro;
+}
+
+void SwVbaFormField::setExitMacro(const OUString& rSet)
+{
+ (*m_rFormField.GetParameters())["ExitMacro"] <<= rSet;
+}
+
+OUString SwVbaFormField::getHelpText() { return m_rFormField.GetFieldHelptext(); }
+
+void SwVbaFormField::setHelpText(const OUString& rSet) { m_rFormField.SetFieldHelptext(rSet); }
+
+sal_Bool SwVbaFormField::getOwnHelp()
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::getOwnHelp stub");
+ return true;
+}
+
+void SwVbaFormField::setOwnHelp(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::setOwnHelp stub");
+}
+
+OUString SwVbaFormField::getName() { return m_rFormField.GetName(); }
+
+void SwVbaFormField::setName(const OUString& rSet)
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::setName[" << rSet << "] stub");
+}
+
+OUString SwVbaFormField::getResult() { return m_rFormField.GetContent(); }
+
+void SwVbaFormField::setResult(const OUString& rSet)
+{
+ if (dynamic_cast<sw::mark::ICheckboxFieldmark*>(&m_rFormField))
+ m_rFormField.ReplaceContent("false");
+ else
+ m_rFormField.ReplaceContent(rSet);
+}
+
+OUString SwVbaFormField::getStatusText()
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::getStatusText stub");
+ return OUString();
+}
+
+void SwVbaFormField::setStatusText(const OUString& rSet)
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::setStatusText[" << rSet << "] stub");
+}
+
+sal_Bool SwVbaFormField::getOwnStatus()
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::getOwnStatus stub");
+ return true;
+}
+
+void SwVbaFormField::setOwnStatus(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaFormField::setOwnStatus stub");
+}
+
+OUString SwVbaFormField::getServiceImplName() { return "SwVbaFormField"; }
+
+uno::Sequence<OUString> SwVbaFormField::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.FormField" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfield.hxx b/sw/source/ui/vba/vbaformfield.hxx
new file mode 100644
index 0000000000..260e790935
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfield.hxx
@@ -0,0 +1,87 @@
+/* -*- 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/text/XTextDocument.hpp>
+#include <ooo/vba/word/XFormField.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <IDocumentMarkAccess.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XFormField> SwVbaFormField_BASE;
+
+class SwVbaFormField : public SwVbaFormField_BASE
+{
+private:
+ css::uno::Reference<css::text::XTextDocument> m_xTextDocument;
+ sw::mark::IFieldmark& m_rFormField;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormField(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ const uno::Reference<text::XTextDocument>& xTextDocument,
+ sw::mark::IFieldmark& rFormField);
+ ~SwVbaFormField() override;
+
+ // XFormField Methods
+ OUString SAL_CALL getDefaultPropertyName() override;
+
+ css::uno::Any SAL_CALL CheckBox() override;
+ css::uno::Any SAL_CALL DropDown() override;
+ css::uno::Any SAL_CALL TextInput() override;
+ css::uno::Any SAL_CALL Previous() override;
+ css::uno::Any SAL_CALL Next() override;
+ css::uno::Reference<ooo::vba::word::XRange> SAL_CALL Range() override;
+
+ // Indicates which of the three form fields this is: oovbaapi/ooo/vba/word/WdFieldType.idl
+ sal_Int32 SAL_CALL getType() override;
+ // True if references to the specified form field
+ // are automatically updated whenever the field is exited
+ sal_Bool SAL_CALL getCalculateOnExit() override;
+ void SAL_CALL setCalculateOnExit(sal_Bool bSet) override;
+ sal_Bool SAL_CALL getEnabled() override;
+ void SAL_CALL setEnabled(sal_Bool bSet) override;
+ OUString SAL_CALL getEntryMacro() override;
+ void SAL_CALL setEntryMacro(const OUString& rSet) override;
+ OUString SAL_CALL getExitMacro() override;
+ void SAL_CALL setExitMacro(const OUString& rSet) override;
+ /*
+ * If the OwnHelp property is set to True,
+ * HelpText specifies the text string value.
+ * If OwnHelp is set to False, HelpText specifies the name of an AutoText entry
+ * that contains help text for the form field.
+ */
+ OUString SAL_CALL getHelpText() override;
+ void SAL_CALL setHelpText(const OUString& rSet) override;
+ sal_Bool SAL_CALL getOwnHelp() override;
+ void SAL_CALL setOwnHelp(sal_Bool bSet) override;
+
+ OUString SAL_CALL getName() override;
+ void SAL_CALL setName(const OUString& rSet) override;
+ OUString SAL_CALL getResult() override;
+ void SAL_CALL setResult(const OUString& rSet) override;
+ /*
+ * If the OwnStatus property is set to True,
+ * StatusText specifies the status bar value.
+ * If OwnStatus is set to False, StatusText specifies the name of an AutoText entry
+ * that contains status bar text for the form field.
+ */
+ OUString SAL_CALL getStatusText() override;
+ void SAL_CALL setStatusText(const OUString& rSet) override;
+ sal_Bool SAL_CALL getOwnStatus() override;
+ void SAL_CALL setOwnStatus(sal_Bool bSet) override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfieldcheckbox.cxx b/sw/source/ui/vba/vbaformfieldcheckbox.cxx
new file mode 100644
index 0000000000..5a32e7e426
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfieldcheckbox.cxx
@@ -0,0 +1,117 @@
+/* -*- 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/log.hxx>
+
+#include "vbaformfieldcheckbox.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/**
+ * CheckBoxes are inline text objects that are only found in MS Word.
+ * They cannot be created in Excel or in Calc.
+ *
+ * Note that VBA might call this a Checkbox, but it might not actually be one,
+ * so make good use of getValid()
+ */
+SwVbaFormFieldCheckBox::SwVbaFormFieldCheckBox(
+ const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext, sw::mark::IFieldmark& rFormField)
+ : SwVbaFormFieldCheckBox_BASE(rParent, rContext)
+ , m_pCheckBox(dynamic_cast<sw::mark::ICheckboxFieldmark*>(&rFormField))
+{
+}
+
+SwVbaFormFieldCheckBox::~SwVbaFormFieldCheckBox() {}
+
+OUString SwVbaFormFieldCheckBox::getDefaultPropertyName() { return "Valid"; }
+
+sal_Bool SwVbaFormFieldCheckBox::getValid()
+{
+ return m_pCheckBox
+ && IDocumentMarkAccess::GetType(*m_pCheckBox)
+ == IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK;
+}
+
+sal_Bool SwVbaFormFieldCheckBox::getAutoSize()
+{
+ if (!getValid())
+ return false;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::getAutoSize stub");
+ return true;
+}
+
+void SwVbaFormFieldCheckBox::setAutoSize(sal_Bool /*bSet*/)
+{
+ if (!getValid())
+ return;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::setAutoSize stub");
+}
+
+sal_Bool SwVbaFormFieldCheckBox::getDefault()
+{
+ if (!getValid())
+ return false;
+
+ return getValue();
+}
+
+void SwVbaFormFieldCheckBox::setDefault(sal_Bool bSet)
+{
+ if (!getValid())
+ return;
+
+ // Hard to know what to do here, since LO doesn't have a default property for checkboxes.
+ // Setting this really only makes sense when macro-adding a checkbox.
+ // In that case, we want it to affect the actual checkbox.
+ // However, if the checkbox has already been set by the user, then this shouldn't do anything.
+ // Assuming this is only ever called when adding a checkbox seems the sanest approach.
+ setValue(bSet);
+}
+
+// Returns the size of a check box, in points
+sal_Int32 SwVbaFormFieldCheckBox::getSize()
+{
+ if (!getValid())
+ return 0;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::getSize stub");
+ return 11;
+}
+
+void SwVbaFormFieldCheckBox::setSize(sal_Int32 nSet)
+{
+ if (!getValid())
+ return;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldCheckBox::setSize[" << nSet << "] stub");
+}
+
+sal_Bool SwVbaFormFieldCheckBox::getValue() { return getValid() && m_pCheckBox->IsChecked(); }
+
+void SwVbaFormFieldCheckBox::setValue(sal_Bool bSet)
+{
+ if (!getValid() || !getValue() == !bSet)
+ return;
+
+ m_pCheckBox->SetChecked(bSet);
+}
+
+OUString SwVbaFormFieldCheckBox::getServiceImplName() { return "SwVbaFormFieldCheckBox"; }
+
+uno::Sequence<OUString> SwVbaFormFieldCheckBox::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.CheckBox" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfieldcheckbox.hxx b/sw/source/ui/vba/vbaformfieldcheckbox.hxx
new file mode 100644
index 0000000000..c62549585b
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfieldcheckbox.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/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XCheckBox.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <IDocumentMarkAccess.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XCheckBox> SwVbaFormFieldCheckBox_BASE;
+
+class SwVbaFormFieldCheckBox : public SwVbaFormFieldCheckBox_BASE
+{
+private:
+ sw::mark::ICheckboxFieldmark* m_pCheckBox;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormFieldCheckBox(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ sw::mark::IFieldmark& rFormField);
+ ~SwVbaFormFieldCheckBox() override;
+
+ // XCheckBox
+ OUString SAL_CALL getDefaultPropertyName() override;
+
+ // Default member: True if the specified form field object is a valid check box form field
+ sal_Bool SAL_CALL getValid() override;
+
+ sal_Bool SAL_CALL getAutoSize() override;
+ void SAL_CALL setAutoSize(sal_Bool bSet) override;
+ // Returns the default check box value
+ sal_Bool SAL_CALL getDefault() override;
+ void SAL_CALL setDefault(sal_Bool bSet) override;
+ // Returns the size of a check box, in points
+ sal_Int32 SAL_CALL getSize() override;
+ void SAL_CALL setSize(sal_Int32 nSet) override;
+
+ sal_Bool SAL_CALL getValue() override;
+ void SAL_CALL setValue(sal_Bool bSet) override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfielddropdown.cxx b/sw/source/ui/vba/vbaformfielddropdown.cxx
new file mode 100644
index 0000000000..f1edc81403
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfielddropdown.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/.
+ */
+
+#include <ooo/vba/word/WdTextFormFieldType.hpp>
+
+#include "vbaformfielddropdown.hxx"
+#include "vbaformfielddropdownlistentries.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/**
+ * DropDown formfields are inline text objects that are only found in MS Word.
+ * They cannot be created in Excel or in Calc.
+ *
+ * Note that VBA might call this a DropDown, but it might not actually be one,
+ * so make good use of getValid()
+ */
+SwVbaFormFieldDropDown::SwVbaFormFieldDropDown(
+ const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext, ::sw::mark::IFieldmark& rFormField)
+ : SwVbaFormFieldDropDown_BASE(rParent, rContext)
+ , m_pDropDown(dynamic_cast<sw::mark::IDropdownFieldmark*>(&rFormField))
+{
+}
+
+SwVbaFormFieldDropDown::~SwVbaFormFieldDropDown() {}
+
+OUString SwVbaFormFieldDropDown::getDefaultPropertyName() { return "Valid"; }
+
+sal_Bool SwVbaFormFieldDropDown::getValid()
+{
+ return m_pDropDown
+ && IDocumentMarkAccess::GetType(*m_pDropDown)
+ == IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK;
+}
+
+sal_Int32 SwVbaFormFieldDropDown::getDefault() { return getValue(); }
+
+void SwVbaFormFieldDropDown::setDefault(sal_Int32 nSet)
+{
+ // Hard to know what to do here, since LO doesn't have a default property for DropDowns.
+ // Setting this really only makes sense when macro-adding a DropDown.
+ // In that case, we want it to affect the actual text content.
+ // However, if an item has already been selected by the user, then this shouldn't do anything.
+ // Assuming this is only ever set when adding a DropDown seems the sanest approach.
+ setValue(nSet);
+}
+
+sal_Int32 SwVbaFormFieldDropDown::getValue()
+{
+ sal_Int32 nRet = 0;
+ if (!getValid())
+ return nRet;
+
+ --nRet; // send -1, which requests being changed to the selected DropDown's zero-based index
+ m_pDropDown->GetContent(&nRet);
+ return nRet + 1;
+}
+
+void SwVbaFormFieldDropDown::setValue(sal_Int32 nIndex)
+{
+ if (!getValid() || nIndex == getValue())
+ return;
+
+ // switch to zero-based index for implementation
+ --nIndex;
+ m_pDropDown->ReplaceContent(/*pText=*/nullptr, &nIndex);
+}
+
+uno::Any SwVbaFormFieldDropDown::ListEntries(const uno::Any& rIndex)
+{
+ if (!getValid())
+ return uno::Any();
+
+ uno::Reference<XCollection> xCol(
+ new SwVbaFormFieldDropDownListEntries(this, mxContext, *m_pDropDown));
+
+ if (rIndex.hasValue())
+ return xCol->Item(rIndex, uno::Any());
+
+ return uno::Any(xCol);
+}
+
+OUString SwVbaFormFieldDropDown::getServiceImplName() { return "SwVbaFormFieldDropDown"; }
+
+uno::Sequence<OUString> SwVbaFormFieldDropDown::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.DropDown" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfielddropdown.hxx b/sw/source/ui/vba/vbaformfielddropdown.hxx
new file mode 100644
index 0000000000..e92caa2f8e
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfielddropdown.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/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XDropDown.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <IDocumentMarkAccess.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XDropDown> SwVbaFormFieldDropDown_BASE;
+
+class SwVbaFormFieldDropDown : public SwVbaFormFieldDropDown_BASE
+{
+private:
+ sw::mark::IDropdownFieldmark* m_pDropDown;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormFieldDropDown(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ sw::mark::IFieldmark& rFormField);
+ ~SwVbaFormFieldDropDown() override;
+
+ // XDropDown
+ OUString SAL_CALL getDefaultPropertyName() override;
+
+ // Default member: True if the specified form field object is a valid listbox field
+ sal_Bool SAL_CALL getValid() override;
+
+ // Returns and sets the index for the default listbox entry
+ sal_Int32 SAL_CALL getDefault() override;
+ void SAL_CALL setDefault(sal_Int32 nSet) override;
+ // Returns and sets the index of the selected listbox entry
+ sal_Int32 SAL_CALL getValue() override;
+ void SAL_CALL setValue(sal_Int32 nIndex) override;
+
+ // Returns a ListEntries collection that represents all the available entries
+ css::uno::Any SAL_CALL ListEntries(const css::uno::Any& rIndex) override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentries.cxx b/sw/source/ui/vba/vbaformfielddropdownlistentries.cxx
new file mode 100644
index 0000000000..c167e16d78
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfielddropdownlistentries.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/.
+ */
+
+#include <xmloff/odffields.hxx>
+
+#include "vbaformfielddropdownlistentries.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static uno::Sequence<OUString> lcl_getListEntries(sw::mark::IDropdownFieldmark& rDropDown)
+{
+ uno::Sequence<OUString> aSeq;
+ (*rDropDown.GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] >>= aSeq;
+ return aSeq;
+}
+
+namespace
+{
+class ListEntriesEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess> mxIndexAccess;
+ sal_Int32 mnIndex;
+
+public:
+ explicit ListEntriesEnumWrapper(uno::Reference<container::XIndexAccess> xIndexAccess)
+ : mxIndexAccess(xIndexAccess)
+ , mnIndex(0)
+ {
+ }
+
+ sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); }
+
+ uno::Any SAL_CALL nextElement() override
+ {
+ if (mnIndex < mxIndexAccess->getCount())
+ {
+ return mxIndexAccess->getByIndex(mnIndex++);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class ListEntryCollectionHelper
+ : public ::cppu::WeakImplHelper<container::XIndexAccess, container::XEnumerationAccess>
+{
+private:
+ uno::Reference<XHelperInterface> mxParent;
+ uno::Reference<uno::XComponentContext> mxContext;
+ sw::mark::IDropdownFieldmark& m_rDropDown;
+
+public:
+ /// @throws css::uno::RuntimeException
+ ListEntryCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
+ uno::Reference<uno::XComponentContext> xContext,
+ sw::mark::IDropdownFieldmark& rFormField)
+ : mxParent(xParent)
+ , mxContext(xContext)
+ , m_rDropDown(rFormField)
+ {
+ }
+
+ sal_Int32 SAL_CALL getCount() override { return lcl_getListEntries(m_rDropDown).getLength(); }
+
+ uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
+ {
+ if (Index < 0 || Index >= getCount())
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any(uno::Reference<word::XListEntry>(
+ new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, Index)));
+ }
+
+ uno::Type SAL_CALL getElementType() override { return cppu::UnoType<word::XListEntry>::get(); }
+
+ sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
+
+ // XEnumerationAccess
+ uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
+ {
+ return new ListEntriesEnumWrapper(this);
+ }
+};
+}
+
+SwVbaFormFieldDropDownListEntries::SwVbaFormFieldDropDownListEntries(
+ const uno::Reference<XHelperInterface>& xParent,
+ const uno::Reference<uno::XComponentContext>& xContext,
+ sw::mark::IDropdownFieldmark& rFormField)
+ : SwVbaFormFieldDropDownListEntries_BASE(
+ xParent, xContext,
+ uno::Reference<container::XIndexAccess>(
+ new ListEntryCollectionHelper(xParent, xContext, rFormField)))
+ , m_rDropDown(rFormField)
+{
+}
+
+// XListEntries
+uno::Reference<word::XListEntry> SwVbaFormFieldDropDownListEntries::Add(const OUString& rName,
+ const uno::Any& rIndex)
+{
+ sal_Int32 nZIndex = 0;
+ rIndex >>= nZIndex;
+ // rIndex is 1-based, nZIndex is 0-based. If rIndex is not given, then add as the last choice.
+
+ // In testing with Word 2010, this gives a compile error: 'ListEntries.Add("Name", 2)'
+ // This compiles, but gets an unsupported runtime error: 'ListEntries.Add("Name", 2) = "Choice'
+ // So the only thing that actually works is to simply append: 'ListEntires.Add("Name")'
+ // but I'll still keep the expected implementation for the broken case.
+ if (!nZIndex)
+ nZIndex = SAL_MAX_INT32;
+ else
+ --nZIndex;
+ m_rDropDown.AddContent(rName + "__allowDuplicates", &nZIndex);
+ m_rDropDown.ReplaceContent(&rName, &nZIndex);
+
+ return uno::Reference<word::XListEntry>(
+ new SwVbaFormFieldDropDownListEntry(mxParent, mxContext, m_rDropDown, nZIndex));
+}
+
+void SwVbaFormFieldDropDownListEntries::Clear() { m_rDropDown.DelContent(); }
+
+sal_Int32 SwVbaFormFieldDropDownListEntries::getCount()
+{
+ return lcl_getListEntries(m_rDropDown).getLength();
+}
+
+// XEnumerationAccess
+uno::Type SwVbaFormFieldDropDownListEntries::getElementType()
+{
+ return cppu::UnoType<word::XListEntry>::get();
+}
+
+uno::Reference<container::XEnumeration> SwVbaFormFieldDropDownListEntries::createEnumeration()
+{
+ return new ListEntriesEnumWrapper(m_xIndexAccess);
+}
+
+// SwVbadropDownListEntries_BASE
+uno::Any SwVbaFormFieldDropDownListEntries::createCollectionObject(const uno::Any& aSource)
+{
+ return aSource;
+}
+
+OUString SwVbaFormFieldDropDownListEntries::getServiceImplName()
+{
+ return "SwVbaFormFieldDropDownListEntries";
+}
+
+uno::Sequence<OUString> SwVbaFormFieldDropDownListEntries::getServiceNames()
+{
+ static uno::Sequence<OUString> const sNames{ "ooo.vba.word.ListEntries" };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentries.hxx b/sw/source/ui/vba/vbaformfielddropdownlistentries.hxx
new file mode 100644
index 0000000000..ef13391270
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfielddropdownlistentries.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 <ooo/vba/word/XListEntries.hpp>
+#include <ooo/vba/word/XListEntry.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+#include "vbaformfielddropdownlistentries.hxx"
+#include "vbaformfielddropdownlistentry.hxx"
+
+typedef CollTestImplHelper<ooo::vba::word::XListEntries> SwVbaFormFieldDropDownListEntries_BASE;
+
+class SwVbaFormFieldDropDownListEntries : public SwVbaFormFieldDropDownListEntries_BASE
+{
+private:
+ sw::mark::IDropdownFieldmark& m_rDropDown;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormFieldDropDownListEntries(
+ const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ sw::mark::IDropdownFieldmark& m_rDropDown);
+
+ // XListEntries
+ css::uno::Reference<ooo::vba::word::XListEntry>
+ SAL_CALL Add(const OUString& rName, const css::uno::Any& rIndex) override;
+ void SAL_CALL Clear() override;
+ sal_Int32 SAL_CALL getCount() override;
+
+ // XEnumerationAccess
+ css::uno::Type SAL_CALL getElementType() override;
+ css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // SwVbaFormFieldDropDownListEntries_BASE
+ css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentry.cxx b/sw/source/ui/vba/vbaformfielddropdownlistentry.cxx
new file mode 100644
index 0000000000..bc02439ed5
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfielddropdownlistentry.cxx
@@ -0,0 +1,56 @@
+/* -*- 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 "vbaformfielddropdownlistentry.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaFormFieldDropDownListEntry::SwVbaFormFieldDropDownListEntry(
+ const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext,
+ sw::mark::IDropdownFieldmark& rFormField, sal_Int32 nZIndex)
+ : SwVbaFormFieldDropDownListEntry_BASE(rParent, rContext)
+ , m_rDropDown(rFormField)
+ , m_nZIndex(nZIndex)
+{
+}
+
+SwVbaFormFieldDropDownListEntry::~SwVbaFormFieldDropDownListEntry() {}
+
+// XListEntry
+sal_Int32 SwVbaFormFieldDropDownListEntry::getIndex() { return m_nZIndex + 1; }
+
+OUString SwVbaFormFieldDropDownListEntry::getName()
+{
+ sal_Int32 nZIndex = m_nZIndex;
+ return m_rDropDown.GetContent(&nZIndex);
+}
+
+void SwVbaFormFieldDropDownListEntry::setName(const OUString& rSet)
+{
+ sal_Int32 nZIndex = m_nZIndex;
+ m_rDropDown.ReplaceContent(&rSet, &nZIndex);
+}
+
+void SwVbaFormFieldDropDownListEntry::Delete() { m_rDropDown.DelContent(m_nZIndex); }
+
+// XHelperInterface
+OUString SwVbaFormFieldDropDownListEntry::getServiceImplName()
+{
+ return "SwVbaFormFieldDropDownListEntry";
+}
+
+uno::Sequence<OUString> SwVbaFormFieldDropDownListEntry::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.ListEntry" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfielddropdownlistentry.hxx b/sw/source/ui/vba/vbaformfielddropdownlistentry.hxx
new file mode 100644
index 0000000000..4ded080e63
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfielddropdownlistentry.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/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XListEntry.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <IDocumentMarkAccess.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XListEntry>
+ SwVbaFormFieldDropDownListEntry_BASE;
+
+class SwVbaFormFieldDropDownListEntry : public SwVbaFormFieldDropDownListEntry_BASE
+{
+private:
+ sw::mark::IDropdownFieldmark& m_rDropDown;
+ // All LO and internal UNO functions are 0-based. Convert to 1-based when sending to VBA
+ const sal_Int32 m_nZIndex;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormFieldDropDownListEntry(
+ const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ sw::mark::IDropdownFieldmark& rFormField, sal_Int32 nZIndex);
+ ~SwVbaFormFieldDropDownListEntry() override;
+
+ // XListEntry
+ sal_Int32 SAL_CALL getIndex() override;
+
+ OUString SAL_CALL getName() override;
+ void SAL_CALL setName(const OUString& sSet) override;
+
+ void SAL_CALL Delete() override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfields.cxx b/sw/source/ui/vba/vbaformfields.cxx
new file mode 100644
index 0000000000..9c8af450d3
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfields.cxx
@@ -0,0 +1,235 @@
+/* -*- 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 <comphelper/sequence.hxx>
+#include <sal/log.hxx>
+
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <IDocumentMarkAccess.hxx>
+
+#include "vbaformfield.hxx"
+#include "vbaformfields.hxx"
+#include "wordvbahelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+// Helper function to access the fieldmarks
+// @param rIndex serves multiple purposes
+// [in] -1 to indicate searching using the provided name, SAL_MAX_INT32 for totals
+// [out] rIndex indicates the found index, or the total number of fieldmarks
+static sw::mark::IFieldmark* lcl_getFieldmark(std::string_view rName, sal_Int32& rIndex,
+ const uno::Reference<frame::XModel>& xModel,
+ uno::Sequence<OUString>* pElementNames = nullptr)
+
+{
+ SwDoc* pDoc = word::getDocShell(xModel)->GetDoc();
+ if (!pDoc)
+ return nullptr;
+
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ if (!pMarkAccess)
+ return nullptr;
+
+ sal_Int32 nCounter = 0;
+ std::vector<OUString> vElementNames;
+ IDocumentMarkAccess::iterator aIter = pMarkAccess->getFieldmarksBegin();
+ while (aIter != pMarkAccess->getFieldmarksEnd())
+ {
+ switch (IDocumentMarkAccess::GetType(**aIter))
+ {
+ case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
+ case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
+ {
+ if (rIndex < 0
+ && (*aIter)->GetName().equalsIgnoreAsciiCase(OUString::fromUtf8(rName)))
+ {
+ rIndex = nCounter;
+ return dynamic_cast<sw::mark::IFieldmark*>(*aIter);
+ }
+ else if (rIndex == nCounter)
+ return dynamic_cast<sw::mark::IFieldmark*>(*aIter);
+
+ ++nCounter;
+ if (pElementNames)
+ vElementNames.push_back((*aIter)->GetName());
+ break;
+ }
+ default:;
+ }
+ aIter++;
+ }
+ rIndex = nCounter;
+ if (pElementNames)
+ *pElementNames = comphelper::containerToSequence(vElementNames);
+ return nullptr;
+}
+
+namespace
+{
+class FormFieldsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess> mxIndexAccess;
+ sal_Int32 mnIndex;
+
+public:
+ explicit FormFieldsEnumWrapper(const uno::Reference<container::XIndexAccess>& xIndexAccess)
+ : mxIndexAccess(xIndexAccess)
+ , mnIndex(0)
+ {
+ }
+ sal_Bool SAL_CALL hasMoreElements() override { return (mnIndex < mxIndexAccess->getCount()); }
+
+ uno::Any SAL_CALL nextElement() override
+ {
+ if (mnIndex < mxIndexAccess->getCount())
+ {
+ return mxIndexAccess->getByIndex(mnIndex++);
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class FormFieldCollectionHelper
+ : public ::cppu::WeakImplHelper<container::XNameAccess, container::XIndexAccess,
+ container::XEnumerationAccess>
+{
+private:
+ uno::Reference<XHelperInterface> mxParent;
+ uno::Reference<uno::XComponentContext> mxContext;
+ uno::Reference<text::XTextDocument> mxTextDocument;
+ sw::mark::IFieldmark* m_pCache;
+
+public:
+ /// @throws css::uno::RuntimeException
+ FormFieldCollectionHelper(uno::Reference<ov::XHelperInterface> xParent,
+ uno::Reference<uno::XComponentContext> xContext,
+ uno::Reference<text::XTextDocument> xTextDocument)
+ : mxParent(std::move(xParent))
+ , mxContext(std::move(xContext))
+ , mxTextDocument(std::move(xTextDocument))
+ , m_pCache(nullptr)
+ {
+ }
+
+ // XIndexAccess
+ sal_Int32 SAL_CALL getCount() override
+ {
+ sal_Int32 nCount = SAL_MAX_INT32;
+ lcl_getFieldmark("", nCount, mxTextDocument);
+ return nCount == SAL_MAX_INT32 ? 0 : nCount;
+ }
+
+ uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
+ {
+ m_pCache = lcl_getFieldmark("", Index, mxTextDocument);
+ if (!m_pCache)
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any(uno::Reference<word::XFormField>(
+ new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache)));
+ }
+
+ // XNameAccess
+ uno::Sequence<OUString> SAL_CALL getElementNames() override
+ {
+ sal_Int32 nCount = SAL_MAX_INT32;
+ uno::Sequence<OUString> aSeq;
+ lcl_getFieldmark("", nCount, mxTextDocument, &aSeq);
+ return aSeq;
+ }
+
+ uno::Any SAL_CALL getByName(const OUString& aName) override
+ {
+ if (!hasByName(aName))
+ throw container::NoSuchElementException();
+
+ return uno::Any(uno::Reference<word::XFormField>(
+ new SwVbaFormField(mxParent, mxContext, mxTextDocument, *m_pCache)));
+ }
+
+ sal_Bool SAL_CALL hasByName(const OUString& aName) override
+ {
+ sal_Int32 nCount = -1;
+ m_pCache = lcl_getFieldmark(aName.toUtf8(), nCount, mxTextDocument);
+ return m_pCache != nullptr;
+ }
+
+ // XElementAccess
+ uno::Type SAL_CALL getElementType() override { return cppu::UnoType<word::XFormField>::get(); }
+
+ sal_Bool SAL_CALL hasElements() override { return getCount() != 0; }
+
+ // XEnumerationAccess
+ uno::Reference<container::XEnumeration> SAL_CALL createEnumeration() override
+ {
+ return new FormFieldsEnumWrapper(this);
+ }
+};
+}
+
+SwVbaFormFields::SwVbaFormFields(const uno::Reference<XHelperInterface>& xParent,
+ const uno::Reference<uno::XComponentContext>& xContext,
+ const uno::Reference<text::XTextDocument>& xTextDocument)
+ : SwVbaFormFields_BASE(xParent, xContext,
+ uno::Reference<container::XIndexAccess>(
+ new FormFieldCollectionHelper(xParent, xContext, xTextDocument)))
+{
+}
+
+sal_Bool SwVbaFormFields::getShaded()
+{
+ SAL_INFO("sw.vba", "SwVbaFormFields::getShaded stub");
+ return false;
+}
+
+void SwVbaFormFields::setShaded(sal_Bool /*bSet*/)
+{
+ SAL_INFO("sw.vba", "SwVbaFormFields::setShaded stub");
+}
+
+// uno::Reference<ooo::vba::word::XFormField> SwVbaFormFields::Add(const uno::Any& Range,
+// sal_Int32 Type)
+// {
+// sw::mark::IFieldmark* pFieldmark = nullptr;
+// switch (Type)
+// {
+// case ooo::vba::word::WdFieldType::wdFieldFormCheckBox:
+// break;
+// case ooo::vba::word::WdFieldType::wdFieldFormDropDown:
+// break;
+// case ooo::vba::word::WdFieldType::wdFieldFormTextInput:
+// default:;
+// }
+//
+// return uno::Reference<ooo::vba::word::XFormField>(
+// new SwVbaFormField(mxParent, mxContext, m_xTextDocument, *pFieldmark));
+// }
+
+// XEnumerationAccess
+uno::Type SwVbaFormFields::getElementType() { return cppu::UnoType<word::XFormField>::get(); }
+
+uno::Reference<container::XEnumeration> SwVbaFormFields::createEnumeration()
+{
+ return new FormFieldsEnumWrapper(m_xIndexAccess);
+}
+
+uno::Any SwVbaFormFields::createCollectionObject(const uno::Any& aSource) { return aSource; }
+
+OUString SwVbaFormFields::getServiceImplName() { return "SwVbaFormFields"; }
+
+uno::Sequence<OUString> SwVbaFormFields::getServiceNames()
+{
+ static uno::Sequence<OUString> const sNames{ "ooo.vba.word.FormFields" };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfields.hxx b/sw/source/ui/vba/vbaformfields.hxx
new file mode 100644
index 0000000000..2dfa9e76b0
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfields.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 <com/sun/star/text/XTextDocument.hpp>
+#include <ooo/vba/word/XFormFields.hpp>
+
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper<ooo::vba::word::XFormFields> SwVbaFormFields_BASE;
+
+class SwVbaFormFields : public SwVbaFormFields_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormFields(const css::uno::Reference<ov::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const css::uno::Reference<css::text::XTextDocument>& xTextDocument);
+
+ // XFormFields
+ sal_Bool SAL_CALL getShaded() override;
+ void SAL_CALL setShaded(sal_Bool bSet) override;
+ //css::uno::Reference<ooo::vba::word::XFormField> SAL_CALL Add(const css::uno::Any& Range, sal_Int32 Type) override;
+
+ // XEnumerationAccess
+ css::uno::Type SAL_CALL getElementType() override;
+ css::uno::Reference<css::container::XEnumeration> SAL_CALL createEnumeration() override;
+
+ // SwVbaFormFields_BASE
+ css::uno::Any createCollectionObject(const css::uno::Any& aSource) override;
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfieldtextinput.cxx b/sw/source/ui/vba/vbaformfieldtextinput.cxx
new file mode 100644
index 0000000000..4f78761f4e
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfieldtextinput.cxx
@@ -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/.
+ */
+
+#include <ooo/vba/word/WdTextFormFieldType.hpp>
+
+#include <sal/log.hxx>
+
+#include "vbaformfieldtextinput.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/**
+ * TextInput formfields are inline text objects that are only found in MS Word.
+ * They cannot be created in Excel or in Calc.
+ *
+ * Note that VBA might call this a TextInput, but it might not actually be one,
+ * so make good use of getValid()
+ */
+SwVbaFormFieldTextInput::SwVbaFormFieldTextInput(
+ const uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const uno::Reference<uno::XComponentContext>& rContext, sw::mark::IFieldmark& rFormField)
+ : SwVbaFormFieldTextInput_BASE(rParent, rContext)
+ , m_rTextInput(rFormField)
+{
+}
+
+SwVbaFormFieldTextInput::~SwVbaFormFieldTextInput() {}
+
+OUString SwVbaFormFieldTextInput::getDefaultPropertyName() { return "Valid"; }
+
+sal_Bool SwVbaFormFieldTextInput::getValid()
+{
+ return IDocumentMarkAccess::GetType(m_rTextInput)
+ == IDocumentMarkAccess::MarkType::TEXT_FIELDMARK;
+}
+
+OUString SwVbaFormFieldTextInput::getDefault()
+{
+ if (!getValid())
+ return OUString();
+
+ return m_rTextInput.GetContent();
+}
+
+void SwVbaFormFieldTextInput::setDefault(const OUString& sSet)
+{
+ // Hard to know what to do here, since LO doesn't have a default property for text input.
+ // This really only makes sense when macro-adding a text input.
+ // In that case, we want it to affect the actual text content.
+ // However, if the text has already been set by the user, then this shouldn't do anything.
+ // Assuming this is only ever set when adding a text input seems the sanest approach.
+ if (!getValid() || getDefault() == sSet)
+ return;
+
+ m_rTextInput.ReplaceContent(sSet);
+}
+
+OUString SwVbaFormFieldTextInput::getFormat()
+{
+ if (!getValid())
+ return OUString();
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getFormat stub");
+ return OUString();
+}
+
+sal_Int32 SwVbaFormFieldTextInput::getType()
+{
+ if (!getValid())
+ return word::WdTextFormFieldType::wdRegularText;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getType stub");
+ return word::WdTextFormFieldType::wdRegularText;
+}
+
+sal_Int32 SwVbaFormFieldTextInput::getWidth()
+{
+ if (!getValid())
+ return 0;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::getWidth stub");
+ return 11 * 50;
+}
+
+void SwVbaFormFieldTextInput::setWidth(sal_Int32 nWidth)
+{
+ if (!getValid())
+ return;
+
+ SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::setWidth[" << nWidth << "] stub");
+}
+
+void SwVbaFormFieldTextInput::Clear()
+{
+ if (!getValid() || m_rTextInput.GetContent().isEmpty())
+ return;
+
+ m_rTextInput.ReplaceContent("");
+}
+
+void SwVbaFormFieldTextInput::EditType(sal_Int32 nType, const uno::Any& rDefault,
+ const uno::Any& rFormat, const uno::Any& rEnabled)
+{
+ OUString sDefault;
+ OUString sFormat;
+ bool bEnabled = true;
+ rDefault >>= sDefault;
+ rFormat >>= sFormat;
+ rEnabled >>= bEnabled;
+ SAL_INFO("sw.vba", "SwVbaFormFieldTextInput::EditType["
+ << nType << "] sDefault[" << sDefault << "] sFormat[" << sFormat
+ << "] bEnabled[" << bEnabled << "] stub");
+}
+
+OUString SwVbaFormFieldTextInput::getServiceImplName() { return "SwVbaFormFieldTextInput"; }
+
+uno::Sequence<OUString> SwVbaFormFieldTextInput::getServiceNames()
+{
+ static uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.TextInput" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaformfieldtextinput.hxx b/sw/source/ui/vba/vbaformfieldtextinput.hxx
new file mode 100644
index 0000000000..513cac64de
--- /dev/null
+++ b/sw/source/ui/vba/vbaformfieldtextinput.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/.
+ */
+#pragma once
+
+#include <ooo/vba/word/XTextInput.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+
+#include <IDocumentMarkAccess.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XTextInput> SwVbaFormFieldTextInput_BASE;
+
+class SwVbaFormFieldTextInput : public SwVbaFormFieldTextInput_BASE
+{
+private:
+ sw::mark::IFieldmark& m_rTextInput;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFormFieldTextInput(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ sw::mark::IFieldmark& rFormField);
+ ~SwVbaFormFieldTextInput() override;
+
+ // XTextInput
+ OUString SAL_CALL getDefaultPropertyName() override;
+
+ // default member: True if the specified form field object is a valid text form field
+ sal_Bool SAL_CALL getValid() override;
+
+ // Returns and sets the default text string of the input box
+ OUString SAL_CALL getDefault() override;
+ void SAL_CALL setDefault(const OUString& bSet) override;
+ // Returns the format string for the current text
+ OUString SAL_CALL getFormat() override;
+ /*
+ * Returns the type of text form field.
+ * Possible return values are:
+ * wdCalculationText - Calculation text field,
+ * wdCurrentDateText - Current date text field,
+ * wdCurrentTimeText - Current time text field,
+ * wdDateText - Date text field,
+ * wdNumberText - Number text field,
+ * wdRegularText - Regular text field.
+ */
+ sal_Int32 SAL_CALL getType() override;
+ // Returns and sets the width, in points
+ sal_Int32 SAL_CALL getWidth() override;
+ void SAL_CALL setWidth(sal_Int32 nSet) override;
+
+ // Deletes the text from the text form field.
+ void SAL_CALL Clear() override;
+ // Sets the type, default text string, format string, and enabled status
+ void SAL_CALL EditType(sal_Int32 nType, const css::uno::Any& rDefault,
+ const css::uno::Any& rFormat, const css::uno::Any& rEnabled) override;
+
+ // XHelperInterface
+ OUString getServiceImplName() override;
+ css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaframe.cxx b/sw/source/ui/vba/vbaframe.cxx
new file mode 100644
index 0000000000..b3a0180fb1
--- /dev/null
+++ b/sw/source/ui/vba/vbaframe.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/.
+ *
+ * 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 "vbaframe.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaFrame::SwVbaFrame( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, css::uno::Reference< frame::XModel > xModel, css::uno::Reference< text::XTextFrame > xTextFrame ) :
+ SwVbaFrame_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxTextFrame(std::move( xTextFrame ))
+{
+}
+
+SwVbaFrame::~SwVbaFrame()
+{
+}
+
+void SAL_CALL SwVbaFrame::Select()
+{
+ uno::Reference< view::XSelectionSupplier > xSelectSupp( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelectSupp->select( uno::Any( mxTextFrame ) );
+}
+
+OUString
+SwVbaFrame::getServiceImplName()
+{
+ return "SwVbaFrame";
+}
+
+uno::Sequence< OUString >
+SwVbaFrame::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Frame"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaframe.hxx b/sw/source/ui/vba/vbaframe.hxx
new file mode 100644
index 0000000000..c24ba4617c
--- /dev/null
+++ b/sw/source/ui/vba/vbaframe.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFRAME_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAFRAME_HXX
+
+#include <ooo/vba/word/XFrame.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextFrame.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XFrame > SwVbaFrame_BASE;
+
+class SwVbaFrame : public SwVbaFrame_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::text::XTextFrame > mxTextFrame;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaFrame( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::text::XTextFrame > xTextFrame );
+ virtual ~SwVbaFrame() override;
+
+ // Methods
+ virtual void SAL_CALL Select() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFRAME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaframes.cxx b/sw/source/ui/vba/vbaframes.cxx
new file mode 100644
index 0000000000..376082054b
--- /dev/null
+++ b/sw/source/ui/vba/vbaframes.cxx
@@ -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 .
+ */
+#include "vbaframes.hxx"
+#include "vbaframe.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class FramesEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< container::XIndexAccess> mxIndexAccess;
+ uno::Reference< frame::XModel > mxModel;
+ sal_Int32 mnCurrentPos;
+public:
+ /// @throws uno::RuntimeException
+ FramesEnumeration( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< container::XIndexAccess > xIndexAccess, uno::Reference< frame::XModel > xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext)), mxIndexAccess(std::move( xIndexAccess )), mxModel(std::move( xModel )), mnCurrentPos(0)
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mnCurrentPos < mxIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ uno::Reference< text::XTextFrame > xTextFrame( mxIndexAccess->getByIndex( mnCurrentPos++ ), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XFrame > ( new SwVbaFrame( mxParent, mxContext, mxModel, xTextFrame ) ) );
+ }
+
+};
+
+}
+
+SwVbaFrames::SwVbaFrames( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xFrames, uno::Reference< frame::XModel > xModel ): SwVbaFrames_BASE( xParent, xContext, xFrames ), mxModel(std::move( xModel ))
+{
+ mxFramesSupplier.set( mxModel, uno::UNO_QUERY_THROW );
+}
+// XEnumerationAccess
+uno::Type
+SwVbaFrames::getElementType()
+{
+ return cppu::UnoType<word::XFrame>::get();
+}
+
+uno::Reference< container::XEnumeration >
+SwVbaFrames::createEnumeration()
+{
+ return new FramesEnumeration( this, mxContext,m_xIndexAccess, mxModel );
+}
+
+uno::Any
+SwVbaFrames::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< text::XTextFrame > xTextFrame( aSource, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XFrame > ( new SwVbaFrame( this, mxContext, mxModel, xTextFrame ) ) );
+}
+
+OUString
+SwVbaFrames::getServiceImplName()
+{
+ return "SwVbaFrames";
+}
+
+css::uno::Sequence<OUString>
+SwVbaFrames::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Frames"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaframes.hxx b/sw/source/ui/vba/vbaframes.hxx
new file mode 100644
index 0000000000..6a0c20c3db
--- /dev/null
+++ b/sw/source/ui/vba/vbaframes.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAFRAMES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAFRAMES_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XFrames.hpp>
+#include <com/sun/star/text/XTextFramesSupplier.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XFrames > SwVbaFrames_BASE;
+
+class SwVbaFrames : public SwVbaFrames_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::text::XTextFramesSupplier > mxFramesSupplier;
+
+public:
+ SwVbaFrames( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xFrames, css::uno::Reference< css::frame::XModel > xModel );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaFrames_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAFRAMES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaglobals.cxx b/sw/source/ui/vba/vbaglobals.cxx
new file mode 100644
index 0000000000..3e9f7dbefe
--- /dev/null
+++ b/sw/source/ui/vba/vbaglobals.cxx
@@ -0,0 +1,224 @@
+/* -*- 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 "vbaglobals.hxx"
+#include "vbawordbasic.hxx"
+#include <sal/log.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <comphelper/sequence.hxx>
+
+#include "vbaapplication.hxx"
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::ooo::vba;
+
+SwVbaGlobals::SwVbaGlobals( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& rxContext ) : SwVbaGlobals_BASE( uno::Reference< XHelperInterface >(), rxContext, "WordDocumentContext" )
+{
+ SAL_INFO("sw.vba", "SwVbaGlobals::SwVbaGlobals()");
+ uno::Sequence< beans::PropertyValue > aInitArgs( aArgs.hasElements() ? 2 : 1 );
+ auto pInitArgs = aInitArgs.getArray();
+ pInitArgs[ 0 ].Name = "Application";
+ pInitArgs[ 0 ].Value <<= getApplication();
+ if ( aArgs.hasElements() )
+ {
+ pInitArgs[ 1 ].Name = "WordDocumentContext";
+ pInitArgs[ 1 ].Value <<= getXSomethingFromArgs< frame::XModel >( aArgs, 0 );
+ }
+ init( aInitArgs );
+}
+
+SwVbaGlobals::~SwVbaGlobals()
+{
+ SAL_INFO("sw.vba", "SwVbaGlobals::~SwVbaGlobals");
+}
+
+// XGlobals
+
+uno::Reference<word::XApplication > const &
+SwVbaGlobals::getApplication()
+{
+ SAL_INFO("sw.vba", "In SwVbaGlobals::getApplication");
+ if ( !mxApplication.is() )
+ mxApplication.set( new SwVbaApplication( mxContext) );
+
+ return mxApplication;
+}
+
+uno::Reference<word::XSystem > SAL_CALL
+SwVbaGlobals::getSystem()
+{
+ return getApplication()->getSystem();
+}
+
+uno::Reference< word::XDocument > SAL_CALL
+SwVbaGlobals::getActiveDocument()
+{
+ return getApplication()->getActiveDocument();
+}
+
+uno::Reference< word::XWindow > SAL_CALL
+SwVbaGlobals::getActiveWindow()
+{
+ return getApplication()->getActiveWindow();
+}
+
+OUString SAL_CALL
+SwVbaGlobals::getName()
+{
+ return getApplication()->getName();
+}
+
+uno::Reference<word::XOptions > SAL_CALL
+SwVbaGlobals::getOptions()
+{
+ return getApplication()->getOptions();
+}
+
+uno::Any SAL_CALL
+SwVbaGlobals::CommandBars( const uno::Any& aIndex )
+{
+ return getApplication()->CommandBars( aIndex );
+}
+
+uno::Any SAL_CALL
+SwVbaGlobals::Documents( const uno::Any& index )
+{
+ return getApplication()->Documents( index );
+}
+
+uno::Any SAL_CALL
+SwVbaGlobals::Addins( const uno::Any& index )
+{
+ return getApplication()->Addins( index );
+}
+
+uno::Any SAL_CALL
+SwVbaGlobals::Dialogs( const uno::Any& index )
+{
+ return getApplication()->Dialogs( index );
+}
+
+uno::Any SAL_CALL
+SwVbaGlobals::ListGalleries( const uno::Any& index )
+{
+ return getApplication()->ListGalleries( index );
+}
+
+uno::Reference<word::XSelection > SAL_CALL
+SwVbaGlobals::getSelection()
+{
+ return getApplication()->getSelection();
+}
+
+uno::Reference<word::XGlobals> SwVbaGlobals::getWord()
+{
+ return uno::Reference<word::XGlobals>(this);
+}
+
+uno::Reference<word::XWordBasic> SAL_CALL SwVbaGlobals::getWordBasic()
+{
+ assert(dynamic_cast<SwVbaApplication*>(getApplication().get()));
+ SwVbaApplication* pVbaApp = static_cast<SwVbaApplication*>(getApplication().get());
+ uno::Reference<word::XWordBasic> xWB(new SwWordBasic(pVbaApp));
+ return xWB;
+}
+
+float SAL_CALL SwVbaGlobals::CentimetersToPoints( float Centimeters )
+{
+ return getApplication()->CentimetersToPoints( Centimeters );
+}
+
+float SAL_CALL SwVbaGlobals::PointsToCentimeters( float Points )
+{
+ return getApplication()->PointsToCentimeters( Points );
+}
+
+float SAL_CALL SwVbaGlobals::PixelsToPoints( float Pixels, ::sal_Bool fVertical )
+{
+ return getApplication()->PixelsToPoints( Pixels, fVertical );
+}
+
+float SAL_CALL SwVbaGlobals::PointsToPixels( float Points, ::sal_Bool fVertical )
+{
+ return getApplication()->PointsToPixels( Points, fVertical );
+}
+
+float SAL_CALL SwVbaGlobals::InchesToPoints( float Inches )
+{
+ return getApplication()->InchesToPoints( Inches );
+}
+
+float SAL_CALL SwVbaGlobals::PointsToInches( float Points )
+{
+ return getApplication()->PointsToInches( Points );
+}
+
+float SAL_CALL SwVbaGlobals::MillimetersToPoints( float Millimeters )
+{
+ return getApplication()->MillimetersToPoints( Millimeters );
+}
+
+float SAL_CALL SwVbaGlobals::PointsToMillimeters( float Points )
+{
+ return getApplication()->PointsToMillimeters( Points );
+}
+
+float SAL_CALL SwVbaGlobals::PicasToPoints( float Picas )
+{
+ return getApplication()->PicasToPoints( Picas );
+}
+
+float SAL_CALL SwVbaGlobals::PointsToPicas( float Points )
+{
+ return getApplication()->PointsToPicas( Points );
+}
+
+OUString
+SwVbaGlobals::getServiceImplName()
+{
+ return "SwVbaGlobals";
+}
+
+uno::Sequence< OUString >
+SwVbaGlobals::getServiceNames()
+{
+ return { "ooo.vba.word.Globals" };
+}
+
+uno::Sequence< OUString >
+SwVbaGlobals::getAvailableServiceNames( )
+{
+ static const uno::Sequence<OUString> serviceNames = comphelper::concatSequences(
+ SwVbaGlobals_BASE::getAvailableServiceNames(),
+ uno::Sequence<OUString>{ "ooo.vba.word.Document",
+ // "ooo.vba.word.Globals",
+ // "ooo.vba.word.WrapFormat",
+ "com.sun.star.script.vba.VBATextEventProcessor" });
+ return serviceNames;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Writer_SwVbaGlobals_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new SwVbaGlobals(args, context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaglobals.hxx b/sw/source/ui/vba/vbaglobals.hxx
new file mode 100644
index 0000000000..c1713502df
--- /dev/null
+++ b/sw/source/ui/vba/vbaglobals.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAGLOBALS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAGLOBALS_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <ooo/vba/word/XGlobals.hpp>
+#include <ooo/vba/word/XApplication.hpp>
+#include <ooo/vba/word/XSystem.hpp>
+#include <ooo/vba/word/XOptions.hpp>
+#include <ooo/vba/word/XSelection.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vbahelper/vbaglobalbase.hxx>
+
+typedef ::cppu::ImplInheritanceHelper<VbaGlobalsBase, ov::word::XGlobals> SwVbaGlobals_BASE;
+
+class SwVbaGlobals : public SwVbaGlobals_BASE
+{
+private:
+ css::uno::Reference<ooo::vba::word::XApplication> mxApplication;
+
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference<ooo::vba::word::XApplication> const& getApplication();
+
+public:
+ SwVbaGlobals(css::uno::Sequence<css::uno::Any> const& aArgs,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext);
+ virtual ~SwVbaGlobals() override;
+
+ // XGlobals
+ virtual OUString SAL_CALL getName() override;
+ virtual css::uno::Reference<ooo::vba::word::XSystem> SAL_CALL getSystem() override;
+ virtual css::uno::Reference<ov::word::XDocument> SAL_CALL getActiveDocument() override;
+ virtual css::uno::Reference<ov::word::XWindow> SAL_CALL getActiveWindow() override;
+ virtual css::uno::Reference<ooo::vba::word::XOptions> SAL_CALL getOptions() override;
+ virtual css::uno::Reference<ooo::vba::word::XSelection> SAL_CALL getSelection() override;
+ virtual css::uno::Reference<ooo::vba::word::XGlobals> SAL_CALL getWord() override;
+ virtual css::uno::Reference<ooo::vba::word::XWordBasic> SAL_CALL getWordBasic() override;
+ virtual css::uno::Any SAL_CALL CommandBars(const css::uno::Any& aIndex) override;
+ virtual css::uno::Any SAL_CALL Documents(const css::uno::Any& aIndex) override;
+ virtual css::uno::Any SAL_CALL Addins(const css::uno::Any& aIndex) override;
+ virtual css::uno::Any SAL_CALL Dialogs(const css::uno::Any& aIndex) override;
+ virtual css::uno::Any SAL_CALL ListGalleries(const css::uno::Any& aIndex) override;
+ virtual float SAL_CALL CentimetersToPoints(float Centimeters) override;
+ virtual float SAL_CALL PointsToCentimeters(float Points) override;
+ virtual float SAL_CALL PixelsToPoints(float Pixels, ::sal_Bool fVertical) override;
+ virtual float SAL_CALL PointsToPixels(float Pixels, ::sal_Bool fVertical) override;
+ virtual float SAL_CALL InchesToPoints(float Inches) override;
+ virtual float SAL_CALL PointsToInches(float Points) override;
+ virtual float SAL_CALL MillimetersToPoints(float Millimeters) override;
+ virtual float SAL_CALL PointsToMillimeters(float Points) override;
+ virtual float SAL_CALL PicasToPoints(float Picas) override;
+ virtual float SAL_CALL PointsToPicas(float Points) override;
+
+ // XMultiServiceFactory
+ virtual css::uno::Sequence<OUString> SAL_CALL getAvailableServiceNames() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAGLOBALS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaheaderfooter.cxx b/sw/source/ui/vba/vbaheaderfooter.cxx
new file mode 100644
index 0000000000..a031b0ecda
--- /dev/null
+++ b/sw/source/ui/vba/vbaheaderfooter.cxx
@@ -0,0 +1,102 @@
+/* -*- 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 "vbaheaderfooter.hxx"
+#include <ooo/vba/word/WdHeaderFooterIndex.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include "vbarange.hxx"
+#include <utility>
+#include <vbahelper/vbashapes.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaHeaderFooter::SwVbaHeaderFooter( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xProps, bool isHeader, sal_Int32 index ) : SwVbaHeaderFooter_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxPageStyleProps(std::move( xProps )), mbHeader( isHeader ), mnIndex( index )
+{
+}
+
+sal_Bool SAL_CALL SwVbaHeaderFooter::getIsHeader()
+{
+ return mbHeader;
+}
+
+sal_Bool SAL_CALL SwVbaHeaderFooter::getLinkToPrevious()
+{
+ // seems always false
+ return false;
+}
+
+void SAL_CALL SwVbaHeaderFooter::setLinkToPrevious( sal_Bool /*_linktoprevious*/ )
+{
+ // not support in Writer
+}
+
+uno::Reference< word::XRange > SAL_CALL SwVbaHeaderFooter::getRange()
+{
+ OUString sPropsNameText;
+ if( mbHeader )
+ {
+ sPropsNameText = "HeaderText";
+ }
+ else
+ {
+ sPropsNameText = "FooterText";
+ }
+ if( mnIndex == word::WdHeaderFooterIndex::wdHeaderFooterEvenPages )
+ {
+ sPropsNameText += "Left";
+ }
+
+ uno::Reference< text::XText > xText( mxPageStyleProps->getPropertyValue( sPropsNameText ), uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW );
+ return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, xDocument, xText->getStart(), xText->getEnd(), xText ) );
+}
+
+uno::Any SAL_CALL
+SwVbaHeaderFooter::Shapes( const uno::Any& index )
+{
+ // #FIXME: only get the shapes in the current header/footer
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxModel, uno::UNO_QUERY_THROW );
+ //uno::Reference< drawing::XShapes > xShapes( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new ScVbaShapes( this, mxContext, xIndexAccess, mxModel ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+OUString
+SwVbaHeaderFooter::getServiceImplName()
+{
+ return "SwVbaHeaderFooter";
+}
+
+uno::Sequence< OUString >
+SwVbaHeaderFooter::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Pane"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaheaderfooter.hxx b/sw/source/ui/vba/vbaheaderfooter.hxx
new file mode 100644
index 0000000000..7425057b26
--- /dev/null
+++ b/sw/source/ui/vba/vbaheaderfooter.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTER_HXX
+
+#include <ooo/vba/word/XHeaderFooter.hpp>
+#include <ooo/vba/word/XRange.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XHeaderFooter > SwVbaHeaderFooter_BASE;
+
+class SwVbaHeaderFooter : public SwVbaHeaderFooter_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::beans::XPropertySet > mxPageStyleProps;
+ bool mbHeader;
+ sal_Int32 mnIndex;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaHeaderFooter( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::beans::XPropertySet > xProps, bool isHeader, sal_Int32 index );
+
+ // Attributes
+ virtual sal_Bool SAL_CALL getIsHeader() override;
+ virtual sal_Bool SAL_CALL getLinkToPrevious() override;
+ virtual void SAL_CALL setLinkToPrevious( sal_Bool _linktoprevious ) override;
+ virtual css::uno::Reference< ::ooo::vba::word::XRange > SAL_CALL getRange() override;
+ virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaheaderfooterhelper.cxx b/sw/source/ui/vba/vbaheaderfooterhelper.cxx
new file mode 100644
index 0000000000..987088b6a5
--- /dev/null
+++ b/sw/source/ui/vba/vbaheaderfooterhelper.cxx
@@ -0,0 +1,174 @@
+/* -*- 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 "vbaheaderfooterhelper.hxx"
+#include "wordvbahelper.hxx"
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+#define FIRST_PAGE 1
+
+// Class HeaderFooterHelper
+bool HeaderFooterHelper::isHeaderFooter( const uno::Reference< frame::XModel >& xModel )
+{
+ return isHeaderFooter( word::getCurrentXText( xModel ) );
+}
+
+bool HeaderFooterHelper::isHeaderFooter( const uno::Reference< text::XText >& xText )
+{
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xText, uno::UNO_QUERY_THROW );
+ OUString aImplName = xServiceInfo->getImplementationName();
+ return aImplName == "SwXHeadFootText";
+}
+
+bool HeaderFooterHelper::isHeader( const uno::Reference< frame::XModel >& xModel )
+{
+ const uno::Reference< text::XText > xCurrentText = word::getCurrentXText( xModel );
+ if( !isHeaderFooter( xCurrentText ) )
+ return false;
+
+ OUString aPropText = "HeaderText";
+ uno::Reference< style::XStyle > xPageStyle = word::getCurrentPageStyle( xModel );
+ uno::Reference< beans::XPropertySet > xPageProps( xPageStyle, uno::UNO_QUERY_THROW );
+ bool isShared = true;
+ xPageProps->getPropertyValue( "HeaderIsShared" ) >>= isShared;
+ if( !isShared )
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ if( 0 == xPageCursor->getPage() % 2 )
+ aPropText = "HeaderTextLeft";
+ else
+ aPropText = "HeaderTextRight";
+ }
+
+ uno::Reference< text::XText > xHeaderText( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRangeCompare > xTRC( xHeaderText, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xTR1( xCurrentText, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xTR2( xHeaderText, uno::UNO_QUERY_THROW );
+ try
+ {
+ if( xTRC->compareRegionStarts( xTR1, xTR2 ) == 0 )
+ return true;
+ }
+ catch (const lang::IllegalArgumentException&)
+ {
+ return false;
+ }
+
+ return false;
+}
+
+bool HeaderFooterHelper::isFirstPageHeader( const uno::Reference< frame::XModel >& xModel )
+{
+ if( isHeader( xModel ) )
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ // FIXME: getPage always returns 1
+ sal_Int32 nPage = xPageCursor->getPage();
+ return nPage == FIRST_PAGE;
+ }
+ return false;
+}
+
+bool HeaderFooterHelper::isEvenPagesHeader( const uno::Reference< frame::XModel >& xModel )
+{
+ if( isHeader( xModel ) )
+ {
+ uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( xModel ), uno::UNO_QUERY_THROW );
+ bool isShared = false;
+ xStyleProps->getPropertyValue("HeaderIsShared") >>= isShared;
+ if( !isShared )
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ return ( 0 == xPageCursor->getPage() % 2 );
+ }
+ }
+ return false;
+}
+
+bool HeaderFooterHelper::isFooter( const uno::Reference< frame::XModel >& xModel )
+{
+ const uno::Reference< text::XText > xCurrentText = word::getCurrentXText( xModel );
+ if( !isHeaderFooter( xCurrentText ) )
+ return false;
+
+ OUString aPropText = "FooterText";
+ uno::Reference< style::XStyle > xPageStyle = word::getCurrentPageStyle( xModel );
+ uno::Reference< beans::XPropertySet > xPageProps( xPageStyle, uno::UNO_QUERY_THROW );
+ bool isShared = true;
+ xPageProps->getPropertyValue( "FooterIsShared" ) >>= isShared;
+ if( !isShared )
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ if( 0 == xPageCursor->getPage() % 2 )
+ aPropText = "FooterTextLeft";
+ else
+ aPropText = "FooterTextRight";
+ }
+
+ uno::Reference< text::XText > xFooterText( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRangeCompare > xTRC( xFooterText, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xTR1( xCurrentText, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xTR2( xFooterText, uno::UNO_QUERY_THROW );
+ try
+ {
+ if( xTRC->compareRegionStarts( xTR1, xTR2 ) == 0 )
+ return true;
+ }
+ catch (const lang::IllegalArgumentException&)
+ {
+ return false;
+ }
+
+ return false;
+}
+
+bool HeaderFooterHelper::isFirstPageFooter( const uno::Reference< frame::XModel >& xModel )
+{
+ if( isFooter( xModel ) )
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ sal_Int32 nPage = xPageCursor->getPage();
+ return nPage == FIRST_PAGE;
+ }
+ return false;
+}
+
+bool HeaderFooterHelper::isEvenPagesFooter( const uno::Reference< frame::XModel >& xModel )
+{
+ if( isFooter( xModel ) )
+ {
+ uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( xModel ), uno::UNO_QUERY_THROW );
+ bool isShared = false;
+ xStyleProps->getPropertyValue("FooterIsShared") >>= isShared;
+ if( !isShared )
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ return ( 0 == xPageCursor->getPage() % 2 );
+ }
+ }
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaheaderfooterhelper.hxx b/sw/source/ui/vba/vbaheaderfooterhelper.hxx
new file mode 100644
index 0000000000..ca66b208ad
--- /dev/null
+++ b/sw/source/ui/vba/vbaheaderfooterhelper.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTERHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERFOOTERHELPER_HXX
+
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/text/XText.hpp>
+
+class HeaderFooterHelper
+{
+public:
+ /// @throws css::uno::RuntimeException
+ static bool isHeaderFooter(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static bool isHeaderFooter(const css::uno::Reference<css::text::XText>& xText);
+ /// @throws css::uno::RuntimeException
+ static bool isHeader(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static bool isFirstPageHeader(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static bool isEvenPagesHeader(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static bool isFooter(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static bool isFirstPageFooter(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static bool isEvenPagesFooter(const css::uno::Reference<css::frame::XModel>& xModel);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaheadersfooters.cxx b/sw/source/ui/vba/vbaheadersfooters.cxx
new file mode 100644
index 0000000000..be205d8e13
--- /dev/null
+++ b/sw/source/ui/vba/vbaheadersfooters.cxx
@@ -0,0 +1,141 @@
+/* -*- 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 "vbaheadersfooters.hxx"
+#include "vbaheaderfooter.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+// I assume there is only one headersfooters in Writer
+class HeadersFootersIndexAccess : public ::cppu::WeakImplHelper<container::XIndexAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+ uno::Reference< beans::XPropertySet > mxPageStyleProps;
+ bool mbHeader;
+
+public:
+ HeadersFootersIndexAccess( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xPageStyleProps, bool bHeader ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )), mxPageStyleProps(std::move( xPageStyleProps )), mbHeader( bHeader ) {}
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ // first page, even pages and primary page
+ return 3;
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if( Index < 1 || Index > 3 )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( mxParent, mxContext, mxModel, mxPageStyleProps, mbHeader, Index ) ) );
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XHeaderFooter>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+};
+
+class HeadersFootersEnumWrapper : public EnumerationHelper_BASE
+{
+ SwVbaHeadersFooters* m_pHeadersFooters;
+ sal_Int32 m_nIndex;
+public:
+ explicit HeadersFootersEnumWrapper( SwVbaHeadersFooters* _pHeadersFooters ) : m_pHeadersFooters( _pHeadersFooters ), m_nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex < m_pHeadersFooters->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex < m_pHeadersFooters->getCount() )
+ return m_pHeadersFooters->Item( uno::Any( ++m_nIndex ), uno::Any() );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaHeadersFooters::SwVbaHeadersFooters( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< beans::XPropertySet >& xPageStyleProps, bool isHeader ): SwVbaHeadersFooters_BASE( xParent, xContext, new HeadersFootersIndexAccess( xParent, xContext, xModel, xPageStyleProps, isHeader ) ), mxModel( xModel ), mxPageStyleProps( xPageStyleProps ), mbHeader( isHeader )
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaHeadersFooters::getCount()
+{
+ // wdHeaderFooterFirstPage, wdHeaderFooterPrimary and wdHeaderFooterEvenPages
+ return 3;
+}
+
+uno::Any SAL_CALL SwVbaHeadersFooters::Item( const uno::Any& Index1, const uno::Any& )
+{
+ sal_Int32 nIndex = 0;
+ Index1 >>= nIndex;
+ if( ( nIndex < 1 ) || ( nIndex > 3 ) )
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+ return uno::Any( uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( this, mxContext, mxModel, mxPageStyleProps, mbHeader, nIndex ) ) );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaHeadersFooters::getElementType()
+{
+ return cppu::UnoType<word::XHeaderFooter>::get();
+}
+uno::Reference< container::XEnumeration >
+
+SwVbaHeadersFooters::createEnumeration()
+{
+ return new HeadersFootersEnumWrapper( this );
+}
+
+uno::Any
+SwVbaHeadersFooters::createCollectionObject( const uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaHeadersFooters::getServiceImplName()
+{
+ return "SwVbaHeadersFooters";
+}
+
+uno::Sequence<OUString>
+SwVbaHeadersFooters::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.HeadersFooters"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaheadersfooters.hxx b/sw/source/ui/vba/vbaheadersfooters.hxx
new file mode 100644
index 0000000000..44aa77cfde
--- /dev/null
+++ b/sw/source/ui/vba/vbaheadersfooters.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERSFOOTERS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERSFOOTERS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XHeadersFooters.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XHeadersFooters > SwVbaHeadersFooters_BASE;
+
+class SwVbaHeadersFooters : public SwVbaHeadersFooters_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::beans::XPropertySet > mxPageStyleProps;
+ bool mbHeader;
+
+public:
+ SwVbaHeadersFooters( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::beans::XPropertySet >& xProps, bool isHeader );
+
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaHeadersFooters_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAHEADERSFOOTERS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbainformationhelper.cxx b/sw/source/ui/vba/vbainformationhelper.cxx
new file mode 100644
index 0000000000..9cda14b7b2
--- /dev/null
+++ b/sw/source/ui/vba/vbainformationhelper.cxx
@@ -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 .
+ */
+#include "vbainformationhelper.hxx"
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <tools/UnitConversion.hxx>
+#include "wordvbahelper.hxx"
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <vbahelper/vbahelper.hxx>
+#include <viewsh.hxx>
+#include <IDocumentLayoutAccess.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int32 DEFAULT_PAGE_DISTANCE = 500;
+
+sal_Int32 SwVbaInformationHelper::handleWdActiveEndPageNumber( const css::uno::Reference< css::text::XTextViewCursor >& xTVCursor )
+{
+ uno::Reference< text::XPageCursor > xPageCursor( xTVCursor, uno::UNO_QUERY_THROW );
+ return xPageCursor->getPage();
+}
+
+sal_Int32 SwVbaInformationHelper::handleWdNumberOfPagesInDocument( const css::uno::Reference< css::frame::XModel >& xModel )
+{
+ return word::getPageCount( xModel );
+}
+
+double SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextViewCursor >& xTVCursor )
+{
+ xTVCursor->collapseToStart();
+ uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( xModel ), uno::UNO_QUERY_THROW );
+ sal_Int32 nTopMargin = 0;
+ xStyleProps->getPropertyValue( "TopMargin" ) >>= nTopMargin;
+ sal_Int32 nCurrentPos = xTVCursor->getPosition().Y;
+
+ sal_Int32 nCurrentPage = handleWdActiveEndPageNumber( xTVCursor );
+ SwDoc* pDoc = word::getDocShell( xModel )->GetDoc();
+ SwViewShell* pViewSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+ sal_Int32 nPageHeight = pViewSh ? pViewSh->GetPageSize( nCurrentPage, false ).Height() : 0;
+ // FIXME: handle multiple page style
+ // it is very strange that the cursor position is incorrect when open Word file.
+ // e.g. if current cursor in the top left of the text body of the first page without header,
+ // the top value of current position should be 0, but is 201 when open a Word file.
+ nCurrentPos = nCurrentPos + nTopMargin - ( DEFAULT_PAGE_DISTANCE + convertTwipToMm100( nPageHeight ) ) * ( nCurrentPage - 1 );
+ return Millimeter::getInPoints( nCurrentPos );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbainformationhelper.hxx b/sw/source/ui/vba/vbainformationhelper.hxx
new file mode 100644
index 0000000000..c60b300cd4
--- /dev/null
+++ b/sw/source/ui/vba/vbainformationhelper.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAINFORMATIONHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAINFORMATIONHELPER_HXX
+
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+class SwVbaInformationHelper
+{
+public:
+ /// @throws css::uno::RuntimeException
+ static sal_Int32
+ handleWdActiveEndPageNumber(const css::uno::Reference<css::text::XTextViewCursor>& xTVCursor);
+ /// @throws css::uno::RuntimeException
+ static sal_Int32
+ handleWdNumberOfPagesInDocument(const css::uno::Reference<css::frame::XModel>& xModel);
+ /// @throws css::uno::RuntimeException
+ static double handleWdVerticalPositionRelativeToPage(
+ const css::uno::Reference<css::frame::XModel>& xModel,
+ const css::uno::Reference<css::text::XTextViewCursor>& xTVCursor);
+ //static double verticalPositionRelativeToPageBoundary( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextViewCursor >& xTVCursor, const css::uno::Reference< css::beans::XPropertySet >& xStyleProps ) throw( css::uno::RuntimeException );
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAINFORMATIONHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistformat.cxx b/sw/source/ui/vba/vbalistformat.cxx
new file mode 100644
index 0000000000..efcbf2dbe8
--- /dev/null
+++ b/sw/source/ui/vba/vbalistformat.cxx
@@ -0,0 +1,328 @@
+/* -*- 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 "vbalistformat.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <ooo/vba/word/WdListApplyTo.hpp>
+#include <ooo/vba/word/WdDefaultListBehavior.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/TabStop.hpp>
+#include <com/sun/star/text/PositionAndSpaceMode.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <comphelper/sequence.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <editeng/numitem.hxx>
+#include "vbalisttemplate.hxx"
+
+#include <vector>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaListFormat::SwVbaListFormat( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextRange > xTextRange ) : SwVbaListFormat_BASE( rParent, rContext ), mxTextRange(std::move( xTextRange ))
+{
+}
+
+SwVbaListFormat::~SwVbaListFormat()
+{
+}
+
+void SAL_CALL SwVbaListFormat::ApplyListTemplate( const css::uno::Reference< word::XListTemplate >& ListTemplate, const css::uno::Any& ContinuePreviousList, const css::uno::Any& ApplyTo, const css::uno::Any& DefaultListBehavior )
+{
+ bool bContinuePreviousList = true;
+ if( ContinuePreviousList.hasValue() )
+ ContinuePreviousList >>= bContinuePreviousList;
+
+ // "applyto" must be current selection
+ sal_Int32 bApplyTo = word::WdListApplyTo::wdListApplyToSelection;
+ if( ApplyTo.hasValue() )
+ ApplyTo >>= bApplyTo;
+ if( bApplyTo != word::WdListApplyTo::wdListApplyToSelection )
+ throw uno::RuntimeException();
+
+ // default behaviour must be wdWord8ListBehavior
+ sal_Int32 nDefaultListBehavior = word::WdDefaultListBehavior::wdWord8ListBehavior;
+ if( DefaultListBehavior.hasValue() )
+ DefaultListBehavior >>= nDefaultListBehavior;
+ if( nDefaultListBehavior != word::WdDefaultListBehavior::wdWord8ListBehavior )
+ throw uno::RuntimeException();
+
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( mxTextRange, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
+ if (!xEnum->hasMoreElements())
+ return;
+
+ SwVbaListTemplate& rListTemplate = dynamic_cast<SwVbaListTemplate&>(*ListTemplate);
+
+ bool isFirstElement = true;
+ do
+ {
+ uno::Reference< beans::XPropertySet > xProps( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+ if( isFirstElement )
+ {
+ bool isNumberingRestart = !bContinuePreviousList;
+ xProps->setPropertyValue("ParaIsNumberingRestart", uno::Any( isNumberingRestart ) );
+ if( isNumberingRestart )
+ {
+ xProps->setPropertyValue("NumberingStartValue", uno::Any( sal_Int16(1) ) );
+ }
+ isFirstElement = false;
+ }
+ else
+ {
+ xProps->setPropertyValue("ParaIsNumberingRestart", uno::Any( false ) );
+ }
+ rListTemplate.applyListTemplate( xProps );
+ }
+ while( xEnum->hasMoreElements() );
+}
+
+template <class Ref>
+static void addParagraphsToList(const Ref& a,
+ std::vector<css::uno::Reference<css::beans::XPropertySet>>& rList)
+{
+ if (css::uno::Reference<css::lang::XServiceInfo> xInfo{ a, css::uno::UNO_QUERY })
+ {
+ if (xInfo->supportsService("com.sun.star.text.Paragraph"))
+ {
+ rList.emplace_back(xInfo, css::uno::UNO_QUERY_THROW);
+ }
+ else if (xInfo->supportsService("com.sun.star.text.TextTable"))
+ {
+ css::uno::Reference<css::text::XTextTable> xTable(xInfo, css::uno::UNO_QUERY_THROW);
+ const auto aNames = xTable->getCellNames();
+ for (const auto& rName : aNames)
+ {
+ addParagraphsToList(xTable->getCellByName(rName), rList);
+ }
+ }
+ }
+ if (css::uno::Reference<css::container::XEnumerationAccess> xEnumAccess{ a,
+ css::uno::UNO_QUERY })
+ {
+ auto xEnum = xEnumAccess->createEnumeration();
+ while (xEnum->hasMoreElements())
+ addParagraphsToList(xEnum->nextElement(), rList);
+ }
+}
+
+void SAL_CALL SwVbaListFormat::ConvertNumbersToText( )
+{
+ css::uno::Reference<css::frame::XModel> xModel(getThisWordDoc(mxContext));
+ css::uno::Reference<css::document::XUndoManagerSupplier> xUndoSupplier(
+ xModel, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::document::XUndoManager> xUndoManager(xUndoSupplier->getUndoManager());
+ xUndoManager->enterUndoContext("ConvertNumbersToText");
+ xModel->lockControllers();
+ comphelper::ScopeGuard g([xModel, xUndoManager]() {
+ xModel->unlockControllers();
+ xUndoManager->leaveUndoContext();
+ });
+
+ std::vector<css::uno::Reference<css::beans::XPropertySet>> aParagraphs;
+ addParagraphsToList(mxTextRange, aParagraphs);
+
+ // in reverse order, to get proper label strings
+ for (auto iter = aParagraphs.rbegin(); iter != aParagraphs.rend(); ++iter)
+ {
+ auto& rPropertySet = *iter;
+ if (bool bNumber; (rPropertySet->getPropertyValue("NumberingIsNumber") >>= bNumber) && bNumber)
+ {
+ css::uno::Reference<css::text::XTextRange> xRange(rPropertySet, css::uno::UNO_QUERY_THROW);
+ OUString sLabelString;
+ rPropertySet->getPropertyValue("ListLabelString") >>= sLabelString;
+ // sal_Int16 nAdjust = SAL_MAX_INT16; // TODO?
+ sal_Int16 nNumberingType = SAL_MAX_INT16; // css::style::NumberingType
+ sal_Int16 nPositionAndSpaceMode = SAL_MAX_INT16;
+ sal_Int16 nLabelFollowedBy = SAL_MAX_INT16;
+ sal_Int32 nListtabStopPosition = SAL_MAX_INT32;
+ sal_Int32 nFirstLineIndent = SAL_MAX_INT32;
+ sal_Int32 nIndentAt = SAL_MAX_INT32;
+ sal_Int32 nLeftMargin = SAL_MAX_INT32;
+ sal_Int32 nSymbolTextDistance = SAL_MAX_INT32;
+ sal_Int32 nFirstLineOffset = SAL_MAX_INT32;
+ OUString sCharStyleName, sBulletChar;
+ css::awt::FontDescriptor aBulletFont;
+ bool bHasFont;
+ css::util::Color aBulletColor = css::util::Color(COL_AUTO);
+ bool bHasColor;
+
+ {
+ sal_uInt16 nLevel = SAL_MAX_UINT16;
+ rPropertySet->getPropertyValue("NumberingLevel") >>= nLevel;
+ css::uno::Reference<css::container::XIndexAccess> xNumberingRules;
+ rPropertySet->getPropertyValue("NumberingRules") >>= xNumberingRules;
+ comphelper::SequenceAsHashMap aLevelRule(xNumberingRules->getByIndex(nLevel));
+
+ // See offapi/com/sun/star/text/NumberingLevel.idl
+ aLevelRule["CharStyleName"] >>= sCharStyleName;
+ aLevelRule["NumberingType"] >>= nNumberingType;
+ // TODO: aLevelRule["Adjust"] >>= nAdjust; // HoriOrientation::LEFT/RIGHT/CENTER
+ aLevelRule["PositionAndSpaceMode"] >>= nPositionAndSpaceMode;
+
+ // for css::text::PositionAndSpaceMode::LABEL_ALIGNMENT
+ aLevelRule["LabelFollowedBy"] >>= nLabelFollowedBy;
+ aLevelRule["ListtabStopPosition"] >>= nListtabStopPosition;
+ aLevelRule["FirstLineIndent"] >>= nFirstLineIndent;
+ aLevelRule["IndentAt"] >>= nIndentAt;
+
+ // for css::text::PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION
+ aLevelRule["LeftMargin"] >>= nLeftMargin;
+ aLevelRule["SymbolTextDistance"] >>= nSymbolTextDistance;
+ aLevelRule["FirstLineOffset"] >>= nFirstLineOffset;
+
+ aLevelRule["BulletChar"] >>= sBulletChar;
+ bHasFont = (aLevelRule["BulletFont"] >>= aBulletFont);
+ bHasColor = (aLevelRule["BulletColor"] >>= aBulletColor);
+ }
+
+ if (nNumberingType != css::style::NumberingType::BITMAP) // TODO
+ {
+ if (nPositionAndSpaceMode
+ == css::text::PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION)
+ {
+ nIndentAt = nLeftMargin;
+ nFirstLineIndent = nFirstLineOffset;
+ nListtabStopPosition = nSymbolTextDistance;
+ nLabelFollowedBy = SvxNumberFormat::LabelFollowedBy::LISTTAB;
+ }
+
+ switch (nLabelFollowedBy)
+ {
+ case SvxNumberFormat::LabelFollowedBy::LISTTAB:
+ sLabelString += "\t";
+ break;
+ case SvxNumberFormat::LabelFollowedBy::SPACE:
+ sLabelString += " ";
+ break;
+ case SvxNumberFormat::LabelFollowedBy::NEWLINE:
+ sLabelString += "\n";
+ break;
+ }
+
+ css::uno::Reference<css::text::XTextRange> xNumberText(xRange->getStart());
+ xNumberText->setString(sLabelString);
+ css::uno::Reference<css::beans::XPropertySet> xNumberProps(
+ xNumberText, css::uno::UNO_QUERY_THROW);
+ if (!sCharStyleName.isEmpty())
+ xNumberProps->setPropertyValue("CharStyleName", css::uno::Any(sCharStyleName));
+
+ if (nNumberingType == css::style::NumberingType::CHAR_SPECIAL)
+ {
+ css::uno::Reference<css::text::XTextRange> xBulletText(xNumberText->getStart());
+ xBulletText->setString(sBulletChar);
+
+ std::unordered_map<OUString, css::uno::Any> aNameValues;
+ if (bHasFont)
+ {
+ aNameValues.insert({
+ { "CharFontName", css::uno::Any(aBulletFont.Name) },
+ { "CharFontStyleName", css::uno::Any(aBulletFont.StyleName) },
+ { "CharFontFamily", css::uno::Any(aBulletFont.Family) },
+ { "CharFontCharSet", css::uno::Any(aBulletFont.CharSet) },
+ { "CharWeight", css::uno::Any(aBulletFont.Weight) },
+ { "CharUnderline", css::uno::Any(aBulletFont.Underline) },
+ { "CharStrikeout", css::uno::Any(aBulletFont.Strikeout) },
+ { "CharAutoKerning", css::uno::Any(aBulletFont.Kerning) },
+ { "CharFontPitch", css::uno::Any(aBulletFont.Pitch) },
+ { "CharWordMode", css::uno::Any(aBulletFont.WordLineMode) },
+ { "CharRotation", css::uno::Any(static_cast<sal_Int16>(
+ std::round(aBulletFont.Orientation * 10))) },
+ });
+ if (aBulletFont.Height)
+ aNameValues["CharHeight"] <<= aBulletFont.Height;
+ }
+ if (bHasColor)
+ {
+ aNameValues["CharColor"] <<= aBulletColor;
+ }
+
+ if (css::uno::Reference<css::beans::XMultiPropertySet> xBulletMultiProps{
+ xBulletText, css::uno::UNO_QUERY })
+ {
+ xBulletMultiProps->setPropertyValues(
+ comphelper::mapKeysToSequence(aNameValues),
+ comphelper::mapValuesToSequence(aNameValues));
+ }
+ else
+ {
+ css::uno::Reference<css::beans::XPropertySet> xBulletProps(
+ xBulletText, css::uno::UNO_QUERY_THROW);
+ for (const auto& [rName, rVal] : aNameValues)
+ xBulletProps->setPropertyValue(rName, rVal);
+ }
+ }
+ else
+ {
+ // TODO: css::style::NumberingType::BITMAP
+ }
+
+ rPropertySet->setPropertyValue("ParaLeftMargin", css::uno::Any(nIndentAt));
+ rPropertySet->setPropertyValue("ParaFirstLineIndent", css::uno::Any(nFirstLineIndent));
+ if (nLabelFollowedBy == SvxNumberFormat::LabelFollowedBy::LISTTAB)
+ {
+ css::uno::Sequence<css::style::TabStop> stops;
+ rPropertySet->getPropertyValue("ParaTabStops") >>= stops;
+ css::style::TabStop tabStop{};
+ tabStop.Position = nListtabStopPosition;
+ tabStop.Alignment = com::sun::star::style::TabAlign::TabAlign_LEFT;
+ tabStop.FillChar = ' ';
+ rPropertySet->setPropertyValue("ParaTabStops",
+ css::uno::Any(comphelper::combineSequences({ tabStop }, stops)));
+ // FIXME: What if added tap stop is greater than already defined ones?
+ }
+ }
+ else
+ {
+ continue; // for now, keep such lists as is
+ }
+
+ // In case of higher outline levels, each assignment of empty value just sets level 1
+ while (rPropertySet->getPropertyValue("NumberingRules") != css::uno::Any())
+ {
+ rPropertySet->setPropertyValue("NumberingRules", css::uno::Any());
+ }
+ }
+ }
+}
+
+OUString
+SwVbaListFormat::getServiceImplName()
+{
+ return "SwVbaListFormat";
+}
+
+uno::Sequence< OUString >
+SwVbaListFormat::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.ListFormat"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistformat.hxx b/sw/source/ui/vba/vbalistformat.hxx
new file mode 100644
index 0000000000..378a42fd62
--- /dev/null
+++ b/sw/source/ui/vba/vbalistformat.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTFORMAT_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTFORMAT_HXX
+
+#include <ooo/vba/word/XListFormat.hpp>
+#include <ooo/vba/word/XListTemplate.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListFormat > SwVbaListFormat_BASE;
+
+class SwVbaListFormat : public SwVbaListFormat_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextRange > mxTextRange;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListFormat( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextRange > xTextRange );
+ virtual ~SwVbaListFormat() override;
+
+ // Methods
+ virtual void SAL_CALL ApplyListTemplate( const css::uno::Reference< ::ooo::vba::word::XListTemplate >& ListTemplate, const css::uno::Any& ContinuePreviousList, const css::uno::Any& ApplyTo, const css::uno::Any& DefaultListBehavior ) override;
+ virtual void SAL_CALL ConvertNumbersToText( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTFORMAT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistgalleries.cxx b/sw/source/ui/vba/vbalistgalleries.cxx
new file mode 100644
index 0000000000..9c047b1b64
--- /dev/null
+++ b/sw/source/ui/vba/vbalistgalleries.cxx
@@ -0,0 +1,108 @@
+/* -*- 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 "vbalistgalleries.hxx"
+#include "vbalistgallery.hxx"
+#include <ooo/vba/word/WdListGalleryType.hpp>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class ListGalleriesEnumWrapper : public EnumerationHelper_BASE
+{
+ SwVbaListGalleries* m_pListGalleries;
+ sal_Int32 m_nIndex;
+public:
+ explicit ListGalleriesEnumWrapper( SwVbaListGalleries* pGalleries ) : m_pListGalleries( pGalleries ), m_nIndex( 1 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex <= m_pListGalleries->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex <= m_pListGalleries->getCount() )
+ return m_pListGalleries->Item( uno::Any( m_nIndex++ ), uno::Any() );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaListGalleries::SwVbaListGalleries( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextDocument > xTextDoc ) : SwVbaListGalleries_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >() ), mxTextDocument(std::move( xTextDoc ))
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaListGalleries::getCount()
+{
+ // 3 types of list( bullet, numbered and outline )
+ return 3;
+}
+
+uno::Any SAL_CALL SwVbaListGalleries::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ )
+{
+ sal_Int32 nIndex = 0;
+ if( Index1 >>= nIndex )
+ {
+ if( nIndex == word::WdListGalleryType::wdBulletGallery
+ || nIndex == word::WdListGalleryType::wdNumberGallery
+ || nIndex == word::WdListGalleryType::wdOutlineNumberGallery )
+ return uno::Any( uno::Reference< word::XListGallery >( new SwVbaListGallery( this, mxContext, mxTextDocument, nIndex ) ) );
+ }
+ throw uno::RuntimeException("Index out of bounds" );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaListGalleries::getElementType()
+{
+ return cppu::UnoType<word::XListGallery>::get();
+}
+
+uno::Reference< container::XEnumeration >
+SwVbaListGalleries::createEnumeration()
+{
+ return new ListGalleriesEnumWrapper( this );
+}
+
+uno::Any
+SwVbaListGalleries::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaListGalleries::getServiceImplName()
+{
+ return "SwVbaListGalleries";
+}
+
+css::uno::Sequence<OUString>
+SwVbaListGalleries::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.ListGalleries"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistgalleries.hxx b/sw/source/ui/vba/vbalistgalleries.hxx
new file mode 100644
index 0000000000..9eb8f58d93
--- /dev/null
+++ b/sw/source/ui/vba/vbalistgalleries.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERIES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERIES_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XListGalleries.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XListGalleries > SwVbaListGalleries_BASE;
+
+class SwVbaListGalleries : public SwVbaListGalleries_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListGalleries( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextDocument > xTextDoc );
+
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaListGalleries_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERIES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistgallery.cxx b/sw/source/ui/vba/vbalistgallery.cxx
new file mode 100644
index 0000000000..8eae71df8e
--- /dev/null
+++ b/sw/source/ui/vba/vbalistgallery.cxx
@@ -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 .
+ */
+#include <utility>
+
+#include "vbalistgallery.hxx"
+#include "vbalisttemplates.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaListGallery::SwVbaListGallery( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDoc, sal_Int32 nType ) : SwVbaListGallery_BASE( rParent, rContext ), mxTextDocument(std::move( xTextDoc )), mnType( nType )
+{
+}
+
+SwVbaListGallery::~SwVbaListGallery()
+{
+}
+
+uno::Any SAL_CALL
+SwVbaListGallery::ListTemplates( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaListTemplates( mxParent, mxContext, mxTextDocument, mnType ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+OUString
+SwVbaListGallery::getServiceImplName()
+{
+ return "SwVbaListGallery";
+}
+
+uno::Sequence< OUString >
+SwVbaListGallery::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.ListGallery"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistgallery.hxx b/sw/source/ui/vba/vbalistgallery.hxx
new file mode 100644
index 0000000000..2b288aa266
--- /dev/null
+++ b/sw/source/ui/vba/vbalistgallery.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERY_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERY_HXX
+
+#include <ooo/vba/word/XListGallery.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListGallery > SwVbaListGallery_BASE;
+
+class SwVbaListGallery : public SwVbaListGallery_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ sal_Int32 mnType;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListGallery( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nType );
+ virtual ~SwVbaListGallery() override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL ListTemplates( const css::uno::Any& index ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTGALLERY_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalisthelper.cxx b/sw/source/ui/vba/vbalisthelper.cxx
new file mode 100644
index 0000000000..4b3ca1304e
--- /dev/null
+++ b/sw/source/ui/vba/vbalisthelper.cxx
@@ -0,0 +1,661 @@
+/* -*- 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 "vbalisthelper.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <sal/log.hxx>
+#include <ooo/vba/word/WdListGalleryType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int32 LIST_LEVEL_COUNT = 9;
+
+constexpr OUString UNO_NAME_PARENT_NUMBERING = u"ParentNumbering"_ustr;
+constexpr OUString UNO_NAME_PREFIX = u"Prefix"_ustr;
+constexpr OUString UNO_NAME_SUFFIX = u"Suffix"_ustr;
+constexpr OUString UNO_NAME_CHAR_STYLE_NAME = u"CharStyleName"_ustr;
+constexpr OUString UNO_NAME_NUMBERING_TYPE = u"NumberingType"_ustr;
+constexpr OUString UNO_NAME_BULLET_CHAR = u"BulletChar"_ustr;
+
+constexpr OUString CHAR_CLOSED_DOT = u"\u2022"_ustr;
+constexpr OUStringLiteral CHAR_EMPTY_DOT = u"o";
+constexpr OUString CHAR_SQUARE = u"\u2540"_ustr;
+constexpr OUStringLiteral CHAR_STAR_SYMBOL = u"\u272A";
+constexpr OUString CHAR_FOUR_DIAMONDS = u"\u2756"_ustr;
+constexpr OUStringLiteral CHAR_DIAMOND = u"\u2726";
+constexpr OUString CHAR_ARROW = u"\u27A2"_ustr;
+constexpr OUStringLiteral CHAR_CHECK_MARK = u"\u2713";
+
+SwVbaListHelper::SwVbaListHelper( css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType ) : mxTextDocument(std::move( xTextDoc )), mnGalleryType( nGalleryType ), mnTemplateType( nTemplateType )
+{
+ Init();
+}
+
+void SwVbaListHelper::Init()
+{
+ // set the numbering style name
+ switch( mnGalleryType )
+ {
+ case word::WdListGalleryType::wdBulletGallery:
+ {
+ msStyleName = "WdBullet";
+ break;
+ }
+ case word::WdListGalleryType::wdNumberGallery:
+ {
+ msStyleName = "WdNumber";
+ break;
+ }
+ case word::WdListGalleryType::wdOutlineNumberGallery:
+ {
+ msStyleName = "WdOutlineNumber";
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ msStyleName += OUString::number( mnTemplateType );
+
+ // get the numbering style
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxTextDocument, uno::UNO_QUERY_THROW );
+ mxStyleFamily.set( xStyleSupplier->getStyleFamilies()->getByName("NumberingStyles"), uno::UNO_QUERY_THROW );
+ SAL_INFO("sw.vba", "numbering style name: " << msStyleName );
+ if( mxStyleFamily->hasByName( msStyleName ) )
+ {
+ mxStyleProps.set( mxStyleFamily->getByName( msStyleName ), uno::UNO_QUERY_THROW );
+ mxNumberingRules.set( mxStyleProps->getPropertyValue("NumberingRules"), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ // create new numbering style
+ uno::Reference< lang::XMultiServiceFactory > xDocMSF( mxTextDocument, uno::UNO_QUERY_THROW );
+ mxStyleProps.set( xDocMSF->createInstance("com.sun.star.style.NumberingStyle"), uno::UNO_QUERY_THROW );
+ // insert this style into style family, or the property NumberingRules doesn't exist.
+ mxStyleFamily->insertByName( msStyleName, uno::Any( mxStyleProps ) );
+ mxStyleProps->getPropertyValue("NumberingRules") >>= mxNumberingRules;
+
+ CreateListTemplate();
+
+ mxStyleProps->setPropertyValue("NumberingRules", uno::Any( mxNumberingRules ) );
+ }
+}
+
+void SwVbaListHelper::CreateListTemplate()
+{
+ switch( mnGalleryType )
+ {
+ case word::WdListGalleryType::wdBulletGallery:
+ {
+ CreateBulletListTemplate();
+ break;
+ }
+ case word::WdListGalleryType::wdNumberGallery:
+ {
+ CreateNumberListTemplate();
+ break;
+ }
+ case word::WdListGalleryType::wdOutlineNumberGallery:
+ {
+ CreateOutlineNumberListTemplate();
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException();
+ }
+ }
+}
+
+void SwVbaListHelper::CreateBulletListTemplate()
+{
+ // there is only 1 level for each bullet list in MSWord
+ sal_Int32 nLevel = 0;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_CHAR_STYLE_NAME, uno::Any( OUString( "Bullet Symbols" ) ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::CHAR_SPECIAL) ) );
+
+ OUString aBulletChar;
+ switch( mnTemplateType )
+ {
+ case 1:
+ {
+ aBulletChar = CHAR_CLOSED_DOT;
+ break;
+ }
+ case 2:
+ {
+ aBulletChar = CHAR_EMPTY_DOT;
+ break;
+ }
+ case 3:
+ {
+ aBulletChar = CHAR_SQUARE;
+ break;
+ }
+ case 4:
+ {
+ aBulletChar = CHAR_STAR_SYMBOL;
+ break;
+ }
+ case 5:
+ {
+ aBulletChar = CHAR_FOUR_DIAMONDS;
+ break;
+ }
+ case 6:
+ {
+ aBulletChar = CHAR_ARROW;
+ break;
+ }
+ case 7:
+ {
+ aBulletChar = CHAR_CHECK_MARK;
+ break;
+ }
+ default:
+ {
+ // we only support 7 types template now
+ throw css::uno::RuntimeException();
+ }
+ }
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_BULLET_CHAR, uno::Any( aBulletChar ) );
+
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+}
+
+void SwVbaListHelper::CreateNumberListTemplate()
+{
+ // there is only 1 level for each bullet list in MSWord
+ sal_Int32 nLevel = 0;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+
+ sal_Int16 nNumberingType = 0;
+ OUString sSuffix;
+ switch( mnTemplateType )
+ {
+ case 1:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sSuffix = ".";
+ break;
+ }
+ case 2:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sSuffix = ")";
+ break;
+ }
+ case 3:
+ {
+ nNumberingType = style::NumberingType::ROMAN_UPPER;
+ sSuffix = ".";
+ break;
+ }
+ case 4:
+ {
+ nNumberingType = style::NumberingType::CHARS_UPPER_LETTER;
+ sSuffix = ".";
+ break;
+ }
+ case 5:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sSuffix = ")";
+ break;
+ }
+ case 6:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sSuffix = ".";
+ break;
+ }
+ case 7:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sSuffix = ".";
+ break;
+ }
+ default:
+ {
+ // we only support 7 types template now
+ throw css::uno::RuntimeException();
+ }
+ }
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) );
+
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+}
+
+void SwVbaListHelper::CreateOutlineNumberListTemplate()
+{
+ switch( mnTemplateType )
+ {
+ case 1:
+ {
+ CreateOutlineNumberForType1();
+ break;
+ }
+ case 2:
+ {
+ CreateOutlineNumberForType2();
+ break;
+ }
+ case 3:
+ {
+ CreateOutlineNumberForType3();
+ break;
+ }
+ case 4:
+ {
+ CreateOutlineNumberForType4();
+ break;
+ }
+ case 5:
+ {
+ CreateOutlineNumberForType5();
+ break;
+ }
+ case 6:
+ {
+ CreateOutlineNumberForType6();
+ break;
+ }
+ case 7:
+ {
+ CreateOutlineNumberForType7();
+ break;
+ }
+ default:
+ {
+ // we only support 7 types template now
+ throw css::uno::RuntimeException();
+ }
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType1()
+{
+ sal_Int16 nNumberingType = 0;
+ OUString sPrefix;
+ OUString sSuffix;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ switch( nLevel )
+ {
+ case 0:
+ case 1:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 2:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 3:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 4:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 5:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 6:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ case 7:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ case 8:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ }
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( sPrefix ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) );
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType2()
+{
+ sal_Int16 nParentNumbering = 0;
+ OUString sSuffix( '.' );
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::ARABIC) ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) );
+ if( nLevel != 0 )
+ {
+ nParentNumbering = sal_Int16( nLevel - 1 );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PARENT_NUMBERING, uno::Any( nParentNumbering ) );
+ }
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType3()
+{
+ OUString aBulletChar;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::CHAR_SPECIAL) ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_CHAR_STYLE_NAME, uno::Any( OUString("Bullet Symbols") ) );
+ switch( nLevel )
+ {
+ case 0:
+ {
+ aBulletChar = CHAR_FOUR_DIAMONDS;
+ break;
+ }
+ case 1:
+ case 5:
+ {
+ aBulletChar = CHAR_ARROW;
+ break;
+ }
+ case 2:
+ case 6:
+ {
+ aBulletChar = CHAR_SQUARE;
+ break;
+ }
+ case 3:
+ case 7:
+ {
+ aBulletChar = CHAR_CLOSED_DOT;
+ break;
+ }
+ case 4:
+ case 8:
+ {
+ aBulletChar = CHAR_DIAMOND;
+ break;
+ }
+ }
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_BULLET_CHAR, uno::Any( aBulletChar ) );
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType4()
+{
+ sal_Int16 nNumberingType = 0;
+ OUString sPrefix;
+ OUString sSuffix;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ switch( nLevel )
+ {
+ case 0:
+ {
+ nNumberingType = style::NumberingType::ROMAN_UPPER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ case 1:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix.clear();
+ sSuffix = ".";
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PARENT_NUMBERING, uno::Any( sal_Int16(0) ) );
+ break;
+ }
+ case 2:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 3:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 4:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 5:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 6:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 7:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ case 8:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ }
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( sPrefix ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) );
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType5()
+{
+ sal_Int16 nParentNumbering = 0;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::ARABIC) ) );
+ if( nLevel != 0 )
+ {
+ nParentNumbering = sal_Int16( nLevel - 1 );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PARENT_NUMBERING, uno::Any( nParentNumbering ) );
+ }
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType6()
+{
+ sal_Int16 nNumberingType = 0;
+ OUString sPrefix;
+ OUString sSuffix;
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ switch( nLevel )
+ {
+ case 0:
+ {
+ nNumberingType = style::NumberingType::ROMAN_UPPER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ case 1:
+ {
+ nNumberingType = style::NumberingType::CHARS_UPPER_LETTER;
+ sPrefix.clear();
+ sSuffix = ".";
+ break;
+ }
+ case 2:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 3:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix.clear();
+ sSuffix = ")";
+ break;
+ }
+ case 4:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 5:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 6:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix = "(";
+ sSuffix = ")";
+ break;
+ }
+ case 7:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER;
+ sPrefix = "(";
+ sSuffix = ".";
+ break;
+ }
+ case 8:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ sPrefix = "(";
+ sSuffix = ".";
+ break;
+ }
+ }
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( nNumberingType ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( sPrefix ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_SUFFIX, uno::Any( sSuffix ) );
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+void SwVbaListHelper::CreateOutlineNumberForType7()
+{
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+
+ for( sal_Int32 nLevel = 0; nLevel < LIST_LEVEL_COUNT; nLevel++ )
+ {
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_NUMBERING_TYPE, uno::Any( sal_Int16(style::NumberingType::ARABIC) ) );
+ setOrAppendPropertyValue( aPropertyValues, UNO_NAME_PREFIX, uno::Any( OUString("Chapter ") ) );
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ }
+}
+
+uno::Any SwVbaListHelper::getPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName )
+{
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ return getPropertyValue( aPropertyValues, sName );
+}
+
+void SwVbaListHelper::setPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName, const css::uno::Any& aValue )
+{
+ uno::Sequence< beans::PropertyValue > aPropertyValues;
+ mxNumberingRules->getByIndex( nLevel ) >>= aPropertyValues;
+ setOrAppendPropertyValue( aPropertyValues, sName, aValue );
+ mxNumberingRules->replaceByIndex( nLevel, uno::Any( aPropertyValues ) );
+ mxStyleProps->setPropertyValue("NumberingRules", uno::Any( mxNumberingRules ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalisthelper.hxx b/sw/source/ui/vba/vbalisthelper.hxx
new file mode 100644
index 0000000000..599e4f6864
--- /dev/null
+++ b/sw/source/ui/vba/vbalisthelper.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/.
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTHELPER_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+#include <memory>
+
+class SwVbaListHelper;
+typedef std::shared_ptr< SwVbaListHelper > SwVbaListHelperRef;
+
+class SwVbaListHelper
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ css::uno::Reference< css::container::XIndexReplace > mxNumberingRules;
+ css::uno::Reference< css::container::XNameContainer > mxStyleFamily;
+ css::uno::Reference< css::beans::XPropertySet > mxStyleProps;
+ sal_Int32 mnGalleryType;
+ sal_Int32 mnTemplateType;
+ OUString msStyleName;
+
+ /// @throws css::uno::RuntimeException
+ void Init();
+ /// @throws css::uno::RuntimeException
+ void CreateListTemplate();
+ /// @throws css::uno::RuntimeException
+ void CreateBulletListTemplate();
+ /// @throws css::uno::RuntimeException
+ void CreateNumberListTemplate();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberListTemplate();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType1();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType2();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType3();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType4();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType5();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType6();
+ /// @throws css::uno::RuntimeException
+ void CreateOutlineNumberForType7();
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListHelper( css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType );
+
+ sal_Int32 getGalleryType() const { return mnGalleryType; }
+ const css::uno::Reference< css::container::XIndexReplace >& getNumberingRules() const { return mxNumberingRules; }
+ /// @throws css::uno::RuntimeException
+ css::uno::Any getPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName );
+ /// @throws css::uno::RuntimeException
+ void setPropertyValueWithNameAndLevel( sal_Int32 nLevel, const OUString& sName, const css::uno::Any& aValue );
+
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistlevel.cxx b/sw/source/ui/vba/vbalistlevel.cxx
new file mode 100644
index 0000000000..43f16e8524
--- /dev/null
+++ b/sw/source/ui/vba/vbalistlevel.cxx
@@ -0,0 +1,386 @@
+/* -*- 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 "vbalistlevel.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <ooo/vba/word/WdListNumberStyle.hpp>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <ooo/vba/word/WdListLevelAlignment.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaListLevel::SwVbaListLevel( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, SwVbaListHelperRef pHelper, sal_Int32 nLevel ) : SwVbaListLevel_BASE( rParent, rContext ), m_pListHelper(std::move( pHelper )), mnLevel( nLevel )
+{
+}
+
+SwVbaListLevel::~SwVbaListLevel()
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevel::getAlignment()
+{
+ sal_Int16 nAlignment = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "Adjust" ) >>= nAlignment;
+ switch( nAlignment )
+ {
+ case text::HoriOrientation::LEFT:
+ {
+ nAlignment = word::WdListLevelAlignment::wdListLevelAlignLeft;
+ break;
+ }
+ case text::HoriOrientation::RIGHT:
+ {
+ nAlignment = word::WdListLevelAlignment::wdListLevelAlignRight;
+ break;
+ }
+ case text::HoriOrientation::CENTER:
+ {
+ nAlignment = word::WdListLevelAlignment::wdListLevelAlignCenter;
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ return nAlignment;
+}
+
+void SAL_CALL SwVbaListLevel::setAlignment( ::sal_Int32 _alignment )
+{
+ sal_Int16 nAlignment = text::HoriOrientation::LEFT;
+ switch( _alignment )
+ {
+ case word::WdListLevelAlignment::wdListLevelAlignLeft:
+ {
+ nAlignment = text::HoriOrientation::LEFT;
+ break;
+ }
+ case word::WdListLevelAlignment::wdListLevelAlignRight:
+ {
+ nAlignment = text::HoriOrientation::RIGHT;
+ break;
+ }
+ case word::WdListLevelAlignment::wdListLevelAlignCenter:
+ {
+ nAlignment = text::HoriOrientation::CENTER;
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "Adjust", uno::Any( nAlignment ) );
+}
+
+uno::Reference< ::ooo::vba::word::XFont > SAL_CALL SwVbaListLevel::getFont()
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+void SAL_CALL SwVbaListLevel::setFont( const uno::Reference< ::ooo::vba::word::XFont >& /*_font*/ )
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevel::getIndex()
+{
+ return mnLevel + 1;
+}
+
+OUString SAL_CALL SwVbaListLevel::getLinkedStyle()
+{
+ // TODO:
+ return OUString();
+}
+
+void SAL_CALL SwVbaListLevel::setLinkedStyle( const OUString& /*_linkedstyle*/ )
+{
+ // TODO:
+}
+
+OUString SAL_CALL SwVbaListLevel::getNumberFormat()
+{
+ // TODO::
+ return OUString();
+}
+
+void SAL_CALL SwVbaListLevel::setNumberFormat( const OUString& /*_numberformat*/ )
+{
+ // TODO::
+}
+
+float SAL_CALL SwVbaListLevel::getNumberPosition()
+{
+ // indentAt + firstlineindent
+ sal_Int32 nIndentAt = 0;
+ sal_Int32 nFirstLineIndent = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent" ) >>= nFirstLineIndent;
+
+ sal_Int32 nResult = nIndentAt + nFirstLineIndent;
+
+ return static_cast< float >( Millimeter::getInPoints( nResult ) );
+}
+
+void SAL_CALL SwVbaListLevel::setNumberPosition( float _numberposition )
+{
+ sal_Int32 nNumberPosition = Millimeter::getInHundredthsOfOneMillimeter( _numberposition );
+
+ sal_Int32 nIndentAt = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt;
+
+ sal_Int32 nFirstLineIndent = nNumberPosition - nIndentAt;
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent", uno::Any( nFirstLineIndent ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevel::getNumberStyle()
+{
+ sal_Int16 nNumberingType = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "NumberingType" ) >>= nNumberingType;
+ switch( nNumberingType )
+ {
+ case style::NumberingType::CHAR_SPECIAL:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleBullet;
+ break;
+ }
+ case style::NumberingType::CHARS_UPPER_LETTER:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleUppercaseLetter;
+ break;
+ }
+ case style::NumberingType::CHARS_LOWER_LETTER:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleLowercaseLetter;
+ break;
+ }
+ case style::NumberingType::ROMAN_UPPER:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleUppercaseRoman;
+ break;
+ }
+ case style::NumberingType::ROMAN_LOWER:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleLowercaseRoman;
+ break;
+ }
+ case style::NumberingType::ARABIC:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleArabic;
+ break;
+ }
+ case style::NumberingType::NUMBER_NONE:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleNone;
+ break;
+ }
+ case style::NumberingType::FULLWIDTH_ARABIC:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleArabicFullWidth;
+ break;
+ }
+ case style::NumberingType::CIRCLE_NUMBER:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleNumberInCircle;
+ break;
+ }
+ case style::NumberingType::CHARS_ARABIC:
+ {
+ nNumberingType = word::WdListNumberStyle::wdListNumberStyleCardinalText;
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+ return nNumberingType;
+}
+
+void SAL_CALL SwVbaListLevel::setNumberStyle( ::sal_Int32 _numberstyle )
+{
+ sal_Int16 nNumberingType = 0;
+ switch( _numberstyle )
+ {
+ case word::WdListNumberStyle::wdListNumberStyleBullet:
+ {
+ nNumberingType = style::NumberingType::CHAR_SPECIAL;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleUppercaseLetter:
+ {
+ nNumberingType = style::NumberingType::CHARS_UPPER_LETTER_N;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleLowercaseLetter:
+ {
+ nNumberingType = style::NumberingType::CHARS_LOWER_LETTER_N;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleUppercaseRoman:
+ {
+ nNumberingType = style::NumberingType::ROMAN_UPPER;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleLowercaseRoman:
+ {
+ nNumberingType = style::NumberingType::ROMAN_LOWER;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleArabic:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleNone:
+ {
+ nNumberingType = style::NumberingType::NUMBER_NONE;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleArabicFullWidth:
+ {
+ nNumberingType = style::NumberingType::FULLWIDTH_ARABIC;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleNumberInCircle:
+ {
+ nNumberingType = style::NumberingType::CIRCLE_NUMBER;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleCardinalText:
+ {
+ nNumberingType = style::NumberingType::CHARS_ARABIC;
+ break;
+ }
+ case word::WdListNumberStyle::wdListNumberStyleOrdinal:
+ case word::WdListNumberStyle::wdListNumberStyleOrdinalText:
+ case word::WdListNumberStyle::wdListNumberStyleKanji:
+ case word::WdListNumberStyle::wdListNumberStyleKanjiDigit:
+ case word::WdListNumberStyle::wdListNumberStyleAiueoHalfWidth:
+ case word::WdListNumberStyle::wdListNumberStyleIrohaHalfWidth:
+ {
+ nNumberingType = style::NumberingType::ARABIC;
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "NumberingType", uno::Any( nNumberingType ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevel::getResetOnHigher()
+{
+ //seems not support?
+ return 0;
+}
+
+void SAL_CALL SwVbaListLevel::setResetOnHigher( ::sal_Int32 /*_resetonhigher*/ )
+{
+ //seems not support?
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevel::getStartAt()
+{
+ sal_Int16 nStartWith = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "StartWith" ) >>= nStartWith;
+ return nStartWith;
+}
+
+void SAL_CALL SwVbaListLevel::setStartAt( ::sal_Int32 _startat )
+{
+ sal_Int16 nStartWith = static_cast<sal_Int16>(_startat);
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "StartWith", uno::Any( nStartWith ) );
+}
+
+float SAL_CALL SwVbaListLevel::getTabPosition()
+{
+ sal_Int32 nTabPosition = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "ListtabStopPosition" ) >>= nTabPosition;
+
+ return static_cast< float >( Millimeter::getInPoints( nTabPosition ) );
+}
+
+void SAL_CALL SwVbaListLevel::setTabPosition( float _tabposition )
+{
+ sal_Int32 nTabPosition = Millimeter::getInHundredthsOfOneMillimeter( _tabposition );
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "ListtabStopPosition", uno::Any( nTabPosition ) );
+}
+
+float SAL_CALL SwVbaListLevel::getTextPosition()
+{
+ // indentAt
+ sal_Int32 nIndentAt = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt;
+
+ return static_cast< float >( Millimeter::getInPoints( nIndentAt ) );
+}
+
+void SAL_CALL SwVbaListLevel::setTextPosition( float _textposition )
+{
+ sal_Int32 nIndentAt = 0;
+ sal_Int32 nFirstLineIndent = 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "IndentAt" ) >>= nIndentAt;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent" ) >>= nFirstLineIndent;
+
+ sal_Int32 nAlignedAt = nIndentAt + nFirstLineIndent;
+
+ nIndentAt = Millimeter::getInHundredthsOfOneMillimeter( _textposition );
+ nFirstLineIndent = nAlignedAt - nIndentAt;
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "IndentAt", uno::Any( nIndentAt ) );
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "FirstLineIndent", uno::Any( nFirstLineIndent ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevel::getTrailingCharacter()
+{
+ sal_Int16 nLabelFollowedBy= 0;
+ m_pListHelper->getPropertyValueWithNameAndLevel( mnLevel, "LabelFollowedBy" ) >>= nLabelFollowedBy;
+
+ return nLabelFollowedBy;
+}
+
+void SAL_CALL SwVbaListLevel::setTrailingCharacter( ::sal_Int32 _trailingcharacter )
+{
+ sal_Int16 nLabelFollowedBy = static_cast<sal_Int16>(_trailingcharacter);
+ m_pListHelper->setPropertyValueWithNameAndLevel( mnLevel, "LabelFollowedBy", uno::Any( nLabelFollowedBy ) );
+}
+
+OUString
+SwVbaListLevel::getServiceImplName()
+{
+ return "SwVbaListLevel";
+}
+
+uno::Sequence< OUString >
+SwVbaListLevel::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.ListLevel"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistlevel.hxx b/sw/source/ui/vba/vbalistlevel.hxx
new file mode 100644
index 0000000000..e9a8e23e13
--- /dev/null
+++ b/sw/source/ui/vba/vbalistlevel.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTLEVEL_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTLEVEL_HXX
+
+#include <ooo/vba/word/XListLevel.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include "vbalisthelper.hxx"
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListLevel > SwVbaListLevel_BASE;
+
+class SwVbaListLevel : public SwVbaListLevel_BASE
+{
+private:
+ SwVbaListHelperRef m_pListHelper;
+ sal_Int32 mnLevel;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListLevel( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, SwVbaListHelperRef pHelper, sal_Int32 nLevel );
+ virtual ~SwVbaListLevel() override;
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getAlignment() override;
+ virtual void SAL_CALL setAlignment( ::sal_Int32 _alignment ) override;
+ virtual css::uno::Reference< ::ooo::vba::word::XFont > SAL_CALL getFont() override;
+ virtual void SAL_CALL setFont( const css::uno::Reference< ::ooo::vba::word::XFont >& _font ) override;
+ virtual ::sal_Int32 SAL_CALL getIndex() override;
+ virtual OUString SAL_CALL getLinkedStyle() override;
+ virtual void SAL_CALL setLinkedStyle( const OUString& _linkedstyle ) override;
+ virtual OUString SAL_CALL getNumberFormat() override;
+ virtual void SAL_CALL setNumberFormat( const OUString& _numberformat ) override;
+ virtual float SAL_CALL getNumberPosition() override;
+ virtual void SAL_CALL setNumberPosition( float _numberposition ) override;
+ virtual ::sal_Int32 SAL_CALL getNumberStyle() override;
+ virtual void SAL_CALL setNumberStyle( ::sal_Int32 _numberstyle ) override;
+ virtual ::sal_Int32 SAL_CALL getResetOnHigher() override;
+ virtual void SAL_CALL setResetOnHigher( ::sal_Int32 _resetonhigher ) override;
+ virtual ::sal_Int32 SAL_CALL getStartAt() override;
+ virtual void SAL_CALL setStartAt( ::sal_Int32 _startat ) override;
+ virtual float SAL_CALL getTabPosition() override;
+ virtual void SAL_CALL setTabPosition( float _tabposition ) override;
+ virtual float SAL_CALL getTextPosition() override;
+ virtual void SAL_CALL setTextPosition( float _textposition ) override;
+ virtual ::sal_Int32 SAL_CALL getTrailingCharacter() override;
+ virtual void SAL_CALL setTrailingCharacter( ::sal_Int32 _trailingcharacter ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTLEVEL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistlevels.cxx b/sw/source/ui/vba/vbalistlevels.cxx
new file mode 100644
index 0000000000..3f0d83e478
--- /dev/null
+++ b/sw/source/ui/vba/vbalistlevels.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 "vbalistlevels.hxx"
+#include "vbalistlevel.hxx"
+#include <ooo/vba/word/WdListGalleryType.hpp>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class ListLevelsEnumWrapper : public EnumerationHelper_BASE
+{
+ SwVbaListLevels* m_pListLevels;
+ sal_Int32 m_nIndex;
+public:
+ explicit ListLevelsEnumWrapper( SwVbaListLevels* pLevels ) : m_pListLevels( pLevels ), m_nIndex( 1 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex <= m_pListLevels->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex <= m_pListLevels->getCount() )
+ return m_pListLevels->Item( uno::Any( m_nIndex++ ), uno::Any() );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaListLevels::SwVbaListLevels( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, SwVbaListHelperRef pHelper ) : SwVbaListLevels_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >() ), m_pListHelper(std::move( pHelper ))
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaListLevels::getCount()
+{
+ sal_Int32 nGalleryType = m_pListHelper->getGalleryType();
+ if( nGalleryType == word::WdListGalleryType::wdBulletGallery
+ || nGalleryType == word::WdListGalleryType::wdNumberGallery )
+ return 1;
+ else if( nGalleryType == word::WdListGalleryType::wdOutlineNumberGallery )
+ return 9;
+ return 0;
+}
+
+uno::Any SAL_CALL SwVbaListLevels::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ )
+{
+ sal_Int32 nIndex = 0;
+ if( !( Index1 >>= nIndex ) )
+ throw uno::RuntimeException();
+ if( nIndex <=0 || nIndex > getCount() )
+ throw uno::RuntimeException("Index out of bounds" );
+
+ return uno::Any( uno::Reference< word::XListLevel >( new SwVbaListLevel( this, mxContext, m_pListHelper, nIndex - 1 ) ) );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaListLevels::getElementType()
+{
+ return cppu::UnoType<word::XListLevel>::get();
+}
+
+uno::Reference< container::XEnumeration >
+SwVbaListLevels::createEnumeration()
+{
+ return new ListLevelsEnumWrapper( this );
+}
+
+uno::Any
+SwVbaListLevels::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaListLevels::getServiceImplName()
+{
+ return "SwVbaListLevels";
+}
+
+css::uno::Sequence<OUString>
+SwVbaListLevels::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.ListLevels"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalistlevels.hxx b/sw/source/ui/vba/vbalistlevels.hxx
new file mode 100644
index 0000000000..2b3bb44d0f
--- /dev/null
+++ b/sw/source/ui/vba/vbalistlevels.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 <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XListLevels.hpp>
+#include "vbalisthelper.hxx"
+
+typedef CollTestImplHelper< ooo::vba::word::XListLevels > SwVbaListLevels_BASE;
+
+class SwVbaListLevels : public SwVbaListLevels_BASE
+{
+private:
+ SwVbaListHelperRef m_pListHelper;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListLevels( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, SwVbaListHelperRef pHelper );
+
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaListLevels_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalisttemplate.cxx b/sw/source/ui/vba/vbalisttemplate.cxx
new file mode 100644
index 0000000000..032bc98162
--- /dev/null
+++ b/sw/source/ui/vba/vbalisttemplate.cxx
@@ -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 .
+ */
+#include "vbalisttemplate.hxx"
+#include "vbalistlevels.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaListTemplate::SwVbaListTemplate( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< text::XTextDocument >& xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType ) : SwVbaListTemplate_BASE( rParent, rContext )
+{
+ m_pListHelper = std::make_shared<SwVbaListHelper>( xTextDoc, nGalleryType, nTemplateType );
+}
+
+SwVbaListTemplate::~SwVbaListTemplate()
+{
+}
+
+uno::Any SAL_CALL
+SwVbaListTemplate::ListLevels( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaListLevels( mxParent, mxContext, m_pListHelper ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+void SwVbaListTemplate::applyListTemplate( uno::Reference< beans::XPropertySet > const & xProps )
+{
+ uno::Reference< container::XIndexReplace > xNumberingRules = m_pListHelper->getNumberingRules();
+ xProps->setPropertyValue("NumberingRules", uno::Any( xNumberingRules ) );
+}
+
+OUString
+SwVbaListTemplate::getServiceImplName()
+{
+ return "SwVbaListTemplate";
+}
+
+uno::Sequence< OUString >
+SwVbaListTemplate::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.ListTemplate"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalisttemplate.hxx b/sw/source/ui/vba/vbalisttemplate.hxx
new file mode 100644
index 0000000000..a690b6c820
--- /dev/null
+++ b/sw/source/ui/vba/vbalisttemplate.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATE_HXX
+
+#include <ooo/vba/word/XListTemplate.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include "vbalisthelper.hxx"
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XListTemplate > SwVbaListTemplate_BASE;
+
+class SwVbaListTemplate : public SwVbaListTemplate_BASE
+{
+private:
+ SwVbaListHelperRef m_pListHelper;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListTemplate( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, const css::uno::Reference< css::text::XTextDocument >& xTextDoc, sal_Int32 nGalleryType, sal_Int32 nTemplateType );
+ virtual ~SwVbaListTemplate() override;
+
+ /// @throws css::uno::RuntimeException
+ void applyListTemplate( css::uno::Reference< css::beans::XPropertySet > const & xProps );
+
+ // Methods
+ virtual css::uno::Any SAL_CALL ListLevels( const css::uno::Any& index ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalisttemplates.cxx b/sw/source/ui/vba/vbalisttemplates.cxx
new file mode 100644
index 0000000000..a9cc52d4bc
--- /dev/null
+++ b/sw/source/ui/vba/vbalisttemplates.cxx
@@ -0,0 +1,106 @@
+/* -*- 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 "vbalisttemplates.hxx"
+#include "vbalisttemplate.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class ListTemplatesEnumWrapper : public EnumerationHelper_BASE
+{
+ SwVbaListTemplates* m_pListTemplates;
+ sal_Int32 m_nIndex;
+public:
+ explicit ListTemplatesEnumWrapper( SwVbaListTemplates* pTemplates ) : m_pListTemplates( pTemplates ), m_nIndex( 1 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex <= m_pListTemplates->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex <= m_pListTemplates->getCount() )
+ return m_pListTemplates->Item( uno::Any( m_nIndex++ ), uno::Any() );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaListTemplates::SwVbaListTemplates( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextDocument > xTextDoc, sal_Int32 nType ) : SwVbaListTemplates_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >() ), mxTextDocument(std::move( xTextDoc )), mnGalleryType( nType )
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaListTemplates::getCount()
+{
+ // 3 types of list( bullet, numbered and outline )
+ return 7;
+}
+
+uno::Any SAL_CALL SwVbaListTemplates::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ )
+{
+ sal_Int32 nIndex = 0;
+ if( !( Index1 >>= nIndex ) )
+ throw uno::RuntimeException();
+ if( nIndex <=0 || nIndex > getCount() )
+ throw uno::RuntimeException("Index out of bounds" );
+
+ return uno::Any( uno::Reference< word::XListTemplate >( new SwVbaListTemplate( this, mxContext, mxTextDocument, mnGalleryType, nIndex ) ) );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaListTemplates::getElementType()
+{
+ return cppu::UnoType<word::XListTemplate>::get();
+}
+
+uno::Reference< container::XEnumeration >
+SwVbaListTemplates::createEnumeration()
+{
+ return new ListTemplatesEnumWrapper( this );
+}
+
+uno::Any
+SwVbaListTemplates::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaListTemplates::getServiceImplName()
+{
+ return "SwVbaListTemplates";
+}
+
+css::uno::Sequence<OUString>
+SwVbaListTemplates::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.ListTemplates"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbalisttemplates.hxx b/sw/source/ui/vba/vbalisttemplates.hxx
new file mode 100644
index 0000000000..bf5c34f6ee
--- /dev/null
+++ b/sw/source/ui/vba/vbalisttemplates.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATES_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XListTemplates.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XListTemplates > SwVbaListTemplates_BASE;
+
+class SwVbaListTemplates : public SwVbaListTemplates_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ sal_Int32 mnGalleryType;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaListTemplates( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextDocument > xTextDoc, sal_Int32 nType );
+
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaListTemplates_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBALISTTEMPLATES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbamailmerge.cxx b/sw/source/ui/vba/vbamailmerge.cxx
new file mode 100644
index 0000000000..479f5dfd7d
--- /dev/null
+++ b/sw/source/ui/vba/vbamailmerge.cxx
@@ -0,0 +1,56 @@
+/* -*- 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 "vbamailmerge.hxx"
+
+#include <ooo/vba/word/WdMailMergeMainDocType.hpp>
+
+SwVbaMailMerge::SwVbaMailMerge(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext)
+ : SwVbaMailMerge_BASE(xParent, xContext)
+ , m_nMainDocType(ooo::vba::word::WdMailMergeMainDocType::wdNotAMergeDocument)
+{
+}
+
+SwVbaMailMerge::~SwVbaMailMerge() {}
+
+rtl::Reference<SwVbaMailMerge> const&
+SwVbaMailMerge::get(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext)
+{
+ static rtl::Reference<SwVbaMailMerge> xInstance(new SwVbaMailMerge(xParent, xContext));
+
+ return xInstance;
+}
+
+sal_Int32 SAL_CALL SwVbaMailMerge::getMainDocumentType() { return m_nMainDocType; }
+
+void SAL_CALL SwVbaMailMerge::setMainDocumentType(sal_Int32 _maindocumenttype)
+{
+ m_nMainDocType = _maindocumenttype;
+}
+
+// Completely dummy, no-op.
+void SAL_CALL SwVbaMailMerge::OpenDataSource(
+ const OUString&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&,
+ const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&,
+ const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&,
+ const css::uno::Any&, const css::uno::Any&, const css::uno::Any&, const css::uno::Any&)
+{
+}
+
+OUString SwVbaMailMerge::getServiceImplName() { return "SwVbaMailMerge"; }
+
+css::uno::Sequence<OUString> SwVbaMailMerge::getServiceNames()
+{
+ static css::uno::Sequence<OUString> const aServiceNames{ "ooo.vba.word.MailMerge" };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbamailmerge.hxx b/sw/source/ui/vba/vbamailmerge.hxx
new file mode 100644
index 0000000000..bfc28667d7
--- /dev/null
+++ b/sw/source/ui/vba/vbamailmerge.hxx
@@ -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/.
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAMAILMERGE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAMAILMERGE_HXX
+
+#include <ooo/vba/word/XMailMerge.hpp>
+#include <rtl/ref.hxx>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XMailMerge> SwVbaMailMerge_BASE;
+
+// Singleton class. Get the single instance using the get() method.
+
+class SwVbaMailMerge : public SwVbaMailMerge_BASE
+{
+ sal_Int32 m_nMainDocType;
+
+ SwVbaMailMerge(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext);
+
+public:
+ virtual ~SwVbaMailMerge() override;
+
+ static rtl::Reference<SwVbaMailMerge> const&
+ get(const css::uno::Reference<ooo::vba::XHelperInterface>& xParent,
+ const css::uno::Reference<css::uno::XComponentContext>& xContext);
+
+ // XMailMerge
+ virtual sal_Int32 SAL_CALL getMainDocumentType() override;
+ virtual void SAL_CALL setMainDocumentType(sal_Int32 _maindocumenttype) override;
+
+ virtual void SAL_CALL
+ OpenDataSource(const OUString& Name, const css::uno::Any& Format,
+ const css::uno::Any& ConfirmConversions, const css::uno::Any& ReadOnly,
+ const css::uno::Any& LinkToSource, const css::uno::Any& AddToRecentFiles,
+ const css::uno::Any& PasswordDocument, const css::uno::Any& PasswordTemplate,
+ const css::uno::Any& Revert, const css::uno::Any& WritePasswordDocument,
+ const css::uno::Any& WritePasswordTemplate, const css::uno::Any& Connection,
+ const css::uno::Any& SQLStatement, const css::uno::Any& SQLStatement1,
+ const css::uno::Any& OpenExclusive, const css::uno::Any& SubType) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAMAILMERGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaoptions.cxx b/sw/source/ui/vba/vbaoptions.cxx
new file mode 100644
index 0000000000..ef74dcd8a6
--- /dev/null
+++ b/sw/source/ui/vba/vbaoptions.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 "vbaoptions.hxx"
+#include <vbahelper/vbahelper.hxx>
+#include <ooo/vba/word/WdDefaultFilePath.hpp>
+#include <ooo/vba/word/WdLineStyle.hpp>
+#include <ooo/vba/word/WdLineWidth.hpp>
+#include <ooo/vba/word/WdColorIndex.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <comphelper/processfactory.hxx>
+#include <basic/sberrors.hxx>
+#include <osl/file.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaOptions::SwVbaOptions( uno::Reference<uno::XComponentContext > const & xContext ) : SwVbaOptions_BASE( uno::Reference< XHelperInterface >(), xContext )
+{
+}
+
+SwVbaOptions::~SwVbaOptions()
+{
+}
+
+uno::Any SAL_CALL
+SwVbaOptions::DefaultFilePath( sal_Int32 _path )
+{
+ switch( _path )
+ {
+ case word::WdDefaultFilePath::wdDocumentsPath:
+ {
+ msDefaultFilePath = "Work";
+ break;
+ }
+ case word::WdDefaultFilePath::wdPicturesPath:
+ {
+ msDefaultFilePath = "Gallery";
+ break;
+ }
+ case word::WdDefaultFilePath::wdUserTemplatesPath:
+ case word::WdDefaultFilePath::wdWorkgroupTemplatesPath:
+ {
+ msDefaultFilePath = "Template";
+ break;
+ }
+ case word::WdDefaultFilePath::wdStartupPath:
+ {
+ msDefaultFilePath = "Addin";
+ break;
+ }
+ case word::WdDefaultFilePath::wdUserOptionsPath:
+ {
+ msDefaultFilePath = "UserConfig";
+ break;
+ }
+ case word::WdDefaultFilePath::wdToolsPath:
+ case word::WdDefaultFilePath::wdProgramPath:
+ {
+ msDefaultFilePath = "Module";
+ break;
+ }
+ case word::WdDefaultFilePath::wdTempFilePath:
+ {
+ msDefaultFilePath = "Temp";
+ break;
+ }
+ default:
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_NOT_IMPLEMENTED, {} );
+ break;
+ }
+ }
+ return uno::Any( uno::Reference< XPropValue > ( new ScVbaPropValue( this ) ) );
+}
+
+void SwVbaOptions::setValueEvent( const uno::Any& value )
+{
+ OUString sNewPath;
+ value >>= sNewPath;
+ OUString sNewPathUrl;
+ ::osl::File::getFileURLFromSystemPath( sNewPath, sNewPathUrl );
+ uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() );
+ OUString sOldPathUrl;
+ xPathSettings->getPropertyValue( msDefaultFilePath ) >>= sOldPathUrl;
+ // path could be a multipath, Microsoft doesn't support this feature in Word currently
+ // only the last path is from interest.
+ sal_Int32 nIndex = sOldPathUrl.lastIndexOf( ';' );
+ if( nIndex != -1 )
+ {
+ sNewPathUrl = sOldPathUrl.subView( 0, nIndex + 1 ) + sNewPathUrl;
+ }
+ xPathSettings->setPropertyValue( msDefaultFilePath, uno::Any( sNewPathUrl ) );
+}
+
+uno::Any SwVbaOptions::getValueEvent()
+{
+ uno::Reference< util::XPathSettings > xPathSettings = util::thePathSettings::get( comphelper::getProcessComponentContext() );
+ OUString sPathUrl;
+ xPathSettings->getPropertyValue( msDefaultFilePath ) >>= sPathUrl;
+ // path could be a multipath, Microsoft doesn't support this feature in Word currently
+ // only the last path is from interest.
+ sal_Int32 nIndex = sPathUrl.lastIndexOf( ';' );
+ if( nIndex != -1 )
+ {
+ sPathUrl = sPathUrl.copy( nIndex + 1 );
+ }
+ OUString sPath;
+ ::osl::File::getSystemPathFromFileURL( sPathUrl, sPath );
+ return uno::Any( sPath );
+}
+
+sal_Int32 SAL_CALL SwVbaOptions::getDefaultBorderLineStyle()
+{
+ return word::WdLineStyle::wdLineStyleSingle;
+}
+
+void SAL_CALL SwVbaOptions::setDefaultBorderLineStyle( ::sal_Int32 /*_defaultborderlinestyle*/ )
+{
+ // not support in Writer
+}
+
+sal_Int32 SAL_CALL SwVbaOptions::getDefaultBorderLineWidth()
+{
+ return word::WdLineWidth::wdLineWidth050pt;
+}
+
+void SAL_CALL SwVbaOptions::setDefaultBorderLineWidth( ::sal_Int32 /*_defaultborderlinewidth*/ )
+{
+ // not support in Writer
+}
+
+sal_Int32 SAL_CALL SwVbaOptions::getDefaultBorderColorIndex()
+{
+ return word::WdColorIndex::wdAuto;
+}
+
+void SAL_CALL SwVbaOptions::setDefaultBorderColorIndex( ::sal_Int32 /*_defaultbordercolorindex*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getReplaceSelection()
+{
+ return true;
+}
+
+void SAL_CALL SwVbaOptions::setReplaceSelection( sal_Bool /*_replaceselection*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getMapPaperSize()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setMapPaperSize( sal_Bool /*_mappapersize*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeApplyHeadings()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeApplyHeadings( sal_Bool /*_autoformatasyoutypeapplyheadings*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeApplyBulletedLists()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeApplyBulletedLists( sal_Bool /*_autoformatasyoutypeapplybulletedlists*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeApplyNumberedLists()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeApplyNumberedLists( sal_Bool /*_autoformatasyoutypeapplynumberedlists*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeFormatListItemBeginning()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeFormatListItemBeginning( sal_Bool /*_autoformatasyoutypeformatlistitembeginning*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatAsYouTypeDefineStyles()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatAsYouTypeDefineStyles( sal_Bool /*_autoformatasyoutypedefinestyles*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatApplyHeadings()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatApplyHeadings( sal_Bool /*_autoformatapplyheadings*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatApplyLists()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatApplyLists( sal_Bool /*_autoformatapplylists*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaOptions::getAutoFormatApplyBulletedLists()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaOptions::setAutoFormatApplyBulletedLists( sal_Bool /*_autoformatapplybulletedlists*/ )
+{
+ // not support in Writer
+}
+
+OUString
+SwVbaOptions::getServiceImplName()
+{
+ return "SwVbaOptions";
+}
+
+uno::Sequence< OUString >
+SwVbaOptions::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Options"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaoptions.hxx b/sw/source/ui/vba/vbaoptions.hxx
new file mode 100644
index 0000000000..92994d5589
--- /dev/null
+++ b/sw/source/ui/vba/vbaoptions.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAOPTIONS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAOPTIONS_HXX
+
+#include <ooo/vba/word/XOptions.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbapropvalue.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XOptions > SwVbaOptions_BASE;
+
+class SwVbaOptions : public SwVbaOptions_BASE,
+ public PropListener
+{
+private:
+ OUString msDefaultFilePath;
+public:
+ explicit SwVbaOptions( css::uno::Reference< css::uno::XComponentContext > const & m_xContext );
+ virtual ~SwVbaOptions() override;
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getDefaultBorderLineStyle() override;
+ virtual void SAL_CALL setDefaultBorderLineStyle( ::sal_Int32 _defaultborderlinestyle ) override;
+ virtual ::sal_Int32 SAL_CALL getDefaultBorderLineWidth() override;
+ virtual void SAL_CALL setDefaultBorderLineWidth( ::sal_Int32 _defaultborderlinewidth ) override;
+ virtual ::sal_Int32 SAL_CALL getDefaultBorderColorIndex() override;
+ virtual void SAL_CALL setDefaultBorderColorIndex( ::sal_Int32 _defaultbordercolorindex ) override;
+ virtual sal_Bool SAL_CALL getReplaceSelection() override;
+ virtual void SAL_CALL setReplaceSelection( sal_Bool _replaceselection ) override;
+ virtual sal_Bool SAL_CALL getMapPaperSize() override;
+ virtual void SAL_CALL setMapPaperSize( sal_Bool _mappapersize ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeApplyHeadings() override;
+ virtual void SAL_CALL setAutoFormatAsYouTypeApplyHeadings( sal_Bool _autoformatasyoutypeapplyheadings ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeApplyBulletedLists() override;
+ virtual void SAL_CALL setAutoFormatAsYouTypeApplyBulletedLists( sal_Bool _autoformatasyoutypeapplybulletedlists ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeApplyNumberedLists() override;
+ virtual void SAL_CALL setAutoFormatAsYouTypeApplyNumberedLists( sal_Bool _autoformatasyoutypeapplynumberedlists ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeFormatListItemBeginning() override;
+ virtual void SAL_CALL setAutoFormatAsYouTypeFormatListItemBeginning( sal_Bool _autoformatasyoutypeformatlistitembeginning ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatAsYouTypeDefineStyles() override;
+ virtual void SAL_CALL setAutoFormatAsYouTypeDefineStyles( sal_Bool _autoformatasyoutypedefinestyles ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatApplyHeadings() override;
+ virtual void SAL_CALL setAutoFormatApplyHeadings( sal_Bool _autoformatapplyheadings ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatApplyLists() override;
+ virtual void SAL_CALL setAutoFormatApplyLists( sal_Bool _autoformatapplylists ) override;
+ virtual sal_Bool SAL_CALL getAutoFormatApplyBulletedLists() override;
+ virtual void SAL_CALL setAutoFormatApplyBulletedLists( sal_Bool _autoformatapplybulletedlists ) override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL DefaultFilePath( sal_Int32 _path ) override;
+
+ //PropListener
+ virtual void setValueEvent( const css::uno::Any& value ) override;
+ virtual css::uno::Any getValueEvent() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAOPTIONS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapagesetup.cxx b/sw/source/ui/vba/vbapagesetup.cxx
new file mode 100644
index 0000000000..b22437dbd2
--- /dev/null
+++ b/sw/source/ui/vba/vbapagesetup.cxx
@@ -0,0 +1,260 @@
+/* -*- 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 "vbapagesetup.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <ooo/vba/word/WdSectionStart.hpp>
+#include <ooo/vba/word/WdOrientation.hpp>
+#include "wordvbahelper.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+SwVbaPageSetup::SwVbaPageSetup(const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< beans::XPropertySet >& xProps ):
+ SwVbaPageSetup_BASE( xParent, xContext )
+{
+ mxModel.set( xModel, uno::UNO_SET_THROW );
+ mxPageProps.set( xProps, uno::UNO_SET_THROW );
+ mnOrientPortrait = word::WdOrientation::wdOrientPortrait;
+ mnOrientLandscape = word::WdOrientation::wdOrientLandscape;
+}
+
+double SAL_CALL SwVbaPageSetup::getGutter()
+{
+ // not support in Writer
+ return 0;
+}
+
+void SAL_CALL SwVbaPageSetup::setGutter( double _gutter )
+{
+ // default add gutter into left margin
+ if( _gutter != 0 )
+ {
+ double margin = VbaPageSetupBase::getLeftMargin() + _gutter;
+ VbaPageSetupBase::setLeftMargin( margin );
+ }
+}
+
+double SAL_CALL SwVbaPageSetup::getHeaderDistance()
+{
+ bool isHeaderOn = false;
+ mxPageProps->getPropertyValue("HeaderIsOn") >>= isHeaderOn;
+ if( !isHeaderOn )
+ mxPageProps->setPropertyValue("HeaderIsOn", uno::Any( true ) );
+ return VbaPageSetupBase::getHeaderMargin();
+}
+
+ /**
+ * changes the value of TopMargin to the value of new MS-Word-HeaderDistance. Subtracts the difference
+ * between old TopMargin and the new headerDistance from the value of HeaderSpacing (which defines the
+ * space between the header and the body of the text). calculates the new HeaderHeight (= height of the
+ * header + headerBodyDistance).
+ *
+ * @param: headerDistance is the value that is set in MS Word for the distance from the top of the page
+ * to the header
+ */
+void SAL_CALL SwVbaPageSetup::setHeaderDistance( double _headerdistance )
+{
+ sal_Int32 newHeaderDistance = Millimeter::getInHundredthsOfOneMillimeter( _headerdistance );
+ bool isHeaderOn = false;
+ sal_Int32 currentTopMargin = 0;
+ sal_Int32 currentSpacing = 0;
+ sal_Int32 currentHeaderHeight = 0;
+
+ mxPageProps->getPropertyValue("HeaderIsOn") >>= isHeaderOn;
+ if( !isHeaderOn )
+ mxPageProps->setPropertyValue("HeaderIsOn", uno::Any( true ) );
+
+ mxPageProps->getPropertyValue("TopMargin") >>= currentTopMargin;
+ mxPageProps->getPropertyValue("HeaderBodyDistance") >>= currentSpacing;
+ mxPageProps->getPropertyValue("HeaderHeight") >>= currentHeaderHeight;
+
+ sal_Int32 newSpacing = currentSpacing - ( newHeaderDistance - currentTopMargin );
+ sal_Int32 height = currentHeaderHeight - currentSpacing;
+ sal_Int32 newHeaderHeight = newSpacing + height;
+
+ mxPageProps->setPropertyValue("TopMargin", uno::Any( newHeaderDistance ) );
+ mxPageProps->setPropertyValue("HeaderBodyDistance", uno::Any( newSpacing ) );
+ mxPageProps->setPropertyValue("HeaderHeight", uno::Any( newHeaderHeight ) );
+}
+
+double SAL_CALL SwVbaPageSetup::getFooterDistance()
+{
+ bool isFooterOn = false;
+ mxPageProps->getPropertyValue("FooterIsOn") >>= isFooterOn;
+ if( !isFooterOn )
+ mxPageProps->setPropertyValue("FooterIsOn", uno::Any( true ) );
+ return VbaPageSetupBase::getFooterMargin();
+}
+
+void SAL_CALL SwVbaPageSetup::setFooterDistance( double _footerdistance )
+{
+ sal_Int32 newFooterDistance = Millimeter::getInHundredthsOfOneMillimeter( _footerdistance );
+ bool isFooterOn = false;
+ sal_Int32 currentBottomMargin = 0;
+ sal_Int32 currentSpacing = 0;
+ sal_Int32 currentFooterHeight = 0;
+
+ mxPageProps->getPropertyValue("FooterIsOn") >>= isFooterOn;
+ if( !isFooterOn )
+ mxPageProps->setPropertyValue("FooterIsOn", uno::Any( true ) );
+
+ mxPageProps->getPropertyValue("BottomMargin") >>= currentBottomMargin;
+ mxPageProps->getPropertyValue("FooterBodyDistance") >>= currentSpacing;
+ mxPageProps->getPropertyValue("FooterHeight") >>= currentFooterHeight;
+
+ sal_Int32 newSpacing = currentSpacing - ( newFooterDistance - currentBottomMargin );
+ sal_Int32 height = currentFooterHeight - currentSpacing;
+ sal_Int32 newFooterHeight = newSpacing + height;
+
+ mxPageProps->setPropertyValue("BottomMargin", uno::Any( newFooterDistance ) );
+ mxPageProps->setPropertyValue("FooterBodyDistance", uno::Any( newSpacing ) );
+ mxPageProps->setPropertyValue("FooterHeight", uno::Any( newFooterHeight ) );
+}
+
+sal_Bool SAL_CALL SwVbaPageSetup::getDifferentFirstPageHeaderFooter()
+{
+ OUString pageStyle = getStyleOfFirstPage();
+ if ( pageStyle == "First Page" )
+ return true;
+
+ return false;
+}
+
+void SAL_CALL SwVbaPageSetup::setDifferentFirstPageHeaderFooter( sal_Bool status )
+{
+ if( status == getDifferentFirstPageHeaderFooter() )
+ return;
+
+ OUString newStyle;
+ if( status )
+ newStyle = "First Page";
+ else
+ newStyle = "Standard";
+
+ uno::Reference< beans::XPropertySet > xStyleProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW );
+ sal_Int32 nTopMargin = 0;
+ xStyleProps->getPropertyValue("TopMargin") >>= nTopMargin;
+ sal_Int32 nBottomMargin = 0;
+ xStyleProps->getPropertyValue("BottomMargin") >>= nBottomMargin;
+ sal_Int32 nLeftMargin = 0;
+ xStyleProps->getPropertyValue("LeftMargin") >>= nLeftMargin;
+ sal_Int32 nRightMargin = 0;
+ xStyleProps->getPropertyValue("RightMargin") >>= nRightMargin;
+ sal_Int32 nHeaderHeight = 0;
+ xStyleProps->getPropertyValue("HeaderHeight") >>= nHeaderHeight;
+ sal_Int32 nFooterHeight = 0;
+ xStyleProps->getPropertyValue("FooterHeight") >>= nFooterHeight;
+
+ bool isHeaderOn = false;
+ xStyleProps->getPropertyValue("HeaderIsOn") >>= isHeaderOn;
+ if( isHeaderOn )
+ {
+ nTopMargin += nHeaderHeight;
+ nBottomMargin += nFooterHeight;
+ xStyleProps->setPropertyValue("HeaderIsOn", uno::Any( false ) );
+ xStyleProps->setPropertyValue("FooterIsOn", uno::Any( false ) );
+ }
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW );
+ if( xPageCursor->getPage() != 1 )
+ {
+ xPageCursor->jumpToFirstPage();
+ }
+
+ uno::Reference< beans::XPropertySet > xCursorProps( xPageCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xTableProps( xCursorProps->getPropertyValue("TextTable"), uno::UNO_QUERY );
+ if( xTableProps.is() )
+ {
+ xTableProps->setPropertyValue("PageDescName", uno::Any( newStyle ) );
+ }
+ else
+ {
+ xCursorProps->setPropertyValue("PageDescName", uno::Any( newStyle ) );
+ }
+
+ uno::Reference< beans::XPropertySet > xFirstPageProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW );
+ xFirstPageProps->setPropertyValue("TopMargin", uno::Any( nTopMargin ) );
+ xFirstPageProps->setPropertyValue("BottomMargin", uno::Any( nBottomMargin ) );
+ xFirstPageProps->setPropertyValue("LeftMargin", uno::Any( nLeftMargin ) );
+ xFirstPageProps->setPropertyValue("RightMargin", uno::Any( nRightMargin ) );
+}
+
+OUString SwVbaPageSetup::getStyleOfFirstPage() const
+{
+ OUString styleFirstPage;
+ uno::Reference< text::XPageCursor > xPageCursor( word::getXTextViewCursor( mxModel ), uno::UNO_QUERY_THROW );
+ if( xPageCursor->getPage() != 1 )
+ {
+ xPageCursor->jumpToFirstPage();
+ }
+
+ uno::Reference< beans::XPropertySet > xCursorProps( xPageCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xTableProps( xCursorProps->getPropertyValue("TextTable"), uno::UNO_QUERY );
+ if( xTableProps.is() )
+ {
+ xTableProps->getPropertyValue("PageDescName") >>= styleFirstPage;
+ }
+ else
+ {
+ xCursorProps->getPropertyValue("PageDescName") >>= styleFirstPage;
+ }
+ return styleFirstPage;
+}
+
+::sal_Int32 SAL_CALL SwVbaPageSetup::getSectionStart()
+{
+ // FIXME:
+ sal_Int32 wdSectionStart = word::WdSectionStart::wdSectionNewPage;
+ uno::Reference< container::XNamed > xNamed( mxPageProps, uno::UNO_QUERY_THROW );
+ OUString sStyleName = xNamed->getName();
+ if ( sStyleName == "Left Page" )
+ wdSectionStart = word::WdSectionStart::wdSectionEvenPage;
+ else if ( sStyleName == "Right Page" )
+ wdSectionStart = word::WdSectionStart::wdSectionOddPage;
+ else
+ wdSectionStart = word::WdSectionStart::wdSectionNewPage;
+ return wdSectionStart;
+}
+
+void SAL_CALL SwVbaPageSetup::setSectionStart( ::sal_Int32 /*_sectionstart*/ )
+{
+ // fail to find corresponding feature in Writer
+ // #FIXME:
+}
+
+OUString
+SwVbaPageSetup::getServiceImplName()
+{
+ return "SwVbaPageSetup";
+}
+
+uno::Sequence< OUString >
+SwVbaPageSetup::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.PageSetup"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapagesetup.hxx b/sw/source/ui/vba/vbapagesetup.hxx
new file mode 100644
index 0000000000..b6b9c01551
--- /dev/null
+++ b/sw/source/ui/vba/vbapagesetup.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPAGESETUP_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAPAGESETUP_HXX
+
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/word/XPageSetup.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbapagesetupbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaPageSetupBase, ooo::vba::word::XPageSetup > SwVbaPageSetup_BASE;
+
+class SwVbaPageSetup : public SwVbaPageSetup_BASE
+{
+private:
+ /// @throws css::uno::RuntimeException
+ OUString getStyleOfFirstPage() const;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaPageSetup( const css::uno::Reference< ooo::vba::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::beans::XPropertySet >& xProps );
+
+ // Attributes
+ virtual double SAL_CALL getGutter() override;
+ virtual void SAL_CALL setGutter( double _gutter ) override;
+ virtual double SAL_CALL getHeaderDistance() override;
+ virtual void SAL_CALL setHeaderDistance( double _headerdistance ) override;
+ virtual double SAL_CALL getFooterDistance() override;
+ virtual void SAL_CALL setFooterDistance( double _footerdistance ) override;
+ virtual sal_Bool SAL_CALL getDifferentFirstPageHeaderFooter() override;
+ virtual void SAL_CALL setDifferentFirstPageHeaderFooter( sal_Bool status ) override;
+ virtual ::sal_Int32 SAL_CALL getSectionStart() override;
+ virtual void SAL_CALL setSectionStart( ::sal_Int32 _sectionstart ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapalette.cxx b/sw/source/ui/vba/vbapalette.cxx
new file mode 100644
index 0000000000..351f2711c5
--- /dev/null
+++ b/sw/source/ui/vba/vbapalette.cxx
@@ -0,0 +1,93 @@
+/* -*- 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 "vbapalette.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <ooo/vba/word/WdColor.hpp>
+#include <sal/macros.h>
+
+using namespace ::ooo::vba;
+using namespace ::ooo::vba::word;
+using namespace ::com::sun::star;
+
+const sal_Int32 ColorTable[] =
+{
+WdColor::wdColorAutomatic, // 0
+WdColor::wdColorBlack, // 1
+WdColor::wdColorBlue, // 2
+WdColor::wdColorTurquoise, // 3
+WdColor::wdColorBrightGreen, // 4
+WdColor::wdColorPink, // 5
+WdColor::wdColorRed, // 6
+WdColor::wdColorYellow, // 7
+WdColor::wdColorWhite, // 8
+WdColor::wdColorDarkBlue, // 9
+WdColor::wdColorTeal, // 10
+WdColor::wdColorGreen, // 11
+WdColor::wdColorViolet, // 12
+WdColor::wdColorDarkRed, // 13
+WdColor::wdColorDarkYellow, // 14
+WdColor::wdColorGray50, // 15
+WdColor::wdColorGray25, // 16
+};
+
+typedef ::cppu::WeakImplHelper< container::XIndexAccess > XIndexAccess_BASE;
+
+namespace {
+
+class DefaultPalette : public XIndexAccess_BASE
+{
+public:
+ DefaultPalette(){}
+
+ // Methods XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount() override
+ {
+ return SAL_N_ELEMENTS(ColorTable);
+ }
+
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( sal_Int32( ColorTable[ Index ] ) );
+ }
+
+ // Methods XElementAccess
+ virtual uno::Type SAL_CALL getElementType() override
+ {
+ return ::cppu::UnoType<sal_Int32>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements() override
+ {
+ return true;
+ }
+
+};
+
+}
+
+VbaPalette::VbaPalette()
+ : mxPalette(new DefaultPalette())
+{
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapalette.hxx b/sw/source/ui/vba/vbapalette.hxx
new file mode 100644
index 0000000000..cbf639301f
--- /dev/null
+++ b/sw/source/ui/vba/vbapalette.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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPALETTE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAPALETTE_HXX
+
+#include <com/sun/star/container/XIndexAccess.hpp>
+
+class VbaPalette
+{
+ css::uno::Reference< css::container::XIndexAccess > mxPalette;
+public:
+ VbaPalette();
+ // if no palette available e.g. because the document doesn't have a
+ // palette defined then a default palette will be returned.
+ const css::uno::Reference< css::container::XIndexAccess >& getPalette() const { return mxPalette;}
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapane.cxx b/sw/source/ui/vba/vbapane.cxx
new file mode 100644
index 0000000000..64a7c411c7
--- /dev/null
+++ b/sw/source/ui/vba/vbapane.cxx
@@ -0,0 +1,65 @@
+/* -*- 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 "vbapane.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include "vbaview.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaPane::SwVbaPane( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,
+ uno::Reference< frame::XModel > xModel ) :
+ SwVbaPane_BASE( rParent, rContext ), mxModel(std::move( xModel ))
+{
+}
+
+SwVbaPane::~SwVbaPane()
+{
+}
+
+uno::Any SAL_CALL
+SwVbaPane::View()
+{
+ return uno::Any( uno::Reference< word::XView >( new SwVbaView( this, mxContext, mxModel ) ) );
+}
+
+void SAL_CALL
+SwVbaPane::Close( )
+{
+ dispatchRequests( mxModel,".uno:CloseWin" );
+}
+
+OUString
+SwVbaPane::getServiceImplName()
+{
+ return "SwVbaPane";
+}
+
+uno::Sequence< OUString >
+SwVbaPane::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Pane"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapane.hxx b/sw/source/ui/vba/vbapane.hxx
new file mode 100644
index 0000000000..e0a81b9e0f
--- /dev/null
+++ b/sw/source/ui/vba/vbapane.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPANE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAPANE_HXX
+
+#include <ooo/vba/word/XPane.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XPane> SwVbaPane_BASE;
+
+class SwVbaPane : public SwVbaPane_BASE
+{
+private:
+ css::uno::Reference<css::frame::XModel> mxModel;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaPane(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ css::uno::Reference<css::frame::XModel> xModel);
+ virtual ~SwVbaPane() override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL View() override;
+ virtual void SAL_CALL Close() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAPANE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapanes.cxx b/sw/source/ui/vba/vbapanes.cxx
new file mode 100644
index 0000000000..05b288e290
--- /dev/null
+++ b/sw/source/ui/vba/vbapanes.cxx
@@ -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 .
+ */
+#include "vbapanes.hxx"
+#include "vbapane.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+// I assume there is only one pane in Writer
+class PanesIndexAccess : public ::cppu::WeakImplHelper<container::XIndexAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+
+public:
+ PanesIndexAccess( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel )) {}
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ return 1;
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if( Index != 0 )
+ throw lang::IndexOutOfBoundsException();
+ return uno::Any( uno::Reference< word::XPane >( new SwVbaPane( mxParent, mxContext, mxModel ) ) );
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XPane>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+};
+
+class PanesEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference<container::XIndexAccess > m_xIndexAccess;
+ sal_Int32 m_nIndex;
+public:
+ explicit PanesEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : m_xIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex < m_xIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex < m_xIndexAccess->getCount() )
+ return m_xIndexAccess->getByIndex( m_nIndex++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaPanes::SwVbaPanes( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ): SwVbaPanes_BASE( xParent, xContext, new PanesIndexAccess( xParent, xContext, xModel ) )
+{
+}
+// XEnumerationAccess
+uno::Type
+SwVbaPanes::getElementType()
+{
+ return cppu::UnoType<word::XPane>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaPanes::createEnumeration()
+{
+ return new PanesEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+SwVbaPanes::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaPanes::getServiceImplName()
+{
+ return "SwVbaPanes";
+}
+
+css::uno::Sequence<OUString>
+SwVbaPanes::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Panes"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbapanes.hxx b/sw/source/ui/vba/vbapanes.hxx
new file mode 100644
index 0000000000..27a6d65671
--- /dev/null
+++ b/sw/source/ui/vba/vbapanes.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 <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XPanes.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XPanes > SwVbaPanes_BASE;
+
+class SwVbaPanes : public SwVbaPanes_BASE
+{
+public:
+ SwVbaPanes( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaPanes_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaparagraph.cxx b/sw/source/ui/vba/vbaparagraph.cxx
new file mode 100644
index 0000000000..19a3127959
--- /dev/null
+++ b/sw/source/ui/vba/vbaparagraph.cxx
@@ -0,0 +1,179 @@
+/* -*- 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 "vbaparagraph.hxx"
+#include "vbarange.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaParagraph::SwVbaParagraph( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xDocument, uno::Reference< text::XTextRange > xTextRange ) :
+ SwVbaParagraph_BASE( rParent, rContext ), mxTextDocument(std::move( xDocument )), mxTextRange(std::move( xTextRange ))
+{
+}
+
+SwVbaParagraph::~SwVbaParagraph()
+{
+}
+
+uno::Reference< word::XRange > SAL_CALL
+SwVbaParagraph::getRange( )
+{
+ return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxTextDocument, mxTextRange->getStart(), mxTextRange->getEnd(), mxTextRange->getText() ) );
+}
+
+uno::Any SAL_CALL
+SwVbaParagraph::getStyle( )
+{
+ uno::Reference< word::XRange > xRange = getRange();
+ return xRange->getStyle();
+}
+
+void SAL_CALL
+SwVbaParagraph::setStyle( const uno::Any& style )
+{
+ uno::Reference< word::XRange > xRange = getRange();
+ xRange->setStyle( style );
+}
+
+OUString
+SwVbaParagraph::getServiceImplName()
+{
+ return "SwVbaParagraph";
+}
+
+uno::Sequence< OUString >
+SwVbaParagraph::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Paragraph"
+ };
+ return aServiceNames;
+}
+
+namespace {
+
+class ParagraphCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< text::XTextDocument > mxTextDocument;
+
+ /// @throws uno::RuntimeException
+ uno::Reference< container::XEnumeration > getEnumeration()
+ {
+ uno::Reference< container::XEnumerationAccess > xParEnumAccess( mxTextDocument->getText(), uno::UNO_QUERY_THROW );
+ return xParEnumAccess->createEnumeration();
+ }
+
+public:
+ /// @throws uno::RuntimeException
+ explicit ParagraphCollectionHelper( uno::Reference< text::XTextDocument > xDocument ): mxTextDocument(std::move( xDocument ))
+ {
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<text::XTextRange>::get(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return true; }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ sal_Int32 nCount = 0;
+ uno::Reference< container::XEnumeration > xParEnum = getEnumeration();
+ while( xParEnum->hasMoreElements() )
+ {
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xParEnum->nextElement(), uno::UNO_QUERY_THROW );
+ if( xServiceInfo->supportsService("com.sun.star.text.Paragraph") )
+ {
+ nCount++;
+ }
+ }
+ return nCount;
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if( Index < getCount() )
+ {
+ sal_Int32 nCount = 0;
+ uno::Reference< container::XEnumeration > xParEnum = getEnumeration();
+ while( xParEnum->hasMoreElements() )
+ {
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xParEnum->nextElement(), uno::UNO_QUERY_THROW );
+ if( xServiceInfo->supportsService("com.sun.star.text.Paragraph") )
+ {
+ if( Index == nCount )
+ return uno::Any( xServiceInfo );
+ nCount++;
+ }
+ }
+ }
+ throw lang::IndexOutOfBoundsException();
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return getEnumeration();
+ }
+};
+
+}
+
+SwVbaParagraphs::SwVbaParagraphs( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< text::XTextDocument >& xDocument ) : SwVbaParagraphs_BASE( xParent, xContext, new ParagraphCollectionHelper( xDocument ) ), mxTextDocument( xDocument )
+{
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaParagraphs::getElementType()
+{
+ return cppu::UnoType<word::XParagraph>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaParagraphs::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xEnumerationAccess->createEnumeration();
+}
+
+uno::Any
+SwVbaParagraphs::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< text::XTextRange > xTextRange( aSource, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XParagraph >( new SwVbaParagraph( this, mxContext, mxTextDocument, xTextRange ) ) );
+}
+
+OUString
+SwVbaParagraphs::getServiceImplName()
+{
+ return "SwVbaParagraphs";
+}
+
+css::uno::Sequence<OUString>
+SwVbaParagraphs::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Paragraphs"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaparagraph.hxx b/sw/source/ui/vba/vbaparagraph.hxx
new file mode 100644
index 0000000000..6c35455614
--- /dev/null
+++ b/sw/source/ui/vba/vbaparagraph.hxx
@@ -0,0 +1,74 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPH_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPH_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XParagraphs.hpp>
+#include <ooo/vba/word/XParagraph.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XParagraph > SwVbaParagraph_BASE;
+
+class SwVbaParagraph : public SwVbaParagraph_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ css::uno::Reference< css::text::XTextRange > mxTextRange;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaParagraph( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xDocument, css::uno::Reference< css::text::XTextRange > xTextRange );
+ virtual ~SwVbaParagraph() override;
+
+ // XParagraph
+ virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL getRange() override;
+ virtual css::uno::Any SAL_CALL getStyle() override;
+ virtual void SAL_CALL setStyle( const css::uno::Any& style ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+typedef CollTestImplHelper< ooo::vba::word::XParagraphs > SwVbaParagraphs_BASE;
+
+class SwVbaParagraphs : public SwVbaParagraphs_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaParagraphs( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::text::XTextDocument >& xDocument );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaParagraphs_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPH_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaparagraphformat.cxx b/sw/source/ui/vba/vbaparagraphformat.cxx
new file mode 100644
index 0000000000..4e5a61fdeb
--- /dev/null
+++ b/sw/source/ui/vba/vbaparagraphformat.cxx
@@ -0,0 +1,567 @@
+/* -*- 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 "vbaparagraphformat.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <basic/sberrors.hxx>
+#include <com/sun/star/style/LineSpacingMode.hpp>
+#include <ooo/vba/word/WdLineSpacing.hpp>
+#include <ooo/vba/word/WdParagraphAlignment.hpp>
+#include <ooo/vba/word/WdOutlineLevel.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "vbatabstops.hxx"
+#include <o3tl/string_view.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int16 CHARACTER_INDENT_FACTOR = 12;
+const sal_Int16 PERCENT100 = 100;
+const sal_Int16 PERCENT150 = 150;
+const sal_Int16 PERCENT200 = 200;
+
+SwVbaParagraphFormat::SwVbaParagraphFormat( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< beans::XPropertySet > xParaProps ) : SwVbaParagraphFormat_BASE( rParent, rContext ), mxParaProps(std::move( xParaProps ))
+{
+}
+
+SwVbaParagraphFormat::~SwVbaParagraphFormat()
+{
+}
+
+sal_Int32 SAL_CALL SwVbaParagraphFormat::getAlignment()
+{
+ style::ParagraphAdjust aParaAdjust = style::ParagraphAdjust_LEFT;
+ mxParaProps->getPropertyValue("ParaAdjust") >>= aParaAdjust;
+ return getMSWordAlignment( aParaAdjust );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setAlignment( sal_Int32 _alignment )
+{
+ style::ParagraphAdjust aParaAdjust = getOOoAlignment( _alignment );
+ mxParaProps->setPropertyValue("ParaAdjust", uno::Any( aParaAdjust ) );
+}
+
+float SAL_CALL SwVbaParagraphFormat::getFirstLineIndent()
+{
+ sal_Int32 indent = 0;
+ mxParaProps->getPropertyValue("ParaFirstLineIndent") >>= indent;
+ return static_cast<float>( Millimeter::getInPoints( indent ) );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setFirstLineIndent( float _firstlineindent )
+{
+ sal_Int32 indent = Millimeter::getInHundredthsOfOneMillimeter( _firstlineindent );
+ mxParaProps->setPropertyValue("ParaFirstLineIndent", uno::Any( indent ) );
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getKeepTogether()
+{
+ bool bKeep = false;
+ mxParaProps->getPropertyValue("ParaKeepTogether") >>= bKeep;
+ return uno::Any ( bKeep );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setKeepTogether( const uno::Any& _keeptogether )
+{
+ bool bKeep = false;
+ if( _keeptogether >>= bKeep )
+ {
+ mxParaProps->setPropertyValue("ParaKeepTogether", uno::Any( bKeep ) );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getKeepWithNext()
+{
+ bool bKeep = false;
+ mxParaProps->getPropertyValue("ParaSplit") >>= bKeep;
+ return uno::Any ( bKeep );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setKeepWithNext( const uno::Any& _keepwithnext )
+{
+ bool bKeep = false;
+ if( _keepwithnext >>= bKeep )
+ {
+ mxParaProps->setPropertyValue("ParaSplit", uno::Any( bKeep ) );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getHyphenation()
+{
+ bool bHypn = false;
+ mxParaProps->getPropertyValue("ParaIsHyphenation") >>= bHypn;
+ return uno::Any ( bHypn );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setHyphenation( const uno::Any& _hyphenation )
+{
+ bool bHypn = false;
+ if( _hyphenation >>= bHypn )
+ {
+ mxParaProps->setPropertyValue("ParaIsHyphenation", uno::Any( bHypn ) );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+}
+
+float SAL_CALL SwVbaParagraphFormat::getLineSpacing()
+{
+ style::LineSpacing aLineSpacing;
+ mxParaProps->getPropertyValue("ParaLineSpacing") >>= aLineSpacing;
+ return getMSWordLineSpacing( aLineSpacing );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setLineSpacing( float _linespacing )
+{
+ style::LineSpacing aLineSpacing;
+ mxParaProps->getPropertyValue("ParaLineSpacing") >>= aLineSpacing;
+ aLineSpacing = getOOoLineSpacing( _linespacing, aLineSpacing.Mode );
+ mxParaProps->setPropertyValue("ParaLineSpacing", uno::Any( aLineSpacing ) );
+}
+
+sal_Int32 SAL_CALL SwVbaParagraphFormat::getLineSpacingRule()
+{
+ style::LineSpacing aLineSpacing;
+ mxParaProps->getPropertyValue("ParaLineSpacing") >>= aLineSpacing;
+ return getMSWordLineSpacingRule( aLineSpacing );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setLineSpacingRule( sal_Int32 _linespacingrule )
+{
+ style::LineSpacing aLineSpacing = getOOoLineSpacingFromRule( _linespacingrule );
+ mxParaProps->setPropertyValue("ParaLineSpacing", uno::Any( aLineSpacing ) );
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getNoLineNumber()
+{
+ bool noLineNum = false;
+ mxParaProps->getPropertyValue("ParaLineNumberCount") >>= noLineNum;
+ return uno::Any ( noLineNum );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setNoLineNumber( const uno::Any& _nolinenumber )
+{
+ bool noLineNum = false;
+ if( _nolinenumber >>= noLineNum )
+ {
+ mxParaProps->setPropertyValue("ParaLineNumberCount", uno::Any( noLineNum ) );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+}
+
+sal_Int32 SAL_CALL SwVbaParagraphFormat::getOutlineLevel()
+{
+ sal_Int32 nLevel = word::WdOutlineLevel::wdOutlineLevelBodyText;
+ OUString aHeading;
+ static constexpr OUString HEADING = u"Heading"_ustr;
+ mxParaProps->getPropertyValue("ParaStyleName") >>= aHeading;
+ if( aHeading.startsWith( HEADING ) )
+ {
+ // get the sub string after "Heading"
+ nLevel = o3tl::toInt32(aHeading.subView( HEADING.getLength() ));
+ }
+ return nLevel;
+}
+
+void SAL_CALL SwVbaParagraphFormat::setOutlineLevel( sal_Int32 _outlinelevel )
+{
+ if( _outlinelevel != getOutlineLevel() )
+ {
+ // TODO: in my test in msword, there is no effect for this function.
+ }
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getPageBreakBefore()
+{
+ style::BreakType aBreakType;
+ mxParaProps->getPropertyValue("BreakType") >>= aBreakType;
+ bool bBreakBefore = ( aBreakType == style::BreakType_PAGE_BEFORE || aBreakType == style::BreakType_PAGE_BOTH );
+ return uno::Any( bBreakBefore );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setPageBreakBefore( const uno::Any& _breakbefore )
+{
+ bool bBreakBefore = false;
+ if( _breakbefore >>= bBreakBefore )
+ {
+ style::BreakType aBreakType;
+ mxParaProps->getPropertyValue("BreakType") >>= aBreakType;
+ if( bBreakBefore )
+ {
+ if( aBreakType == style::BreakType_NONE )
+ aBreakType = style::BreakType_PAGE_BEFORE;
+ else if ( aBreakType == style::BreakType_PAGE_AFTER )
+ aBreakType = style::BreakType_PAGE_BOTH;
+ }
+ else
+ {
+ if( aBreakType == style::BreakType_PAGE_BOTH )
+ aBreakType = style::BreakType_PAGE_AFTER;
+ else if ( aBreakType == style::BreakType_PAGE_BEFORE )
+ aBreakType = style::BreakType_PAGE_AFTER;
+ }
+ mxParaProps->setPropertyValue("BreakType", uno::Any( aBreakType ) );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+}
+
+float SAL_CALL SwVbaParagraphFormat::getSpaceBefore()
+{
+ sal_Int32 nSpace = 0;
+ mxParaProps->getPropertyValue("ParaTopMargin") >>= nSpace;
+ return static_cast<float>( Millimeter::getInPoints( nSpace ) );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setSpaceBefore( float _space )
+{
+ sal_Int32 nSpace = Millimeter::getInHundredthsOfOneMillimeter( _space );
+ mxParaProps->setPropertyValue("ParaTopMargin", uno::Any( nSpace ) );
+}
+
+float SAL_CALL SwVbaParagraphFormat::getSpaceAfter()
+{
+ sal_Int32 nSpace = 0;
+ mxParaProps->getPropertyValue("ParaBottomMargin") >>= nSpace;
+ return static_cast<float>( Millimeter::getInPoints( nSpace ) );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setSpaceAfter( float _space )
+{
+ sal_Int32 nSpace = Millimeter::getInHundredthsOfOneMillimeter( _space );
+ mxParaProps->setPropertyValue("ParaBottomMargin", uno::Any( nSpace ) );
+}
+
+float SAL_CALL SwVbaParagraphFormat::getLeftIndent()
+{
+ sal_Int32 nIndent = 0;
+ mxParaProps->getPropertyValue("ParaLeftMargin") >>= nIndent;
+ return static_cast<float>( Millimeter::getInPoints( nIndent ) );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setLeftIndent( float _leftindent )
+{
+ sal_Int32 nIndent = Millimeter::getInHundredthsOfOneMillimeter( _leftindent );
+ mxParaProps->setPropertyValue("ParaLeftMargin", uno::Any( nIndent ) );
+}
+
+float SAL_CALL SwVbaParagraphFormat::getRightIndent()
+{
+ sal_Int32 nIndent = 0;
+ mxParaProps->getPropertyValue("ParaRightMargin") >>= nIndent;
+ return static_cast<float>( Millimeter::getInPoints( nIndent ) );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setRightIndent( float _rightindent )
+{
+ sal_Int32 nIndent = Millimeter::getInHundredthsOfOneMillimeter( _rightindent );
+ mxParaProps->setPropertyValue("ParaRightMargin", uno::Any( nIndent ) );
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getTabStops()
+{
+ return uno::Any( uno::Reference< word::XTabStops >( new SwVbaTabStops( this, mxContext, mxParaProps ) ) );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setTabStops( const uno::Any& /*_tabstops*/ )
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+uno::Any SAL_CALL SwVbaParagraphFormat::getWidowControl()
+{
+ sal_Int8 nWidow = 0;
+ mxParaProps->getPropertyValue("ParaWidows") >>= nWidow;
+ sal_Int8 nOrphan = 0;
+ mxParaProps->getPropertyValue("ParaOrphans") >>= nOrphan;
+ // if the amount of single lines on one page > 1 and the same of start and end of the paragraph,
+ // true is returned.
+ bool bWidow = ( nWidow > 1 && nOrphan == nWidow );
+ return uno::Any( bWidow );
+}
+
+void SAL_CALL SwVbaParagraphFormat::setWidowControl( const uno::Any& _widowcontrol )
+{
+ // if we get true, the part of the paragraph on one page has to be
+ // at least two lines
+ bool bWidow = false;
+ if( _widowcontrol >>= bWidow )
+ {
+ sal_Int8 nControl = bWidow? 2:1;
+ mxParaProps->setPropertyValue("ParaWidows", uno::Any( nControl ) );
+ mxParaProps->setPropertyValue("ParaOrphans", uno::Any( nControl ) );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+}
+
+style::LineSpacing SwVbaParagraphFormat::getOOoLineSpacing( float _lineSpace, sal_Int16 mode )
+{
+ style::LineSpacing aLineSpacing;
+ if( mode != style::LineSpacingMode::MINIMUM && mode != style::LineSpacingMode::FIX )
+ {
+ // special behaviour of word: if the space is set to these values, the rule and
+ // the height are changed accordingly
+ if( _lineSpace == CHARACTER_INDENT_FACTOR )
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = PERCENT100;
+ }
+ else if( _lineSpace == CHARACTER_INDENT_FACTOR * 1.5 ) // no rounding issues, == 18
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = PERCENT150;
+ }
+ else if( _lineSpace == CHARACTER_INDENT_FACTOR * 2 )
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = PERCENT200;
+ }
+ else
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::FIX;
+ aLineSpacing.Height = static_cast<sal_Int16>( Millimeter::getInHundredthsOfOneMillimeter( _lineSpace ) );
+ }
+ }
+ else
+ {
+ aLineSpacing.Mode = mode;
+ aLineSpacing.Height = static_cast<sal_Int16>( Millimeter::getInHundredthsOfOneMillimeter( _lineSpace ) );
+ }
+ return aLineSpacing;
+}
+
+style::LineSpacing SwVbaParagraphFormat::getOOoLineSpacingFromRule( sal_Int32 _linespacingrule )
+{
+ style::LineSpacing aLineSpacing;
+ switch( _linespacingrule )
+ {
+ case word::WdLineSpacing::wdLineSpace1pt5:
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = PERCENT150;
+ break;
+ }
+ case word::WdLineSpacing::wdLineSpaceAtLeast:
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::MINIMUM;
+ aLineSpacing.Height = getCharHeight();
+ break;
+ }
+ case word::WdLineSpacing::wdLineSpaceDouble:
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = getCharHeight();
+ break;
+ }
+ case word::WdLineSpacing::wdLineSpaceExactly:
+ case word::WdLineSpacing::wdLineSpaceMultiple:
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::FIX;
+ aLineSpacing.Height = getCharHeight();
+ break;
+ }
+ case word::WdLineSpacing::wdLineSpaceSingle:
+ {
+ aLineSpacing.Mode = style::LineSpacingMode::PROP;
+ aLineSpacing.Height = PERCENT100;
+ break;
+ }
+ default:
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ break;
+ }
+ }
+ return aLineSpacing;
+}
+
+float SwVbaParagraphFormat::getMSWordLineSpacing( style::LineSpacing const & rLineSpacing )
+{
+ float wdLineSpacing = 0;
+ if( rLineSpacing.Mode != style::LineSpacingMode::PROP )
+ {
+ wdLineSpacing = static_cast<float>( Millimeter::getInPoints( rLineSpacing.Height ) );
+ }
+ else
+ {
+ wdLineSpacing = static_cast<float>( CHARACTER_INDENT_FACTOR * rLineSpacing.Height ) / PERCENT100;
+ }
+ return wdLineSpacing;
+}
+
+sal_Int32 SwVbaParagraphFormat::getMSWordLineSpacingRule( style::LineSpacing const & rLineSpacing )
+{
+ sal_Int32 wdLineSpacing = word::WdLineSpacing::wdLineSpaceSingle;
+ switch( rLineSpacing.Mode )
+ {
+ case style::LineSpacingMode::PROP:
+ {
+ switch( rLineSpacing.Height )
+ {
+ case PERCENT100:
+ {
+ wdLineSpacing = word::WdLineSpacing::wdLineSpaceSingle;
+ break;
+ }
+ case PERCENT150:
+ {
+ wdLineSpacing = word::WdLineSpacing::wdLineSpace1pt5;
+ break;
+ }
+ case PERCENT200:
+ {
+ wdLineSpacing = word::WdLineSpacing::wdLineSpaceDouble;
+ break;
+ }
+ default:
+ {
+ wdLineSpacing = word::WdLineSpacing::wdLineSpaceMultiple;
+ }
+ }
+ break;
+ }
+ case style::LineSpacingMode::MINIMUM:
+ {
+ wdLineSpacing = word::WdLineSpacing::wdLineSpaceAtLeast;
+ break;
+ }
+ case style::LineSpacingMode::FIX:
+ case style::LineSpacingMode::LEADING:
+ {
+ wdLineSpacing = word::WdLineSpacing::wdLineSpaceExactly;
+ break;
+ }
+ default:
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+ }
+ return wdLineSpacing;
+}
+
+sal_Int16 SwVbaParagraphFormat::getCharHeight()
+{
+ float fCharHeight = 0.0;
+ mxParaProps->getPropertyValue("CharHeight") >>= fCharHeight;
+ return static_cast<sal_Int16>( Millimeter::getInHundredthsOfOneMillimeter( fCharHeight ) );
+}
+
+style::ParagraphAdjust SwVbaParagraphFormat::getOOoAlignment( sal_Int32 _alignment )
+{
+ style::ParagraphAdjust nParaAjust = style::ParagraphAdjust_LEFT;
+ switch( _alignment )
+ {
+ case word::WdParagraphAlignment::wdAlignParagraphCenter:
+ {
+ nParaAjust = style::ParagraphAdjust_CENTER;
+ break;
+ }
+ case word::WdParagraphAlignment::wdAlignParagraphJustify:
+ {
+ nParaAjust = style::ParagraphAdjust_BLOCK;
+ break;
+ }
+ case word::WdParagraphAlignment::wdAlignParagraphLeft:
+ {
+ nParaAjust = style::ParagraphAdjust_LEFT;
+ break;
+ }
+ case word::WdParagraphAlignment::wdAlignParagraphRight:
+ {
+ nParaAjust = style::ParagraphAdjust_RIGHT;
+ break;
+ }
+ default:
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER );
+ }
+ }
+ return nParaAjust;
+}
+
+sal_Int32 SwVbaParagraphFormat::getMSWordAlignment( style::ParagraphAdjust _alignment )
+{
+ sal_Int32 wdAlignment = word::WdParagraphAlignment::wdAlignParagraphLeft;
+ switch( _alignment )
+ {
+ case style::ParagraphAdjust_CENTER:
+ {
+ wdAlignment = word::WdParagraphAlignment::wdAlignParagraphCenter;
+ break;
+ }
+ case style::ParagraphAdjust_LEFT:
+ {
+ wdAlignment = word::WdParagraphAlignment::wdAlignParagraphLeft;
+ break;
+ }
+ case style::ParagraphAdjust_BLOCK:
+ {
+ wdAlignment = word::WdParagraphAlignment::wdAlignParagraphJustify;
+ break;
+ }
+ case style::ParagraphAdjust_RIGHT:
+ {
+ wdAlignment = word::WdParagraphAlignment::wdAlignParagraphRight;
+ break;
+ }
+ default:
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );
+ }
+ }
+ return wdAlignment;
+}
+
+OUString
+SwVbaParagraphFormat::getServiceImplName()
+{
+ return "SwVbaParagraphFormat";
+}
+
+uno::Sequence< OUString >
+SwVbaParagraphFormat::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.ParagraphFormat"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaparagraphformat.hxx b/sw/source/ui/vba/vbaparagraphformat.hxx
new file mode 100644
index 0000000000..a80c21e1b1
--- /dev/null
+++ b/sw/source/ui/vba/vbaparagraphformat.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPHFORMAT_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPHFORMAT_HXX
+
+#include <ooo/vba/word/XParagraphFormat.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XParagraphFormat > SwVbaParagraphFormat_BASE;
+
+class SwVbaParagraphFormat : public SwVbaParagraphFormat_BASE
+{
+private:
+ css::uno::Reference< css::beans::XPropertySet > mxParaProps;
+
+private:
+ static css::style::LineSpacing getOOoLineSpacing( float _lineSpace, sal_Int16 mode );
+ css::style::LineSpacing getOOoLineSpacingFromRule( sal_Int32 _linespacingrule );
+ static float getMSWordLineSpacing( css::style::LineSpacing const & rLineSpacing );
+ static sal_Int32 getMSWordLineSpacingRule( css::style::LineSpacing const & rLineSpacing );
+ /// @throws css::uno::RuntimeException
+ sal_Int16 getCharHeight();
+ static css::style::ParagraphAdjust getOOoAlignment( sal_Int32 _alignment );
+ static sal_Int32 getMSWordAlignment( css::style::ParagraphAdjust _alignment );
+
+public:
+ SwVbaParagraphFormat( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::beans::XPropertySet > xParaProps );
+ virtual ~SwVbaParagraphFormat() override;
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getAlignment() override;
+ virtual void SAL_CALL setAlignment( ::sal_Int32 _alignment ) override;
+ virtual float SAL_CALL getFirstLineIndent() override;
+ virtual void SAL_CALL setFirstLineIndent( float _firstlineindent ) override;
+ virtual css::uno::Any SAL_CALL getKeepTogether() override;
+ virtual void SAL_CALL setKeepTogether( const css::uno::Any& _keeptogether ) override;
+ virtual css::uno::Any SAL_CALL getKeepWithNext() override;
+ virtual void SAL_CALL setKeepWithNext( const css::uno::Any& _keepwithnext ) override;
+ virtual css::uno::Any SAL_CALL getHyphenation() override;
+ virtual void SAL_CALL setHyphenation( const css::uno::Any& _hyphenation ) override;
+ virtual float SAL_CALL getLineSpacing() override;
+ virtual void SAL_CALL setLineSpacing( float _linespacing ) override;
+ virtual ::sal_Int32 SAL_CALL getLineSpacingRule() override;
+ virtual void SAL_CALL setLineSpacingRule( ::sal_Int32 _linespacingrule ) override;
+ virtual css::uno::Any SAL_CALL getNoLineNumber() override;
+ virtual void SAL_CALL setNoLineNumber( const css::uno::Any& _nolinenumber ) override;
+ virtual ::sal_Int32 SAL_CALL getOutlineLevel() override;
+ virtual void SAL_CALL setOutlineLevel( ::sal_Int32 _outlinelevel ) override;
+ virtual css::uno::Any SAL_CALL getPageBreakBefore() override;
+ virtual void SAL_CALL setPageBreakBefore( const css::uno::Any& _pagebreakbefore ) override;
+ virtual float SAL_CALL getSpaceBefore() override;
+ virtual void SAL_CALL setSpaceBefore( float _spacebefore ) override;
+ virtual float SAL_CALL getSpaceAfter() override;
+ virtual void SAL_CALL setSpaceAfter( float _spaceafter ) override;
+ virtual float SAL_CALL getLeftIndent() override;
+ virtual void SAL_CALL setLeftIndent( float _leftindent ) override;
+ virtual float SAL_CALL getRightIndent() override;
+ virtual void SAL_CALL setRightIndent( float _rightindent ) override;
+ virtual css::uno::Any SAL_CALL getTabStops() override;
+ virtual void SAL_CALL setTabStops( const css::uno::Any& _tabstops ) override;
+ virtual css::uno::Any SAL_CALL getWidowControl() override;
+ virtual void SAL_CALL setWidowControl( const css::uno::Any& _widowcontrol ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAPARAGRAPHFORMAT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarange.cxx b/sw/source/ui/vba/vbarange.cxx
new file mode 100644
index 0000000000..c48dd6193c
--- /dev/null
+++ b/sw/source/ui/vba/vbarange.cxx
@@ -0,0 +1,434 @@
+/* -*- 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 "vbarange.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <basic/sberrors.hxx>
+#include "vbarangehelper.hxx"
+#include <ooo/vba/word/WdBreakType.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include "vbaparagraphformat.hxx"
+#include "vbastyle.hxx"
+#include "vbafont.hxx"
+#include "vbafind.hxx"
+#include "vbapalette.hxx"
+#include "vbapagesetup.hxx"
+#include "vbalistformat.hxx"
+#include "vbarevisions.hxx"
+#include "vbabookmarks.hxx"
+#include "vbasections.hxx"
+#include "vbafield.hxx"
+#include "wordvbahelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaRange::SwVbaRange( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDocument, const uno::Reference< text::XTextRange >& rStart ) : SwVbaRange_BASE( rParent, rContext ), mxTextDocument(std::move( xTextDocument ))
+{
+ uno::Reference< text::XTextRange > xEnd;
+ initialize( rStart, xEnd );
+}
+
+SwVbaRange::SwVbaRange( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDocument, const uno::Reference< text::XTextRange >& rStart, const uno::Reference< text::XTextRange >& rEnd ) : SwVbaRange_BASE( rParent, rContext ), mxTextDocument(std::move( xTextDocument ))
+{
+ initialize( rStart, rEnd );
+}
+
+SwVbaRange::SwVbaRange( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xTextDocument, const uno::Reference< text::XTextRange >& rStart, const uno::Reference< text::XTextRange >& rEnd, uno::Reference< text::XText > xText ) : SwVbaRange_BASE( rParent, rContext ),mxTextDocument(std::move( xTextDocument )), mxText(std::move( xText ))
+{
+ initialize( rStart, rEnd );
+}
+
+SwVbaRange::~SwVbaRange()
+{
+}
+
+void SwVbaRange::initialize( const uno::Reference< text::XTextRange >& rStart, const uno::Reference< text::XTextRange >& rEnd )
+{
+ if( !mxText.is() )
+ {
+ mxText = mxTextDocument->getText();
+ }
+
+ mxTextCursor = SwVbaRangeHelper::initCursor( rStart, mxText );
+ if( !mxTextCursor.is() )
+ throw uno::RuntimeException("Fails to create text cursor" );
+ mxTextCursor->collapseToStart();
+
+ if( rEnd.is() )
+ mxTextCursor->gotoRange( rEnd, true );
+ else
+ mxTextCursor->gotoEnd( true );
+}
+
+uno::Reference< text::XTextRange > SAL_CALL
+SwVbaRange::getXTextRange()
+{
+ uno::Reference< text::XTextRange > xTextRange( mxTextCursor, uno::UNO_QUERY_THROW );
+ return xTextRange;
+}
+
+/**
+* The complexity in this method is because we need to workaround
+* an issue that the last paragraph in a document does not have a trailing CRLF.
+* @return
+*/
+OUString SAL_CALL
+SwVbaRange::getText()
+{
+ OUString aText = mxTextCursor->getString();
+ sal_Int32 nLen = aText.getLength();
+
+ // FIXME: should add a line separator if the range includes the last paragraph
+ if( nLen == 0 )
+ {
+ if( mxTextCursor->isCollapsed() )
+ {
+ mxTextCursor->goRight( 1, true );
+ aText = mxTextCursor->getString();
+ mxTextCursor->collapseToStart();
+ }
+ else
+ {
+ uno::Reference< text::XTextRange > xStart = mxTextCursor->getStart();
+ uno::Reference< text::XTextRange > xEnd = mxTextCursor->getEnd();
+ mxTextCursor->collapseToEnd();
+ mxTextCursor->goRight( 1, true );
+ mxTextCursor->gotoRange( xStart, false );
+ mxTextCursor->gotoRange( xEnd, true );
+ }
+ }
+
+ return aText;
+}
+
+void SAL_CALL
+SwVbaRange::setText( const OUString& rText )
+{
+ // Emulate the MSWord behavior, Don't delete the bookmark
+ // which contains no text string in current inserting position,
+ OUString sName;
+ uno::Reference< text::XTextRange > xRange( mxTextCursor, uno::UNO_QUERY_THROW );
+ try
+ {
+ uno::Reference< text::XTextContent > xBookmark = SwVbaRangeHelper::findBookmarkByPosition( mxTextDocument, xRange->getStart() );
+ if( xBookmark.is() )
+ {
+ uno::Reference< container::XNamed > xNamed( xBookmark, uno::UNO_QUERY_THROW );
+ sName = xNamed->getName();
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ // do nothing
+ }
+
+ if( rText.indexOf( '\n' ) != -1 )
+ {
+ mxTextCursor->setString( OUString() );
+ // process CR in strings
+ SwVbaRangeHelper::insertString( xRange, mxText, rText, true );
+ }
+ else
+ {
+ mxTextCursor->setString( rText );
+ }
+
+ // insert the bookmark if the bookmark is deleted during setting text string
+ if( !sName.isEmpty() )
+ {
+ uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xNameAccess( xBookmarksSupplier->getBookmarks(), uno::UNO_SET_THROW );
+ if( !xNameAccess->hasByName( sName ) )
+ {
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ SwVbaBookmarks::addBookmarkByName( xModel, sName, xRange->getStart() );
+ }
+ }
+}
+
+// FIXME: test is not pass
+void SAL_CALL SwVbaRange::InsertBreak(const uno::Any& _breakType)
+{
+ // default type is wdPageBreak;
+ sal_Int32 nBreakType = word::WdBreakType::wdPageBreak;
+ if( _breakType.hasValue() )
+ _breakType >>= nBreakType;
+
+ style::BreakType eBreakType = style::BreakType_NONE;
+ switch( nBreakType )
+ {
+ case word::WdBreakType::wdPageBreak:
+ eBreakType = style::BreakType_PAGE_BEFORE;
+ break;
+ case word::WdBreakType::wdColumnBreak:
+ eBreakType = style::BreakType_COLUMN_AFTER;
+ break;
+ case word::WdBreakType::wdLineBreak:
+ case word::WdBreakType::wdLineBreakClearLeft:
+ case word::WdBreakType::wdLineBreakClearRight:
+ case word::WdBreakType::wdSectionBreakContinuous:
+ case word::WdBreakType::wdSectionBreakEvenPage:
+ case word::WdBreakType::wdSectionBreakNextPage:
+ case word::WdBreakType::wdSectionBreakOddPage:
+ case word::WdBreakType::wdTextWrappingBreak:
+ DebugHelper::basicexception( ERRCODE_BASIC_NOT_IMPLEMENTED, {} );
+ break;
+ default:
+ DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER, {} );
+ }
+
+ if( eBreakType != style::BreakType_NONE )
+ {
+ if( !mxTextCursor->isCollapsed() )
+ {
+ mxTextCursor->setString( OUString() );
+ mxTextCursor->collapseToStart();
+ }
+
+ uno::Reference< beans::XPropertySet > xProp( mxTextCursor, uno::UNO_QUERY_THROW );
+ xProp->setPropertyValue("BreakType", uno::Any( eBreakType ) );
+ }
+}
+
+void SAL_CALL
+SwVbaRange::Select()
+{
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextViewCursor > xTextViewCursor = word::getXTextViewCursor( xModel );
+ xTextViewCursor->gotoRange( mxTextCursor->getStart(), false );
+ xTextViewCursor->gotoRange( mxTextCursor->getEnd(), true );
+}
+
+void SAL_CALL
+SwVbaRange::InsertParagraph()
+{
+ mxTextCursor->setString( "" );
+ InsertParagraphBefore();
+}
+
+void SAL_CALL
+SwVbaRange::InsertParagraphBefore()
+{
+ uno::Reference< text::XTextRange > xTextRange = mxTextCursor->getStart();
+ mxText->insertControlCharacter( xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, true );
+ mxTextCursor->gotoRange( xTextRange, true );
+}
+
+void SAL_CALL
+SwVbaRange::InsertParagraphAfter()
+{
+ uno::Reference< text::XTextRange > xTextRange = mxTextCursor->getEnd();
+ mxText->insertControlCharacter( xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, true );
+}
+
+uno::Reference< word::XParagraphFormat > SAL_CALL
+SwVbaRange::getParagraphFormat()
+{
+ uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW );
+ return uno::Reference< word::XParagraphFormat >( new SwVbaParagraphFormat( this, mxContext, xParaProps ) );
+}
+
+void SAL_CALL
+SwVbaRange::setParagraphFormat( const uno::Reference< word::XParagraphFormat >& /*rParagraphFormat*/ )
+{
+ throw uno::RuntimeException("Not implemented" );
+}
+
+void SwVbaRange::GetStyleInfo(OUString& aStyleName, OUString& aStyleType )
+{
+ uno::Reference< beans::XPropertySet > xProp( mxTextCursor, uno::UNO_QUERY_THROW );
+ if( ( xProp->getPropertyValue("CharStyleName") >>= aStyleName ) && !aStyleName.isEmpty() )
+ {
+ aStyleType = "CharacterStyles";
+ }
+ else if( ( xProp->getPropertyValue("ParaStyleName") >>= aStyleName ) && !aStyleName.isEmpty() )
+ {
+ aStyleType = "ParagraphStyles";
+ }
+ if( aStyleType.isEmpty() )
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_INTERNAL_ERROR );
+ }
+}
+
+uno::Any SAL_CALL
+SwVbaRange::getStyle()
+{
+ OUString aStyleName;
+ OUString aStyleType;
+ GetStyleInfo( aStyleName, aStyleType );
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxTextDocument, uno::UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xStylesAccess( xStyleSupplier->getStyleFamilies()->getByName( aStyleType ), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xStyleProps( xStylesAccess->getByName( aStyleName ), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XStyle >( new SwVbaStyle( this, mxContext, xModel, xStyleProps ) ) );
+}
+
+void SAL_CALL
+SwVbaRange::setStyle( const uno::Any& rStyle )
+{
+ uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW );
+ SwVbaStyle::setStyle( xParaProps, rStyle );
+}
+
+uno::Reference< word::XFont > SAL_CALL
+SwVbaRange::getFont()
+{
+ VbaPalette aColors;
+ return new SwVbaFont( mxParent, mxContext, aColors.getPalette(), uno::Reference< beans::XPropertySet >( getXTextRange(), uno::UNO_QUERY_THROW ) );
+}
+
+uno::Reference< word::XFind > SAL_CALL
+SwVbaRange::getFind()
+{
+ uno::Reference< text::XTextRange > xTextRange = getXTextRange();
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ return SwVbaFind::GetOrCreateFind(this, mxContext, xModel, xTextRange);
+}
+
+uno::Reference< word::XListFormat > SAL_CALL
+SwVbaRange::getListFormat()
+{
+ return uno::Reference< word::XListFormat >( new SwVbaListFormat( this, mxContext, getXTextRange() ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaRange::getLanguageID()
+{
+ uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW );
+ return static_cast<sal_uInt16>(SwVbaStyle::getLanguageID( xParaProps ));
+}
+
+void SAL_CALL SwVbaRange::setLanguageID( ::sal_Int32 _languageid )
+{
+ uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW );
+ SwVbaStyle::setLanguageID( xParaProps, LanguageType(_languageid) );
+}
+
+uno::Any SAL_CALL
+SwVbaRange::PageSetup( )
+{
+ uno::Reference< beans::XPropertySet > xParaProps( mxTextCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ OUString aPageStyleName;
+ xParaProps->getPropertyValue("PageStyleName") >>= aPageStyleName;
+ uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW );
+ uno::Reference< container::XNameAccess > xPageStyles( xSytleFamNames->getByName("PageStyles"), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPageProps( xPageStyles->getByName( aPageStyleName ), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XPageSetup >( new SwVbaPageSetup( this, mxContext, xModel, xPageProps ) ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaRange::getStart()
+{
+ uno::Reference< text::XText > xText = mxTextDocument->getText();
+ return SwVbaRangeHelper::getPosition( xText, mxTextCursor->getStart() );
+}
+
+void SAL_CALL SwVbaRange::setStart( ::sal_Int32 _start )
+{
+ uno::Reference< text::XText > xText = mxTextDocument->getText();
+ uno::Reference< text::XTextRange > xStart = SwVbaRangeHelper::getRangeByPosition( xText, _start );
+ uno::Reference< text::XTextRange > xEnd = mxTextCursor->getEnd();
+
+ mxTextCursor->gotoRange( xStart, false );
+ mxTextCursor->gotoRange( xEnd, true );
+}
+
+::sal_Int32 SAL_CALL SwVbaRange::getEnd()
+{
+ uno::Reference< text::XText > xText = mxTextDocument->getText();
+ return SwVbaRangeHelper::getPosition( xText, mxTextCursor->getEnd() );
+}
+
+void SAL_CALL SwVbaRange::setEnd( ::sal_Int32 _end )
+{
+ uno::Reference< text::XText > xText = mxTextDocument->getText();
+ uno::Reference< text::XTextRange > xEnd = SwVbaRangeHelper::getRangeByPosition( xText, _end );
+
+ mxTextCursor->collapseToStart();
+ mxTextCursor->gotoRange( xEnd, true );
+}
+
+sal_Bool SAL_CALL SwVbaRange::InRange( const uno::Reference< ::ooo::vba::word::XRange >& Range )
+{
+ SwVbaRange* pRange = dynamic_cast< SwVbaRange* >( Range.get() );
+ if( !pRange )
+ throw uno::RuntimeException();
+ uno::Reference< text::XTextRange > xTextRange = pRange->getXTextRange();
+ uno::Reference< text::XTextRangeCompare > xTRC( mxTextCursor->getText(), uno::UNO_QUERY_THROW );
+ if( xTRC->compareRegionStarts( xTextRange, getXTextRange() ) >= 0 && xTRC->compareRegionEnds( xTextRange, getXTextRange() ) <= 0 )
+ return true;
+ return false;
+}
+
+uno::Any SAL_CALL
+SwVbaRange::Revisions( const uno::Any& index )
+{
+ uno::Reference< text::XTextRange > xTextRange = getXTextRange();
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaRevisions( mxParent, mxContext, xModel, xTextRange ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaRange::Sections( const uno::Any& index )
+{
+ uno::Reference< text::XTextRange > xTextRange = getXTextRange();
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaSections( mxParent, mxContext, xModel, xTextRange ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaRange::Fields( const uno::Any& index )
+{
+ //FIXME: should be get the field in current range
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, xModel ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+OUString
+SwVbaRange::getServiceImplName()
+{
+ return "SwVbaRange";
+}
+
+uno::Sequence< OUString >
+SwVbaRange::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Range"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarange.hxx b/sw/source/ui/vba/vbarange.hxx
new file mode 100644
index 0000000000..f0dd156350
--- /dev/null
+++ b/sw/source/ui/vba/vbarange.hxx
@@ -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/.
+ *
+ * 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBARANGE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBARANGE_HXX
+
+#include <ooo/vba/word/XRange.hpp>
+#include <ooo/vba/word/XParagraphFormat.hpp>
+#include <ooo/vba/word/XFont.hpp>
+#include <ooo/vba/word/XFind.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <ooo/vba/word/XListFormat.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XRange > SwVbaRange_BASE;
+
+class SwVbaRange : public SwVbaRange_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ css::uno::Reference< css::text::XTextCursor > mxTextCursor;
+ css::uno::Reference< css::text::XText > mxText;
+
+private:
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ void initialize( const css::uno::Reference< css::text::XTextRange >& rStart, const css::uno::Reference< css::text::XTextRange >& rEnd );
+ /// @throws css::uno::RuntimeException
+ void GetStyleInfo(OUString& aStyleName, OUString& aStyleType );
+public:
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ SwVbaRange( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDocument, const css::uno::Reference< css::text::XTextRange >& rStart);
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ SwVbaRange( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDocument, const css::uno::Reference< css::text::XTextRange >& rStart, const css::uno::Reference< css::text::XTextRange >& rEnd );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ SwVbaRange( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xTextDocument, const css::uno::Reference< css::text::XTextRange >& rStart, const css::uno::Reference< css::text::XTextRange >& rEnd, css::uno::Reference< css::text::XText > xText);
+ virtual ~SwVbaRange() override;
+ const css::uno::Reference< css::text::XTextDocument >& getDocument() const { return mxTextDocument; }
+
+ virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getXTextRange() override;
+ const css::uno::Reference< css::text::XText >& getXText() const { return mxText; }
+ void setXTextCursor( const css::uno::Reference< css::text::XTextCursor >& xTextCursor ) { mxTextCursor = xTextCursor; }
+
+ // Attribute
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& rText ) override;
+ virtual css::uno::Reference< ooo::vba::word::XParagraphFormat > SAL_CALL getParagraphFormat() override;
+ virtual void SAL_CALL setParagraphFormat( const css::uno::Reference< ooo::vba::word::XParagraphFormat >& rParagraphFormat ) override;
+ virtual css::uno::Any SAL_CALL getStyle() override;
+ virtual void SAL_CALL setStyle( const css::uno::Any& _xStyle ) override;
+ virtual css::uno::Reference< ooo::vba::word::XFont > SAL_CALL getFont() override;
+ virtual css::uno::Reference< ooo::vba::word::XFind > SAL_CALL getFind() override;
+ virtual css::uno::Reference< ooo::vba::word::XListFormat > SAL_CALL getListFormat() override;
+
+ //XDefaultProperty
+ virtual OUString SAL_CALL getDefaultPropertyName() override { return "Text"; }
+
+ // Methods
+ virtual void SAL_CALL InsertBreak(const css::uno::Any& _breakType) override;
+ virtual void SAL_CALL Select() override;
+ virtual void SAL_CALL InsertParagraph() override;
+ virtual void SAL_CALL InsertParagraphBefore() override;
+ virtual void SAL_CALL InsertParagraphAfter() override;
+ virtual ::sal_Int32 SAL_CALL getLanguageID() override;
+ virtual void SAL_CALL setLanguageID( ::sal_Int32 _languageid ) override;
+ virtual css::uno::Any SAL_CALL PageSetup() override;
+ virtual ::sal_Int32 SAL_CALL getStart() override;
+ virtual void SAL_CALL setStart( ::sal_Int32 _start ) override;
+ virtual ::sal_Int32 SAL_CALL getEnd() override;
+ virtual void SAL_CALL setEnd( ::sal_Int32 _end ) override;
+ virtual sal_Bool SAL_CALL InRange( const css::uno::Reference< ::ooo::vba::word::XRange >& Range ) override;
+ virtual css::uno::Any SAL_CALL Revisions( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Sections( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Fields( const css::uno::Any& aIndex ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBARANGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarangehelper.cxx b/sw/source/ui/vba/vbarangehelper.cxx
new file mode 100644
index 0000000000..1760d0f985
--- /dev/null
+++ b/sw/source/ui/vba/vbarangehelper.cxx
@@ -0,0 +1,191 @@
+/* -*- 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 "vbarangehelper.hxx"
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <com/sun/star/text/XBookmarksSupplier.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/**
+ * get a range in a xText by creating
+ * a cursor that iterates over the text. If the iterating cursor is
+ * equal to the desired position, the range equivalent is returned.
+ * Some special cases are tables that are inside of the text, because the
+ * position has to be adjusted.
+ * @param xText a text where a range position is searched
+ * @param position a position inside o the text
+ * @return a range for the position; null is returned if no range can be
+ * constructed.
+ */
+uno::Reference< text::XTextRange > SwVbaRangeHelper::getRangeByPosition( const uno::Reference< text::XText >& rText, sal_Int32 _position )
+{
+ uno::Reference< text::XTextRange > xRange;
+ if( rText.is() )
+ {
+ sal_Int32 nPos = 0;
+ uno::Reference< text::XTextCursor > xCursor = rText->createTextCursor();
+ xCursor->collapseToStart();
+ bool bCanGo = true;
+ while( !xRange.is() && bCanGo )
+ {
+ if( _position == nPos )
+ {
+ xRange = xCursor->getStart();
+ }
+ else
+ {
+ bCanGo = xCursor->goRight( 1, false );
+ nPos++;
+ }
+ }
+ }
+ return xRange;
+}
+
+void SwVbaRangeHelper::insertString( uno::Reference< text::XTextRange > const & rTextRange, uno::Reference< text::XText > const & rText, std::u16string_view aStr, bool _bAbsorb )
+{
+ size_t nlastIndex = 0;
+ size_t nIndex = 0;
+ uno::Reference< text::XTextRange > xRange = rTextRange;
+
+ while( ( nIndex = aStr.find('\n', nlastIndex)) != std::u16string_view::npos )
+ {
+ xRange = xRange->getEnd();
+ if( nlastIndex < ( nIndex - 1 ) )
+ {
+ rText->insertString( xRange, OUString(aStr.substr( nlastIndex, ( nIndex - 1 - nlastIndex ) )), _bAbsorb );
+ xRange = xRange->getEnd();
+ }
+
+ rText->insertControlCharacter( xRange, text::ControlCharacter::PARAGRAPH_BREAK, _bAbsorb );
+ nlastIndex = nIndex + 1;
+ }
+
+ if( nlastIndex < aStr.size() )
+ {
+ xRange = xRange->getEnd();
+
+ OUString aWatt( aStr.substr( nlastIndex ) );
+ rText->insertString( xRange, aWatt, _bAbsorb );
+ }
+}
+
+uno::Reference< text::XTextCursor > SwVbaRangeHelper::initCursor( const uno::Reference< text::XTextRange >& rTextRange,
+ const uno::Reference< text::XText >& rText )
+{
+ uno::Reference< text::XTextCursor > xTextCursor;
+ bool bGotTextCursor = false;
+
+ try
+ {
+ xTextCursor = rText->createTextCursorByRange( rTextRange );
+ bGotTextCursor = true;
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+
+ if( !bGotTextCursor || !xTextCursor.is() )
+ {
+ try
+ {
+ uno::Reference< text::XText > xText = rTextRange->getText();
+ xTextCursor = xText->createTextCursor();
+ bGotTextCursor = true;
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+ }
+
+ if( !bGotTextCursor || !xTextCursor.is() )
+ {
+ try
+ {
+ xTextCursor = rText->createTextCursor();
+ }
+ catch (const uno::Exception& e)
+ {
+ DebugHelper::basicexception(e);
+ }
+ }
+ return xTextCursor;
+}
+
+sal_Int32 SwVbaRangeHelper::getPosition( const uno::Reference< text::XText >& rText, const uno::Reference< text::XTextRange >& rTextRange )
+{
+ sal_Int32 nPosition = -1;
+ if( rText.is() && rTextRange.is() )
+ {
+ nPosition = 0;
+ uno::Reference< text::XTextCursor > xCursor = rText->createTextCursor();
+ xCursor->collapseToStart();
+ uno::Reference< text::XTextRangeCompare > xCompare( rText, uno::UNO_QUERY_THROW );
+ // compareValue is 0 if the ranges are equal
+ sal_Int32 nCompareValue = xCompare->compareRegionStarts( xCursor->getStart(), rTextRange );
+ bool canGo = true;
+
+ while( nCompareValue !=0 && canGo )
+ {
+ canGo = xCursor->goRight( 1, false );
+ nCompareValue = xCompare->compareRegionStarts( xCursor->getStart(), rTextRange );
+ nPosition++;
+ }
+
+ // check fails: no correct position found
+ if( !canGo && nCompareValue != 0 )
+ {
+ nPosition = -1;
+ }
+ }
+
+ return nPosition;
+}
+
+uno::Reference< text::XTextContent > SwVbaRangeHelper::findBookmarkByPosition( const uno::Reference< text::XTextDocument >& xTextDoc, const uno::Reference< text::XTextRange >& xTextRange )
+{
+ uno::Reference< text::XBookmarksSupplier > xBookmarksSupplier( xTextDoc, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xIndexAccess( xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY_THROW );
+ for( sal_Int32 index = 0; index < xIndexAccess->getCount(); index++ )
+ {
+ uno::Reference< text::XTextContent > xBookmark( xIndexAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xBkAnchor = xBookmark->getAnchor();
+ uno::Reference< text::XTextRangeCompare > xCompare( xBkAnchor->getText(), uno::UNO_QUERY_THROW );
+ if( xCompare->compareRegionStarts( xBkAnchor->getStart(), xBkAnchor->getEnd() ) == 0 )
+ {
+ try
+ {
+ if( xCompare->compareRegionStarts( xTextRange, xBkAnchor->getStart() ) == 0 )
+ return xBookmark;
+ }
+ catch (const uno::Exception&)
+ {
+ continue;
+ }
+ }
+ }
+ return uno::Reference< text::XTextContent >();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarangehelper.hxx b/sw/source/ui/vba/vbarangehelper.hxx
new file mode 100644
index 0000000000..af3f885e4a
--- /dev/null
+++ b/sw/source/ui/vba/vbarangehelper.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBARANGEHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBARANGEHELPER_HXX
+
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
+class SwVbaRangeHelper
+{
+public:
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< css::text::XTextRange > getRangeByPosition( const css::uno::Reference< css::text::XText >& rText, sal_Int32 _position );
+ /// @throws css::uno::RuntimeException
+ static void insertString( css::uno::Reference< css::text::XTextRange > const & rTextRange, css::uno::Reference< css::text::XText > const & rText, std::u16string_view aStr, bool _bAbsorb );
+ /// @throws css::uno::RuntimeException
+ /// @throws css::script::BasicErrorException
+ static css::uno::Reference< css::text::XTextCursor > initCursor( const css::uno::Reference< css::text::XTextRange >& rTextRange, const css::uno::Reference< css::text::XText >& rText );
+ /// @throws css::uno::RuntimeException
+ static sal_Int32 getPosition( const css::uno::Reference< css::text::XText >& rText, const css::uno::Reference< css::text::XTextRange >& rTextRange );
+ /// @throws css::uno::RuntimeException
+ static css::uno::Reference< css::text::XTextContent > findBookmarkByPosition( const css::uno::Reference< css::text::XTextDocument >& xTextDoc, const css::uno::Reference< css::text::XTextRange >& xTextRange );
+
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBARANGEHELPER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbareplacement.cxx b/sw/source/ui/vba/vbareplacement.cxx
new file mode 100644
index 0000000000..bed7aee8d7
--- /dev/null
+++ b/sw/source/ui/vba/vbareplacement.cxx
@@ -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 .
+ */
+#include <utility>
+
+#include "vbareplacement.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaReplacement::SwVbaReplacement( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< util::XPropertyReplace > xPropertyReplace ) :
+ SwVbaReplacement_BASE( rParent, rContext ), mxPropertyReplace(std::move( xPropertyReplace ))
+{
+}
+
+SwVbaReplacement::~SwVbaReplacement()
+{
+}
+
+OUString SAL_CALL SwVbaReplacement::getText()
+{
+ return mxPropertyReplace->getReplaceString();
+}
+
+void SAL_CALL SwVbaReplacement::setText( const OUString& _text )
+{
+ mxPropertyReplace->setReplaceString( _text );
+}
+
+void SAL_CALL SwVbaReplacement::ClearFormatting( )
+{
+ uno::Sequence< beans::PropertyValue > aPropValues;
+ mxPropertyReplace->setReplaceAttributes( aPropValues );
+}
+
+OUString
+SwVbaReplacement::getServiceImplName()
+{
+ return "SwVbaReplacement";
+}
+
+uno::Sequence< OUString >
+SwVbaReplacement::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Replacement"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbareplacement.hxx b/sw/source/ui/vba/vbareplacement.hxx
new file mode 100644
index 0000000000..6c6ee89422
--- /dev/null
+++ b/sw/source/ui/vba/vbareplacement.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAREPLACEMENT_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAREPLACEMENT_HXX
+
+#include <ooo/vba/word/XReplacement.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/util/XPropertyReplace.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XReplacement > SwVbaReplacement_BASE;
+
+class SwVbaReplacement : public SwVbaReplacement_BASE
+{
+private:
+ css::uno::Reference< css::util::XPropertyReplace> mxPropertyReplace;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaReplacement( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::util::XPropertyReplace > xPropertyReplace );
+ virtual ~SwVbaReplacement() override;
+
+ // Attributes
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& _text ) override;
+
+ //Methods
+ virtual void SAL_CALL ClearFormatting() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAREPLACEMENT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarevision.cxx b/sw/source/ui/vba/vbarevision.cxx
new file mode 100644
index 0000000000..f8b1c5978d
--- /dev/null
+++ b/sw/source/ui/vba/vbarevision.cxx
@@ -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 .
+ */
+#include "vbarevision.hxx"
+#include <sal/log.hxx>
+#include <com/sun/star/document/XRedlinesSupplier.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include "wordvbahelper.hxx"
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaRevision::SwVbaRevision( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xRedlineProps ) : SwVbaRevision_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxRedlineProps(std::move( xRedlineProps ))
+{
+}
+
+SwVbaRevision::~SwVbaRevision()
+{
+}
+
+sal_Int32 SwVbaRevision::GetPosition()
+{
+ sal_Int32 nPos = -1;
+ uno::Reference< document::XRedlinesSupplier > xRedlinesSupp( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xRedlines( xRedlinesSupp->getRedlines(), uno::UNO_QUERY_THROW );
+ sal_Int32 nCount = xRedlines->getCount();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ uno::Reference< beans::XPropertySet > xProps( xRedlines->getByIndex( i ), uno::UNO_QUERY_THROW );
+ if( xProps == mxRedlineProps )
+ {
+ nPos = i;
+ SAL_INFO("sw.ui", "the redline position is " << nPos);
+ break;
+ }
+ }
+ if( nPos == -1 )
+ throw uno::RuntimeException();
+
+ return nPos;
+}
+
+void SAL_CALL
+SwVbaRevision::Accept()
+{
+ SwDoc* pDoc = word::getDocShell( mxModel )->GetDoc();
+ if( pDoc )
+ pDoc->getIDocumentRedlineAccess().AcceptRedline( GetPosition(), true );
+}
+
+void SAL_CALL
+SwVbaRevision::Reject( )
+{
+ SwDoc* pDoc = word::getDocShell( mxModel )->GetDoc();
+ if( pDoc )
+ pDoc->getIDocumentRedlineAccess().RejectRedline( GetPosition(), true );
+}
+
+OUString
+SwVbaRevision::getServiceImplName()
+{
+ return "SwVbaRevision";
+}
+
+uno::Sequence< OUString >
+SwVbaRevision::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Revision"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarevision.hxx b/sw/source/ui/vba/vbarevision.hxx
new file mode 100644
index 0000000000..c483f6578f
--- /dev/null
+++ b/sw/source/ui/vba/vbarevision.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAREVISION_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAREVISION_HXX
+
+#include <ooo/vba/word/XRevision.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XRevision > SwVbaRevision_BASE;
+
+class SwVbaRevision : public SwVbaRevision_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::beans::XPropertySet > mxRedlineProps;
+
+private:
+ /// @throws css::uno::RuntimeException
+ sal_Int32 GetPosition();
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaRevision( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::beans::XPropertySet > xRedlineProps );
+ virtual ~SwVbaRevision() override;
+
+ // Methods
+ virtual void SAL_CALL Accept( ) override;
+ virtual void SAL_CALL Reject( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAREVISION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarevisions.cxx b/sw/source/ui/vba/vbarevisions.cxx
new file mode 100644
index 0000000000..bfd8c68eae
--- /dev/null
+++ b/sw/source/ui/vba/vbarevisions.cxx
@@ -0,0 +1,185 @@
+/* -*- 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 "vbarevisions.hxx"
+#include "vbarevision.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XRedlinesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+typedef std::vector< uno::Reference< beans::XPropertySet > > RevisionMap;
+
+namespace {
+
+class RedlinesEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+ RevisionMap mRevisionMap;
+ RevisionMap::iterator mIt;
+public:
+ explicit RedlinesEnumeration( RevisionMap&& sMap ) : mRevisionMap( std::move(sMap) ), mIt( mRevisionMap.begin() ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mIt != mRevisionMap.end() );
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ uno::Reference< beans::XPropertySet > xRevision( *mIt++ );
+ return uno::Any( xRevision ) ;
+ }
+};
+
+class RevisionCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+ RevisionMap mRevisionMap;
+public:
+/// @throws css::uno::RuntimeException
+RevisionCollectionHelper( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange );
+
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<beans::XPropertySet>::get(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return ( !mRevisionMap.empty() ); }
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override { return mRevisionMap.size(); }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any( mRevisionMap[ Index ] );
+
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new RedlinesEnumeration( std::vector(mRevisionMap) );
+ }
+};
+
+}
+
+RevisionCollectionHelper::RevisionCollectionHelper( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange )
+ {
+ uno::Reference< text::XTextRangeCompare > xTRC( xTextRange->getText(), uno::UNO_QUERY_THROW );
+ uno::Reference< document::XRedlinesSupplier > xRedlinesSupp( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xRedlines( xRedlinesSupp->getRedlines(), uno::UNO_QUERY_THROW );
+ sal_Int32 nCount = xRedlines->getCount();
+ for( sal_Int32 index = 0; index < nCount; index++ )
+ {
+ uno::Reference< text::XTextRange > xRedlineRange( xRedlines->getByIndex( index ), uno::UNO_QUERY_THROW );
+ if( xTRC->compareRegionStarts( xTextRange, xRedlineRange ) >= 0 && xTRC->compareRegionEnds( xTextRange, xRedlineRange ) <= 0 )
+ {
+ uno::Reference< beans::XPropertySet > xRedlineProps( xRedlineRange, uno::UNO_QUERY_THROW );
+ mRevisionMap.push_back( xRedlineProps );
+ }
+ }
+ }
+
+namespace {
+
+class RevisionsEnumeration : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > m_xModel;
+public:
+ /// @throws uno::RuntimeException
+ RevisionsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Reference< frame::XModel > xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel(std::move( xModel )) {}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< beans::XPropertySet > xRevision( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XRevision > ( new SwVbaRevision( m_xParent, m_xContext, m_xModel, xRevision ) ) );
+ }
+
+};
+
+}
+
+SwVbaRevisions::SwVbaRevisions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ): SwVbaRevisions_BASE( xParent, xContext, new RevisionCollectionHelper( xModel, xTextRange ) ), mxModel( xModel )
+{
+}
+
+SwVbaRevisions::SwVbaRevisions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< frame::XModel > xModel, const uno::Reference< container::XIndexAccess >& xIndexAccess ): SwVbaRevisions_BASE( xParent, xContext, xIndexAccess ), mxModel(std::move( xModel ))
+{
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaRevisions::getElementType()
+{
+ return cppu::UnoType<word::XRevision>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaRevisions::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new RevisionsEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+SwVbaRevisions::createCollectionObject( const css::uno::Any& aSource )
+{
+ uno::Reference< beans::XPropertySet > xRevision( aSource, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XRevision > ( new SwVbaRevision( this, mxContext, mxModel, xRevision ) ) );
+}
+
+void SAL_CALL SwVbaRevisions::AcceptAll( )
+{
+ // First we need to put all the redline into a vector, because if the redline is accepted,
+ // it will auto delete in the document.
+ std::vector< uno::Reference< word::XRevision > > aRevisions;
+ uno::Reference< container::XEnumeration > xEnumeration = createEnumeration();
+ while( xEnumeration->hasMoreElements() )
+ {
+ uno::Reference< word::XRevision > xRevision( xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ aRevisions.push_back( xRevision );
+ }
+
+ for( const auto& xRevision : aRevisions )
+ xRevision->Accept();
+}
+
+void SAL_CALL SwVbaRevisions::RejectAll( )
+{
+ throw uno::RuntimeException();
+}
+
+OUString
+SwVbaRevisions::getServiceImplName()
+{
+ return "SwVbaRevisions";
+}
+
+css::uno::Sequence<OUString>
+SwVbaRevisions::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Revisions"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarevisions.hxx b/sw/source/ui/vba/vbarevisions.hxx
new file mode 100644
index 0000000000..a3fe79108a
--- /dev/null
+++ b/sw/source/ui/vba/vbarevisions.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAREVISIONS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAREVISIONS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XRevisions.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XRevisions > SwVbaRevisions_BASE;
+
+class SwVbaRevisions : public SwVbaRevisions_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+
+public:
+ SwVbaRevisions( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextRange >& xTextRange );
+
+ SwVbaRevisions( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::frame::XModel > xModel, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess );
+
+ // Methods
+ virtual void SAL_CALL AcceptAll( ) override;
+ virtual void SAL_CALL RejectAll( ) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaRevisions_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAREVISIONS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarow.cxx b/sw/source/ui/vba/vbarow.cxx
new file mode 100644
index 0000000000..aa4f7701fd
--- /dev/null
+++ b/sw/source/ui/vba/vbarow.cxx
@@ -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 .
+ */
+#include "vbarow.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <ooo/vba/word/WdRowHeightRule.hpp>
+#include <ooo/vba/word/WdConstants.hpp>
+#include "vbatablehelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaRow::SwVbaRow( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,uno::Reference< text::XTextTable > xTextTable, sal_Int32 nIndex ) :
+ SwVbaRow_BASE( rParent, rContext ), mxTextTable(std::move( xTextTable )), mnIndex( nIndex )
+{
+ mxTableRows = mxTextTable->getRows();
+ mxRowProps.set( mxTableRows->getByIndex( mnIndex ), uno::UNO_QUERY_THROW );
+}
+
+SwVbaRow::~SwVbaRow()
+{
+}
+
+uno::Any SAL_CALL SwVbaRow::getHeight()
+{
+ if( getHeightRule() == word::WdRowHeightRule::wdRowHeightAuto )
+ return uno::Any( sal_Int32( word::WdConstants::wdUndefined ) );
+
+ sal_Int32 nHeight = 0;
+ mxRowProps->getPropertyValue("Height") >>= nHeight;
+ return uno::Any( static_cast<float>(Millimeter::getInPoints( nHeight )) );
+}
+
+void SAL_CALL SwVbaRow::setHeight( const uno::Any& _height )
+{
+ float height = 0;
+ _height >>= height;
+
+ sal_Int32 nHeight = Millimeter::getInHundredthsOfOneMillimeter( height );
+ mxRowProps->setPropertyValue("Height", uno::Any( nHeight ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaRow::getHeightRule()
+{
+ bool isAutoHeight = false;
+ mxRowProps->getPropertyValue("IsAutoHeight") >>= isAutoHeight;
+ return isAutoHeight ? word::WdRowHeightRule::wdRowHeightAuto : word::WdRowHeightRule::wdRowHeightExactly;
+}
+
+void SAL_CALL SwVbaRow::setHeightRule( ::sal_Int32 _heightrule )
+{
+ bool isAutoHeight = ( _heightrule == word::WdRowHeightRule::wdRowHeightAuto );
+ mxRowProps->setPropertyValue("IsAutoHeight", uno::Any( isAutoHeight ) );
+}
+
+void SAL_CALL
+SwVbaRow::Select( )
+{
+ SelectRow( getCurrentWordDoc(mxContext), mxTextTable, mnIndex, mnIndex );
+}
+
+void SwVbaRow::SelectRow( const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextTable >& xTextTable, sal_Int32 nStartRow, sal_Int32 nEndRow )
+{
+ OUString sRangeName = "A" + OUString::number(nStartRow + 1);
+ SwVbaTableHelper aTableHelper( xTextTable );
+ sal_Int32 nColCount = aTableHelper.getTabColumnsCount( nEndRow );
+ // FIXME: the column count > 26
+ //char cCol = 'A' + nColCount - 1;
+ OUString sCol = SwVbaTableHelper::getColumnStr( nColCount - 1);
+ sRangeName += ":" + sCol + OUString::number(nEndRow + 1);
+
+ uno::Reference< table::XCellRange > xCellRange( xTextTable, uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xSelRange = xCellRange->getCellRangeByName( sRangeName );
+
+ uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelection->select( uno::Any( xSelRange ) );
+}
+
+void SAL_CALL SwVbaRow::SetHeight( float height, sal_Int32 heightrule )
+{
+ setHeightRule( heightrule );
+ setHeight( uno::Any( height ) );
+}
+
+OUString
+SwVbaRow::getServiceImplName()
+{
+ return "SwVbaRow";
+}
+
+uno::Sequence< OUString >
+SwVbaRow::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Row"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarow.hxx b/sw/source/ui/vba/vbarow.hxx
new file mode 100644
index 0000000000..40abaee2ee
--- /dev/null
+++ b/sw/source/ui/vba/vbarow.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAROW_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAROW_HXX
+
+#include <ooo/vba/word/XRow.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XRow > SwVbaRow_BASE;
+
+class SwVbaRow : public SwVbaRow_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ css::uno::Reference< css::table::XTableRows > mxTableRows;
+ css::uno::Reference< css::beans::XPropertySet > mxRowProps;
+ sal_Int32 mnIndex;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaRow( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextTable > xTextTable, sal_Int32 nIndex );
+ virtual ~SwVbaRow() override;
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getHeight() override;
+ virtual void SAL_CALL setHeight( const css::uno::Any& _height ) override;
+ virtual ::sal_Int32 SAL_CALL getHeightRule() override;
+ virtual void SAL_CALL setHeightRule( ::sal_Int32 _heightrule ) override;
+
+ // Methods
+ virtual void SAL_CALL Select( ) override;
+ virtual void SAL_CALL SetHeight( float height, sal_Int32 heightrule ) override;
+
+ /// @throws css::uno::RuntimeException
+ static void SelectRow( const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextTable >& xTextTable, sal_Int32 nStartRow, sal_Int32 nEndRow );
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAROW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarows.cxx b/sw/source/ui/vba/vbarows.cxx
new file mode 100644
index 0000000000..2b757ff31f
--- /dev/null
+++ b/sw/source/ui/vba/vbarows.cxx
@@ -0,0 +1,370 @@
+/* -*- 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 "vbarows.hxx"
+#include "vbarow.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <ooo/vba/word/WdRowAlignment.hpp>
+#include <ooo/vba/word/WdConstants.hpp>
+#include <ooo/vba/word/WdRulerStyle.hpp>
+#include <basic/sberrors.hxx>
+#include <utility>
+#include "vbacolumns.hxx"
+#include "vbatablehelper.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class RowsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::WeakReference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< text::XTextTable > mxTextTable;
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ sal_Int32 m_nIndex;
+
+public:
+ RowsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< text::XTextTable > xTextTable ) : mxParent( xParent ), mxContext(std::move( xContext )), mxTextTable(std::move( xTextTable )), m_nIndex( 0 )
+ {
+ mxIndexAccess = mxTextTable->getRows();
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex < mxIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if( m_nIndex < mxIndexAccess->getCount() )
+ {
+ return uno::Any( uno::Reference< word::XRow > ( new SwVbaRow( mxParent, mxContext, mxTextTable, m_nIndex++ ) ) );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaRows::SwVbaRows( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableRows >& xTableRows ) : SwVbaRows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableRows, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )), mxTableRows( xTableRows )
+{
+ mnStartRowIndex = 0;
+ mnEndRowIndex = m_xIndexAccess->getCount() - 1;
+}
+
+SwVbaRows::SwVbaRows( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< text::XTextTable > xTextTable, const uno::Reference< table::XTableRows >& xTableRows, sal_Int32 nStarIndex, sal_Int32 nEndIndex ) : SwVbaRows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( xTableRows, uno::UNO_QUERY_THROW ) ), mxTextTable(std::move( xTextTable )), mxTableRows( xTableRows ), mnStartRowIndex( nStarIndex ), mnEndRowIndex( nEndIndex )
+{
+ if( mnEndRowIndex < mnStartRowIndex )
+ throw uno::RuntimeException();
+}
+
+/**
+ * get the alignment of the rows: SO format com.sun.star.text.HoriOrientation
+ * is mapped to WdRowAlignment in Word
+ * @return the alignment
+ */
+::sal_Int32 SAL_CALL SwVbaRows::getAlignment()
+{
+ sal_Int16 nAlignment = text::HoriOrientation::LEFT;
+ uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
+ xTableProps->getPropertyValue("HoriOrient") >>= nAlignment;
+ sal_Int32 nRet = 0;
+ switch( nAlignment )
+ {
+ case text::HoriOrientation::CENTER:
+ {
+ nRet = word::WdRowAlignment::wdAlignRowCenter;
+ break;
+ }
+ case text::HoriOrientation::RIGHT:
+ {
+ nRet = word::WdRowAlignment::wdAlignRowRight;
+ break;
+ }
+ default:
+ {
+ nRet = word::WdRowAlignment::wdAlignRowLeft;
+ }
+ }
+ return nRet;
+}
+
+void SAL_CALL SwVbaRows::setAlignment( ::sal_Int32 _alignment )
+{
+ sal_Int16 nAlignment = text::HoriOrientation::LEFT;
+ switch( _alignment )
+ {
+ case word::WdRowAlignment::wdAlignRowCenter:
+ {
+ nAlignment = text::HoriOrientation::CENTER;
+ break;
+ }
+ case word::WdRowAlignment::wdAlignRowRight:
+ {
+ nAlignment = text::HoriOrientation::RIGHT;
+ break;
+ }
+ default:
+ {
+ nAlignment = text::HoriOrientation::LEFT;
+ }
+ }
+ uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
+ xTableProps->setPropertyValue("HoriOrient", uno::Any( nAlignment ) );
+}
+
+uno::Any SAL_CALL SwVbaRows::getAllowBreakAcrossPages()
+{
+ bool bAllowBreak = false;
+ uno::Reference< container::XIndexAccess > xRowsAccess( mxTableRows, uno::UNO_QUERY_THROW );
+ for( sal_Int32 index = mnStartRowIndex; index <= mnEndRowIndex; ++index )
+ {
+ uno::Reference< beans::XPropertySet > xRowProps( xRowsAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ bool bSplit = false;
+ xRowProps->getPropertyValue("IsSplitAllowed") >>= bSplit;
+ if( index == 0 )
+ {
+ bAllowBreak = bSplit;
+ }
+ if( bSplit != bAllowBreak )
+ {
+ return uno::Any( sal_Int32(word::WdConstants::wdUndefined) );
+ }
+ }
+ return uno::Any( bAllowBreak );
+}
+
+void SAL_CALL SwVbaRows::setAllowBreakAcrossPages( const uno::Any& _allowbreakacrosspages )
+{
+ bool bAllowBreak = false;
+ _allowbreakacrosspages >>= bAllowBreak;
+ uno::Reference< container::XIndexAccess > xRowsAccess( mxTableRows, uno::UNO_QUERY_THROW );
+ for( sal_Int32 index = mnStartRowIndex; index <= mnEndRowIndex; ++index )
+ {
+ uno::Reference< beans::XPropertySet > xRowProps( xRowsAccess->getByIndex( index ), uno::UNO_QUERY_THROW );
+ xRowProps->setPropertyValue("IsSplitAllowed", uno::Any( bAllowBreak ) );
+ }
+}
+
+float SAL_CALL SwVbaRows::getSpaceBetweenColumns()
+{
+ // just get the first spacing of the first cell
+ uno::Reference< table::XCellRange > xCellRange( mxTextTable, uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xCellProps( xCellRange->getCellByPosition( 0, mnStartRowIndex ), uno::UNO_QUERY_THROW );
+ sal_Int32 nLeftBorderDistance = 0;
+ sal_Int32 nRightBorderDistance = 0;
+ xCellProps->getPropertyValue("LeftBorderDistance") >>= nLeftBorderDistance;
+ xCellProps->getPropertyValue("RightBorderDistance") >>= nRightBorderDistance;
+ return static_cast< float >( Millimeter::getInPoints( nLeftBorderDistance + nRightBorderDistance ) );
+}
+
+void SAL_CALL SwVbaRows::setSpaceBetweenColumns( float _spacebetweencolumns )
+{
+ sal_Int32 nSpace = Millimeter::getInHundredthsOfOneMillimeter( _spacebetweencolumns ) / 2;
+ uno::Reference< container::XIndexAccess > xColumnAccess( mxTextTable->getColumns(), uno::UNO_QUERY_THROW );
+ uno::Reference< table::XCellRange > xCellRange( mxTextTable, uno::UNO_QUERY_THROW );
+ SwVbaTableHelper aTableHelper( mxTextTable );
+ for( sal_Int32 row = mnStartRowIndex; row <= mnEndRowIndex; ++row )
+ {
+ sal_Int32 nColumns = aTableHelper.getTabColumnsCount( row );
+ for( sal_Int32 column = 0; column < nColumns; ++column )
+ {
+ uno::Reference< beans::XPropertySet > xCellProps( xCellRange->getCellByPosition( column, row ), uno::UNO_QUERY_THROW );
+ xCellProps->setPropertyValue("LeftBorderDistance", uno::Any( nSpace ) );
+ xCellProps->setPropertyValue("RightBorderDistance", uno::Any( nSpace ) );
+ }
+ }
+}
+
+void SAL_CALL SwVbaRows::Delete( )
+{
+ mxTableRows->removeByIndex( mnStartRowIndex, getCount() );
+}
+
+void SAL_CALL SwVbaRows::SetLeftIndent( float LeftIndent, ::sal_Int32 RulerStyle )
+{
+ uno::Reference< word::XColumns > xColumns( new SwVbaColumns( getParent(), mxContext, mxTextTable, mxTextTable->getColumns() ) );
+ sal_Int32 nIndent = static_cast<sal_Int32>(LeftIndent);
+ switch( RulerStyle )
+ {
+ case word::WdRulerStyle::wdAdjustFirstColumn:
+ {
+ setIndentWithAdjustFirstColumn( xColumns, nIndent );
+ break;
+ }
+ case word::WdRulerStyle::wdAdjustNone:
+ {
+ setIndentWithAdjustNone( nIndent );
+ break;
+ }
+ case word::WdRulerStyle::wdAdjustProportional:
+ {
+ setIndentWithAdjustProportional( xColumns, nIndent );
+ break;
+ }
+ case word::WdRulerStyle::wdAdjustSameWidth:
+ {
+ setIndentWithAdjustSameWidth( xColumns, nIndent );
+ break;
+ }
+ default:
+ {
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT);
+ }
+ }
+}
+
+void SwVbaRows::setIndentWithAdjustNone( sal_Int32 indent )
+{
+ uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
+ sal_Int32 nMargin = 0;
+ xTableProps->getPropertyValue("LeftMargin") >>= nMargin;
+ nMargin += indent;
+ xTableProps->setPropertyValue("LeftMargin", uno::Any( nMargin ) );
+}
+
+ void SwVbaRows::setIndentWithAdjustFirstColumn( const uno::Reference< word::XColumns >& xColumns, sal_Int32 indent )
+ {
+ uno::Reference< XCollection > xCol( xColumns, uno::UNO_QUERY_THROW );
+ uno::Reference< word::XColumn > xColumn( xCol->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW );
+ sal_Int32 nWidth = xColumn->getWidth();
+ nWidth -= indent;
+ xColumn->setWidth( nWidth );
+ setIndentWithAdjustNone( indent );
+ }
+
+ void SwVbaRows::setIndentWithAdjustProportional(
+ const uno::Reference< word::XColumns >& xColumns,
+ sal_Int32 indent
+)
+ {
+ // calculate the new width and get the proportion between old and new
+ uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
+ sal_Int32 nWidth = 0;
+ xTableProps->getPropertyValue("Width") >>= nWidth;
+ sal_Int32 nNewWidth = nWidth - indent;
+ if ((nNewWidth <= 0) || (nWidth <= 0))
+ {
+ throw uno::RuntimeException(
+ "Pb with width, in SwVbaRows::setIndentWithAdjustProportional "
+ "(nNewWidth <= 0) || (nWidth <= 0)"
+ );
+ }
+ double propFactor = static_cast<double>(nNewWidth)/static_cast<double>(nWidth);
+
+ // get all columns, calculate and set the new width of the columns
+ uno::Reference< XCollection > xCol( xColumns, uno::UNO_QUERY_THROW );
+ sal_Int32 nColCount = xCol->getCount();
+ for( sal_Int32 i = 0; i < nColCount; i++ )
+ {
+ uno::Reference< word::XColumn > xColumn( xCol->Item( uno::Any( i ), uno::Any() ), uno::UNO_QUERY_THROW );
+ sal_Int32 nColWidth = xColumn->getWidth();
+ sal_Int32 nNewColWidth = static_cast<sal_Int32>( propFactor * nColWidth );
+ xColumn->setWidth( nNewColWidth );
+ }
+
+ // set the width and position of the table
+ setIndentWithAdjustNone( indent );
+ xTableProps->setPropertyValue("Width", uno::Any( nNewWidth ) );
+ }
+
+ void SwVbaRows::setIndentWithAdjustSameWidth( const uno::Reference< word::XColumns >& xColumns, sal_Int32 indent )
+ {
+ // calculate the new width and get the width of all columns
+ uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
+ sal_Int32 nWidth = 0;
+ xTableProps->getPropertyValue("Width") >>= nWidth;
+ sal_Int32 nNewWidth = nWidth - indent;
+
+ // get all columns, calculate and set the new width of the columns
+ uno::Reference< XCollection > xCol( xColumns, uno::UNO_QUERY_THROW );
+ sal_Int32 nColCount = xCol->getCount();
+ sal_Int32 nNewColWidth = static_cast<sal_Int32>( double( nNewWidth )/nColCount );
+ for( sal_Int32 i = 0; i < nColCount; i++ )
+ {
+ uno::Reference< word::XColumn > xColumn( xCol->Item( uno::Any( i ), uno::Any() ), uno::UNO_QUERY_THROW );
+ xColumn->setWidth( nNewColWidth );
+ }
+
+ // set the width and position of the table
+ setIndentWithAdjustNone( indent );
+ xTableProps->setPropertyValue("Width", uno::Any( nNewWidth ) );
+ }
+
+void SAL_CALL SwVbaRows::Select( )
+{
+ SwVbaRow::SelectRow( getCurrentWordDoc(mxContext), mxTextTable, mnStartRowIndex, mnEndRowIndex );
+}
+
+::sal_Int32 SAL_CALL SwVbaRows::getCount()
+{
+ return ( mnEndRowIndex - mnStartRowIndex + 1 );
+}
+
+uno::Any SAL_CALL SwVbaRows::Item( const uno::Any& Index1, const uno::Any& /*not processed in this base class*/ )
+{
+ sal_Int32 nIndex = 0;
+ if( Index1 >>= nIndex )
+ {
+ if( nIndex <= 0 || nIndex > getCount() )
+ {
+ throw lang::IndexOutOfBoundsException("Index out of bounds" );
+ }
+ return uno::Any( uno::Reference< word::XRow >( new SwVbaRow( this, mxContext, mxTextTable, nIndex - 1 ) ) );
+ }
+ throw uno::RuntimeException("Index out of bounds" );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaRows::getElementType()
+{
+ return cppu::UnoType<word::XRow>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaRows::createEnumeration()
+{
+ return new RowsEnumWrapper( this, mxContext, mxTextTable );
+}
+
+uno::Any
+SwVbaRows::createCollectionObject( const uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaRows::getServiceImplName()
+{
+ return "SwVbaRows";
+}
+
+uno::Sequence<OUString>
+SwVbaRows::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Rows"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbarows.hxx b/sw/source/ui/vba/vbarows.hxx
new file mode 100644
index 0000000000..98a1069fa8
--- /dev/null
+++ b/sw/source/ui/vba/vbarows.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAROWS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAROWS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XRows.hpp>
+#include <ooo/vba/word/XColumns.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XRows > SwVbaRows_BASE;
+
+class SwVbaRows : public SwVbaRows_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ css::uno::Reference< css::table::XTableRows > mxTableRows;
+ sal_Int32 mnStartRowIndex;
+ sal_Int32 mnEndRowIndex;
+
+private:
+ /// @throws css::uno::RuntimeException
+ void setIndentWithAdjustNone( sal_Int32 indent );
+ /// @throws css::uno::RuntimeException
+ void setIndentWithAdjustFirstColumn( const css::uno::Reference< ooo::vba::word::XColumns >& xColumns, sal_Int32 indent );
+ /// @throws css::uno::RuntimeException
+ void setIndentWithAdjustProportional( const css::uno::Reference< ooo::vba::word::XColumns >& xColumns, sal_Int32 indent );
+ /// @throws css::uno::RuntimeException
+ void setIndentWithAdjustSameWidth( const css::uno::Reference< ooo::vba::word::XColumns >& xColumns, sal_Int32 indent );
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaRows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableRows >& xTableRows );
+ /// @throws css::uno::RuntimeException
+ SwVbaRows( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::text::XTextTable > xTextTable, const css::uno::Reference< css::table::XTableRows >& xTableRows, sal_Int32 nStarIndex, sal_Int32 nEndIndex );
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getAlignment() override;
+ virtual void SAL_CALL setAlignment( ::sal_Int32 _alignment ) override;
+ virtual css::uno::Any SAL_CALL getAllowBreakAcrossPages() override;
+ virtual void SAL_CALL setAllowBreakAcrossPages( const css::uno::Any& _allowbreakacrosspages ) override;
+ virtual float SAL_CALL getSpaceBetweenColumns() override;
+ virtual void SAL_CALL setSpaceBetweenColumns( float _spacebetweencolumns ) override;
+
+ // Methods
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL SetLeftIndent( float LeftIndent, ::sal_Int32 RulerStyle ) override;
+ virtual void SAL_CALL Select( ) override;
+
+ //XCollection
+ virtual ::sal_Int32 SAL_CALL getCount() override;
+ virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaRows_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAROWS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbasection.cxx b/sw/source/ui/vba/vbasection.cxx
new file mode 100644
index 0000000000..40ecdaabd5
--- /dev/null
+++ b/sw/source/ui/vba/vbasection.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 "vbasection.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include "vbapagesetup.hxx"
+#include "vbaheadersfooters.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaSection::SwVbaSection( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel, uno::Reference< beans::XPropertySet > xProps ) :
+ SwVbaSection_BASE( rParent, rContext ), mxModel(std::move( xModel )), mxPageProps(std::move( xProps ))
+{
+}
+
+SwVbaSection::~SwVbaSection()
+{
+}
+
+sal_Bool SAL_CALL SwVbaSection::getProtectedForForms()
+{
+ return false;
+}
+
+void SAL_CALL SwVbaSection::setProtectedForForms( sal_Bool /*_protectedforforms*/ )
+{
+}
+
+uno::Any SAL_CALL SwVbaSection::Headers( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaHeadersFooters( this, mxContext, mxModel, mxPageProps, true ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL SwVbaSection::Footers( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaHeadersFooters( this, mxContext, mxModel, mxPageProps, false ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaSection::PageSetup( )
+{
+ return uno::Any( uno::Reference< word::XPageSetup >( new SwVbaPageSetup( this, mxContext, mxModel, mxPageProps ) ) );
+}
+
+OUString
+SwVbaSection::getServiceImplName()
+{
+ return "SwVbaSection";
+}
+
+uno::Sequence< OUString >
+SwVbaSection::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Section"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbasection.hxx b/sw/source/ui/vba/vbasection.hxx
new file mode 100644
index 0000000000..9a1b927424
--- /dev/null
+++ b/sw/source/ui/vba/vbasection.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASECTION_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBASECTION_HXX
+
+#include <ooo/vba/word/XSection.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XSection > SwVbaSection_BASE;
+
+class SwVbaSection : public SwVbaSection_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::beans::XPropertySet > mxPageProps;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaSection( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel, css::uno::Reference< css::beans::XPropertySet > xProps );
+ virtual ~SwVbaSection() override;
+
+ // Attributes
+ virtual sal_Bool SAL_CALL getProtectedForForms() override;
+ virtual void SAL_CALL setProtectedForForms( sal_Bool _protectedforforms ) override;
+
+ // Methods
+ virtual css::uno::Any SAL_CALL Headers( const css::uno::Any& index ) override;
+ virtual css::uno::Any SAL_CALL Footers( const css::uno::Any& index ) override;
+ virtual css::uno::Any SAL_CALL PageSetup( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbasections.cxx b/sw/source/ui/vba/vbasections.cxx
new file mode 100644
index 0000000000..fe9315ebf6
--- /dev/null
+++ b/sw/source/ui/vba/vbasections.cxx
@@ -0,0 +1,195 @@
+/* -*- 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 "vbasections.hxx"
+#include "vbasection.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include "wordvbahelper.hxx"
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+typedef std::vector< uno::Reference< beans::XPropertySet > > XSectionVec;
+
+namespace {
+
+class SectionEnumeration : public ::cppu::WeakImplHelper< container::XEnumeration >
+{
+ XSectionVec mxSections;
+ XSectionVec::iterator mIt;
+
+public:
+ explicit SectionEnumeration( XSectionVec&& rVec ) : mxSections( std::move(rVec) ), mIt( mxSections.begin() ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mIt != mxSections.end() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( hasMoreElements() )
+ return uno::Any( *mIt++ );
+ throw container::NoSuchElementException();
+ }
+};
+
+// here I regard pagestyle as section
+class SectionCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxModel;
+ XSectionVec mxSections;
+
+public:
+ /// @throws uno::RuntimeException
+ SectionCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel ))
+ {
+ uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW );
+ uno::Reference< container::XIndexAccess > xPageStyles( xSytleFamNames->getByName("PageStyles"), uno::UNO_QUERY_THROW );
+ sal_Int32 nCount = xPageStyles->getCount();
+ for( sal_Int32 index = 0; index < nCount; ++index )
+ {
+ uno::Reference< style::XStyle > xStyle( xPageStyles->getByIndex( index ), uno::UNO_QUERY_THROW );
+ // only the pagestyles in using are considered
+ if( xStyle->isInUse( ) )
+ {
+ uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW );
+ mxSections.push_back( xPageProps );
+ }
+ }
+ }
+
+ /// @throws uno::RuntimeException
+ SectionCollectionHelper( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xModel, const uno::Reference< text::XTextRange >& xTextRange ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxModel(std::move( xModel ))
+ {
+ // Hacky implementation of Range.Sections, only support 1 section
+ uno::Reference< beans::XPropertySet > xRangeProps( xTextRange, uno::UNO_QUERY_THROW );
+ uno::Reference< style::XStyle > xStyle = word::getCurrentPageStyle( mxModel, xRangeProps );
+ uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW );
+ mxSections.push_back( xPageProps );
+ }
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ return mxSections.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw css::lang::IndexOutOfBoundsException();
+
+ uno::Reference< beans::XPropertySet > xPageProps( mxSections[ Index ], uno::UNO_SET_THROW );
+ return uno::Any( uno::Reference< word::XSection >( new SwVbaSection( mxParent, mxContext, mxModel, xPageProps ) ) );
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XSection>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new SectionEnumeration( std::vector(mxSections) );
+ }
+};
+
+class SectionsEnumWrapper : public EnumerationHelperImpl
+{
+ uno::Reference< frame::XModel > mxModel;
+public:
+ /// @throws uno::RuntimeException
+ SectionsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, uno::Reference< frame::XModel > xModel ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel(std::move( xModel )){}
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ uno::Reference< beans::XPropertySet > xPageProps( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XSection > ( new SwVbaSection( m_xParent, m_xContext, mxModel, xPageProps ) ) );
+ }
+};
+
+}
+
+SwVbaSections::SwVbaSections( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ): SwVbaSections_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new SectionCollectionHelper( xParent, xContext, xModel ) ) ), mxModel( xModel )
+{
+}
+
+SwVbaSections::SwVbaSections( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel, const uno::Reference< text::XTextRange >& xTextRange ): SwVbaSections_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new SectionCollectionHelper( xParent, xContext, xModel, xTextRange ) ) ), mxModel( xModel )
+{
+}
+
+uno::Any SAL_CALL
+SwVbaSections::PageSetup( )
+{
+ if( m_xIndexAccess->getCount() )
+ {
+ // check if the first section is our want
+ uno::Reference< word::XSection > xSection( m_xIndexAccess->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ return xSection->PageSetup();
+ }
+ throw uno::RuntimeException("There is no section" );
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+SwVbaSections::getElementType()
+{
+ return cppu::UnoType<word::XSection>::get();
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwVbaSections::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return new SectionsEnumWrapper( this, mxContext, xEnumAccess->createEnumeration(), mxModel );
+}
+
+uno::Any
+SwVbaSections::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaSections::getServiceImplName()
+{
+ return "SwVbaSections";
+}
+
+css::uno::Sequence<OUString>
+SwVbaSections::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Sections"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbasections.hxx b/sw/source/ui/vba/vbasections.hxx
new file mode 100644
index 0000000000..3bf3ab4ca3
--- /dev/null
+++ b/sw/source/ui/vba/vbasections.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASECTIONS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBASECTIONS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XSections.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XSections > SwVbaSections_BASE;
+
+class SwVbaSections : public SwVbaSections_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+
+public:
+ SwVbaSections( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+ SwVbaSections( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel, const css::uno::Reference< css::text::XTextRange >& xTextRange );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ virtual css::uno::Any SAL_CALL PageSetup( ) override;
+
+ // SwVbaSections_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASECTIONS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaselection.cxx b/sw/source/ui/vba/vbaselection.cxx
new file mode 100644
index 0000000000..d983bd2bd2
--- /dev/null
+++ b/sw/source/ui/vba/vbaselection.cxx
@@ -0,0 +1,1169 @@
+/* -*- 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 "vbaselection.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include "vbarange.hxx"
+#include "vbafind.hxx"
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/XTextTableCursor.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <basic/sberrors.hxx>
+#include <ooo/vba/word/WdUnits.hpp>
+#include <ooo/vba/word/WdMovementType.hpp>
+#include <ooo/vba/word/WdGoToItem.hpp>
+#include <ooo/vba/word/WdGoToDirection.hpp>
+#include <ooo/vba/word/XBookmark.hpp>
+#include <ooo/vba/word/XApplication.hpp>
+#include <ooo/vba/word/WdCollapseDirection.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <unotbl.hxx>
+#include <unocoll.hxx>
+#include "vbatable.hxx"
+#include <com/sun/star/view/XViewCursor.hpp>
+#include <com/sun/star/view/XLineCursor.hpp>
+#include <com/sun/star/text/XWordCursor.hpp>
+#include <com/sun/star/text/XParagraphCursor.hpp>
+#include <ooo/vba/word/WdInformation.hpp>
+#include <ooo/vba/word/WdHeaderFooterIndex.hpp>
+#include <ooo/vba/word/WdSeekView.hpp>
+#include "vbainformationhelper.hxx"
+#include "vbafield.hxx"
+#include "vbaheaderfooter.hxx"
+#include "vbaheaderfooterhelper.hxx"
+#include <vbahelper/vbashaperange.hxx>
+#include <com/sun/star/drawing/ShapeCollection.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include "vbarows.hxx"
+#include "vbacolumns.hxx"
+#include "vbatablehelper.hxx"
+#include "vbacells.hxx"
+#include "vbaview.hxx"
+#include "vbaparagraph.hxx"
+#include "vbastyle.hxx"
+#include <docsh.hxx>
+#include <tblenum.hxx>
+#include <sal/log.hxx>
+#include <fesh.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaSelection::SwVbaSelection( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< frame::XModel > xModel ) : SwVbaSelection_BASE( rParent, rContext ), mxModel(std::move( xModel ))
+{
+ mxTextViewCursor = word::getXTextViewCursor( mxModel );
+}
+
+SwVbaSelection::~SwVbaSelection()
+{
+}
+
+uno::Reference< text::XTextRange > SwVbaSelection::GetSelectedRange()
+{
+ uno::Reference< text::XTextRange > xTextRange;
+ uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
+ if( !xServiceInfo->supportsService("com.sun.star.text.TextRanges") )
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+
+ uno::Reference< container::XIndexAccess > xTextRanges( xServiceInfo, uno::UNO_QUERY_THROW );
+ if( xTextRanges->getCount() > 0 )
+ {
+ // if there are multiple selection, just return the last selected Range.
+ xTextRange.set( xTextRanges->getByIndex( xTextRanges->getCount()-1 ), uno::UNO_QUERY_THROW );
+ }
+
+ return xTextRange;
+}
+
+uno::Reference< word::XRange > SAL_CALL
+SwVbaSelection::getRange()
+{
+ uno::Reference< text::XTextRange > xTextRange = GetSelectedRange();
+ uno::Reference< text::XTextDocument > xDocument( mxModel, uno::UNO_QUERY_THROW );
+ return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, xDocument, xTextRange->getStart(), xTextRange->getEnd(), mxTextViewCursor->getText() ) );
+}
+
+OUString SAL_CALL
+SwVbaSelection::getText()
+{
+ return getRange()->getText();
+}
+
+void SAL_CALL
+SwVbaSelection::setText( const OUString& rText )
+{
+ getRange()->setText( rText );
+}
+
+void SAL_CALL
+SwVbaSelection::TypeText( const OUString& rText )
+{
+ // FIXME: handle the property Options.ReplaceSelection, the default value is true
+ setText( rText );
+}
+
+void SAL_CALL
+SwVbaSelection::HomeKey( const uno::Any& _unit, const uno::Any& _extend )
+{
+ sal_Int32 nUnit = word::WdUnits::wdLine;
+ sal_Int32 nExtend = word::WdMovementType::wdMove;
+ _unit >>= nUnit;
+ _extend >>= nExtend;
+ bool bExtend = nExtend == word::WdMovementType::wdExtend;
+
+ switch( nUnit )
+ {
+ case word::WdUnits::wdStory:
+ {
+ // go to the valid text first so that the current view cursor is valid to call gotoRange.
+ word::gotoSelectedObjectAnchor(mxModel);
+ // go to the begin of the document
+ uno::Reference< text::XText > xCurrentText = word::getCurrentXText( mxModel );
+ uno::Reference< text::XTextRange > xFirstRange = word::getFirstObjectPosition( xCurrentText );
+ mxTextViewCursor->gotoRange( xFirstRange, bExtend );
+ break;
+ }
+ case word::WdUnits::wdLine:
+ {
+ // go to the begin of the Line
+ uno::Reference< view::XLineCursor > xLineCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ xLineCursor->gotoStartOfLine( bExtend );
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+}
+
+void SAL_CALL
+SwVbaSelection::EndKey( const uno::Any& _unit, const uno::Any& _extend )
+{
+ sal_Int32 nUnit = word::WdUnits::wdLine;
+ sal_Int32 nExtend = word::WdMovementType::wdMove;
+ _unit >>= nUnit;
+ _extend >>= nExtend;
+ bool bExtend = nExtend == word::WdMovementType::wdExtend;
+
+ switch( nUnit )
+ {
+ case word::WdUnits::wdStory:
+ {
+ // go to the valid text first so that the current view cursor is valid to call gotoRange.
+ word::gotoSelectedObjectAnchor(mxModel);
+ // go to the end of the document
+ uno::Reference< text::XText > xCurrentText = word::getCurrentXText( mxModel );
+ uno::Reference< text::XTextRange > xEnd = xCurrentText->getEnd();
+ mxTextViewCursor->gotoRange( xEnd, bExtend );
+ break;
+ }
+ case word::WdUnits::wdLine:
+ {
+ // go to the end of the Line
+ uno::Reference< view::XLineCursor > xLineCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ xLineCursor->gotoEndOfLine( bExtend );
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+}
+
+void SAL_CALL
+SwVbaSelection::Delete( const uno::Any& _unit, const uno::Any& _count )
+{
+ sal_Int32 nUnit = word::WdUnits::wdLine;
+ sal_Int32 nCount = 0;
+ if( _count.hasValue() )
+ _count >>= nCount;
+ if( _unit.hasValue() && ( nCount > 0 ) )
+ {
+ _unit >>= nUnit;
+ switch( nUnit )
+ {
+ case word::WdUnits::wdCharacter:
+ {
+ if( HasSelection() )
+ nCount--;
+ mxTextViewCursor->goRight( nCount, true );
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+ }
+ dispatchRequests( mxModel,".uno:Delete" );
+}
+
+void
+SwVbaSelection::Move( const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend, word::E_DIRECTION eDirection )
+{
+ sal_Int32 nUnit = word::WdUnits::wdCharacter;
+ sal_Int32 nCount = 1;
+ sal_Int32 nExtend = word::WdMovementType::wdMove;
+
+ if( _unit.hasValue() )
+ _unit >>= nUnit;
+ if( _count.hasValue() )
+ _count >>= nCount;
+ if( _extend.hasValue() )
+ _extend >>= nExtend;
+
+ if( nCount == 0 )
+ return;
+
+ bool bExpand = nExtend != word::WdMovementType::wdMove;
+
+ switch( nUnit )
+ {
+ case word::WdUnits::wdCell:
+ {
+ if( nExtend == word::WdMovementType::wdExtend )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ return;
+ }
+ NextCell( nCount, eDirection );
+ break;
+ }
+ case word::WdUnits::wdLine:
+ {
+ if( eDirection == word::MOVE_LEFT || eDirection == word::MOVE_RIGHT )
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ uno::Reference< view::XViewCursor > xViewCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ if( eDirection == word::MOVE_UP )
+ xViewCursor->goUp( nCount, bExpand );
+ else if( eDirection == word::MOVE_DOWN )
+ xViewCursor->goDown( nCount, bExpand );
+ break;
+ }
+ case word::WdUnits::wdCharacter:
+ {
+ if( eDirection == word::MOVE_UP || eDirection == word::MOVE_DOWN )
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ if( word::gotoSelectedObjectAnchor( mxModel ) )
+ {
+ nCount--;
+ }
+ uno::Reference< view::XViewCursor > xViewCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ if( eDirection == word::MOVE_LEFT )
+ {
+ // if current select is a cellrange or table,
+ // the first count of move should move to the first selected cell.
+ uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY );
+ if ( xTextTableCursor.is() )
+ {
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextTable > xTextTable;
+ xCursorProps->getPropertyValue("TextTable") >>= xTextTable;
+ if( xTextTable.is() )
+ {
+ uno::Reference< text::XTextRange > xRange( xTextTable->getCellByName( xTextTableCursor->getRangeName()), uno::UNO_QUERY_THROW );
+ mxTextViewCursor->gotoRange( xRange->getStart(), bExpand );
+ nCount--;
+ }
+ }
+ xViewCursor->goLeft( nCount, bExpand );
+ }
+ else if( eDirection == word::MOVE_RIGHT )
+ xViewCursor->goRight( nCount, bExpand );
+ break;
+ }
+ case word::WdUnits::wdWord:
+ case word::WdUnits::wdParagraph:
+ {
+ uno::Reference< text::XTextRange > xRange = GetSelectedRange();
+ uno::Reference< text::XText > xText = xRange->getText();
+ uno::Reference< text::XTextCursor > xTextCursor = xText->createTextCursorByRange( xRange );
+ if( nUnit == word::WdUnits::wdParagraph )
+ {
+ if( eDirection == word::MOVE_LEFT || eDirection == word::MOVE_RIGHT )
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ uno::Reference< text::XParagraphCursor > xParagraphCursor( xTextCursor, uno::UNO_QUERY_THROW );
+ for( sal_Int32 i=0; i<nCount; i++ )
+ {
+ if( ( eDirection == word::MOVE_UP ) && !xParagraphCursor->gotoPreviousParagraph( bExpand ) )
+ break;
+ else if( ( eDirection == word::MOVE_DOWN ) && !xParagraphCursor->gotoNextParagraph( bExpand ) )
+ break;
+ }
+ }
+ else if( nUnit == word::WdUnits::wdWord )
+ {
+ if( eDirection == word::MOVE_UP || eDirection == word::MOVE_DOWN )
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ uno::Reference< text::XWordCursor > xWordCursor( xTextCursor, uno::UNO_QUERY_THROW );
+ for( sal_Int32 i=0; i<nCount; i++ )
+ {
+ if( (eDirection == word::MOVE_LEFT ) && !xWordCursor->gotoPreviousWord( bExpand ) )
+ break;
+ else if( ( eDirection == word::MOVE_RIGHT ) && !xWordCursor->gotoNextWord( bExpand ) )
+ break;
+ }
+ }
+ mxTextViewCursor->gotoRange( xTextCursor->getStart(), false );
+ mxTextViewCursor->gotoRange( xTextCursor->getEnd(), true );
+ break;
+ }
+ default:
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+}
+
+void SwVbaSelection::NextCell(sal_Int32 nCount, word::E_DIRECTION eDirection)
+{
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextTable > xTextTable;
+ uno::Reference< table::XCell > xCell;
+ xCursorProps->getPropertyValue("TextTable") >>= xTextTable;
+ xCursorProps->getPropertyValue("Cell") >>= xCell;
+ if( !xTextTable.is() || !xCell.is() )
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ return;
+ }
+ uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW );
+ OUString aCellName;
+ xCellProps->getPropertyValue("CellName") >>= aCellName;
+ uno::Reference< text::XTextTableCursor > xTextTableCursor = xTextTable->createCursorByCellName( aCellName );
+ // move the table cursor
+ switch( eDirection )
+ {
+ case word::MOVE_LEFT:
+ {
+ xTextTableCursor->goLeft( nCount, false );
+ break;
+ }
+ case word::MOVE_RIGHT:
+ {
+ xTextTableCursor->goRight( nCount, false );
+ break;
+ }
+ case word::MOVE_UP:
+ {
+ xTextTableCursor->goUp( nCount, false );
+ break;
+ }
+ case word::MOVE_DOWN:
+ {
+ xTextTableCursor->goDown( nCount, false );
+ break;
+ }
+ default:
+ {
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ return;
+ }
+ }
+ // move the view cursor
+ xCell = xTextTable->getCellByName( xTextTableCursor->getRangeName() );
+ mxTextViewCursor->gotoRange( uno::Reference< text::XTextRange >( xCell, uno::UNO_QUERY_THROW ), false );
+}
+
+void SAL_CALL
+SwVbaSelection::MoveRight(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
+{
+ sal_Int32 nCount = 1;
+
+ if( _count.hasValue() )
+ _count >>= nCount;
+
+ if( nCount == 0 )
+ return;
+
+ if( nCount < 0 )
+ {
+ MoveLeft( _unit, uno::Any( -nCount ), _extend );
+ return;
+ }
+
+ Move( _unit, _count, _extend, word::MOVE_RIGHT );
+}
+
+void SAL_CALL
+SwVbaSelection::MoveLeft(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
+{
+ sal_Int32 nCount = 1;
+ if( _count.hasValue() )
+ _count >>= nCount;
+
+ if( nCount == 0 )
+ return;
+
+ if( nCount < 0 )
+ {
+ MoveRight( _unit, uno::Any( -nCount ), _extend );
+ return;
+ }
+
+ Move( _unit, _count, _extend, word::MOVE_LEFT );
+}
+
+void SAL_CALL
+SwVbaSelection::MoveDown(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
+{
+ sal_Int32 nCount = 1;
+
+ if( _count.hasValue() )
+ _count >>= nCount;
+
+ if( nCount == 0 )
+ return;
+
+ if( nCount < 0 )
+ {
+ MoveUp( _unit, uno::Any( -nCount ), _extend );
+ return;
+ }
+
+ Move( _unit, _count, _extend, word::MOVE_DOWN );
+}
+
+void SAL_CALL
+SwVbaSelection::MoveUp(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
+{
+ sal_Int32 nCount = 1;
+
+ if( _count.hasValue() )
+ _count >>= nCount;
+
+ if( nCount == 0 )
+ return;
+
+ if( nCount < 0 )
+ {
+ MoveDown( _unit, uno::Any( -nCount ), _extend );
+ return;
+ }
+
+ Move( _unit, _count, _extend, word::MOVE_UP );
+}
+
+void SAL_CALL
+SwVbaSelection::TypeParagraph()
+{
+ // #FIXME: if the selection is an entire paragraph, it's replaced
+ // by the new paragraph
+ bool isCollapsed = mxTextViewCursor->isCollapsed();
+ InsertParagraph();
+ if( isCollapsed )
+ mxTextViewCursor->collapseToStart();
+}
+
+void SAL_CALL
+SwVbaSelection::InsertParagraph()
+{
+ // #FIXME: the selection should include the new paragraph.
+ getRange()->InsertParagraph();
+}
+
+void SAL_CALL
+SwVbaSelection::InsertParagraphBefore()
+{
+ getRange()->InsertParagraphBefore();
+}
+
+void SAL_CALL
+SwVbaSelection::InsertParagraphAfter()
+{
+ getRange()->InsertParagraphAfter();
+}
+
+uno::Reference< word::XParagraphFormat > SAL_CALL
+SwVbaSelection::getParagraphFormat()
+{
+ return getRange()->getParagraphFormat();
+}
+
+void SAL_CALL
+SwVbaSelection::setParagraphFormat( const uno::Reference< word::XParagraphFormat >& rParagraphFormat )
+{
+ return getRange()->setParagraphFormat( rParagraphFormat );
+}
+
+uno::Reference< word::XFind > SAL_CALL
+SwVbaSelection::getFind()
+{
+ uno::Reference< text::XTextRange > xTextRange = GetSelectedRange();
+ uno::Reference< text::XTextRange > xStart = xTextRange->getStart();
+ uno::Reference< text::XTextRange > xEnd = xTextRange->getEnd();
+ uno::Reference< text::XTextRangeCompare > xTRC( xTextRange->getText(), uno::UNO_QUERY_THROW );
+ int n = xTRC->compareRegionStarts( xStart, xEnd);
+ if( n == 0 )
+ {
+ WholeStory();
+ xTextRange = GetSelectedRange();
+ }
+ return SwVbaFind::GetOrCreateFind(this, mxContext, mxModel, xTextRange);
+}
+
+uno::Any SAL_CALL
+SwVbaSelection::getStyle()
+{
+ return getRange()->getStyle();
+}
+
+void SAL_CALL
+SwVbaSelection::setStyle( const uno::Any& rStyle )
+{
+ uno::Reference< beans::XPropertySet > xParaProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ return SwVbaStyle::setStyle( xParaProps, rStyle );
+}
+
+uno::Reference< word::XFont > SAL_CALL
+SwVbaSelection::getFont()
+{
+ return getRange()->getFont();
+}
+
+void SAL_CALL
+SwVbaSelection::TypeBackspace()
+{
+ dispatchRequests( mxModel,".uno:SwBackspace" );
+}
+
+uno::Reference< word::XRange > SAL_CALL SwVbaSelection::GoTo( const uno::Any& _what, const uno::Any& _which, const uno::Any& _count, const uno::Any& _name )
+{
+ sal_Int32 nWhat = 0;
+ if( !( _what >>= nWhat ) )
+ DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
+ switch( nWhat )
+ {
+ case word::WdGoToItem::wdGoToBookmark:
+ {
+ uno::Reference< word::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
+ uno::Reference< word::XBookmark > xBookmark( xApplication->getActiveDocument()->Bookmarks(_name), uno::UNO_QUERY_THROW );
+ xBookmark->Select();
+ break;
+ }
+ case word::WdGoToItem::wdGoToPage:
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ sal_Int32 nCurrPage = xPageCursor->getPage();
+ sal_Int32 nLastPage = word::getPageCount( mxModel );
+ sal_Int32 nCount = 0;
+ if( _count.hasValue() )
+ _count >>= nCount;
+ sal_Int32 nWhich = 0;
+ if( _which.hasValue() )
+ _which >>= nWhich;
+ sal_Int32 nPage = 0;
+ switch( nWhich )
+ {
+ case word::WdGoToDirection::wdGoToLast:
+ {
+ nPage = nLastPage;
+ break;
+ }
+ case word::WdGoToDirection::wdGoToNext:
+ {
+ if( nCount !=0 )
+ nPage = nCurrPage + nCount;
+ else
+ nPage = nCurrPage + 1;
+ break;
+ }
+ case word::WdGoToDirection::wdGoToPrevious:
+ {
+ if( nCount !=0 )
+ nPage = nCurrPage - nCount;
+ else
+ nPage = nCurrPage - 1;
+ break;
+ }
+ default:
+ {
+ nPage = nCount;
+ }
+ }
+ if( _name.hasValue() )
+ {
+ OUString sName;
+ _name >>= sName;
+ sal_Int32 nName = sName.toInt32();
+ if( nName !=0 )
+ nPage = nName;
+ }
+ if( nPage <= 0 )
+ nPage = 1;
+ if( nPage > nLastPage )
+ nPage = nLastPage;
+ xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) );
+ break;
+ }
+ case word::WdGoToItem::wdGoToSection:
+ {
+ uno::Reference< text::XPageCursor > xPageCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ sal_Int32 nCount = 0;
+ if( _count.hasValue() )
+ _count >>= nCount;
+ sal_Int32 nWhich = 0;
+ if( _which.hasValue() )
+ _which >>= nWhich;
+ sal_Int32 nPage = 0;
+ switch( nWhich )
+ {
+ case word::WdGoToDirection::wdGoToAbsolute:
+ {
+ // currently only support this type
+ if( nCount == 1 )
+ nPage = 1;
+ break;
+ }
+ default:
+ {
+ nPage = 0;
+ }
+ }
+ if( nPage == 0 )
+ throw uno::RuntimeException("Not implemented" );
+ xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) );
+ break;
+ }
+ default:
+ throw uno::RuntimeException("Not implemented" );
+ }
+ return getRange();
+}
+
+::sal_Int32 SAL_CALL SwVbaSelection::getLanguageID()
+{
+ return getRange()->getLanguageID();
+}
+
+void SAL_CALL SwVbaSelection::setLanguageID( ::sal_Int32 _languageid )
+{
+ getRange()->setLanguageID( _languageid );
+}
+
+uno::Any SAL_CALL SwVbaSelection::Information( sal_Int32 _type )
+{
+ uno::Any result;
+ switch( _type )
+ {
+ case word::WdInformation::wdActiveEndPageNumber:
+ {
+ result <<= SwVbaInformationHelper::handleWdActiveEndPageNumber( mxTextViewCursor );
+ break;
+ }
+ case word::WdInformation::wdNumberOfPagesInDocument:
+ {
+ result <<= SwVbaInformationHelper::handleWdNumberOfPagesInDocument( mxModel );
+ break;
+ }
+ case word::WdInformation::wdVerticalPositionRelativeToPage:
+ {
+ result <<= SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( mxModel, mxTextViewCursor );
+ break;
+ }
+ case word::WdInformation::wdWithInTable:
+ {
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextTable > xTextTable;
+ xCursorProps->getPropertyValue("TextTable") >>= xTextTable;
+ result <<= xTextTable.is();
+ break;
+ }
+ case word::WdInformation::wdHeaderFooterType:
+ {
+ uno::Reference< word::XView > xView( new SwVbaView( this, mxContext, mxModel ) );
+ sal_Int32 nView = xView->getSeekView();
+ sal_Int32 nHeaderFooterType = 0;
+ switch( nView )
+ {
+ case word::WdSeekView::wdSeekMainDocument:
+ {
+ nHeaderFooterType = -1; // not in a header or footer
+ break;
+ }
+ case word::WdSeekView::wdSeekEvenPagesHeader:
+ {
+ nHeaderFooterType = 0; // even page header
+ break;
+ }
+ case word::WdSeekView::wdSeekPrimaryHeader:
+ {
+ nHeaderFooterType = 1; // odd page header
+ break;
+ }
+ case word::WdSeekView::wdSeekEvenPagesFooter:
+ {
+ nHeaderFooterType = 2; // even page footer
+ break;
+ }
+ case word::WdSeekView::wdSeekPrimaryFooter:
+ {
+ nHeaderFooterType = 3; // odd page footer
+ break;
+ }
+ case word::WdSeekView::wdSeekFirstPageHeader:
+ case word::WdSeekView::wdSeekFirstPageFooter:
+ {
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ OUString aPageStyleName;
+ xCursorProps->getPropertyValue("PageStyleName") >>= aPageStyleName;
+ bool bFirstPage = false;
+ if ( aPageStyleName == "First Page" )
+ bFirstPage = true;
+ if( nView == word::WdSeekView::wdSeekFirstPageHeader )
+ {
+ if( bFirstPage )
+ nHeaderFooterType = 4;
+ else
+ nHeaderFooterType = 1;
+ }
+ else
+ {
+ if( bFirstPage )
+ nHeaderFooterType = 5;
+ else
+ nHeaderFooterType = 3;
+ }
+ break;
+ }
+ default:
+ {
+ nHeaderFooterType = -1;
+ }
+ }
+ result <<= nHeaderFooterType;
+ break;
+ }
+ default:
+ throw uno::RuntimeException("Not implemented" );
+ }
+ return result;
+}
+
+void SAL_CALL SwVbaSelection::InsertBreak( const uno::Any& _breakType )
+{
+ getRange()->InsertBreak( _breakType );
+}
+
+uno::Any SAL_CALL
+SwVbaSelection::Tables( const uno::Any& aIndex )
+{
+ // Hacky implementation due to missing api ( and lack of knowledge )
+ // we can only support a selection that is a single table
+ if ( !aIndex.hasValue() ) // currently we can't support multiple tables in a selection
+ throw uno::RuntimeException();
+
+ sal_Int32 nIndex = 0;
+ aIndex >>= nIndex;
+
+ uno::Any aRet;
+
+ if ( nIndex != 1 )
+ throw uno::RuntimeException();
+
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextTable > xTextTable;
+ xCursorProps->getPropertyValue("TextTable") >>= xTextTable;
+ if( xTextTable.is() )
+ {
+ uno::Reference< css::text::XTextDocument > xTextDoc( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< word::XTable > xVBATable = new SwVbaTable( mxParent, mxContext, xTextDoc, xTextTable );
+ aRet <<= xVBATable;
+ return aRet;
+ }
+
+ // if the current selection is a XTextTableCursor and the index is 1 then we can service this request, otherwise we just have to throw
+ uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
+ SwXTextTableCursor* pTTCursor = dynamic_cast< SwXTextTableCursor* >( xTextTableCursor.get() );
+ if ( pTTCursor )
+ {
+ SwFrameFormat* pFormat = pTTCursor->GetFrameFormat();
+ if ( pFormat )
+ {
+ uno::Reference< text::XTextTable > xTable = SwXTextTables::GetObject(*pFormat);
+ uno::Reference< css::text::XTextDocument > xTextDoc( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< word::XTable > xVBATable = new SwVbaTable( mxParent, mxContext, xTextDoc, xTable );
+ aRet <<= xVBATable;
+ }
+ }
+ return aRet;
+
+}
+
+uno::Any SAL_CALL
+SwVbaSelection::Fields( const uno::Any& index )
+{
+ uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, mxModel ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Reference< word::XHeaderFooter > SAL_CALL
+SwVbaSelection::getHeaderFooter()
+{
+ if( HeaderFooterHelper::isHeaderFooter( mxModel ) )
+ {
+ uno::Reference< beans::XPropertySet > xPageStyleProps( word::getCurrentPageStyle( mxModel ), uno::UNO_QUERY_THROW );
+ sal_Int32 nIndex = word::WdHeaderFooterIndex::wdHeaderFooterPrimary;
+ bool isHeader = HeaderFooterHelper::isHeader( mxModel );
+ if( HeaderFooterHelper::isEvenPagesHeader( mxModel ) || HeaderFooterHelper::isEvenPagesFooter( mxModel ) )
+ nIndex = word::WdHeaderFooterIndex::wdHeaderFooterEvenPages;
+ else if( HeaderFooterHelper::isFirstPageHeader( mxModel ) || HeaderFooterHelper::isFirstPageFooter( mxModel ) )
+ nIndex = word::WdHeaderFooterIndex::wdHeaderFooterFirstPage;
+
+ return uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( this, mxContext, mxModel, xPageStyleProps, isHeader, nIndex ) );
+
+ }
+ return uno::Reference< word::XHeaderFooter >();
+}
+
+uno::Any SAL_CALL
+SwVbaSelection::ShapeRange( )
+{
+ uno::Reference< drawing::XShapes > xShapes( mxModel->getCurrentSelection(), uno::UNO_QUERY );
+ if ( !xShapes.is() )
+ {
+ uno::Reference< drawing::XShape > xShape( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
+ xShapes.set( drawing::ShapeCollection::create(mxContext) );
+ xShapes->add( xShape );
+ }
+
+ uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xDrawPage = xDrawPageSupplier->getDrawPage();
+ uno::Reference< container::XIndexAccess > xShapesAccess( xShapes, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< msforms::XShapeRange >( new ScVbaShapeRange( this, mxContext, xShapesAccess, xDrawPage, mxModel ) ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaSelection::getStart()
+{
+ return getRange()->getStart();
+}
+
+void SAL_CALL SwVbaSelection::setStart( ::sal_Int32 _start )
+{
+ getRange()->setStart( _start );
+}
+::sal_Int32 SAL_CALL SwVbaSelection::getEnd()
+{
+ return getRange()->getEnd();
+}
+
+void SAL_CALL SwVbaSelection::setEnd( ::sal_Int32 _end )
+{
+ getRange()->setEnd( _end );
+}
+
+void SAL_CALL SwVbaSelection::SelectRow()
+{
+ uno::Reference< word::XRows > xRows( Rows( uno::Any() ), uno::UNO_QUERY_THROW );
+ xRows->Select();
+}
+
+void SAL_CALL SwVbaSelection::SelectColumn()
+{
+ uno::Reference< word::XColumns > xColumns( Columns( uno::Any() ), uno::UNO_QUERY_THROW );
+ xColumns->Select();
+}
+
+uno::Any SAL_CALL SwVbaSelection::Rows( const uno::Any& index )
+{
+ OUString sTLName;
+ OUString sBRName;
+ GetSelectedCellRange( sTLName, sBRName );
+
+ sal_Int32 nStartRow = 0;
+ sal_Int32 nEndRow = 0;
+ uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
+ SwVbaTableHelper aTableHelper( xTextTable );
+ nStartRow = aTableHelper.getTabRowIndex( sTLName );
+ if( !sBRName.isEmpty() )
+ {
+ nEndRow = aTableHelper.getTabRowIndex( sBRName );
+ }
+ else
+ {
+ nEndRow = nStartRow;
+ }
+
+ uno::Reference< XCollection > xCol( new SwVbaRows( this, mxContext, xTextTable, xTextTable->getRows(), nStartRow, nEndRow ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL SwVbaSelection::Columns( const uno::Any& index )
+{
+ OUString sTLName;
+ OUString sBRName;
+ GetSelectedCellRange( sTLName, sBRName );
+ sal_Int32 nStartColumn = 0;
+ sal_Int32 nEndColumn = 0;
+
+ uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
+ SwVbaTableHelper aTableHelper( xTextTable );
+ nStartColumn = aTableHelper.getTabColIndex( sTLName );
+ if( !sBRName.isEmpty() )
+ {
+ nEndColumn = aTableHelper.getTabColIndex( sBRName );
+ }
+ else
+ {
+ nEndColumn = nStartColumn;
+ }
+
+ uno::Reference< XCollection > xCol( new SwVbaColumns( this, mxContext, xTextTable, xTextTable->getColumns(), nStartColumn, nEndColumn ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Reference< text::XTextTable > SwVbaSelection::GetXTextTable() const
+{
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextTable > xTextTable;
+ xCursorProps->getPropertyValue("TextTable") >>= xTextTable;
+ return xTextTable;
+}
+
+bool SwVbaSelection::IsInTable() const
+{
+ uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
+ return xTextTable.is();
+}
+
+bool SwVbaSelection::HasSelection()
+{
+ uno::Reference< text::XTextRange > xStart = mxTextViewCursor->getStart();
+ uno::Reference< text::XTextRange > xEnd = mxTextViewCursor->getEnd();
+ uno::Reference< text::XTextRangeCompare > xTRC( mxTextViewCursor->getText(), uno::UNO_QUERY_THROW );
+ return xTRC->compareRegionStarts( xStart, xEnd ) != 0 || xTRC->compareRegionEnds( xStart, xEnd ) != 0;
+}
+
+void SwVbaSelection::GetSelectedCellRange( OUString& sTLName, OUString& sBRName )
+{
+ uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextTable > xTextTable;
+ xCursorProps->getPropertyValue("TextTable") >>= xTextTable;
+ if( !xTextTable.is() )
+ throw uno::RuntimeException( );
+
+ uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY );
+ if( xTextTableCursor.is() )
+ {
+ const OUString sRange( xTextTableCursor->getRangeName() );
+ if (!sRange.isEmpty())
+ {
+ sal_Int32 nIdx{0};
+ sTLName = sRange.getToken(0, ':', nIdx);
+ sBRName = sRange.getToken(0, ':', nIdx);
+ }
+ }
+ if( sTLName.isEmpty() )
+ {
+ uno::Reference< table::XCell > xCell;
+ xCursorProps->getPropertyValue("Cell") >>= xCell;
+ if( !xCell.is() )
+ {
+ throw uno::RuntimeException( );
+ }
+ uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW );
+ xCellProps->getPropertyValue("CellName") >>= sTLName;
+ }
+}
+
+uno::Any SAL_CALL SwVbaSelection::Cells( const uno::Any& index )
+{
+ OUString sTLName;
+ OUString sBRName;
+ GetSelectedCellRange( sTLName, sBRName );
+ sal_Int32 nLeft = 0;
+ sal_Int32 nTop = 0;
+ sal_Int32 nRight = 0;
+ sal_Int32 nBottom = 0;
+
+ uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
+ SwVbaTableHelper aTableHelper( xTextTable );
+ nLeft = aTableHelper.getTabColIndex( sTLName );
+ nTop = aTableHelper.getTabRowIndex( sTLName );
+ if( !sBRName.isEmpty() )
+ {
+ nRight = aTableHelper.getTabColIndex( sBRName );
+ nBottom = aTableHelper.getTabRowIndex( sBRName );
+ }
+ else
+ {
+ nRight = nLeft;
+ nBottom = nTop;
+ }
+
+ uno::Reference< XCollection > xCol( new SwVbaCells( this, mxContext, xTextTable, nLeft, nTop, nRight, nBottom ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+void SAL_CALL SwVbaSelection::Copy( )
+{
+ dispatchRequests( mxModel,".uno:Copy" );
+}
+
+void SAL_CALL SwVbaSelection::CopyAsPicture( )
+{
+ // seems not support in Writer
+ Copy();
+}
+
+void SAL_CALL SwVbaSelection::Paste( )
+{
+ dispatchRequests( mxModel,".uno:Paste" );
+}
+
+void SAL_CALL SwVbaSelection::Collapse( const uno::Any& Direction )
+{
+ if( word::gotoSelectedObjectAnchor( mxModel ) )
+ return;
+
+ sal_Int32 nDirection = word::WdCollapseDirection::wdCollapseStart;
+ if( Direction.hasValue() )
+ Direction >>= nDirection;
+
+ uno::Reference< text::XTextViewCursor > xTextViewCursor = word::getXTextViewCursor( mxModel );
+ if( nDirection == word::WdCollapseDirection::wdCollapseStart )
+ {
+ // it is inaccurate if current selection is multiple cells, so it needs to go to start
+ uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getStart();
+ xTextViewCursor->gotoRange( xTextRange, false );
+ xTextViewCursor->collapseToStart();
+ }
+ else if( nDirection == word::WdCollapseDirection::wdCollapseEnd )
+ {
+ uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getEnd();
+ xTextViewCursor->gotoRange( xTextRange, false );
+ xTextViewCursor->collapseToEnd();
+ }
+ else
+ {
+ throw uno::RuntimeException();
+ }
+}
+
+void SAL_CALL SwVbaSelection::WholeStory( )
+{
+ uno::Reference< text::XText > xText = word::getCurrentXText( mxModel );
+ // FIXME: for i#7747,if the first line is a table, it fails to select all the contents in the story.
+ // Temporary solution, insert an empty line before the table so that it could select all the contents.
+ uno::Reference< container::XEnumerationAccess > xParaAccess( xText, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration> xParaEnum = xParaAccess->createEnumeration();
+ if( xParaEnum->hasMoreElements() )
+ {
+ uno::Reference< text::XTextTable > xTextTable( xParaEnum->nextElement(), uno::UNO_QUERY );
+ if( xTextTable.is() )
+ {
+ // insert an empty line
+ uno::Reference< text::XTextRange > xFirstCellRange = word::getFirstObjectPosition( xText );
+ mxTextViewCursor->gotoRange( xFirstCellRange, false );
+ dispatchRequests( mxModel,".uno:InsertPara" );
+ }
+ }
+ uno::Reference< text::XTextRange > xStart = xText->getStart();
+ uno::Reference< text::XTextRange > xEnd = xText->getEnd();
+ mxTextViewCursor->gotoRange( xStart, false );
+ mxTextViewCursor->gotoRange( xEnd, true );
+}
+
+sal_Bool SAL_CALL SwVbaSelection::InRange( const uno::Reference< ::ooo::vba::word::XRange >& Range )
+{
+ return getRange()->InRange( Range );
+}
+
+void SAL_CALL SwVbaSelection::SplitTable()
+{
+ if( !IsInTable() )
+ throw uno::RuntimeException();
+
+ SwDocShell* pDocShell = word::getDocShell( mxModel );
+ if( pDocShell )
+ {
+ if (SwFEShell* pFEShell = pDocShell->GetFEShell())
+ pFEShell->SplitTable( SplitTable_HeadlineOption::ContentCopy );
+ }
+}
+
+uno::Any SAL_CALL
+SwVbaSelection::Paragraphs( const uno::Any& aIndex )
+{
+ // Hacky implementation due to missing api ( and lack of knowledge )
+ // we can only support a selection that is a single paragraph
+ if ( !aIndex.hasValue() ) // currently we can't support multiple paragraphs in a selection
+ throw uno::RuntimeException();
+
+ sal_Int32 nIndex = 0;
+ aIndex >>= nIndex;
+
+ uno::Any aRet;
+
+ if ( nIndex != 1 )
+ throw uno::RuntimeException();
+
+ uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getStart();
+ uno::Reference< text::XText > xText = xTextRange->getText();
+ uno::Reference< text::XParagraphCursor > xParaCursor( xText->createTextCursor(), uno::UNO_QUERY_THROW );
+ xParaCursor->gotoStartOfParagraph( false );
+ xParaCursor->gotoStartOfParagraph( true );
+
+ uno::Reference< text::XTextDocument > xTextDoc( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xParaRange( xParaCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< word::XParagraph > xParagraph = new SwVbaParagraph( mxParent, mxContext, xTextDoc, xParaRange );
+
+ aRet <<= xParagraph;
+ return aRet;
+}
+
+OUString
+SwVbaSelection::getServiceImplName()
+{
+ return "SwVbaSelection";
+}
+
+uno::Sequence< OUString >
+SwVbaSelection::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Selection"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaselection.hxx b/sw/source/ui/vba/vbaselection.hxx
new file mode 100644
index 0000000000..0dba75b729
--- /dev/null
+++ b/sw/source/ui/vba/vbaselection.hxx
@@ -0,0 +1,120 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASELECTION_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBASELECTION_HXX
+
+#include <ooo/vba/word/XSelection.hpp>
+#include <ooo/vba/word/XRange.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <ooo/vba/word/XParagraphFormat.hpp>
+#include <ooo/vba/word/XFind.hpp>
+#include <ooo/vba/word/XFont.hpp>
+#include <ooo/vba/word/XHeaderFooter.hpp>
+#include "wordvbahelper.hxx"
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XSelection > SwVbaSelection_BASE;
+
+class SwVbaSelection : public SwVbaSelection_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::text::XTextViewCursor > mxTextViewCursor;
+
+private:
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ void Move( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend, ooo::vba::word::E_DIRECTION eDirection );
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ void NextCell( sal_Int32 nCount, ooo::vba::word::E_DIRECTION eDirection );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XTextRange > GetSelectedRange();
+ /// @throws css::uno::RuntimeException
+ void GetSelectedCellRange( OUString& sTLName, OUString& sBRName );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XTextTable > GetXTextTable() const;
+ /// @throws css::uno::RuntimeException
+ bool IsInTable() const;
+ /// @throws css::uno::RuntimeException
+ bool HasSelection();
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaSelection( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::frame::XModel > xModel );
+ virtual ~SwVbaSelection() override;
+
+ // Attribute
+ virtual OUString SAL_CALL getText() override;
+ virtual void SAL_CALL setText( const OUString& rText ) override;
+ virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL getRange() override;
+ virtual void SAL_CALL HomeKey( const css::uno::Any& _unit, const css::uno::Any& _extend ) override;
+ virtual void SAL_CALL EndKey( const css::uno::Any& _unit, const css::uno::Any& _extend ) override;
+ virtual void SAL_CALL TypeText( const OUString& rText ) override;
+ virtual void SAL_CALL Delete( const css::uno::Any& _unit, const css::uno::Any& _count ) override;
+ virtual void SAL_CALL MoveRight( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override;
+ virtual void SAL_CALL MoveLeft( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override;
+ virtual void SAL_CALL MoveDown( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override;
+ virtual void SAL_CALL MoveUp( const css::uno::Any& _unit, const css::uno::Any& _count, const css::uno::Any& _extend ) override;
+ virtual void SAL_CALL TypeParagraph() override;
+ virtual void SAL_CALL InsertParagraph() override;
+ virtual void SAL_CALL InsertParagraphBefore() override;
+ virtual void SAL_CALL InsertParagraphAfter() override;
+ virtual css::uno::Reference< ooo::vba::word::XParagraphFormat > SAL_CALL getParagraphFormat() override;
+ virtual void SAL_CALL setParagraphFormat( const css::uno::Reference< ooo::vba::word::XParagraphFormat >& rParagraphFormat ) override;
+ virtual css::uno::Reference< ooo::vba::word::XFind > SAL_CALL getFind() override;
+ virtual css::uno::Any SAL_CALL getStyle() override;
+ virtual void SAL_CALL setStyle( const css::uno::Any& _xStyle ) override;
+ virtual css::uno::Reference< ooo::vba::word::XFont > SAL_CALL getFont() override;
+ virtual void SAL_CALL TypeBackspace() override;
+ virtual css::uno::Reference< ooo::vba::word::XRange > SAL_CALL GoTo( const css::uno::Any& _what, const css::uno::Any& _which, const css::uno::Any& _count, const css::uno::Any& _name ) override;
+ virtual ::sal_Int32 SAL_CALL getLanguageID( ) override;
+ virtual void SAL_CALL setLanguageID( ::sal_Int32 _languageid ) override;
+ virtual css::uno::Any SAL_CALL Information( sal_Int32 _type ) override;
+ virtual void SAL_CALL InsertBreak( const css::uno::Any& _breakType ) override;
+ virtual css::uno::Any SAL_CALL Tables( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Fields( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Reference< ooo::vba::word::XHeaderFooter > SAL_CALL getHeaderFooter() override;
+ virtual css::uno::Any SAL_CALL ShapeRange( ) override;
+ virtual ::sal_Int32 SAL_CALL getStart() override;
+ virtual void SAL_CALL setStart( ::sal_Int32 _start ) override;
+ virtual ::sal_Int32 SAL_CALL getEnd() override;
+ virtual void SAL_CALL setEnd( ::sal_Int32 _end ) override;
+ virtual void SAL_CALL SelectRow() override;
+ virtual void SAL_CALL SelectColumn() override;
+ virtual css::uno::Any SAL_CALL Rows( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Columns( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Cells( const css::uno::Any& aIndex ) override;
+ virtual void SAL_CALL Copy( ) override;
+ virtual void SAL_CALL CopyAsPicture( ) override;
+ virtual void SAL_CALL Paste( ) override;
+ virtual void SAL_CALL Collapse( const css::uno::Any& Direction ) override;
+ virtual void SAL_CALL WholeStory( ) override;
+ virtual sal_Bool SAL_CALL InRange( const css::uno::Reference< ::ooo::vba::word::XRange >& Range ) override;
+ virtual void SAL_CALL SplitTable() override;
+ virtual css::uno::Any SAL_CALL Paragraphs( const css::uno::Any& aIndex ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASELECTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbastyle.cxx b/sw/source/ui/vba/vbastyle.cxx
new file mode 100644
index 0000000000..771e03ae33
--- /dev/null
+++ b/sw/source/ui/vba/vbastyle.cxx
@@ -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 .
+ */
+
+#include "vbastyle.hxx"
+#include <ooo/vba/word/WdStyleType.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <i18nlangtag/languagetag.hxx>
+#include <utility>
+#include "vbafont.hxx"
+#include "vbapalette.hxx"
+#include "vbaparagraphformat.hxx"
+#include "vbastyles.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaStyle::SwVbaStyle( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, uno::Reference< frame::XModel> xModel, const uno::Reference< beans::XPropertySet >& _xPropertySet ) : SwVbaStyle_BASE( xParent, xContext ) , mxModel(std::move( xModel )), mxStyleProps( _xPropertySet )
+{
+ mxStyle.set( _xPropertySet, uno::UNO_QUERY_THROW );
+}
+
+void SAL_CALL
+SwVbaStyle::setName( const OUString& Name )
+{
+ mxStyle->setName(Name);
+}
+
+OUString SAL_CALL
+SwVbaStyle::getName()
+{
+ return mxStyle->getName();
+}
+
+LanguageType SwVbaStyle::getLanguageID( const uno::Reference< beans::XPropertySet >& xTCProps )
+{
+ lang::Locale aLocale;
+ xTCProps->getPropertyValue("CharLocale") >>= aLocale;
+ return LanguageTag::convertToLanguageType( aLocale, false);
+}
+
+void SwVbaStyle::setLanguageID( const uno::Reference< beans::XPropertySet >& xTCProps, LanguageType _languageid )
+{
+ lang::Locale aLocale = LanguageTag( _languageid ).getLocale();
+ xTCProps->setPropertyValue("CharLocale", uno::Any( aLocale ) ) ;
+}
+
+::sal_Int32 SAL_CALL SwVbaStyle::getLanguageID()
+{
+ return static_cast<sal_uInt16>(getLanguageID( mxStyleProps ));
+}
+
+void SAL_CALL SwVbaStyle::setLanguageID( ::sal_Int32 _languageid )
+{
+ setLanguageID( mxStyleProps, LanguageType(_languageid) );
+}
+
+::sal_Int32 SAL_CALL SwVbaStyle::getType()
+{
+ sal_Int32 nType = word::WdStyleType::wdStyleTypeParagraph;
+ uno::Reference< lang::XServiceInfo > xServiceInfo( mxStyle, uno::UNO_QUERY_THROW );
+ if( xServiceInfo->supportsService("com.sun.star.style.ParagraphStyle") )
+ nType = word::WdStyleType::wdStyleTypeParagraph;
+ else if( xServiceInfo->supportsService("com.sun.star.style.CharacterStyle") )
+ nType = word::WdStyleType::wdStyleTypeCharacter;
+ else
+ nType = word::WdStyleType::wdStyleTypeList;
+ return nType;
+}
+
+uno::Reference< word::XFont > SAL_CALL
+SwVbaStyle::getFont()
+{
+ VbaPalette aColors;
+ return new SwVbaFont( mxParent, mxContext, aColors.getPalette(), mxStyleProps );
+}
+
+void SwVbaStyle::setStyle( const uno::Reference< beans::XPropertySet >& xParaProps, const uno::Any& rStyle )
+{
+ OUString sStyle;
+ uno::Reference< word::XStyle > xStyle;
+ if( rStyle >>= xStyle )
+ {
+ sStyle = xStyle->getName();
+ }
+ else
+ {
+ rStyle >>= sStyle;
+ }
+
+ if( !sStyle.isEmpty() )
+ {
+ xParaProps->setPropertyValue("ParaStyleName", uno::Any( sStyle ) );
+ return;
+ }
+
+ throw uno::RuntimeException();
+}
+
+OUString SAL_CALL SwVbaStyle::getNameLocal()
+{
+ OUString sNameLocal;
+ mxStyleProps->getPropertyValue("DisplayName") >>= sNameLocal;
+ return sNameLocal;
+}
+
+void SAL_CALL SwVbaStyle::setNameLocal( const OUString& _namelocal )
+{
+ mxStyleProps->setPropertyValue("DisplayName", uno::Any( _namelocal ) );
+}
+
+uno::Reference< word::XParagraphFormat > SAL_CALL SwVbaStyle::getParagraphFormat()
+{
+ if( word::WdStyleType::wdStyleTypeParagraph != getType() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW );
+ return uno::Reference< word::XParagraphFormat >( new SwVbaParagraphFormat( this, mxContext, mxStyleProps ) );
+}
+
+sal_Bool SAL_CALL SwVbaStyle::getAutomaticallyUpdate()
+{
+ bool isAutoUpdate = false;
+ mxStyleProps->getPropertyValue("IsAutoUpdate") >>= isAutoUpdate;
+ return isAutoUpdate;
+}
+
+void SAL_CALL SwVbaStyle::setAutomaticallyUpdate( sal_Bool _automaticallyupdate )
+{
+ mxStyleProps->setPropertyValue("IsAutoUpdate", uno::Any( _automaticallyupdate ) );
+}
+
+uno::Any SAL_CALL SwVbaStyle::getBaseStyle()
+{
+ // ParentStyle
+ OUString sBaseStyle;
+ mxStyleProps->getPropertyValue("ParentStyle") >>= sBaseStyle;
+ if( sBaseStyle.isEmpty() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference< XCollection > xCol( new SwVbaStyles( this, mxContext, mxModel ) );
+ return xCol->Item( uno::Any( sBaseStyle ), uno::Any() );
+}
+
+void SAL_CALL SwVbaStyle::setBaseStyle( const uno::Any& _basestyle )
+{
+ uno::Reference< word::XStyle > xStyle;
+ _basestyle >>= xStyle;
+ if( !xStyle.is() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ OUString sBaseStyle = xStyle->getName();
+ mxStyleProps->setPropertyValue("ParentStyle", uno::Any( sBaseStyle ) );
+}
+
+uno::Any SAL_CALL SwVbaStyle::getNextParagraphStyle()
+{
+ //FollowStyle
+ OUString sFollowStyle;
+ mxStyleProps->getPropertyValue("FollowStyle") >>= sFollowStyle;
+ if( sFollowStyle.isEmpty() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference< XCollection > xCol( new SwVbaStyles( this, mxContext, mxModel ) );
+ return xCol->Item( uno::Any( sFollowStyle ), uno::Any() );
+}
+
+void SAL_CALL SwVbaStyle::setNextParagraphStyle( const uno::Any& _nextparagraphstyle )
+{
+ uno::Reference< word::XStyle > xStyle;
+ _nextparagraphstyle >>= xStyle;
+ if( !xStyle.is() )
+ {
+ throw uno::RuntimeException();
+ }
+
+ OUString sFollowStyle = xStyle->getName();
+ mxStyleProps->setPropertyValue("FollowStyle", uno::Any( sFollowStyle ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaStyle::getListLevelNumber()
+{
+ sal_Int16 nNumberingLevel = 0;
+ mxStyleProps->getPropertyValue("NumberingLevel") >>= nNumberingLevel;
+ return nNumberingLevel;
+}
+
+OUString
+SwVbaStyle::getServiceImplName()
+{
+ return "SwVbaStyle";
+}
+
+uno::Sequence< OUString >
+SwVbaStyle::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.XStyle"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbastyle.hxx b/sw/source/ui/vba/vbastyle.hxx
new file mode 100644
index 0000000000..dc7ae051f1
--- /dev/null
+++ b/sw/source/ui/vba/vbastyle.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASTYLE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBASTYLE_HXX
+
+#include <ooo/vba/word/XStyle.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <i18nlangtag/lang.h>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <ooo/vba/word/XFont.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XStyle > SwVbaStyle_BASE;
+
+class SwVbaStyle : public SwVbaStyle_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::beans::XPropertySet > mxStyleProps;
+ css::uno::Reference< css::style::XStyle > mxStyle;
+public:
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ SwVbaStyle( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, css::uno::Reference< css::frame::XModel > xModel, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet );
+
+ /// @throws css::uno::RuntimeException
+ static void setStyle( const css::uno::Reference< css::beans::XPropertySet >& xParaProps, const css::uno::Any& xStyle );
+ /// @throws css::uno::RuntimeException
+ static LanguageType getLanguageID( const css::uno::Reference< css::beans::XPropertySet >& xTCProps );
+ /// @throws css::uno::RuntimeException
+ static void setLanguageID( const css::uno::Reference< css::beans::XPropertySet >& xTCProps, LanguageType _languageid );
+
+ // Attributes
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString& Name ) override;
+ virtual ::sal_Int32 SAL_CALL getLanguageID( ) override;
+ virtual void SAL_CALL setLanguageID( ::sal_Int32 _languageid ) override;
+ virtual ::sal_Int32 SAL_CALL getType() override;
+ virtual css::uno::Reference< ooo::vba::word::XFont > SAL_CALL getFont() override;
+ virtual OUString SAL_CALL getNameLocal() override;
+ virtual void SAL_CALL setNameLocal( const OUString& _namelocal ) override;
+ virtual css::uno::Reference< ::ooo::vba::word::XParagraphFormat > SAL_CALL getParagraphFormat() override;
+ virtual sal_Bool SAL_CALL getAutomaticallyUpdate() override;
+ virtual void SAL_CALL setAutomaticallyUpdate( sal_Bool _automaticallyupdate ) override;
+ virtual css::uno::Any SAL_CALL getBaseStyle() override;
+ virtual void SAL_CALL setBaseStyle( const css::uno::Any& _basestyle ) override;
+ virtual css::uno::Any SAL_CALL getNextParagraphStyle() override;
+ virtual void SAL_CALL setNextParagraphStyle( const css::uno::Any& _nextparagraphstyle ) override;
+ virtual ::sal_Int32 SAL_CALL getListLevelNumber() override;
+
+ //XDefaultProperty
+ virtual OUString SAL_CALL getDefaultPropertyName( ) override { return "Name"; }
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif //SW_VBA_AXIS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbastyles.cxx b/sw/source/ui/vba/vbastyles.cxx
new file mode 100644
index 0000000000..5e9ce270ff
--- /dev/null
+++ b/sw/source/ui/vba/vbastyles.cxx
@@ -0,0 +1,378 @@
+/* -*- 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 "vbastyles.hxx"
+#include "vbastyle.hxx"
+#include <basic/sberrors.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <sal/log.hxx>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <ooo/vba/word/WdBuiltinStyle.hpp>
+#include <ooo/vba/word/WdStyleType.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+struct BuiltinStyleTable
+{
+ sal_Int32 wdBuiltinStyle;
+ const char* pOOoStyleName;
+ sal_Int32 wdStyleType;
+};
+
+}
+
+const BuiltinStyleTable aBuiltinStyleTable[] =
+{
+ { word::WdBuiltinStyle::wdStyleBlockQuotation, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyText, "Text body", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyText2, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyText3, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyTextFirstIndent, "First line indent", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyTextFirstIndent2, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyTextIndent, "Text body indent", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyTextIndent2, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleBodyTextIndent3, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleCaption, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleClosing, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleCommentReference, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleCommentText, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleDate, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleDefaultParagraphFont, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleEmphasis, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleEndnoteReference, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleEndnoteText, "Endnote", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleEnvelopeAddress, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleEnvelopeReturn, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleFooter, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleFootnoteReference, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleFootnoteText, "Footnote", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeader, "Header", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading1, "Heading 1", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading2, "Heading 2", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading3, "Heading 3", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading4, "Heading 4", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading5, "Heading 5", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading6, "Heading 6", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading7, "Heading 7", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading8, "Heading 8", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHeading9, "Heading 9", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlAcronym, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlAddress, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlCite, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlCode, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlDfn, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlKbd, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlNormal, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlPre, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlSamp, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlTt, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHtmlVar, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHyperlink, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleHyperlinkFollowed, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex1, "Index 1", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex2, "Index 2", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex3, "Index 3", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex4, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex5, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex6, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex7, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex8, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndex9, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleIndexHeading, "Index Heading", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleLineNumber, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleList, "List", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleList2, "List 2", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleList3, "List 3", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleList4, "List 4", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleList5, "List 5", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleListBullet, "List 1", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListBullet2, "List 2", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListBullet3, "List 3", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListBullet4, "List 4", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListBullet5, "List 5", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListContinue, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleListContinue2, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleListContinue3, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleListContinue4, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleListContinue5, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleListNumber, "Numbering 123", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListNumber2, "Numbering ABC", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListNumber3, "Numbering abc", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListNumber4, "Numbering IVX", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleListNumber5, "Numbering ivx", word::WdStyleType::wdStyleTypeList },
+ { word::WdBuiltinStyle::wdStyleMacroText, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleMessageHeader, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleNavPane, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleNormal, "Default", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleNormalIndent, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleNormalTable, "Table", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleNoteHeading, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStylePageNumber, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStylePlainText, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleSalutation, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleSignature, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleStrong, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleSubtitle, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTableOfAuthorities, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTableOfFigures, "", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTitle, "Title", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOAHeading, "Contents Heading", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC1, "Contents 1", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC2, "Contents 2", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC3, "Contents 3", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC4, "Contents 4", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC5, "Contents 5", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC6, "Contents 6", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC7, "Contents 7", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC8, "Contents 8", word::WdStyleType::wdStyleTypeParagraph },
+ { word::WdBuiltinStyle::wdStyleTOC9, "Contents 9", word::WdStyleType::wdStyleTypeParagraph },
+ { 0, nullptr, 0 }
+};
+
+namespace {
+
+struct MSOStyleNameTable
+{
+ const char* pMSOStyleName;
+ const char* pOOoStyleName;
+};
+
+}
+
+const MSOStyleNameTable aMSOStyleNameTable[] =
+{
+ { "Normal", "Default" },
+ { nullptr, nullptr }
+};
+
+namespace {
+
+class StyleCollectionHelper : public ::cppu::WeakImplHelper< container::XNameAccess,
+ container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< container::XNameAccess > mxParaStyles;
+ uno::Any m_cachePos;
+public:
+ explicit StyleCollectionHelper( const uno::Reference< frame::XModel >& _xModel )
+ {
+ // we only concern about the Paragraph styles
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( _xModel, uno::UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xStyleFamilies = xStyleSupplier->getStyleFamilies();
+ mxParaStyles.set( xStyleFamilies->getByName("ParagraphStyles"), uno::UNO_QUERY_THROW );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<style::XStyle>::get(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return getCount() > 0; }
+ // XNameAccess
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName(aName) )
+ throw container::NoSuchElementException();
+ return m_cachePos;
+ }
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ return mxParaStyles->getElementNames();
+ }
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ // search in the MSOStyleName table first
+ for( const MSOStyleNameTable* pTable = aMSOStyleNameTable; pTable->pMSOStyleName != nullptr; pTable++ )
+ {
+ if( aName.equalsIgnoreAsciiCaseAscii( pTable->pMSOStyleName ) )
+ {
+ //Found it
+ OUString sStyleName = OUString::createFromAscii( pTable->pOOoStyleName );
+ if( mxParaStyles->hasByName( sStyleName ) )
+ {
+ m_cachePos = mxParaStyles->getByName( sStyleName );
+ return true;
+ }
+ return false;
+ }
+ }
+
+ if( mxParaStyles->hasByName( aName ) )
+ {
+ m_cachePos = mxParaStyles->getByName( aName );
+ return true;
+ }
+ else
+ {
+ const uno::Sequence< OUString > sElementNames = mxParaStyles->getElementNames();
+ auto pStyleName = std::find_if(sElementNames.begin(), sElementNames.end(),
+ [&aName](const OUString& rStyleName) { return rStyleName.equalsIgnoreAsciiCase( aName ); });
+ if (pStyleName != sElementNames.end())
+ {
+ m_cachePos = mxParaStyles->getByName( *pStyleName );
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // XIndexAccess
+ virtual ::sal_Int32 SAL_CALL getCount( ) override
+ {
+ uno::Reference< container::XIndexAccess > xIndexAccess( mxParaStyles, uno::UNO_QUERY_THROW );
+ return xIndexAccess->getCount();
+ }
+ virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference< container::XIndexAccess > xIndexAccess( mxParaStyles, uno::UNO_QUERY_THROW );
+ return xIndexAccess->getByIndex( Index );
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ throw uno::RuntimeException("Not implemented" );
+ }
+};
+
+class StylesEnumWrapper : public EnumerationHelper_BASE
+{
+ SwVbaStyles* m_pStyles;
+ sal_Int32 m_nIndex;
+public:
+ explicit StylesEnumWrapper( SwVbaStyles* _pStyles ) : m_pStyles( _pStyles ), m_nIndex( 1 ) {}
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex <= m_pStyles->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( m_nIndex <= m_pStyles->getCount() )
+ return m_pStyles->Item( uno::Any( m_nIndex++ ), uno::Any() );
+ throw container::NoSuchElementException();
+ }
+};
+
+}
+
+SwVbaStyles::SwVbaStyles( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel )
+ : SwVbaStyles_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new StyleCollectionHelper( xModel ) ) ), mxModel( xModel )
+{
+ mxMSF.set( mxModel, uno::UNO_QUERY_THROW );
+}
+
+uno::Any
+SwVbaStyles::createCollectionObject(const uno::Any& aObject)
+{
+ uno::Reference< beans::XPropertySet > xStyleProp( aObject, uno::UNO_QUERY_THROW );
+ return uno::Any( uno::Reference< word::XStyle >( new SwVbaStyle( this, mxContext, mxModel, xStyleProp ) ) );
+}
+
+uno::Type SAL_CALL
+SwVbaStyles::getElementType()
+{
+ return cppu::UnoType<word::XStyle>::get();
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwVbaStyles::createEnumeration()
+{
+ return new StylesEnumWrapper( this );
+}
+
+uno::Any SAL_CALL
+SwVbaStyles::Item( const uno::Any& Index1, const uno::Any& Index2 )
+{
+ //handle WdBuiltinStyle
+ sal_Int32 nIndex = 0;
+ if( ( Index1 >>= nIndex ) && ( nIndex < 0 ) )
+ {
+ for( const BuiltinStyleTable* pTable = aBuiltinStyleTable; pTable != nullptr; pTable++ )
+ {
+ if( nIndex == pTable->wdBuiltinStyle )
+ {
+ OUString aStyleName = OUString::createFromAscii( pTable->pOOoStyleName );
+ if( !aStyleName.isEmpty() )
+ {
+ OUString aStyleType;
+ switch( pTable->wdStyleType )
+ {
+ case word::WdStyleType::wdStyleTypeParagraph:
+ case word::WdStyleType::wdStyleTypeTable:
+ {
+ aStyleType = "ParagraphStyles";
+ break;
+ }
+ case word::WdStyleType::wdStyleTypeCharacter:
+ {
+ aStyleType = "CharacterStyles";
+ break;
+ }
+ case word::WdStyleType::wdStyleTypeList:
+ {
+ // should use Paragraph style and set the property "NumberingStyleName"
+ aStyleType = "ParagraphStyles";
+ break;
+ }
+ default:
+ DebugHelper::basicexception( ERRCODE_BASIC_INTERNAL_ERROR, {} );
+ }
+ uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( mxModel, uno::UNO_QUERY_THROW);
+ uno::Reference< container::XNameAccess > xStylesAccess( xStyleSupplier->getStyleFamilies()->getByName( aStyleType ), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xStyleProps( xStylesAccess->getByName( aStyleName ), uno::UNO_QUERY_THROW );
+ // set the property "NumberingStyleName" if it is a listbullet
+ if( pTable->wdStyleType == word::WdStyleType::wdStyleTypeList )
+ {
+ xStyleProps->setPropertyValue("NumberingStyleName", uno::Any( aStyleName ) );
+ }
+ return uno::Any( uno::Reference< word::XStyle >( new SwVbaStyle( this, mxContext, mxModel, xStyleProps ) ) );
+ }
+ else
+ {
+ SAL_WARN("sw.vba", "the builtin style type is not implemented");
+ throw uno::RuntimeException("Not implemented" );
+ }
+ }
+ }
+ }
+ return SwVbaStyles_BASE::Item( Index1, Index2 );
+}
+
+OUString
+SwVbaStyles::getServiceImplName()
+{
+ return "SwVbaStyles";
+}
+
+uno::Sequence< OUString >
+SwVbaStyles::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.XStyles"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbastyles.hxx b/sw/source/ui/vba/vbastyles.hxx
new file mode 100644
index 0000000000..390225cd08
--- /dev/null
+++ b/sw/source/ui/vba/vbastyles.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASTYLES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBASTYLES_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <ooo/vba/word/XStyles.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ooo::vba::word::XStyles > SwVbaStyles_BASE;
+class SwVbaStyles: public SwVbaStyles_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::lang::XMultiServiceFactory > mxMSF;
+public:
+ /// @throws css::script::BasicErrorException
+ /// @throws css::uno::RuntimeException
+ SwVbaStyles( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xModel );
+
+ virtual css::uno::Any SAL_CALL Item(const css::uno::Any& Index1, const css::uno::Any& Index2) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ virtual css::uno::Any createCollectionObject(const css::uno::Any&) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbasystem.cxx b/sw/source/ui/vba/vbasystem.cxx
new file mode 100644
index 0000000000..e09c89554e
--- /dev/null
+++ b/sw/source/ui/vba/vbasystem.cxx
@@ -0,0 +1,275 @@
+/* -*- 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 "vbasystem.hxx"
+
+#include <ooo/vba/word/WdCursorType.hpp>
+#include <tools/config.hxx>
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+
+#ifdef _WIN32
+#include <cstddef>
+#include <string_view>
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+PrivateProfileStringListener::~PrivateProfileStringListener()
+{
+}
+
+void PrivateProfileStringListener::Initialize( const OUString& rFileName, const OString& rGroupName, const OString& rKey )
+{
+ maFileName = rFileName;
+ maGroupName = rGroupName;
+ maKey = rKey;
+}
+#ifdef _WIN32
+static void lcl_getRegKeyInfo( std::string_view sKeyInfo, HKEY& hBaseKey, OString& sSubKey )
+{
+ std::size_t nBaseKeyIndex = sKeyInfo.find('\\');
+ if( nBaseKeyIndex != std::string_view::npos )
+ {
+ std::string_view sBaseKey = sKeyInfo.substr( 0, nBaseKeyIndex );
+ sSubKey = OString(sKeyInfo.substr( nBaseKeyIndex + 1 ));
+ if( sBaseKey == "HKEY_CURRENT_USER" )
+ {
+ hBaseKey = HKEY_CURRENT_USER;
+ }
+ else if( sBaseKey == "HKEY_LOCAL_MACHINE" )
+ {
+ hBaseKey = HKEY_LOCAL_MACHINE;
+ }
+ else if( sBaseKey == "HKEY_CLASSES_ROOT" )
+ {
+ hBaseKey = HKEY_CLASSES_ROOT;
+ }
+ else if( sBaseKey == "HKEY_USERS" )
+ {
+ hBaseKey = HKEY_USERS;
+ }
+ else if( sBaseKey == "HKEY_CURRENT_CONFIG" )
+ {
+ hBaseKey = HKEY_CURRENT_CONFIG;
+ }
+ }
+}
+#endif
+
+uno::Any PrivateProfileStringListener::getValueEvent()
+{
+ // get the private profile string
+ OUString sValue;
+ if(maFileName.isEmpty())
+ {
+ // get key/value from Windows registry
+#ifdef _WIN32
+ HKEY hBaseKey = nullptr;
+ OString sSubKey;
+ lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey );
+ if( hBaseKey != nullptr )
+ {
+ HKEY hKey = nullptr;
+ LPCSTR lpSubKey = sSubKey.getStr();
+ // We use RegOpenKeyExA here for convenience, because we already have subkey name as 8-bit string
+ LONG lResult = RegOpenKeyExA( hBaseKey, lpSubKey, 0, KEY_QUERY_VALUE, &hKey );
+ if( ERROR_SUCCESS == lResult )
+ {
+ OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW);
+ LPCWSTR lpValueName = o3tl::toW(sUValName.getStr());
+ WCHAR szBuffer[1024];
+ DWORD cbData = sizeof(szBuffer);
+ lResult = RegQueryValueExW( hKey, lpValueName, nullptr, nullptr, reinterpret_cast<LPBYTE>(szBuffer), &cbData );
+ RegCloseKey( hKey );
+ // https://msdn.microsoft.com/en-us/ms724911 mentions that
+ // "the string may not have been stored with the proper terminating null characters"
+ szBuffer[std::min(size_t(cbData / sizeof(szBuffer[0])), SAL_N_ELEMENTS(szBuffer)-1)] = 0;
+ sValue = o3tl::toU(szBuffer);
+ }
+ }
+#else
+ throw uno::RuntimeException("Only support on Windows" );
+#endif
+ }
+
+ // get key/value from a file
+ Config aCfg( maFileName );
+ aCfg.SetGroup( maGroupName );
+ sValue = OStringToOUString(aCfg.ReadKey(maKey), RTL_TEXTENCODING_DONTKNOW);
+
+
+ return uno::Any( sValue );
+}
+
+void PrivateProfileStringListener::setValueEvent( const css::uno::Any& value )
+{
+ // set the private profile string
+ OUString aValue;
+ value >>= aValue;
+ if(maFileName.isEmpty())
+ {
+ //set value into Windows registry
+#ifdef _WIN32
+ HKEY hBaseKey = nullptr;
+ OString sSubKey;
+ lcl_getRegKeyInfo( maGroupName, hBaseKey, sSubKey );
+ if( hBaseKey != nullptr )
+ {
+ HKEY hKey = nullptr;
+ LPCSTR lpSubKey = sSubKey.getStr();
+ // We use RegCreateKeyExA here for convenience, because we already have subkey name as 8-bit string
+ LONG lResult = RegCreateKeyExA( hBaseKey, lpSubKey, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr, &hKey, nullptr );
+ if( ERROR_SUCCESS == lResult )
+ {
+ DWORD cbData = sizeof(WCHAR) * (aValue.getLength() + 1);
+ OUString sUValName = OStringToOUString(maKey, RTL_TEXTENCODING_DONTKNOW);
+ LPCWSTR lpValueName = o3tl::toW(sUValName.getStr());
+ lResult = RegSetValueExW( hKey, lpValueName, 0 /* Reserved */, REG_SZ, reinterpret_cast<BYTE const *>(aValue.getStr()), cbData );
+ RegCloseKey( hKey );
+ }
+ }
+ return;
+#else
+ throw uno::RuntimeException("Not implemented" );
+#endif
+ }
+
+ // set value into a file
+ Config aCfg( maFileName );
+ aCfg.SetGroup( maGroupName );
+ aCfg.WriteKey( maKey, OUStringToOString(aValue, RTL_TEXTENCODING_DONTKNOW) );
+
+
+}
+
+SwVbaSystem::SwVbaSystem( uno::Reference<uno::XComponentContext > const & xContext ): SwVbaSystem_BASE( uno::Reference< XHelperInterface >(), xContext )
+{
+}
+
+SwVbaSystem::~SwVbaSystem()
+{
+}
+
+sal_Int32 SAL_CALL
+SwVbaSystem::getCursor()
+{
+ PointerStyle nPointerStyle = getPointerStyle( getCurrentWordDoc(mxContext) );
+
+ switch( nPointerStyle )
+ {
+ case PointerStyle::Arrow:
+ return word::WdCursorType::wdCursorNorthwestArrow;
+ case PointerStyle::Null:
+ return word::WdCursorType::wdCursorNormal;
+ case PointerStyle::Wait:
+ return word::WdCursorType::wdCursorWait;
+ case PointerStyle::Text:
+ return word::WdCursorType::wdCursorIBeam;
+ default:
+ return word::WdCursorType::wdCursorNormal;
+ }
+}
+
+void SAL_CALL
+SwVbaSystem::setCursor( sal_Int32 _cursor )
+{
+ try
+ {
+ switch( _cursor )
+ {
+ case word::WdCursorType::wdCursorNorthwestArrow:
+ {
+ setCursorHelper( getCurrentWordDoc(mxContext), PointerStyle::Arrow, false );
+ break;
+ }
+ case word::WdCursorType::wdCursorWait:
+ {
+ //It will set the edit window, toobar and statusbar's mouse pointer.
+ setCursorHelper( getCurrentWordDoc(mxContext), PointerStyle::Wait, true );
+ break;
+ }
+ case word::WdCursorType::wdCursorIBeam:
+ {
+ //It will set the edit window, toobar and statusbar's mouse pointer.
+ setCursorHelper( getCurrentWordDoc( mxContext ), PointerStyle::Text, true );
+ break;
+ }
+ case word::WdCursorType::wdCursorNormal:
+ {
+ setCursorHelper( getCurrentWordDoc( mxContext ), PointerStyle::Null, false );
+ break;
+ }
+ default:
+ throw uno::RuntimeException("Unknown value for Cursor pointer" );
+ // TODO: isn't this a flaw in the API? It should be allowed to throw an
+ // IllegalArgumentException, or so
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ }
+}
+
+uno::Any SAL_CALL
+SwVbaSystem::PrivateProfileString( const OUString& rFilename, const OUString& rSection, const OUString& rKey )
+{
+ // FIXME: need to detect whether it is a relative file path
+ // we need to detect if this is a URL, if not then assume it's a file path
+ OUString sFileUrl;
+ if( !rFilename.isEmpty() )
+ {
+ INetURLObject aObj;
+ aObj.SetURL( rFilename );
+ bool bIsURL = aObj.GetProtocol() != INetProtocol::NotValid;
+ if ( bIsURL )
+ sFileUrl = rFilename;
+ else
+ osl::FileBase::getFileURLFromSystemPath( rFilename, sFileUrl);
+ }
+
+ OString aGroupName(OUStringToOString(rSection, RTL_TEXTENCODING_DONTKNOW));
+ OString aKey(OUStringToOString(rKey, RTL_TEXTENCODING_DONTKNOW));
+ maPrivateProfileStringListener.Initialize( sFileUrl, aGroupName, aKey );
+
+ return uno::Any( uno::Reference< XPropValue > ( new ScVbaPropValue( &maPrivateProfileStringListener ) ) );
+}
+
+OUString
+SwVbaSystem::getServiceImplName()
+{
+ return "SwVbaSystem";
+}
+
+uno::Sequence< OUString >
+SwVbaSystem::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.System"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbasystem.hxx b/sw/source/ui/vba/vbasystem.hxx
new file mode 100644
index 0000000000..c0acb2ad49
--- /dev/null
+++ b/sw/source/ui/vba/vbasystem.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBASYSTEM_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBASYSTEM_HXX
+
+#include <ooo/vba/word/XSystem.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbapropvalue.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XSystem > SwVbaSystem_BASE;
+
+class PrivateProfileStringListener : public PropListener
+{
+private:
+ OUString maFileName;
+ OString maGroupName;
+ OString maKey;
+public:
+ PrivateProfileStringListener(){};
+ virtual ~PrivateProfileStringListener();
+ void Initialize( const OUString& rFileName, const OString& rGroupName, const OString& rKey );
+
+ //PropListener
+ virtual void setValueEvent( const css::uno::Any& value ) override;
+ virtual css::uno::Any getValueEvent() override;
+};
+
+class SwVbaSystem : public SwVbaSystem_BASE
+{
+private:
+ PrivateProfileStringListener maPrivateProfileStringListener;
+
+public:
+ explicit SwVbaSystem( css::uno::Reference< css::uno::XComponentContext > const & m_xContext );
+ virtual ~SwVbaSystem() override;
+
+ // XSystem
+ virtual sal_Int32 SAL_CALL getCursor() override;
+ virtual void SAL_CALL setCursor( sal_Int32 _cursor ) override;
+ virtual css::uno::Any SAL_CALL PrivateProfileString( const OUString& rFilename, const OUString& rSection, const OUString& rKey ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBASYSTEM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatable.cxx b/sw/source/ui/vba/vbatable.cxx
new file mode 100644
index 0000000000..25e370a1c5
--- /dev/null
+++ b/sw/source/ui/vba/vbatable.cxx
@@ -0,0 +1,211 @@
+/* -*- 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 "vbatable.hxx"
+#include "vbarange.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/table/TableBorderDistances.hpp>
+#include <utility>
+#include "vbaborders.hxx"
+#include "vbapalette.hxx"
+#include "vbarows.hxx"
+#include "vbacolumns.hxx"
+#include "vbaapplication.hxx"
+
+#include <tools/UnitConversion.hxx>
+
+#include <sal/log.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaTable::SwVbaTable( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xDocument, const uno::Reference< text::XTextTable >& xTextTable) : SwVbaTable_BASE( rParent, rContext ), mxTextDocument(std::move( xDocument ))
+{
+ mxTextTable.set( xTextTable, uno::UNO_SET_THROW );
+}
+
+uno::Reference< word::XRange > SAL_CALL
+SwVbaTable::Range( )
+{
+ return new SwVbaRange( mxParent, mxContext, mxTextDocument, mxTextTable->getAnchor() );
+}
+
+void SAL_CALL
+SwVbaTable::Select( )
+{
+ uno::Reference< frame::XModel > xModel( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XController > xController = xModel->getCurrentController();
+
+ uno::Reference< text::XTextViewCursorSupplier > xViewCursorSupplier( xController, uno::UNO_QUERY_THROW );
+ uno::Reference< view::XSelectionSupplier > xSelectionSupplier( xController, uno::UNO_QUERY_THROW );
+
+ // set the view cursor to the start of the table.
+ xSelectionSupplier->select( uno::Any( mxTextTable ) );
+
+ // go to the end of the table and span the view
+ uno::Reference< text::XTextViewCursor > xCursor = xViewCursorSupplier->getViewCursor();
+ xCursor->gotoEnd(true);
+
+}
+
+void SAL_CALL
+SwVbaTable::Delete( )
+{
+ uno::Reference< table::XTableRows > xRows( mxTextTable->getRows() );
+ xRows->removeByIndex( 0, xRows->getCount() );
+}
+
+OUString SAL_CALL
+SwVbaTable::getName( )
+{
+ uno::Reference< container::XNamed > xNamed( mxTextTable, uno::UNO_QUERY_THROW );
+ return xNamed->getName();
+}
+
+uno::Any SAL_CALL
+SwVbaTable::Borders( const uno::Any& index )
+{
+ uno::Reference< table::XCellRange > aCellRange( mxTextTable, uno::UNO_QUERY_THROW );
+ VbaPalette aPalette;
+ uno::Reference< XCollection > xCol( new SwVbaBorders( this, mxContext, aCellRange, aPalette ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+double SAL_CALL
+SwVbaTable::getBottomPadding()
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances;
+ return convertMm100ToPoint(aTableBorderDistances.BottomDistance);
+}
+
+void SAL_CALL
+SwVbaTable::setBottomPadding( double fValue )
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ aTableBorderDistances.IsBottomDistanceValid = true;
+ aTableBorderDistances.BottomDistance = convertPointToMm100(fValue);
+ xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) );
+}
+
+double SAL_CALL
+SwVbaTable::getLeftPadding()
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances;
+ return convertMm100ToPoint(aTableBorderDistances.LeftDistance);
+}
+
+void SAL_CALL
+SwVbaTable::setLeftPadding( double fValue )
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ aTableBorderDistances.IsLeftDistanceValid = true;
+ aTableBorderDistances.LeftDistance = convertPointToMm100(fValue);
+ xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) );
+}
+
+double SAL_CALL
+SwVbaTable::getRightPadding()
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances;
+ return convertMm100ToPoint(aTableBorderDistances.RightDistance);
+}
+
+void SAL_CALL
+SwVbaTable::setRightPadding( double fValue )
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ aTableBorderDistances.IsRightDistanceValid = true;
+ aTableBorderDistances.RightDistance = convertPointToMm100(fValue);
+ xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) );
+}
+
+double SAL_CALL
+SwVbaTable::getTopPadding()
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ xPropertySet->getPropertyValue("TableBorderDistances") >>= aTableBorderDistances;
+ return convertMm100ToPoint(aTableBorderDistances.TopDistance);
+}
+
+void SAL_CALL
+SwVbaTable::setTopPadding( double fValue )
+{
+ uno::Reference< beans::XPropertySet > xPropertySet( mxTextTable, uno::UNO_QUERY_THROW);
+ table::TableBorderDistances aTableBorderDistances;
+ aTableBorderDistances.IsTopDistanceValid = true;
+ aTableBorderDistances.TopDistance = convertPointToMm100(fValue);
+ xPropertySet->setPropertyValue( "TableBorderDistances", uno::Any( aTableBorderDistances ) );
+}
+
+uno::Any SAL_CALL
+SwVbaTable::Rows( const uno::Any& index )
+{
+ uno::Reference< table::XTableRows > xTableRows( mxTextTable->getRows(), uno::UNO_SET_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaRows( this, mxContext, mxTextTable, xTableRows ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+uno::Any SAL_CALL
+SwVbaTable::Columns( const uno::Any& index )
+{
+ uno::Reference< table::XTableColumns > xTableColumns( mxTextTable->getColumns(), uno::UNO_SET_THROW );
+ uno::Reference< XCollection > xCol( new SwVbaColumns( this, mxContext, mxTextTable, xTableColumns ) );
+ if ( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+// XHelperInterface
+OUString
+SwVbaTable::getServiceImplName()
+{
+ return "SwVbaTable";
+}
+
+uno::Sequence<OUString>
+SwVbaTable::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Table"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatable.hxx b/sw/source/ui/vba/vbatable.hxx
new file mode 100644
index 0000000000..2bb802b5c6
--- /dev/null
+++ b/sw/source/ui/vba/vbatable.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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLE_HXX
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <ooo/vba/word/XRange.hpp>
+#include <ooo/vba/word/XTable.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XTable > SwVbaTable_BASE;
+
+class SwVbaTable : public SwVbaTable_BASE
+{
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaTable( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xDocument, const css::uno::Reference< css::text::XTextTable >& xTextTable);
+ virtual css::uno::Reference< ::ooo::vba::word::XRange > SAL_CALL Range( ) override;
+ virtual void SAL_CALL Select( ) override;
+ virtual void SAL_CALL Delete( ) override;
+ virtual OUString SAL_CALL getName( ) override;
+ virtual css::uno::Any SAL_CALL Borders( const css::uno::Any& aIndex ) override;
+ virtual double SAL_CALL getBottomPadding( ) override;
+ virtual void SAL_CALL setBottomPadding( double fValue ) override;
+ virtual double SAL_CALL getLeftPadding( ) override;
+ virtual void SAL_CALL setLeftPadding( double fValue ) override;
+ virtual double SAL_CALL getRightPadding( ) override;
+ virtual void SAL_CALL setRightPadding( double fValue ) override;
+ virtual double SAL_CALL getTopPadding( ) override;
+ virtual void SAL_CALL setTopPadding( double fValue ) override;
+ virtual css::uno::Any SAL_CALL Rows( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL Columns( const css::uno::Any& aIndex ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatablehelper.cxx b/sw/source/ui/vba/vbatablehelper.cxx
new file mode 100644
index 0000000000..2d7a1b393e
--- /dev/null
+++ b/sw/source/ui/vba/vbatablehelper.cxx
@@ -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 .
+ */
+
+#include <comphelper/servicehelper.hxx>
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include "vbatablehelper.hxx"
+#include <swtable.hxx>
+#include <unotbl.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+#define UNO_TABLE_COLUMN_SUM 10000
+
+SwVbaTableHelper::SwVbaTableHelper( uno::Reference< text::XTextTable > xTextTable ) : mxTextTable(std::move( xTextTable ))
+{
+ m_pTable = GetSwTable( mxTextTable );
+}
+
+SwTable* SwVbaTableHelper::GetSwTable( const uno::Reference< text::XTextTable >& xTextTable )
+{
+ SwXTextTable* pXTextTable = dynamic_cast<SwXTextTable*>(xTextTable.get());
+ if( !pXTextTable )
+ throw uno::RuntimeException();
+
+ SwFrameFormat* pFrameFormat = pXTextTable->GetFrameFormat();
+ if( !pFrameFormat )
+ throw uno::RuntimeException();
+
+ SwTable* pTable = SwTable::FindTable( pFrameFormat );
+ return pTable;
+}
+
+sal_Int32 SwVbaTableHelper::getTabColumnsCount( sal_Int32 nRowIndex )
+{
+ sal_Int32 nRet = 0;
+ if(!m_pTable->IsTableComplex())
+ {
+ SwTableLines& rLines = m_pTable->GetTabLines();
+ SwTableLine* pLine = rLines[ nRowIndex ];
+ nRet = pLine->GetTabBoxes().size();
+ }
+ return nRet;
+}
+
+sal_Int32 SwVbaTableHelper::getTabColumnsMaxCount( )
+{
+ sal_Int32 nRet = 0;
+ sal_Int32 nRowCount = m_pTable->GetTabLines().size();
+ for( sal_Int32 index = 0; index < nRowCount; index++ )
+ {
+ sal_Int32 nColCount = getTabColumnsCount( index );
+ if( nRet < nColCount )
+ nRet = nColCount;
+ }
+ return nRet;
+}
+
+sal_Int32 SwVbaTableHelper::getTabRowIndex( const OUString& rCellName )
+{
+ sal_Int32 nRet = 0;
+ SwTableBox* pBox = const_cast<SwTableBox*>(m_pTable->GetTableBox( rCellName ));
+ if( !pBox )
+ throw uno::RuntimeException();
+
+ const SwTableLine* pLine = pBox->GetUpper();
+ const SwTableLines* pLines = pLine->GetUpper()
+ ? &pLine->GetUpper()->GetTabLines() : &m_pTable->GetTabLines();
+ nRet = pLines->GetPos( pLine );
+ return nRet;
+}
+
+sal_Int32 SwVbaTableHelper::getTabColIndex( const OUString& rCellName )
+{
+ const SwTableBox* pBox = m_pTable->GetTableBox( rCellName );
+ if( !pBox )
+ throw uno::RuntimeException();
+ return pBox->GetUpper()->GetBoxPos( pBox );
+}
+
+OUString SwVbaTableHelper::getColumnStr( sal_Int32 nCol )
+{
+ const sal_Int32 coDiff = 52; // 'A'-'Z' 'a' - 'z'
+ sal_Int32 nCalc = 0;
+
+ OUString sRet;
+ do{
+ nCalc = nCol % coDiff;
+ if( nCalc >= 26 )
+ sRet = OUStringChar( sal_Unicode('a' - 26 + nCalc) ) + sRet;
+ else
+ sRet = OUStringChar( sal_Unicode('A' + nCalc) ) + sRet;
+
+ nCol = nCol - nCalc;
+ if( 0 == nCol )
+ break;
+ nCol /= coDiff;
+ --nCol;
+ }while(true);
+ return sRet;
+}
+
+sal_Int32 SwVbaTableHelper::getTableWidth( ) const
+{
+ sal_Int32 nWidth = 0;
+ bool isWidthRelatvie = false;
+ uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
+ xTableProps->getPropertyValue("IsWidthRelative") >>= isWidthRelatvie;
+ if( isWidthRelatvie )
+ {
+ xTableProps->getPropertyValue("RelativeWidth") >>= nWidth;
+ }
+ else
+ {
+ xTableProps->getPropertyValue("Width") >>= nWidth;
+ }
+ return nWidth;
+}
+
+SwTableBox* SwVbaTableHelper::GetTabBox( sal_Int32 nCol, sal_Int32 nRow )
+{
+ SwTableLines& rLines = m_pTable->GetTabLines();
+ sal_Int32 nRowCount = rLines.size();
+ if (nRow < 0 || nRow >= nRowCount)
+ throw uno::RuntimeException();
+
+ SwTableLine* pLine = rLines[ nRow ];
+ sal_Int32 nColCount = pLine->GetTabBoxes().size();
+ if (nCol < 0 || nCol >= nColCount)
+ throw uno::RuntimeException();
+
+ SwTableBox* pStart = pLine->GetTabBoxes()[ nCol ];
+
+ if( !pStart )
+ throw uno::RuntimeException();
+
+ return pStart;
+}
+
+void SwVbaTableHelper::InitTabCols( SwTabCols& rCols, const SwTableBox *pStart )
+{
+ rCols.SetLeftMin ( 0 );
+ rCols.SetLeft ( 0 );
+ rCols.SetRight ( UNO_TABLE_COLUMN_SUM );
+ rCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
+ m_pTable->GetTabCols( rCols, pStart );
+}
+
+sal_Int32 SwVbaTableHelper::GetColCount( SwTabCols const & rCols )
+{
+ sal_Int32 nCount = 0;
+ for( size_t i = 0; i < rCols.Count(); ++i )
+ if(rCols.IsHidden(i))
+ nCount ++;
+ return rCols.Count() - nCount;
+}
+
+sal_Int32 SwVbaTableHelper::GetRightSeparator( SwTabCols const & rCols, sal_Int32 nNum)
+{
+ OSL_ENSURE( nNum < GetColCount( rCols ) ,"Index out of range");
+ sal_Int32 i = 0;
+ while( nNum >= 0 )
+ {
+ if( !rCols.IsHidden(i) )
+ nNum--;
+ i++;
+ }
+ return i - 1;
+}
+
+sal_Int32 SwVbaTableHelper::GetColWidth( sal_Int32 nCol, sal_Int32 nRow )
+{
+ SwTableBox* pStart = GetTabBox( nCol, nRow );
+ SwTabCols aCols;
+ InitTabCols( aCols, pStart );
+ sal_Int32 nWidth = GetColWidth( aCols, nCol );
+
+ sal_Int32 nTableWidth = getTableWidth( );
+ double dAbsWidth = ( static_cast<double>(nWidth) / UNO_TABLE_COLUMN_SUM ) * static_cast<double>(nTableWidth);
+ return static_cast<sal_Int32>(Millimeter::getInPoints( static_cast<int>(dAbsWidth) ));
+}
+
+sal_Int32 SwVbaTableHelper::GetColWidth( SwTabCols& rCols, sal_Int32 nNum )
+{
+ SwTwips nWidth = 0;
+
+ if( rCols.Count() > 0 )
+ {
+ if(rCols.Count() == static_cast<size_t>(GetColCount( rCols )))
+ {
+ if(static_cast<size_t>(nNum) == rCols.Count())
+ nWidth = rCols.GetRight() - rCols[nNum-1];
+ else
+ {
+ nWidth = rCols[nNum];
+ if(nNum == 0)
+ nWidth -= rCols.GetLeft();
+ else
+ nWidth -= rCols[nNum-1];
+ }
+ }
+ else
+ {
+ SwTwips nRValid = nNum < GetColCount( rCols ) ?
+ rCols[GetRightSeparator( rCols, nNum )]:
+ rCols.GetRight();
+ SwTwips nLValid = nNum ?
+ rCols[GetRightSeparator( rCols, nNum - 1 )]:
+ rCols.GetLeft();
+ nWidth = nRValid - nLValid;
+ }
+ }
+ else
+ nWidth = rCols.GetRight();
+
+ return nWidth;
+}
+
+void SwVbaTableHelper::SetColWidth( sal_Int32 _width, sal_Int32 nCol, sal_Int32 nRow, bool bCurRowOnly )
+{
+ double dAbsWidth = Millimeter::getInHundredthsOfOneMillimeter( _width );
+ sal_Int32 nTableWidth = getTableWidth( );
+ if (!nTableWidth)
+ throw uno::RuntimeException();
+ sal_Int32 nNewWidth = dAbsWidth/nTableWidth * UNO_TABLE_COLUMN_SUM;
+
+ SwTableBox* pStart = GetTabBox( nCol, nRow );
+ SwTabCols aOldCols;
+ InitTabCols( aOldCols, pStart );
+
+ SwTabCols aCols( aOldCols );
+ if ( aCols.Count() > 0 )
+ {
+ SwTwips nWidth = GetColWidth( aCols, nCol);
+
+ int nDiff = nNewWidth - nWidth;
+ if( !nCol )
+ aCols[ GetRightSeparator(aCols, 0) ] += nDiff;
+ else if( nCol < GetColCount( aCols ) )
+ {
+ if(nDiff < GetColWidth( aCols, nCol + 1) - MINLAY)
+ aCols[ GetRightSeparator( aCols, nCol ) ] += nDiff;
+ else
+ {
+ int nDiffLeft = nDiff - static_cast<int>(GetColWidth( aCols, nCol + 1)) + int(MINLAY);
+ aCols[ GetRightSeparator( aCols, nCol ) ] += (nDiff - nDiffLeft);
+ aCols[ GetRightSeparator( aCols, nCol - 1 ) ] -= nDiffLeft;
+ }
+ }
+ else
+ aCols[ GetRightSeparator( aCols, nCol-1 ) ] -= nDiff;
+ }
+ else
+ aCols.SetRight( std::min( static_cast<tools::Long>(nNewWidth), aCols.GetRightMax()) );
+
+ m_pTable->SetTabCols(aCols, aOldCols, pStart, bCurRowOnly );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatablehelper.hxx b/sw/source/ui/vba/vbatablehelper.hxx
new file mode 100644
index 0000000000..b3b48dc005
--- /dev/null
+++ b/sw/source/ui/vba/vbatablehelper.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLEHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLEHELPER_HXX
+
+#include <com/sun/star/text/XTextTable.hpp>
+#include <swtable.hxx>
+#include <tabcol.hxx>
+
+class SwVbaTableHelper
+{
+private:
+ css::uno::Reference< css::text::XTextTable > mxTextTable;
+ SwTable* m_pTable;
+
+private:
+ /// @throws css::uno::RuntimeException
+ SwTableBox* GetTabBox( sal_Int32 nCol, sal_Int32 nRow );
+ void InitTabCols( SwTabCols& rCols, const SwTableBox *pStart );
+ static sal_Int32 GetRightSeparator( SwTabCols const & rCols, sal_Int32 nNum);
+ static sal_Int32 GetColCount( SwTabCols const & rCols );
+ /// @throws css::uno::RuntimeException
+ static sal_Int32 GetColWidth( SwTabCols& rCols, sal_Int32 nNum );
+
+public:
+ /// @throws css::uno::RuntimeException
+ explicit SwVbaTableHelper( css::uno::Reference< css::text::XTextTable > xTextTable );
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getTabColumnsCount( sal_Int32 nRowIndex );
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getTabColumnsMaxCount( );
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getTabRowIndex( const OUString& sCellName );
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getTabColIndex( const OUString& sCellName );
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getTableWidth( ) const;
+
+ /// @throws css::uno::RuntimeException
+ sal_Int32 GetColWidth( sal_Int32 nCol, sal_Int32 nRow = 0 );
+ /// @throws css::uno::RuntimeException
+ void SetColWidth( sal_Int32 _width, sal_Int32 nCol, sal_Int32 nRow = 0, bool bCurRowOnly = false );
+
+ /// @throws css::uno::RuntimeException
+ static SwTable* GetSwTable( const css::uno::Reference< css::text::XTextTable >& xTextTable );
+ static OUString getColumnStr( sal_Int32 nCol );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatableofcontents.cxx b/sw/source/ui/vba/vbatableofcontents.cxx
new file mode 100644
index 0000000000..e0d80cfb1c
--- /dev/null
+++ b/sw/source/ui/vba/vbatableofcontents.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 "vbatableofcontents.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <ooo/vba/word/WdTabLeader.hpp>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaTableOfContents::SwVbaTableOfContents( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, uno::Reference< text::XTextDocument > xDoc, uno::Reference< text::XDocumentIndex > xDocumentIndex ) :
+ SwVbaTableOfContents_BASE( rParent, rContext ), mxTextDocument(std::move( xDoc )), mxDocumentIndex(std::move( xDocumentIndex ))
+{
+ mxTocProps.set( mxDocumentIndex, uno::UNO_QUERY_THROW );
+}
+
+SwVbaTableOfContents::~SwVbaTableOfContents()
+{
+}
+
+::sal_Int32 SAL_CALL SwVbaTableOfContents::getLowerHeadingLevel()
+{
+ sal_Int16 nLevel = 0;
+ mxTocProps->getPropertyValue("Level") >>= nLevel;
+ return nLevel;
+}
+
+void SAL_CALL SwVbaTableOfContents::setLowerHeadingLevel( ::sal_Int32 _lowerheadinglevel )
+{
+ mxTocProps->setPropertyValue("Level", uno::Any( sal_Int8( _lowerheadinglevel ) ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaTableOfContents::getTabLeader()
+{
+ // not support in Writer
+ return word::WdTabLeader::wdTabLeaderDots;
+}
+
+void SAL_CALL SwVbaTableOfContents::setTabLeader( ::sal_Int32 /*_tableader*/ )
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL SwVbaTableOfContents::getUseFields()
+{
+ bool bUseFields = false;
+ mxTocProps->getPropertyValue("CreateFromMarks") >>= bUseFields;
+ return bUseFields;
+}
+
+void SAL_CALL SwVbaTableOfContents::setUseFields( sal_Bool _useFields )
+{
+ mxTocProps->setPropertyValue("CreateFromMarks", uno::Any( _useFields ) );
+}
+
+sal_Bool SAL_CALL SwVbaTableOfContents::getUseOutlineLevels()
+{
+ bool bUseOutlineLevels = false;
+ mxTocProps->getPropertyValue("CreateFromOutline") >>= bUseOutlineLevels;
+ return bUseOutlineLevels;
+}
+
+void SAL_CALL SwVbaTableOfContents::setUseOutlineLevels( sal_Bool _useOutlineLevels )
+{
+ mxTocProps->setPropertyValue("CreateFromOutline", uno::Any( _useOutlineLevels ) );
+}
+
+void SAL_CALL SwVbaTableOfContents::Delete( )
+{
+ uno::Reference< text::XTextContent > xTextContent( mxDocumentIndex, uno::UNO_QUERY_THROW );
+ mxTextDocument->getText()->removeTextContent( xTextContent );
+}
+
+void SAL_CALL SwVbaTableOfContents::Update( )
+{
+ mxDocumentIndex->update();
+}
+
+OUString
+SwVbaTableOfContents::getServiceImplName()
+{
+ return "SwVbaTableOfContents";
+}
+
+uno::Sequence< OUString >
+SwVbaTableOfContents::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.TableOfContents"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatableofcontents.hxx b/sw/source/ui/vba/vbatableofcontents.hxx
new file mode 100644
index 0000000000..69ccd9394f
--- /dev/null
+++ b/sw/source/ui/vba/vbatableofcontents.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLEOFCONTENTS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLEOFCONTENTS_HXX
+
+#include <ooo/vba/word/XTableOfContents.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XTableOfContents > SwVbaTableOfContents_BASE;
+
+class SwVbaTableOfContents : public SwVbaTableOfContents_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+ css::uno::Reference< css::text::XDocumentIndex > mxDocumentIndex;
+ css::uno::Reference< css::beans::XPropertySet > mxTocProps;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaTableOfContents( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext, css::uno::Reference< css::text::XTextDocument > xDoc, css::uno::Reference< css::text::XDocumentIndex > xDocumentIndex );
+ virtual ~SwVbaTableOfContents() override;
+
+ // Attributes
+ virtual ::sal_Int32 SAL_CALL getLowerHeadingLevel() override;
+ virtual void SAL_CALL setLowerHeadingLevel( ::sal_Int32 _lowerheadinglevel ) override;
+ virtual ::sal_Int32 SAL_CALL getTabLeader() override;
+ virtual void SAL_CALL setTabLeader( ::sal_Int32 _tableader ) override;
+ virtual sal_Bool SAL_CALL getUseFields() override;
+ virtual void SAL_CALL setUseFields( sal_Bool _useFields ) override;
+ virtual sal_Bool SAL_CALL getUseOutlineLevels() override;
+ virtual void SAL_CALL setUseOutlineLevels( sal_Bool _useOutlineLevels ) override;
+
+ // Methods
+ virtual void SAL_CALL Delete( ) override;
+ virtual void SAL_CALL Update( ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABLEOFCONTENTS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatables.cxx b/sw/source/ui/vba/vbatables.cxx
new file mode 100644
index 0000000000..b7aa4cadda
--- /dev/null
+++ b/sw/source/ui/vba/vbatables.cxx
@@ -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 .
+ */
+
+#include "vbatables.hxx"
+#include "vbatable.hxx"
+#include "vbarange.hxx"
+#include "wordvbahelper.hxx"
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace css;
+
+static uno::Reference< container::XIndexAccess > lcl_getTables( const uno::Reference< frame::XModel >& xDoc )
+{
+ uno::Reference< container::XIndexAccess > xTables;
+ uno::Reference< text::XTextTablesSupplier > xSupp( xDoc, uno::UNO_QUERY );
+ if ( xSupp.is() )
+ xTables.set( xSupp->getTextTables(), uno::UNO_QUERY_THROW );
+ return xTables;
+}
+
+static uno::Any lcl_createTable( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xDocument, const uno::Any& aSource )
+{
+ uno::Reference< text::XTextTable > xTextTable( aSource, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextDocument > xTextDocument( xDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< word::XTable > xTable( new SwVbaTable( xParent, xContext, xTextDocument, xTextTable ) );
+ return uno::Any( xTable );
+}
+
+static bool lcl_isInHeaderFooter( const uno::Reference< text::XTextTable >& xTable )
+{
+ uno::Reference< text::XTextContent > xTextContent( xTable, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XText > xText = xTextContent->getAnchor()->getText();
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xText, uno::UNO_QUERY );
+ if ( !xServiceInfo )
+ return false;
+ OUString aImplName = xServiceInfo->getImplementationName();
+ return aImplName == "SwXHeadFootText";
+}
+
+typedef std::vector< uno::Reference< text::XTextTable > > XTextTableVec;
+
+namespace {
+
+class TableCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XNameAccess >
+{
+ XTextTableVec mxTables;
+ XTextTableVec::iterator m_cachePos;
+
+public:
+ explicit TableCollectionHelper( const uno::Reference< frame::XModel >& xDocument )
+ {
+ // only count the tables in the body text, not in the header/footer
+ uno::Reference< container::XIndexAccess > xTables = lcl_getTables( xDocument );
+ sal_Int32 nCount = xTables->getCount();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ uno::Reference< text::XTextTable > xTable( xTables->getByIndex( i ) , uno::UNO_QUERY_THROW );
+ if( !lcl_isInHeaderFooter( xTable ) )
+ mxTables.push_back( xTable );
+ }
+ m_cachePos = mxTables.begin();
+ }
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ return mxTables.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+ uno::Reference< text::XTextTable > xTable( mxTables[ Index ], uno::UNO_SET_THROW );
+ return uno::Any( xTable );
+ }
+ // XElementAccess
+ virtual uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType<text::XTextTable>::get(); }
+ virtual sal_Bool SAL_CALL hasElements( ) override { return getCount() > 0 ; }
+ // XNameAccess
+ virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
+ {
+ if ( !hasByName(aName) )
+ throw container::NoSuchElementException();
+ uno::Reference< text::XTextTable > xTable( *m_cachePos, uno::UNO_SET_THROW );
+ return uno::Any( xTable );
+ }
+ virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
+ {
+ uno::Sequence< OUString > sNames( mxTables.size() );
+ OUString* pString = sNames.getArray();
+ for ( const auto& rxTable : mxTables )
+ {
+ uno::Reference< container::XNamed > xName( rxTable, uno::UNO_QUERY_THROW );
+ *pString = xName->getName();
+ ++pString;
+ }
+ return sNames;
+ }
+ virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
+ {
+ m_cachePos = mxTables.begin();
+ XTextTableVec::iterator it_end = mxTables.end();
+ for ( ; m_cachePos != it_end; ++m_cachePos )
+ {
+ uno::Reference< container::XNamed > xName( *m_cachePos, uno::UNO_QUERY_THROW );
+ if ( aName.equalsIgnoreAsciiCase( xName->getName() ) )
+ break;
+ }
+ return ( m_cachePos != it_end );
+ }
+};
+
+class TableEnumerationImpl : public ::cppu::WeakImplHelper< css::container::XEnumeration >
+{
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< frame::XModel > mxDocument;
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ sal_Int32 mnCurIndex;
+public:
+ TableEnumerationImpl( uno::Reference< XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< frame::XModel > xDocument, uno::Reference< container::XIndexAccess > xIndexAccess ) : mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxDocument(std::move( xDocument )), mxIndexAccess(std::move( xIndexAccess )), mnCurIndex(0)
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( mnCurIndex < mxIndexAccess->getCount() );
+ }
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if ( !hasMoreElements() )
+ throw container::NoSuchElementException();
+ return lcl_createTable( mxParent, mxContext, mxDocument, mxIndexAccess->getByIndex( mnCurIndex++ ) );
+ }
+
+};
+
+}
+
+SwVbaTables::SwVbaTables( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xDocument ) : SwVbaTables_BASE( xParent, xContext , uno::Reference< container::XIndexAccess >( new TableCollectionHelper( xDocument ) ) ), mxDocument( xDocument )
+{
+}
+
+uno::Reference< word::XTable > SAL_CALL
+SwVbaTables::Add( const uno::Reference< word::XRange >& Range, const uno::Any& NumRows, const uno::Any& NumColumns, const uno::Any& /*DefaultTableBehavior*/, const uno::Any& /*AutoFitBehavior*/ )
+{
+ sal_Int32 nCols = 0;
+ sal_Int32 nRows = 0;
+ SwVbaRange* pVbaRange = dynamic_cast< SwVbaRange* >( Range.get() );
+ // Preconditions
+ if ( !( pVbaRange && ( NumRows >>= nRows ) && ( NumColumns >>= nCols ) ) )
+ throw uno::RuntimeException(); // #FIXME better exception??
+ if ( nCols <= 0 || nRows <= 0 )
+ throw uno::RuntimeException(); // #FIXME better exception??
+
+ uno::Reference< frame::XModel > xModel( pVbaRange->getDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< lang::XMultiServiceFactory > xMsf( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextRange > xTextRange = pVbaRange->getXTextRange();
+
+ uno::Reference< text::XTextTable > xTable;
+ xTable.set( xMsf->createInstance("com.sun.star.text.TextTable"), uno::UNO_QUERY_THROW );
+
+ xTable->initialize( nRows, nCols );
+ uno::Reference< text::XText > xText = xTextRange->getText();
+ uno::Reference< text::XTextContent > xContext( xTable, uno::UNO_QUERY_THROW );
+
+ xText->insertTextContent( xTextRange, xContext, true );
+
+ // move the current cursor to the first table cell
+ uno::Reference< table::XCellRange > xCellRange( xTable, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XText> xFirstCellText( xCellRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ word::getXTextViewCursor( mxDocument )->gotoRange( xFirstCellText->getStart(), false );
+
+ uno::Reference< word::XTable > xVBATable( new SwVbaTable( mxParent, mxContext, pVbaRange->getDocument(), xTable ) );
+ return xVBATable;
+}
+
+uno::Reference< container::XEnumeration > SAL_CALL
+SwVbaTables::createEnumeration()
+{
+ return new TableEnumerationImpl( mxParent, mxContext, mxDocument, m_xIndexAccess );
+}
+
+// ScVbaCollectionBaseImpl
+uno::Any
+SwVbaTables::createCollectionObject( const uno::Any& aSource )
+{
+ return lcl_createTable( mxParent, mxContext, mxDocument, aSource );
+}
+
+// XHelperInterface
+OUString
+SwVbaTables::getServiceImplName()
+{
+ return "SwVbaTables";
+}
+
+// XEnumerationAccess
+uno::Type SAL_CALL
+SwVbaTables::getElementType()
+{
+ return cppu::UnoType<word::XTable>::get();
+}
+
+uno::Sequence<OUString>
+SwVbaTables::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Tables"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatables.hxx b/sw/source/ui/vba/vbatables.hxx
new file mode 100644
index 0000000000..ae7de0b00c
--- /dev/null
+++ b/sw/source/ui/vba/vbatables.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 .
+ */
+
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLES_HXX
+
+#include <ooo/vba/word/XTables.hpp>
+#include <vbahelper/vbacollectionimpl.hxx>
+
+typedef CollTestImplHelper< ov::word::XTables > SwVbaTables_BASE;
+
+class SwVbaTables : public SwVbaTables_BASE
+{
+ css::uno::Reference< css::frame::XModel > mxDocument;
+public:
+ SwVbaTables( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::frame::XModel >& xDocument );
+ // XTables
+ virtual css::uno::Reference< ov::word::XTable > SAL_CALL Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& NumRows, const css::uno::Any& NumColumns, const css::uno::Any& DefaultTableBehavior, const css::uno::Any& AutoFitBehavior ) override;
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+ // ScVbaCollectionBaseImpl
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatablesofcontents.cxx b/sw/source/ui/vba/vbatablesofcontents.cxx
new file mode 100644
index 0000000000..8df156fecf
--- /dev/null
+++ b/sw/source/ui/vba/vbatablesofcontents.cxx
@@ -0,0 +1,186 @@
+/* -*- 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 "vbatablesofcontents.hxx"
+#include "vbatableofcontents.hxx"
+#include "vbarange.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+namespace {
+
+class TablesOfContentsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ sal_Int32 m_nIndex;
+
+public:
+ explicit TablesOfContentsEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 )
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex < mxIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if( m_nIndex < mxIndexAccess->getCount() )
+ {
+ return mxIndexAccess->getByIndex( m_nIndex++ );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class TableOfContentsCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ uno::Reference< text::XTextDocument > mxTextDocument;
+ std::vector< uno::Reference< text::XDocumentIndex > > maToc;
+
+public:
+ /// @throws uno::RuntimeException
+ TableOfContentsCollectionHelper( uno::Reference< ov::XHelperInterface > xParent, uno::Reference< uno::XComponentContext > xContext, uno::Reference< text::XTextDocument > xDoc ): mxParent(std::move( xParent )), mxContext(std::move( xContext )), mxTextDocument(std::move( xDoc ))
+ {
+ uno::Reference< text::XDocumentIndexesSupplier > xDocIndexSupp( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xDocIndexes = xDocIndexSupp->getDocumentIndexes();
+ sal_Int32 nCount = xDocIndexes->getCount();
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ uno::Reference< text::XDocumentIndex > xToc( xDocIndexes->getByIndex(i), uno::UNO_QUERY_THROW );
+ if( xToc->getServiceName() == "com.sun.star.text.ContentIndex" )
+ {
+ maToc.push_back( xToc );
+ }
+ }
+ }
+
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ return maToc.size();
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw lang::IndexOutOfBoundsException();
+
+ uno::Reference< text::XDocumentIndex > xToc( maToc[Index], uno::UNO_SET_THROW );
+ return uno::Any( uno::Reference< word::XTableOfContents >( new SwVbaTableOfContents( mxParent, mxContext, mxTextDocument, xToc ) ) );
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XTableOfContents>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new TablesOfContentsEnumWrapper( this );
+ }
+};
+
+}
+
+SwVbaTablesOfContents::SwVbaTablesOfContents( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< text::XTextDocument >& xDoc ) : SwVbaTablesOfContents_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new TableOfContentsCollectionHelper( xParent, xContext, xDoc ) ) ), mxTextDocument( xDoc )
+{
+}
+
+uno::Reference< word::XTableOfContents > SAL_CALL
+SwVbaTablesOfContents::Add( const uno::Reference< word::XRange >& Range, const uno::Any& /*UseHeadingStyles*/, const uno::Any& /*UpperHeadingLevel*/, const uno::Any& LowerHeadingLevel, const uno::Any& UseFields, const uno::Any& /*TableID*/, const uno::Any& /*RightAlignPageNumbers*/, const uno::Any& /*IncludePageNumbers*/, const uno::Any& /*AddedStyles*/, const uno::Any& /*UseHyperlinks*/, const uno::Any& /*HidePageNumbersInWeb*/, const uno::Any& /*UseOutlineLevels*/ )
+{
+ uno::Reference< lang::XMultiServiceFactory > xDocMSF( mxTextDocument, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XDocumentIndex > xDocumentIndex( xDocMSF->createInstance("com.sun.star.text.ContentIndex"), uno::UNO_QUERY_THROW );
+
+ uno::Reference< beans::XPropertySet > xTocProps( xDocumentIndex, uno::UNO_QUERY_THROW );
+ xTocProps->setPropertyValue("IsProtected", uno::Any( false ) );
+
+ uno::Reference< word::XTableOfContents > xToc( new SwVbaTableOfContents( this, mxContext, mxTextDocument, xDocumentIndex ) );
+
+ sal_Int32 nLowerHeadingLevel = 9;
+ if( LowerHeadingLevel.hasValue() )
+ LowerHeadingLevel >>= nLowerHeadingLevel;
+ xToc->setLowerHeadingLevel( nLowerHeadingLevel );
+
+ bool bUseFields = false;
+ if( UseFields.hasValue() )
+ UseFields >>= bUseFields;
+ xToc->setUseFields( bUseFields );
+
+ xToc->setUseOutlineLevels( true );
+
+ SwVbaRange* pVbaRange = dynamic_cast<SwVbaRange*>( Range.get() );
+ if( !pVbaRange )
+ throw uno::RuntimeException();
+
+ uno::Reference< text::XTextRange > xTextRange = pVbaRange->getXTextRange();
+ uno::Reference< text::XText > xText = pVbaRange->getXText();
+ uno::Reference< text::XTextContent > xTextContent( xDocumentIndex, uno::UNO_QUERY_THROW );
+ xText->insertTextContent( xTextRange, xTextContent, false );
+ xToc->Update();
+
+ return xToc;
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaTablesOfContents::getElementType()
+{
+ return cppu::UnoType<word::XTableOfContents>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaTablesOfContents::createEnumeration()
+{
+ return new TablesOfContentsEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+SwVbaTablesOfContents::createCollectionObject( const uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaTablesOfContents::getServiceImplName()
+{
+ return "SwVbaTablesOfContents";
+}
+
+uno::Sequence<OUString>
+SwVbaTablesOfContents::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.TablesOfContents"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatablesofcontents.hxx b/sw/source/ui/vba/vbatablesofcontents.hxx
new file mode 100644
index 0000000000..37048ae1bc
--- /dev/null
+++ b/sw/source/ui/vba/vbatablesofcontents.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABLESOFCONTENTS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABLESOFCONTENTS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XTablesOfContents.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <ooo/vba/word/XTableOfContents.hpp>
+#include <ooo/vba/word/XRange.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XTablesOfContents > SwVbaTablesOfContents_BASE;
+
+class SwVbaTablesOfContents : public SwVbaTablesOfContents_BASE
+{
+private:
+ css::uno::Reference< css::text::XTextDocument > mxTextDocument;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaTablesOfContents( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::text::XTextDocument >& xDoc );
+
+ // Methods
+ virtual css::uno::Reference< ::ooo::vba::word::XTableOfContents > SAL_CALL Add( const css::uno::Reference< ::ooo::vba::word::XRange >& Range, const css::uno::Any& UseHeadingStyles, const css::uno::Any& UpperHeadingLevel, const css::uno::Any& LowerHeadingLevel, const css::uno::Any& UseFields, const css::uno::Any& TableID, const css::uno::Any& RightAlignPageNumbers, const css::uno::Any& IncludePageNumbers, const css::uno::Any& AddedStyles, const css::uno::Any& UseHyperlinks, const css::uno::Any& HidePageNumbersInWeb, const css::uno::Any& UseOutlineLevels ) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaTablesOfContents_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABLESOFCONTENTS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatabstop.cxx b/sw/source/ui/vba/vbatabstop.cxx
new file mode 100644
index 0000000000..8ebfdfa421
--- /dev/null
+++ b/sw/source/ui/vba/vbatabstop.cxx
@@ -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 .
+ */
+#include "vbatabstop.hxx"
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaTabStop::SwVbaTabStop( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext ) : SwVbaTabStop_BASE( rParent, rContext )
+{
+}
+
+SwVbaTabStop::~SwVbaTabStop()
+{
+}
+
+OUString
+SwVbaTabStop::getServiceImplName()
+{
+ return "SwVbaTabStop";
+}
+
+uno::Sequence< OUString >
+SwVbaTabStop::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.TabStop"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatabstop.hxx b/sw/source/ui/vba/vbatabstop.hxx
new file mode 100644
index 0000000000..3be2c29e47
--- /dev/null
+++ b/sw/source/ui/vba/vbatabstop.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOP_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOP_HXX
+
+#include <ooo/vba/word/XTabStop.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl<ooo::vba::word::XTabStop> SwVbaTabStop_BASE;
+
+class SwVbaTabStop : public SwVbaTabStop_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaTabStop(const css::uno::Reference<ooo::vba::XHelperInterface>& rParent,
+ const css::uno::Reference<css::uno::XComponentContext>& rContext);
+ virtual ~SwVbaTabStop() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatabstops.cxx b/sw/source/ui/vba/vbatabstops.cxx
new file mode 100644
index 0000000000..7d2d86824a
--- /dev/null
+++ b/sw/source/ui/vba/vbatabstops.cxx
@@ -0,0 +1,270 @@
+/* -*- 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 "vbatabstops.hxx"
+#include "vbatabstop.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/TabAlign.hpp>
+#include <com/sun/star/style/TabStop.hpp>
+#include <ooo/vba/word/WdTabLeader.hpp>
+#include <ooo/vba/word/WdTabAlignment.hpp>
+#include <basic/sberrors.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/// @throws uno::RuntimeException
+static uno::Sequence< style::TabStop > lcl_getTabStops( const uno::Reference< beans::XPropertySet >& xParaProps )
+{
+ uno::Sequence< style::TabStop > aSeq;
+ xParaProps->getPropertyValue("ParaTabStops") >>= aSeq;
+ return aSeq;
+}
+
+/// @throws uno::RuntimeException
+static void lcl_setTabStops( const uno::Reference< beans::XPropertySet >& xParaProps, const uno::Sequence< style::TabStop >& aSeq )
+{
+ xParaProps->setPropertyValue("ParaTabStops", uno::Any( aSeq ) );
+}
+
+namespace {
+
+class TabStopsEnumWrapper : public EnumerationHelper_BASE
+{
+ uno::Reference< container::XIndexAccess > mxIndexAccess;
+ sal_Int32 m_nIndex;
+
+public:
+ explicit TabStopsEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : mxIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 )
+ {
+ }
+ virtual sal_Bool SAL_CALL hasMoreElements( ) override
+ {
+ return ( m_nIndex < mxIndexAccess->getCount() );
+ }
+
+ virtual uno::Any SAL_CALL nextElement( ) override
+ {
+ if( m_nIndex < mxIndexAccess->getCount() )
+ {
+ return mxIndexAccess->getByIndex( m_nIndex++ );
+ }
+ throw container::NoSuchElementException();
+ }
+};
+
+class TabStopCollectionHelper : public ::cppu::WeakImplHelper< container::XIndexAccess,
+ container::XEnumerationAccess >
+{
+private:
+ uno::Reference< XHelperInterface > mxParent;
+ uno::Reference< uno::XComponentContext > mxContext;
+ sal_Int32 mnTabStops;
+
+public:
+ /// @throws css::uno::RuntimeException
+ TabStopCollectionHelper( css::uno::Reference< ov::XHelperInterface > xParent, css::uno::Reference< css::uno::XComponentContext > xContext, const css::uno::Reference< css::beans::XPropertySet >& xParaProps ): mxParent(std::move( xParent )), mxContext(std::move( xContext )), mnTabStops(lcl_getTabStops( xParaProps ).getLength())
+ {
+ }
+
+ virtual sal_Int32 SAL_CALL getCount( ) override
+ {
+ return mnTabStops;
+ }
+ virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override
+ {
+ if ( Index < 0 || Index >= getCount() )
+ throw css::lang::IndexOutOfBoundsException();
+
+ return uno::Any( uno::Reference< word::XTabStop >( new SwVbaTabStop( mxParent, mxContext ) ) );
+ }
+ virtual uno::Type SAL_CALL getElementType( ) override
+ {
+ return cppu::UnoType<word::XTabStop>::get();
+ }
+ virtual sal_Bool SAL_CALL hasElements( ) override
+ {
+ return true;
+ }
+ // XEnumerationAccess
+ virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
+ {
+ return new TabStopsEnumWrapper( this );
+ }
+};
+
+}
+
+SwVbaTabStops::SwVbaTabStops( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertySet >& xParaProps ) : SwVbaTabStops_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new TabStopCollectionHelper( xParent, xContext, xParaProps ) ) ), mxParaProps( xParaProps )
+{
+}
+
+uno::Reference< word::XTabStop > SAL_CALL SwVbaTabStops::Add( float Position, const uno::Any& Alignment, const uno::Any& Leader )
+{
+ sal_Int32 nPosition = Millimeter::getInHundredthsOfOneMillimeter( Position );
+
+ style::TabAlign nAlign = style::TabAlign_LEFT;
+ if( Alignment.hasValue() )
+ {
+ sal_Int32 wdAlign = word::WdTabAlignment::wdAlignTabLeft;
+ Alignment >>= wdAlign;
+ switch( wdAlign )
+ {
+ case word::WdTabAlignment::wdAlignTabLeft:
+ {
+ nAlign = style::TabAlign_LEFT;
+ break;
+ }
+ case word::WdTabAlignment::wdAlignTabRight:
+ {
+ nAlign = style::TabAlign_RIGHT;
+ break;
+ }
+ case word::WdTabAlignment::wdAlignTabCenter:
+ {
+ nAlign = style::TabAlign_CENTER;
+ break;
+ }
+ case word::WdTabAlignment::wdAlignTabDecimal:
+ {
+ nAlign = style::TabAlign_DECIMAL;
+ break;
+ }
+ case word::WdTabAlignment::wdAlignTabBar:
+ case word::WdTabAlignment::wdAlignTabList:
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_NOT_IMPLEMENTED, {} );
+ break;
+ }
+ default:
+ {
+ //left
+ }
+ }
+ }
+
+ sal_Unicode cLeader = ' '; // default is space
+ if( Leader.hasValue() )
+ {
+ sal_Int32 wdLeader = word::WdTabLeader::wdTabLeaderSpaces;
+ Leader >>= wdLeader;
+ switch( wdLeader )
+ {
+ case word::WdTabLeader::wdTabLeaderSpaces:
+ {
+ cLeader = ' ';
+ break;
+ }
+ case word::WdTabLeader::wdTabLeaderMiddleDot:
+ {
+ cLeader = 183; // U+00B7 MIDDLE DOT
+ break;
+ }
+ case word::WdTabLeader::wdTabLeaderDots:
+ {
+ cLeader = '.';
+ break;
+ }
+ case word::WdTabLeader::wdTabLeaderDashes:
+ case word::WdTabLeader::wdTabLeaderHeavy:
+ case word::WdTabLeader::wdTabLeaderLines:
+ {
+ cLeader = '_';
+ break;
+ }
+ default:
+ {
+ //left
+ }
+ }
+ }
+
+ style::TabStop aTab;
+ aTab.Position = nPosition;
+ aTab.Alignment = nAlign;
+ aTab.DecimalChar = '.'; // default value
+ aTab.FillChar = cLeader;
+
+ uno::Sequence< style::TabStop > aOldTabs = lcl_getTabStops( mxParaProps );
+ auto [begin, end] = asNonConstRange(aOldTabs);
+
+ style::TabStop* pOldTab = std::find_if(begin, end,
+ [nPosition](const style::TabStop& rTab) { return rTab.Position == nPosition; });
+ bool bOverWriter = pOldTab != end;
+ if( bOverWriter )
+ {
+ *pOldTab = aTab;
+ lcl_setTabStops( mxParaProps, aOldTabs );
+ }
+ else
+ {
+ sal_Int32 nTabs = aOldTabs.getLength();
+ uno::Sequence< style::TabStop > aNewTabs( nTabs + 1 );
+
+ auto it = aNewTabs.getArray();
+ *it = aTab;
+ std::copy(begin, end, std::next(it));
+ lcl_setTabStops( mxParaProps, aNewTabs );
+ }
+
+ return uno::Reference< word::XTabStop >( new SwVbaTabStop( this, mxContext ) );
+}
+
+void SAL_CALL SwVbaTabStops::ClearAll()
+{
+ uno::Sequence< style::TabStop > aSeq;
+ lcl_setTabStops( mxParaProps, aSeq );
+}
+
+// XEnumerationAccess
+uno::Type
+SwVbaTabStops::getElementType()
+{
+ return cppu::UnoType<word::XTabStop>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaTabStops::createEnumeration()
+{
+ return new TabStopsEnumWrapper( m_xIndexAccess );
+}
+
+uno::Any
+SwVbaTabStops::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+OUString
+SwVbaTabStops::getServiceImplName()
+{
+ return "SwVbaTabStops";
+}
+
+css::uno::Sequence<OUString>
+SwVbaTabStops::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.TabStops"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatabstops.hxx b/sw/source/ui/vba/vbatabstops.hxx
new file mode 100644
index 0000000000..66a163d492
--- /dev/null
+++ b/sw/source/ui/vba/vbatabstops.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOPS_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOPS_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XTabStops.hpp>
+#include <ooo/vba/word/XTabStop.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XTabStops > SwVbaTabStops_BASE;
+
+class SwVbaTabStops : public SwVbaTabStops_BASE
+{
+private:
+ css::uno::Reference< css::beans::XPropertySet > mxParaProps;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaTabStops( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& xParaProps );
+
+ // Methods
+ virtual css::uno::Reference< ::ooo::vba::word::XTabStop > SAL_CALL Add( float Position, const css::uno::Any& Alignment, const css::uno::Any& Leader ) override;
+ virtual void SAL_CALL ClearAll( ) override;
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaTabStops_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATABSTOPS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatemplate.cxx b/sw/source/ui/vba/vbatemplate.cxx
new file mode 100644
index 0000000000..f05b699187
--- /dev/null
+++ b/sw/source/ui/vba/vbatemplate.cxx
@@ -0,0 +1,129 @@
+/* -*- 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 "vbatemplate.hxx"
+#include "vbaautotextentry.hxx"
+#include <com/sun/star/text/AutoTextContainer.hpp>
+#include <comphelper/processfactory.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/character.hxx>
+#include <osl/file.hxx>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+static OUString lcl_CheckGroupName( std::u16string_view aGroupName )
+{
+ OUStringBuffer sRet(aGroupName.size());
+ //group name should contain only A-Z and a-z and spaces
+ for( size_t i = 0; i < aGroupName.size(); i++ )
+ {
+ sal_Unicode cChar = aGroupName[i];
+ if (rtl::isAsciiAlphanumeric(cChar) ||
+ cChar == '_' || cChar == 0x20)
+ {
+ sRet.append(cChar);
+ }
+ }
+ sRet.strip(' ');
+ return sRet.makeStringAndClear();
+}
+
+SwVbaTemplate::SwVbaTemplate( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, OUString aFullUrl )
+ : SwVbaTemplate_BASE( rParent, rContext ), msFullUrl(std::move( aFullUrl ))
+{
+}
+
+SwVbaTemplate::~SwVbaTemplate()
+{
+}
+
+OUString
+SwVbaTemplate::getName()
+{
+ OUString sName;
+ if( !msFullUrl.isEmpty() )
+ {
+ INetURLObject aURL( msFullUrl );
+ ::osl::File::getSystemPathFromFileURL( aURL.GetLastName(), sName );
+ }
+ return sName;
+}
+
+OUString
+SwVbaTemplate::getPath()
+{
+ OUString sPath;
+ if( !msFullUrl.isEmpty() )
+ {
+ INetURLObject aURL( msFullUrl );
+ OUString sURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ) );
+ sURL = sURL.copy( 0, sURL.getLength() - aURL.GetLastName().getLength() - 1 );
+ ::osl::File::getSystemPathFromFileURL( sURL, sPath );
+ }
+ return sPath;
+}
+
+uno::Any SAL_CALL
+SwVbaTemplate::AutoTextEntries( const uno::Any& index )
+{
+ uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+ uno::Reference< text::XAutoTextContainer2 > xAutoTextContainer = text::AutoTextContainer::create( xContext );
+
+ // the default template is "Normal.dot" in Word.
+ OUString sGroup("Normal");
+ OUString sName = getName();
+ sal_Int32 nIndex = sName.lastIndexOf( '.' );
+ if( nIndex > 0 )
+ {
+ sGroup = sName.copy( 0, sName.lastIndexOf( '.' ) );
+ }
+ OUString sNewGroup = lcl_CheckGroupName( sGroup );
+
+ uno::Reference< container::XIndexAccess > xGroup;
+ if( !xAutoTextContainer->hasByName( sNewGroup ) )
+ {
+ throw uno::RuntimeException("Auto Text Entry doesn't exist" );
+ }
+
+ xGroup.set( xAutoTextContainer->getByName( sNewGroup ), uno::UNO_QUERY_THROW );
+
+ uno::Reference< XCollection > xCol( new SwVbaAutoTextEntries( this, mxContext, xGroup ) );
+ if( index.hasValue() )
+ return xCol->Item( index, uno::Any() );
+ return uno::Any( xCol );
+}
+
+OUString
+SwVbaTemplate::getServiceImplName()
+{
+ return "SwVbaTemplate";
+}
+
+uno::Sequence< OUString >
+SwVbaTemplate::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Template"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbatemplate.hxx b/sw/source/ui/vba/vbatemplate.hxx
new file mode 100644
index 0000000000..146684b18c
--- /dev/null
+++ b/sw/source/ui/vba/vbatemplate.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBATEMPLATE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBATEMPLATE_HXX
+
+#include <ooo/vba/word/XTemplate.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XTemplate > SwVbaTemplate_BASE;
+
+class SwVbaTemplate : public SwVbaTemplate_BASE
+{
+private:
+ OUString msFullUrl;
+public:
+ SwVbaTemplate( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext,
+ OUString );
+ virtual ~SwVbaTemplate() override;
+
+ // XTemplate
+ virtual OUString SAL_CALL getName() override;
+ virtual OUString SAL_CALL getPath() override;
+ virtual css::uno::Any SAL_CALL AutoTextEntries( const css::uno::Any& index ) override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBATEMPLATE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbavariable.cxx b/sw/source/ui/vba/vbavariable.cxx
new file mode 100644
index 0000000000..dea82686e1
--- /dev/null
+++ b/sw/source/ui/vba/vbavariable.cxx
@@ -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 .
+ */
+#include "vbavariable.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <utility>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwVbaVariable::SwVbaVariable( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,
+ uno::Reference< beans::XPropertyAccess > xUserDefined, OUString aVariableName ) :
+ SwVbaVariable_BASE( rParent, rContext ), mxUserDefined(std::move( xUserDefined )), maVariableName(std::move( aVariableName ))
+{
+}
+
+SwVbaVariable::~SwVbaVariable()
+{
+}
+
+OUString SAL_CALL
+SwVbaVariable::getName()
+{
+ return maVariableName;
+}
+
+void SAL_CALL
+SwVbaVariable::setName( const OUString& )
+{
+ throw uno::RuntimeException(" Fail to set name" );
+}
+
+uno::Any SAL_CALL
+SwVbaVariable::getValue()
+{
+ uno::Reference< beans::XPropertySet > xProp( mxUserDefined, uno::UNO_QUERY_THROW );
+ return xProp->getPropertyValue( maVariableName );
+}
+
+void SAL_CALL
+SwVbaVariable::setValue( const uno::Any& rValue )
+{
+ // FIXME: fail to set the value if the new type of value is different from the original one.
+ uno::Reference< beans::XPropertySet > xProp( mxUserDefined, uno::UNO_QUERY_THROW );
+ xProp->setPropertyValue( maVariableName, rValue );
+}
+
+sal_Int32 SAL_CALL
+SwVbaVariable::getIndex()
+{
+ const uno::Sequence< beans::PropertyValue > props = mxUserDefined->getPropertyValues();
+ auto pProp = std::find_if(props.begin(), props.end(),
+ [this](const beans::PropertyValue& rProp) { return rProp.Name == maVariableName; });
+ if (pProp != props.end())
+ return static_cast<sal_Int32>(std::distance(props.begin(), pProp)) + 1;
+
+ return 0;
+}
+
+OUString
+SwVbaVariable::getServiceImplName()
+{
+ return "SwVbaVariable";
+}
+
+uno::Sequence< OUString >
+SwVbaVariable::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Variable"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbavariable.hxx b/sw/source/ui/vba/vbavariable.hxx
new file mode 100644
index 0000000000..6b3ab37c78
--- /dev/null
+++ b/sw/source/ui/vba/vbavariable.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLE_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLE_HXX
+
+#include <ooo/vba/word/XVariable.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XVariable > SwVbaVariable_BASE;
+
+class SwVbaVariable : public SwVbaVariable_BASE
+{
+private:
+ css::uno::Reference< css::beans::XPropertyAccess > mxUserDefined;
+ OUString maVariableName;
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaVariable( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext,
+ css::uno::Reference< css::beans::XPropertyAccess > xUserDefined, OUString aName );
+ virtual ~SwVbaVariable() override;
+
+ // XVariable
+ virtual OUString SAL_CALL getName() override;
+ virtual void SAL_CALL setName( const OUString& ) override;
+ virtual css::uno::Any SAL_CALL getValue() override;
+ virtual void SAL_CALL setValue( const css::uno::Any& rValue ) override;
+ virtual sal_Int32 SAL_CALL getIndex() override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbavariables.cxx b/sw/source/ui/vba/vbavariables.cxx
new file mode 100644
index 0000000000..6505eb23e0
--- /dev/null
+++ b/sw/source/ui/vba/vbavariables.cxx
@@ -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 .
+ */
+#include "vbavariables.hxx"
+#include "vbavariable.hxx"
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+/// @throws uno::RuntimeException
+static uno::Reference< container::XIndexAccess > createVariablesAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< beans::XPropertyAccess >& xUserDefined )
+{
+ // FIXME: the performance is poor?
+ XNamedObjectCollectionHelper< word::XVariable >::XNamedVec aVariables;
+ const uno::Sequence< beans::PropertyValue > props = xUserDefined->getPropertyValues();
+ sal_Int32 nCount = props.getLength();
+ aVariables.reserve( nCount );
+ std::transform(props.begin(), props.end(), std::back_inserter(aVariables),
+ [&xParent, &xContext, &xUserDefined](const beans::PropertyValue& rProp) -> uno::Reference< word::XVariable > {
+ return uno::Reference< word::XVariable > ( new SwVbaVariable( xParent, xContext, xUserDefined, rProp.Name ) ); });
+
+ uno::Reference< container::XIndexAccess > xVariables( new XNamedObjectCollectionHelper< word::XVariable >( std::move(aVariables) ) );
+ return xVariables;
+}
+
+SwVbaVariables::SwVbaVariables( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext > & xContext, const uno::Reference< beans::XPropertyAccess >& rUserDefined ): SwVbaVariables_BASE( xParent, xContext, createVariablesAccess( xParent, xContext, rUserDefined ) ), mxUserDefined( rUserDefined )
+{
+}
+// XEnumerationAccess
+uno::Type
+SwVbaVariables::getElementType()
+{
+ return cppu::UnoType<word::XVariable>::get();
+}
+uno::Reference< container::XEnumeration >
+SwVbaVariables::createEnumeration()
+{
+ uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
+ return xEnumerationAccess->createEnumeration();
+}
+
+uno::Any
+SwVbaVariables::createCollectionObject( const css::uno::Any& aSource )
+{
+ return aSource;
+}
+
+uno::Any SAL_CALL
+SwVbaVariables::Add( const OUString& rName, const uno::Any& rValue )
+{
+ uno::Any aValue;
+ if( rValue.hasValue() )
+ aValue = rValue;
+ else
+ aValue <<= OUString();
+ uno::Reference< beans::XPropertyContainer > xPropertyContainer( mxUserDefined, uno::UNO_QUERY_THROW );
+ xPropertyContainer->addProperty( rName, beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::REMOVABLE, aValue );
+
+ return uno::Any( uno::Reference< word::XVariable >( new SwVbaVariable( getParent(), mxContext, mxUserDefined, rName ) ) );
+}
+
+OUString
+SwVbaVariables::getServiceImplName()
+{
+ return "SwVbaVariables";
+}
+
+css::uno::Sequence<OUString>
+SwVbaVariables::getServiceNames()
+{
+ static uno::Sequence< OUString > const sNames
+ {
+ "ooo.vba.word.Variables"
+ };
+ return sNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbavariables.hxx b/sw/source/ui/vba/vbavariables.hxx
new file mode 100644
index 0000000000..639c54a33e
--- /dev/null
+++ b/sw/source/ui/vba/vbavariables.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLES_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLES_HXX
+
+#include <vbahelper/vbacollectionimpl.hxx>
+#include <ooo/vba/word/XVariables.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+
+typedef CollTestImplHelper< ooo::vba::word::XVariables > SwVbaVariables_BASE;
+
+class SwVbaVariables : public SwVbaVariables_BASE
+{
+private:
+ css::uno::Reference< css::beans::XPropertyAccess > mxUserDefined;
+
+public:
+ SwVbaVariables( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertyAccess >& rUserDefined );
+
+ // XEnumerationAccess
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override;
+
+ // SwVbaVariables_BASE
+ virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) override;
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+
+ // XVariables
+ virtual css::uno::Any SAL_CALL Add( const OUString& rName, const css::uno::Any& rValue ) override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAVARIABLES_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaview.cxx b/sw/source/ui/vba/vbaview.cxx
new file mode 100644
index 0000000000..822c4f93e5
--- /dev/null
+++ b/sw/source/ui/vba/vbaview.cxx
@@ -0,0 +1,399 @@
+/* -*- 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 "vbaview.hxx"
+#include <utility>
+#include <vbahelper/vbahelper.hxx>
+#include <basic/sberrors.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/view/XViewSettingsSupplier.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XFootnotesSupplier.hpp>
+#include <com/sun/star/text/XEndnotesSupplier.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <ooo/vba/word/WdSpecialPane.hpp>
+#include <ooo/vba/word/WdViewType.hpp>
+#include <ooo/vba/word/WdSeekView.hpp>
+
+#include "wordvbahelper.hxx"
+#include "vbaheaderfooterhelper.hxx"
+#include <view.hxx>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+const sal_Int32 DEFAULT_BODY_DISTANCE = 500;
+
+SwVbaView::SwVbaView( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext,
+ uno::Reference< frame::XModel > xModel ) :
+ SwVbaView_BASE( rParent, rContext ), mxModel(std::move( xModel ))
+{
+ uno::Reference< frame::XController > xController = mxModel->getCurrentController();
+
+ uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupp( xController, uno::UNO_QUERY_THROW );
+ mxViewCursor = xTextViewCursorSupp->getViewCursor();
+
+ uno::Reference< view::XViewSettingsSupplier > xViewSettingSupp( xController, uno::UNO_QUERY_THROW );
+ mxViewSettings.set( xViewSettingSupp->getViewSettings(), uno::UNO_SET_THROW );
+}
+
+SwVbaView::~SwVbaView()
+{
+}
+
+sal_Bool SwVbaView::getShowAll()
+{
+ bool bShowFormattingMarks = false;
+ mxViewSettings->getPropertyValue("ShowNonprintingCharacters") >>= bShowFormattingMarks;
+ return bShowFormattingMarks;
+}
+
+void SwVbaView::setShowAll(sal_Bool bSet)
+{
+ mxViewSettings->setPropertyValue("ShowNonprintingCharacters", uno::Any(bSet));
+}
+
+::sal_Int32 SAL_CALL
+SwVbaView::getSeekView()
+{
+ // FIXME: if the view cursor is in table, field, section and frame
+ // handle if the cursor is in table
+ uno::Reference< text::XText > xCurrentText = mxViewCursor->getText();
+ uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextContent > xTextContent;
+ while( xCursorProps->getPropertyValue("TextTable") >>= xTextContent )
+ {
+ xCurrentText = xTextContent->getAnchor()->getText();
+ xCursorProps.set( xCurrentText->createTextCursor(), uno::UNO_QUERY_THROW );
+ }
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xCurrentText, uno::UNO_QUERY_THROW );
+ OUString aImplName = xServiceInfo->getImplementationName();
+ if ( aImplName == "SwXBodyText" )
+ {
+ return word::WdSeekView::wdSeekMainDocument;
+ }
+ else if ( aImplName == "SwXHeadFootText" )
+ {
+ if( HeaderFooterHelper::isHeader( mxModel ) )
+ {
+ if( HeaderFooterHelper::isFirstPageHeader( mxModel ) )
+ return word::WdSeekView::wdSeekFirstPageHeader;
+ else if( HeaderFooterHelper::isEvenPagesHeader( mxModel ) )
+ return word::WdSeekView::wdSeekEvenPagesHeader;
+ else
+ return word::WdSeekView::wdSeekPrimaryHeader;
+ }
+ else
+ {
+ if( HeaderFooterHelper::isFirstPageFooter( mxModel ) )
+ return word::WdSeekView::wdSeekFirstPageFooter;
+ else if( HeaderFooterHelper::isEvenPagesFooter( mxModel ) )
+ return word::WdSeekView::wdSeekEvenPagesFooter;
+ else
+ return word::WdSeekView::wdSeekPrimaryFooter;
+ }
+ }
+ else if ( aImplName == "SwXFootnote" )
+ {
+ if( xServiceInfo->supportsService("com.sun.star.text.Endnote") )
+ return word::WdSeekView::wdSeekEndnotes;
+ else
+ return word::WdSeekView::wdSeekFootnotes;
+ }
+
+ return word::WdSeekView::wdSeekMainDocument;
+}
+
+void SAL_CALL
+SwVbaView::setSeekView( ::sal_Int32 _seekview )
+{
+ // FIXME: save the current cursor position, if the cursor is in the main
+ // document, so we can jump back to this position, if the macro sets
+ // the ViewMode back to wdSeekMainDocument
+
+ word::gotoSelectedObjectAnchor( mxModel );
+ switch( _seekview )
+ {
+ case word::WdSeekView::wdSeekFirstPageFooter:
+ case word::WdSeekView::wdSeekFirstPageHeader:
+ case word::WdSeekView::wdSeekCurrentPageFooter:
+ case word::WdSeekView::wdSeekCurrentPageHeader:
+ case word::WdSeekView::wdSeekPrimaryFooter:
+ case word::WdSeekView::wdSeekPrimaryHeader:
+ case word::WdSeekView::wdSeekEvenPagesFooter:
+ case word::WdSeekView::wdSeekEvenPagesHeader:
+ {
+ // need to test
+ mxViewCursor->gotoRange( getHFTextRange( _seekview ), false );
+ break;
+ }
+ case word::WdSeekView::wdSeekFootnotes:
+ {
+ uno::Reference< text::XFootnotesSupplier > xFootnotesSupp( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xFootnotes( xFootnotesSupp->getFootnotes(), uno::UNO_SET_THROW );
+ if( xFootnotes->getCount() > 0 )
+ {
+ uno::Reference< text::XText > xText( xFootnotes->getByIndex(0), uno::UNO_QUERY_THROW );
+ mxViewCursor->gotoRange( xText->getStart(), false );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT );
+ }
+ break;
+ }
+ case word::WdSeekView::wdSeekEndnotes:
+ {
+ uno::Reference< text::XEndnotesSupplier > xEndnotesSupp( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XIndexAccess > xEndnotes( xEndnotesSupp->getEndnotes(), uno::UNO_SET_THROW );
+ if( xEndnotes->getCount() > 0 )
+ {
+ uno::Reference< text::XText > xText( xEndnotes->getByIndex(0), uno::UNO_QUERY_THROW );
+ mxViewCursor->gotoRange( xText->getStart(), false );
+ }
+ else
+ {
+ DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT );
+ }
+ break;
+ }
+ case word::WdSeekView::wdSeekMainDocument:
+ {
+ uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XText > xText = xTextDocument->getText();
+ mxViewCursor->gotoRange( word::getFirstObjectPosition( xText ), false );
+ break;
+ }
+ }
+}
+
+::sal_Int32 SAL_CALL
+SwVbaView::getSplitSpecial()
+{
+ return word::WdSpecialPane::wdPaneNone;
+}
+
+void SAL_CALL
+SwVbaView::setSplitSpecial( ::sal_Int32/* _splitspecial */)
+{
+ // not support in Writer
+}
+
+sal_Bool SAL_CALL
+SwVbaView::getTableGridLines()
+{
+ bool bShowTableGridLine = false;
+ mxViewSettings->getPropertyValue("ShowTableBoundaries") >>= bShowTableGridLine;
+ return bShowTableGridLine;
+}
+
+void SAL_CALL
+SwVbaView::setTableGridLines( sal_Bool _tablegridlines )
+{
+ mxViewSettings->setPropertyValue("ShowTableBoundaries", uno::Any( _tablegridlines ) );
+}
+
+::sal_Int32 SAL_CALL
+SwVbaView::getType()
+{
+ // FIXME: handle wdPrintPreview type
+ bool bOnlineLayout = false;
+ mxViewSettings->getPropertyValue("ShowOnlineLayout") >>= bOnlineLayout;
+ return bOnlineLayout ? word::WdViewType::wdWebView : word::WdViewType::wdPrintView;
+}
+
+void SAL_CALL
+SwVbaView::setType( ::sal_Int32 _type )
+{
+ // FIXME: handle wdPrintPreview type
+ switch( _type )
+ {
+ case word::WdViewType::wdPrintView:
+ case word::WdViewType::wdNormalView:
+ {
+ mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::Any( false ) );
+ break;
+ }
+ case word::WdViewType::wdWebView:
+ {
+ mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::Any( true ) );
+ break;
+ }
+ case word::WdViewType::wdPrintPreview:
+ {
+ PrintPreviewHelper( uno::Any(),word::getView( mxModel ) );
+ break;
+ }
+ default:
+ DebugHelper::runtimeexception( ERRCODE_BASIC_NOT_IMPLEMENTED );
+
+ }
+}
+
+uno::Reference< text::XTextRange > SwVbaView::getHFTextRange( sal_Int32 nType )
+{
+ mxModel->lockControllers();
+
+ OUString aPropIsOn;
+ OUString aPropIsShared;
+ OUString aPropBodyDistance;
+ OUString aPropText;
+
+ switch( nType )
+ {
+ case word::WdSeekView::wdSeekCurrentPageFooter:
+ case word::WdSeekView::wdSeekFirstPageFooter:
+ case word::WdSeekView::wdSeekPrimaryFooter:
+ case word::WdSeekView::wdSeekEvenPagesFooter:
+ {
+ aPropIsOn = "FooterIsOn";
+ aPropIsShared = "FooterIsShared";
+ aPropBodyDistance = "FooterBodyDistance";
+ aPropText = "FooterText";
+ break;
+ }
+ case word::WdSeekView::wdSeekCurrentPageHeader:
+ case word::WdSeekView::wdSeekFirstPageHeader:
+ case word::WdSeekView::wdSeekPrimaryHeader:
+ case word::WdSeekView::wdSeekEvenPagesHeader:
+ {
+ aPropIsOn = "HeaderIsOn";
+ aPropIsShared = "HeaderIsShared";
+ aPropBodyDistance = "HeaderBodyDistance";
+ aPropText = "HeaderText";
+ break;
+ }
+ }
+
+ uno::Reference< text::XPageCursor > xPageCursor( mxViewCursor, uno::UNO_QUERY_THROW );
+
+ if( nType == word::WdSeekView::wdSeekFirstPageFooter
+ || nType == word::WdSeekView::wdSeekFirstPageHeader )
+ {
+ xPageCursor->jumpToFirstPage();
+ }
+
+ uno::Reference< style::XStyle > xStyle;
+ uno::Reference< text::XText > xText;
+ switch( nType )
+ {
+ case word::WdSeekView::wdSeekPrimaryFooter:
+ case word::WdSeekView::wdSeekPrimaryHeader:
+ case word::WdSeekView::wdSeekEvenPagesFooter:
+ case word::WdSeekView::wdSeekEvenPagesHeader:
+ {
+ // The primary header is the first header of the section.
+ // If the header is not shared between odd and even pages
+ // the odd page's header is the primary header. If the
+ // first page's header is different from the rest of the
+ // document, it is NOT the primary header ( the next primary
+ // header would be on page 3 )
+ // The even pages' header is only available if the header is
+ // not shared and the current style is applied to a page with
+ // an even page number
+ uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW );
+ OUString aPageStyleName;
+ xCursorProps->getPropertyValue("PageStyleName") >>= aPageStyleName;
+ if ( aPageStyleName == "First Page" )
+ {
+ // go to the beginning of where the next style is used
+ bool hasNextPage = false;
+ xStyle = word::getCurrentPageStyle( mxModel );
+ do
+ {
+ hasNextPage = xPageCursor->jumpToNextPage();
+ }
+ while( hasNextPage && ( xStyle == word::getCurrentPageStyle( mxModel ) ) );
+
+ if( !hasNextPage )
+ DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, {} );
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ xStyle = word::getCurrentPageStyle( mxModel );
+ uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW );
+ bool isOn = false;
+ xPageProps->getPropertyValue( aPropIsOn ) >>= isOn;
+ bool isShared = false;
+ xPageProps->getPropertyValue( aPropIsShared ) >>= isShared;
+ if( !isOn )
+ {
+ xPageProps->setPropertyValue( aPropIsOn, uno::Any( true ) );
+ xPageProps->setPropertyValue( aPropBodyDistance, uno::Any( DEFAULT_BODY_DISTANCE ) );
+ }
+ if( !isShared )
+ {
+ OUString aTempPropText = aPropText;
+ if( nType == word::WdSeekView::wdSeekEvenPagesFooter
+ || nType == word::WdSeekView::wdSeekEvenPagesHeader )
+ {
+ aTempPropText += "Left";
+ }
+ else
+ {
+ aTempPropText += "Right";
+ }
+ xText.set( xPageProps->getPropertyValue( aTempPropText), uno::UNO_QUERY_THROW );
+ }
+ else
+ {
+ if( nType == word::WdSeekView::wdSeekEvenPagesFooter
+ || nType == word::WdSeekView::wdSeekEvenPagesHeader )
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, {} );
+ }
+ xText.set( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW );
+ }
+
+ mxModel->unlockControllers();
+ if( !xText.is() )
+ {
+ DebugHelper::basicexception( ERRCODE_BASIC_INTERNAL_ERROR, {} );
+ }
+ uno::Reference< text::XTextRange > xTextRange = word::getFirstObjectPosition( xText );
+ return xTextRange;
+}
+
+OUString
+SwVbaView::getServiceImplName()
+{
+ return "SwVbaView";
+}
+
+uno::Sequence< OUString >
+SwVbaView::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.View"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbaview.hxx b/sw/source/ui/vba/vbaview.hxx
new file mode 100644
index 0000000000..66cd0db612
--- /dev/null
+++ b/sw/source/ui/vba/vbaview.hxx
@@ -0,0 +1,63 @@
+/* -*- 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 <ooo/vba/word/XView.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XView > SwVbaView_BASE;
+
+class SwVbaView : public SwVbaView_BASE
+{
+private:
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::text::XTextViewCursor > mxViewCursor;
+ css::uno::Reference< css::beans::XPropertySet > mxViewSettings;
+
+ /// @throws css::uno::RuntimeException
+ /// @throws css::script::BasicErrorException
+ css::uno::Reference< css::text::XTextRange > getHFTextRange( sal_Int32 nType );
+
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaView( const css::uno::Reference< ooo::vba::XHelperInterface >& rParent, const css::uno::Reference< css::uno::XComponentContext >& rContext,
+ css::uno::Reference< css::frame::XModel > xModel );
+ virtual ~SwVbaView() override;
+
+ // XView
+ sal_Bool SAL_CALL getShowAll() override;
+ void SAL_CALL setShowAll(sal_Bool bSet) override;
+ virtual ::sal_Int32 SAL_CALL getSeekView() override;
+ virtual void SAL_CALL setSeekView( ::sal_Int32 _seekview ) override;
+ virtual ::sal_Int32 SAL_CALL getSplitSpecial() override;
+ virtual void SAL_CALL setSplitSpecial( ::sal_Int32 _splitspecial ) override;
+ virtual sal_Bool SAL_CALL getTableGridLines() override;
+ virtual void SAL_CALL setTableGridLines( sal_Bool _tablegridlines ) override;
+ virtual ::sal_Int32 SAL_CALL getType() override;
+ virtual void SAL_CALL setType( ::sal_Int32 _type ) override;
+
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbawindow.cxx b/sw/source/ui/vba/vbawindow.cxx
new file mode 100644
index 0000000000..9114f4b8d4
--- /dev/null
+++ b/sw/source/ui/vba/vbawindow.cxx
@@ -0,0 +1,179 @@
+/* -*- 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 <ooo/vba/word/WdWindowState.hpp>
+#include <sal/log.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include "vbawindow.hxx"
+#include "vbadocument.hxx"
+#include "vbaview.hxx"
+#include "vbapanes.hxx"
+#include "vbapane.hxx"
+#include "wordvbahelper.hxx"
+#include <view.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+SwVbaWindow::SwVbaWindow(
+ const uno::Reference< XHelperInterface >& xParent,
+ const uno::Reference< uno::XComponentContext >& xContext,
+ const uno::Reference< frame::XModel >& xModel,
+ const uno::Reference< frame::XController >& xController ) :
+ WindowImpl_BASE( xParent, xContext, xModel, xController )
+{
+}
+
+void
+SwVbaWindow::Activate()
+{
+ rtl::Reference<SwVbaDocument> document( new SwVbaDocument(uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel) );
+
+ document->Activate();
+}
+
+void
+SwVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& RouteDocument )
+{
+ // FIXME: it is incorrect when there are more than 1 windows
+ rtl::Reference<SwVbaDocument> document( new SwVbaDocument(uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), mxContext, m_xModel) );
+ uno::Any FileName;
+ document->Close(SaveChanges, FileName, RouteDocument );
+}
+
+uno::Any SAL_CALL
+SwVbaWindow::getView()
+{
+ return uno::Any( uno::Reference< word::XView >( new SwVbaView( this, mxContext, m_xModel ) ) );
+}
+
+void SAL_CALL SwVbaWindow::setView( const uno::Any& _view )
+{
+ sal_Int32 nType = 0;
+ if( _view >>= nType )
+ {
+ rtl::Reference<SwVbaView> view( new SwVbaView(this, mxContext, m_xModel) );
+ view->setType( nType );
+ }
+}
+
+uno::Any SAL_CALL
+SwVbaWindow::getWindowState()
+{
+ sal_Int32 nwindowState = word::WdWindowState::wdWindowStateNormal;
+ SwView* pView = word::getView( m_xModel );
+ SfxViewFrame& rViewFrame = pView->GetViewFrame();
+ WorkWindow* pWork = static_cast<WorkWindow*>( rViewFrame.GetFrame().GetSystemWindow() );
+ if ( pWork )
+ {
+ if ( pWork -> IsMaximized())
+ nwindowState = word::WdWindowState::wdWindowStateMaximize;
+ else if (pWork -> IsMinimized())
+ nwindowState = word::WdWindowState::wdWindowStateMinimize;
+ }
+ return uno::Any( nwindowState );
+}
+
+void SAL_CALL
+SwVbaWindow::setWindowState( const uno::Any& _windowstate )
+{
+ sal_Int32 nwindowState = word::WdWindowState::wdWindowStateMaximize;
+ _windowstate >>= nwindowState;
+ SwView* pView = word::getView( m_xModel );
+ SfxViewFrame& rViewFrame = pView->GetViewFrame();
+ WorkWindow* pWork = static_cast<WorkWindow*>( rViewFrame.GetFrame().GetSystemWindow() );
+ if ( pWork )
+ {
+ if ( nwindowState == word::WdWindowState::wdWindowStateMaximize )
+ pWork -> Maximize();
+ else if (nwindowState == word::WdWindowState::wdWindowStateMinimize)
+ pWork -> Minimize();
+ else if (nwindowState == word::WdWindowState::wdWindowStateNormal)
+ pWork -> Restore();
+ else
+ SAL_WARN("sw.vba", "Unhandled window state " << nwindowState);
+ }
+}
+
+OUString SAL_CALL
+SwVbaWindow::getCaption()
+{
+ SwView* pView = word::getView( m_xModel );
+ if( !pView )
+ return "";
+
+ uno::Reference< css::beans::XPropertySet > xFrameProps( pView->GetViewFrame().GetFrame().GetFrameInterface()->getController()->getFrame(), uno::UNO_QUERY );
+ if( !xFrameProps.is() )
+ return "";
+
+ OUString sTitle;
+ xFrameProps->getPropertyValue( "Title" ) >>= sTitle;
+
+ return sTitle;
+}
+
+void SAL_CALL
+SwVbaWindow::setCaption( const OUString& _caption )
+{
+ SwView* pView = word::getView( m_xModel );
+ if( !pView )
+ return;
+
+ uno::Reference< css::beans::XPropertySet > xFrameProps( pView->GetViewFrame().GetFrame().GetFrameInterface()->getController()->getFrame(), uno::UNO_QUERY );
+ if( !xFrameProps.is() )
+ return;
+
+ xFrameProps->setPropertyValue( "Title", uno::Any( _caption ) );
+}
+
+uno::Any SAL_CALL
+SwVbaWindow::Panes( const uno::Any& aIndex )
+{
+ uno::Reference< XCollection > xPanes( new SwVbaPanes( this, mxContext, m_xModel ) );
+ if( aIndex.getValueTypeClass() == uno::TypeClass_VOID )
+ return uno::Any( xPanes );
+
+ return xPanes->Item( aIndex, uno::Any() );
+}
+
+uno::Any SAL_CALL
+SwVbaWindow::ActivePane()
+{
+ return uno::Any( uno::Reference< word::XPane >( new SwVbaPane( this, mxContext, m_xModel ) ) );
+}
+
+OUString
+SwVbaWindow::getServiceImplName()
+{
+ return "SwVbaWindow";
+}
+
+uno::Sequence< OUString >
+SwVbaWindow::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.Window"
+ };
+ return aServiceNames;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbawindow.hxx b/sw/source/ui/vba/vbawindow.hxx
new file mode 100644
index 0000000000..ee435b1505
--- /dev/null
+++ b/sw/source/ui/vba/vbawindow.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAWINDOW_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAWINDOW_HXX
+#include <cppuhelper/implbase.hxx>
+#include <ooo/vba/word/XWindow.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vbahelper/vbahelperinterface.hxx>
+#include <vbahelper/vbawindowbase.hxx>
+
+typedef cppu::ImplInheritanceHelper< VbaWindowBase, ov::word::XWindow > WindowImpl_BASE;
+
+class SwVbaWindow : public WindowImpl_BASE
+{
+public:
+ /// @throws css::uno::RuntimeException
+ SwVbaWindow(
+ const css::uno::Reference< ov::XHelperInterface >& xParent,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::frame::XController >& xController );
+
+ // Attributes
+ virtual css::uno::Any SAL_CALL getView() override;
+ virtual void SAL_CALL setView( const css::uno::Any& _view ) override;
+ virtual css::uno::Any SAL_CALL getWindowState() override;
+ virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) override;
+ virtual OUString SAL_CALL getCaption() override;
+ virtual void SAL_CALL setCaption( const OUString& _caption ) override;
+ // Methods
+ virtual void SAL_CALL Activate( ) override;
+ virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& RouteDocument ) override;
+ virtual css::uno::Any SAL_CALL Panes( const css::uno::Any& aIndex ) override;
+ virtual css::uno::Any SAL_CALL ActivePane() override;
+ // XHelperInterface
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAWINDOW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbawordbasic.cxx b/sw/source/ui/vba/vbawordbasic.cxx
new file mode 100644
index 0000000000..f08ed4e0da
--- /dev/null
+++ b/sw/source/ui/vba/vbawordbasic.cxx
@@ -0,0 +1,265 @@
+/* -*- 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 "vbaapplication.hxx"
+#include "vbafilterpropsfromformat.hxx"
+#include "vbamailmerge.hxx"
+#include "vbawordbasic.hxx"
+
+#include <basic/sbx.hxx>
+#include <basic/sbxvar.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <osl/file.hxx>
+#include <sal/log.hxx>
+#include <tools/urlobj.hxx>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <ooo/vba/word/XBookmarks.hpp>
+#include <ooo/vba/word/XDocuments.hpp>
+
+using namespace ::ooo::vba;
+using namespace ::com::sun::star;
+
+SwWordBasic::SwWordBasic(SwVbaApplication* pApp)
+ : mpApp(pApp)
+{
+}
+
+sal_Int32 SAL_CALL SwWordBasic::getMailMergeMainDocumentType()
+{
+ return SwVbaMailMerge::get(mpApp->getParent(), mpApp->getContext())->getMainDocumentType();
+}
+
+void SAL_CALL SwWordBasic::setMailMergeMainDocumentType(sal_Int32 _mailmergemaindocumenttype)
+{
+ SwVbaMailMerge::get(mpApp->getParent(), mpApp->getContext())
+ ->setMainDocumentType(_mailmergemaindocumenttype);
+}
+
+void SAL_CALL SwWordBasic::FileOpen(const OUString& Name, const uno::Any& ConfirmConversions,
+ const uno::Any& ReadOnly, const uno::Any& AddToMru,
+ const uno::Any& PasswordDoc, const uno::Any& PasswordDot,
+ const uno::Any& Revert, const uno::Any& WritePasswordDoc,
+ const uno::Any& WritePasswordDot)
+{
+ uno::Any aDocuments = mpApp->Documents(uno::Any());
+
+ uno::Reference<word::XDocuments> rDocuments;
+
+ if (aDocuments >>= rDocuments)
+ rDocuments->Open(Name, ConfirmConversions, ReadOnly, AddToMru, PasswordDoc, PasswordDot,
+ Revert, WritePasswordDoc, WritePasswordDot, uno::Any(), uno::Any(),
+ uno::Any(), uno::Any(), uno::Any(), uno::Any(), uno::Any());
+}
+
+void SAL_CALL SwWordBasic::FileSave()
+{
+ uno::Reference<frame::XModel> xModel(mpApp->getCurrentDocument(), uno::UNO_SET_THROW);
+ dispatchRequests(xModel, ".uno:Save");
+}
+
+void SAL_CALL SwWordBasic::FileSaveAs(
+ const css::uno::Any& Name, const css::uno::Any& Format, const css::uno::Any& /*LockAnnot*/,
+ const css::uno::Any& /*Password*/, const css::uno::Any& /*AddToMru*/,
+ const css::uno::Any& /*WritePassword*/, const css::uno::Any& /*RecommendReadOnly*/,
+ const css::uno::Any& /*EmbedFonts*/, const css::uno::Any& /*NativePictureFormat*/,
+ const css::uno::Any& /*FormsData*/, const css::uno::Any& /*SaveAsAOCELetter*/)
+{
+ SAL_INFO("sw.vba", "WordBasic.FileSaveAs(Name:=" << Name << ",Format:=" << Format << ")");
+
+ uno::Reference<frame::XModel> xModel(mpApp->getCurrentDocument(), uno::UNO_SET_THROW);
+
+ // Based on SwVbaDocument::SaveAs2000.
+
+ OUString sFileName;
+ Name >>= sFileName;
+
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath(sFileName, sURL);
+
+ // Detect if there is no path then we need to use the current folder.
+ INetURLObject aURL(sURL);
+ sURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
+ if (sURL.isEmpty())
+ {
+ // Need to add cur dir ( of this document ) or else the 'Work' dir
+ sURL = xModel->getURL();
+
+ if (sURL.isEmpty())
+ {
+ // Not path available from 'this' document. Need to add the 'document'/work directory then.
+ // Based on SwVbaOptions::getValueEvent()
+ uno::Reference<util::XPathSettings> xPathSettings
+ = util::thePathSettings::get(comphelper::getProcessComponentContext());
+ OUString sPathUrl;
+ xPathSettings->getPropertyValue("Work") >>= sPathUrl;
+ // Path could be a multipath, Microsoft doesn't support this feature in Word currently.
+ // Only the last path is from interest.
+ // No idea if this crack is relevant for WordBasic or not.
+ sal_Int32 nIndex = sPathUrl.lastIndexOf(';');
+ if (nIndex != -1)
+ {
+ sPathUrl = sPathUrl.copy(nIndex + 1);
+ }
+
+ aURL.SetURL(sPathUrl);
+ }
+ else
+ {
+ aURL.SetURL(sURL);
+ aURL.Append(sFileName);
+ }
+ sURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
+ }
+ sal_Int32 nFileFormat = word::WdSaveFormat::wdFormatDocument;
+ Format >>= nFileFormat;
+
+ uno::Sequence aProps{ comphelper::makePropertyValue("FilterName", css::uno::Any()),
+ comphelper::makePropertyValue("FileName", sURL) };
+
+ setFilterPropsFromFormat(nFileFormat, aProps);
+
+ dispatchRequests(xModel, ".uno:SaveAs", aProps);
+}
+
+void SAL_CALL SwWordBasic::FileClose(const css::uno::Any& Save)
+{
+ uno::Reference<frame::XModel> xModel(mpApp->getCurrentDocument(), uno::UNO_SET_THROW);
+
+ sal_Int16 nSave = 0;
+ if (Save.hasValue() && (Save >>= nSave) && (nSave == 0 || nSave == 1))
+ FileSave();
+
+ // FIXME: Here I would much prefer to call VbaDocumentBase::Close() but not sure how to get at
+ // the VbaDocumentBase of the current document. (Probably it is easy and I haven't looked hard
+ // enough.)
+ //
+ // FIXME: Error handling. If there is no current document, return some kind of error? But for
+ // now, just ignore errors. This code is written to work for a very specific customer use case
+ // anyway, not for an arbitrary sequence of COM calls to the "VBA" API.
+ dispatchRequests(xModel, ".uno:CloseDoc");
+}
+
+void SAL_CALL SwWordBasic::ToolsOptionsView(
+ const css::uno::Any& DraftFont, const css::uno::Any& WrapToWindow,
+ const css::uno::Any& PicturePlaceHolders, const css::uno::Any& FieldCodes,
+ const css::uno::Any& BookMarks, const css::uno::Any& FieldShading,
+ const css::uno::Any& StatusBar, const css::uno::Any& HScroll, const css::uno::Any& VScroll,
+ const css::uno::Any& StyleAreaWidth, const css::uno::Any& Tabs, const css::uno::Any& Spaces,
+ const css::uno::Any& Paras, const css::uno::Any& Hyphens, const css::uno::Any& Hidden,
+ const css::uno::Any& ShowAll, const css::uno::Any& Drawings, const css::uno::Any& Anchors,
+ const css::uno::Any& TextBoundaries, const css::uno::Any& VRuler,
+ const css::uno::Any& Highlight)
+{
+ SAL_INFO("sw.vba", "WordBasic.ToolsOptionsView("
+ "DraftFont:="
+ << DraftFont << ", WrapToWindow:=" << WrapToWindow
+ << ", PicturePlaceHolders:=" << PicturePlaceHolders
+ << ", FieldCodes:=" << FieldCodes << ", BookMarks:=" << BookMarks
+ << ", FieldShading:=" << FieldShading << ", StatusBar:=" << StatusBar
+ << ", HScroll:=" << HScroll << ", VScroll:=" << VScroll
+ << ", StyleAreaWidth:=" << StyleAreaWidth << ", Tabs:=" << Tabs
+ << ", Spaces:=" << Spaces << ", Paras:=" << Paras
+ << ", Hyphens:=" << Hyphens << ", Hidden:=" << Hidden
+ << ", ShowAll:=" << ShowAll << ", Drawings:=" << Drawings
+ << ", Anchors:=" << Anchors << ", TextBoundaries:=" << TextBoundaries
+ << ", VRuler:=" << VRuler << ", Highlight:=" << Highlight << ")");
+}
+
+css::uno::Any SAL_CALL SwWordBasic::WindowName(const css::uno::Any& /*Number*/)
+{
+ return css::uno::Any(mpApp->getActiveSwVbaWindow()->getCaption());
+}
+
+css::uno::Any SAL_CALL SwWordBasic::ExistingBookmark(const OUString& Name)
+{
+ uno::Reference<word::XBookmarks> xBookmarks(mpApp->getActiveDocument()->Bookmarks(uno::Any()),
+ uno::UNO_QUERY);
+ return css::uno::Any(xBookmarks.is() && xBookmarks->Exists(Name));
+}
+
+void SAL_CALL SwWordBasic::MailMergeOpenDataSource(
+ const OUString& Name, const css::uno::Any& Format, const css::uno::Any& ConfirmConversions,
+ const css::uno::Any& ReadOnly, const css::uno::Any& LinkToSource,
+ const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument,
+ const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert,
+ const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate,
+ const css::uno::Any& Connection, const css::uno::Any& SQLStatement,
+ const css::uno::Any& SQLStatement1, const css::uno::Any& OpenExclusive,
+ const css::uno::Any& SubType)
+{
+ mpApp->getActiveDocument()->getMailMerge()->OpenDataSource(
+ Name, Format, ConfirmConversions, ReadOnly, LinkToSource, AddToRecentFiles,
+ PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate,
+ Connection, SQLStatement, SQLStatement1, OpenExclusive, SubType);
+}
+
+css::uno::Any SAL_CALL SwWordBasic::AppMaximize(const css::uno::Any& WindowName,
+ const css::uno::Any& State)
+{
+ SAL_INFO("sw.vba", "WordBasic.AppMaximize( WindowName:=" << WindowName << ", State:=" << State);
+
+ // FIXME: Implement if necessary
+ return css::uno::Any(sal_Int32(0));
+}
+
+css::uno::Any SAL_CALL SwWordBasic::DocMaximize(const css::uno::Any& State)
+{
+ SAL_INFO("sw.vba", "WordBasic.DocMaximize(State:=" << State << ")");
+
+ // FIXME: Implement if necessary
+ return css::uno::Any(sal_Int32(0));
+}
+
+void SAL_CALL SwWordBasic::AppShow(const css::uno::Any& WindowName)
+{
+ SAL_INFO("sw.vba", "WordBasic.AppShow(WindowName:=" << WindowName << ")");
+
+ // FIXME: Implement if necessary
+}
+
+css::uno::Any SAL_CALL SwWordBasic::AppCount()
+{
+ SAL_INFO("sw.vba", "WordBasic.AppCount()");
+
+ // FIXME: Implement if necessary. Return a random number for now.
+ return css::uno::Any(sal_Int32(2));
+}
+
+void SAL_CALL SwWordBasic::MsgBox(const OUString& sPrompt)
+{
+ SbxArrayRef pArgs = new SbxArray;
+ SbxVariable* pVar = new SbxVariable();
+ pVar->PutString(sPrompt);
+ pArgs->Put(pVar, 1);
+
+ if (!executeRunTimeLibrary(u"MsgBox", pArgs.get()))
+ SAL_WARN("sw.vba", "failed to execute runtime library function MsgBox (" << sPrompt << ")");
+}
+
+void SAL_CALL SwWordBasic::ScreenUpdating(const uno::Any& On)
+{
+ sal_Int32 nOn;
+ if (On >>= nOn)
+ mpApp->setScreenUpdating(nOn != 0);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbawordbasic.hxx b/sw/source/ui/vba/vbawordbasic.hxx
new file mode 100644
index 0000000000..05589f0c58
--- /dev/null
+++ b/sw/source/ui/vba/vbawordbasic.hxx
@@ -0,0 +1,95 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAWORDBASIC_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAWORDBASIC_HXX
+
+class SwVbaApplication;
+
+/**
+ * This is a representation of the WordBasic statements and functions
+ * that were available in Word version 6.0 and Word for Windows 95.
+ *
+ * It can be specified as "Application.WordBasic." or "WordBasic.".
+ *
+ * Starting with Word 2000, old macros were automatically converted
+ * into Visual Basic modules, and the WordBasic prefix was added where
+ * no VBA methods precisely corresponded.
+ *
+ * In other words, it is a compatibility shim.
+ */
+class SwWordBasic : public cppu::WeakImplHelper<ooo::vba::word::XWordBasic>
+{
+private:
+ SwVbaApplication* mpApp;
+
+public:
+ SwWordBasic(SwVbaApplication* pApp);
+
+ // XWordBasic
+ virtual sal_Int32 SAL_CALL getMailMergeMainDocumentType() override;
+ virtual void SAL_CALL
+ setMailMergeMainDocumentType(sal_Int32 _mailmergemaindocumenttype) override;
+
+ virtual void SAL_CALL FileOpen(const OUString& Name, const css::uno::Any& ConfirmConversions,
+ const css::uno::Any& ReadOnly, const css::uno::Any& AddToMru,
+ const css::uno::Any& PasswordDoc,
+ const css::uno::Any& PasswordDot, const css::uno::Any& Revert,
+ const css::uno::Any& WritePasswordDoc,
+ const css::uno::Any& WritePasswordDot) override;
+ virtual void SAL_CALL FileSave() override;
+ virtual void SAL_CALL FileSaveAs(
+ const css::uno::Any& Name, const css::uno::Any& Format, const css::uno::Any& LockAnnot,
+ const css::uno::Any& Password, const css::uno::Any& AddToMru,
+ const css::uno::Any& WritePassword, const css::uno::Any& RecommendReadOnly,
+ const css::uno::Any& EmbedFonts, const css::uno::Any& NativePictureFormat,
+ const css::uno::Any& FormsData, const css::uno::Any& SaveAsAOCELetter) override;
+ virtual void SAL_CALL FileClose(const css::uno::Any& Save) override;
+ virtual void SAL_CALL ToolsOptionsView(
+ const css::uno::Any& DraftFont, const css::uno::Any& WrapToWindow,
+ const css::uno::Any& PicturePlaceHolders, const css::uno::Any& FieldCodes,
+ const css::uno::Any& BookMarks, const css::uno::Any& FieldShading,
+ const css::uno::Any& StatusBar, const css::uno::Any& HScroll, const css::uno::Any& VScroll,
+ const css::uno::Any& StyleAreaWidth, const css::uno::Any& Tabs, const css::uno::Any& Spaces,
+ const css::uno::Any& Paras, const css::uno::Any& Hyphens, const css::uno::Any& Hidden,
+ const css::uno::Any& ShowAll, const css::uno::Any& Drawings, const css::uno::Any& Anchors,
+ const css::uno::Any& TextBoundaries, const css::uno::Any& VRuler,
+ const css::uno::Any& Highlight) override;
+ virtual css::uno::Any SAL_CALL WindowName(const css::uno::Any& Number) override;
+ virtual css::uno::Any SAL_CALL ExistingBookmark(const OUString& Name) override;
+ virtual void SAL_CALL MailMergeOpenDataSource(
+ const OUString& Name, const css::uno::Any& Format, const css::uno::Any& ConfirmConversions,
+ const css::uno::Any& ReadOnly, const css::uno::Any& LinkToSource,
+ const css::uno::Any& AddToRecentFiles, const css::uno::Any& PasswordDocument,
+ const css::uno::Any& PasswordTemplate, const css::uno::Any& Revert,
+ const css::uno::Any& WritePasswordDocument, const css::uno::Any& WritePasswordTemplate,
+ const css::uno::Any& Connection, const css::uno::Any& SQLStatement,
+ const css::uno::Any& SQLStatement1, const css::uno::Any& OpenExclusive,
+ const css::uno::Any& SubType) override;
+ virtual css::uno::Any SAL_CALL AppMaximize(const css::uno::Any& WindowName,
+ const css::uno::Any& State) override;
+ virtual css::uno::Any SAL_CALL DocMaximize(const css::uno::Any& State) override;
+ virtual void SAL_CALL AppShow(const css::uno::Any& WindowName) override;
+ virtual css::uno::Any SAL_CALL AppCount() override;
+ virtual void SAL_CALL MsgBox(const OUString& sPrompt) override;
+ virtual void SAL_CALL ScreenUpdating(const css::uno::Any& On) override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAWORDBASIC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbawrapformat.cxx b/sw/source/ui/vba/vbawrapformat.cxx
new file mode 100644
index 0000000000..2aef0523b4
--- /dev/null
+++ b/sw/source/ui/vba/vbawrapformat.cxx
@@ -0,0 +1,243 @@
+/* -*- 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 "vbawrapformat.hxx"
+#include <ooo/vba/word/WdWrapSideType.hpp>
+#include <ooo/vba/word/WdWrapType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <basic/sberrors.hxx>
+#include <vbahelper/vbahelper.hxx>
+
+using namespace ooo::vba;
+using namespace com::sun::star;
+
+SwVbaWrapFormat::SwVbaWrapFormat( uno::Sequence< uno::Any > const& aArgs, uno::Reference< uno::XComponentContext >const& xContext ) : SwVbaWrapFormat_BASE( getXSomethingFromArgs< XHelperInterface >( aArgs, 0 ), xContext ), m_xShape( getXSomethingFromArgs< drawing::XShape >( aArgs, 1, false ) ), mnWrapFormatType( 0 ), mnSide( word::WdWrapSideType::wdWrapBoth )
+{
+ m_xPropertySet.set( m_xShape, uno::UNO_QUERY_THROW );
+}
+
+void SwVbaWrapFormat::makeWrap()
+{
+ text::WrapTextMode eTextMode = text::WrapTextMode_NONE;
+ if( mnSide == word::WdWrapSideType::wdWrapLeft )
+ {
+ eTextMode = text::WrapTextMode_LEFT;
+ }
+ else if( mnSide == word::WdWrapSideType::wdWrapRight )
+ {
+ eTextMode = text::WrapTextMode_RIGHT;
+ }
+ else if( mnSide == word::WdWrapSideType::wdWrapBoth ||
+ mnSide == word::WdWrapSideType::wdWrapLargest )
+ {
+ switch( mnWrapFormatType )
+ {
+ case word::WdWrapType::wdWrapNone:
+ case word::WdWrapType::wdWrapThrough:
+ {
+ eTextMode = text::WrapTextMode_THROUGH;
+ break;
+ }
+ case word::WdWrapType::wdWrapInline:
+ case word::WdWrapType::wdWrapTopBottom:
+ {
+ eTextMode = text::WrapTextMode_NONE;
+ break;
+ }
+ case word::WdWrapType::wdWrapSquare:
+ {
+ eTextMode = text::WrapTextMode_PARALLEL;
+ m_xPropertySet->setPropertyValue("SurroundContour", uno::Any( false ) );
+ break;
+ }
+ case word::WdWrapType::wdWrapTight:
+ {
+ eTextMode = text::WrapTextMode_PARALLEL;
+ m_xPropertySet->setPropertyValue("SurroundContour", uno::Any( true ) );
+ break;
+ }
+ default:
+ {
+ DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT);
+ }
+ }
+ }
+ m_xPropertySet->setPropertyValue("TextWrap", uno::Any( eTextMode ) );
+}
+
+::sal_Int32 SAL_CALL SwVbaWrapFormat::getType()
+{
+ sal_Int32 nType = word::WdWrapType::wdWrapSquare;
+ text::WrapTextMode eTextMode;
+ m_xPropertySet->getPropertyValue("TextWrap") >>= eTextMode;
+ switch( eTextMode )
+ {
+ case text::WrapTextMode_NONE:
+ {
+ nType = word::WdWrapType::wdWrapTopBottom;
+ break;
+ }
+ case text::WrapTextMode_THROUGH:
+ {
+ nType = word::WdWrapType::wdWrapNone;
+ break;
+ }
+ case text::WrapTextMode_PARALLEL:
+ {
+ bool bContour = false;
+ m_xPropertySet->getPropertyValue("SurroundContour") >>= bContour;
+ if( bContour )
+ nType = word::WdWrapType::wdWrapTight;
+ else
+ nType = word::WdWrapType::wdWrapSquare;
+ break;
+ }
+ case text::WrapTextMode_DYNAMIC:
+ case text::WrapTextMode_LEFT:
+ case text::WrapTextMode_RIGHT:
+ {
+ nType = word::WdWrapType::wdWrapThrough;
+ break;
+ }
+ default:
+ {
+ nType = word::WdWrapType::wdWrapSquare;
+ }
+ }
+ return nType;
+}
+
+void SAL_CALL SwVbaWrapFormat::setType( ::sal_Int32 _type )
+{
+ mnWrapFormatType = _type;
+ makeWrap();
+}
+
+::sal_Int32 SAL_CALL SwVbaWrapFormat::getSide()
+{
+ sal_Int32 nSide = word::WdWrapSideType::wdWrapBoth;
+ text::WrapTextMode eTextMode;
+ m_xPropertySet->getPropertyValue("TextWrap") >>= eTextMode;
+ switch( eTextMode )
+ {
+ case text::WrapTextMode_LEFT:
+ {
+ nSide = word::WdWrapSideType::wdWrapLeft;
+ break;
+ }
+ case text::WrapTextMode_RIGHT:
+ {
+ nSide = word::WdWrapSideType::wdWrapRight;
+ break;
+ }
+ default:
+ {
+ nSide = word::WdWrapSideType::wdWrapBoth;
+ }
+ }
+ return nSide;
+}
+
+void SAL_CALL SwVbaWrapFormat::setSide( ::sal_Int32 _side )
+{
+ mnSide = _side;
+ makeWrap();
+}
+
+float SwVbaWrapFormat::getDistance( const OUString& sName )
+{
+ sal_Int32 nDistance = 0;
+ m_xPropertySet->getPropertyValue( sName ) >>= nDistance;
+ return static_cast< float >( Millimeter::getInPoints( nDistance ) );
+}
+
+void SwVbaWrapFormat::setDistance( const OUString& sName, float _distance )
+{
+ sal_Int32 nDistance = Millimeter::getInHundredthsOfOneMillimeter( _distance );
+ m_xPropertySet->setPropertyValue( sName, uno::Any( nDistance ) );
+}
+
+float SAL_CALL SwVbaWrapFormat::getDistanceTop()
+{
+ return getDistance( "TopMargin" );
+}
+
+void SAL_CALL SwVbaWrapFormat::setDistanceTop( float _distancetop )
+{
+ setDistance( "TopMargin", _distancetop );
+}
+
+float SAL_CALL SwVbaWrapFormat::getDistanceBottom()
+{
+ return getDistance( "BottomMargin" );
+}
+
+void SAL_CALL SwVbaWrapFormat::setDistanceBottom( float _distancebottom )
+{
+ setDistance( "BottomMargin", _distancebottom );
+}
+
+float SAL_CALL SwVbaWrapFormat::getDistanceLeft()
+{
+ return getDistance( "LeftMargin" );
+}
+
+void SAL_CALL SwVbaWrapFormat::setDistanceLeft( float _distanceleft )
+{
+ setDistance( "LeftMargin", _distanceleft );
+}
+
+float SAL_CALL SwVbaWrapFormat::getDistanceRight()
+{
+ return getDistance( "RightMargin" );
+}
+
+void SAL_CALL SwVbaWrapFormat::setDistanceRight( float _distanceright )
+{
+ setDistance( "RightMargin", _distanceright );
+}
+
+OUString
+SwVbaWrapFormat::getServiceImplName()
+{
+ return "SwVbaWrapFormat";
+}
+
+uno::Sequence< OUString >
+SwVbaWrapFormat::getServiceNames()
+{
+ static uno::Sequence< OUString > const aServiceNames
+ {
+ "ooo.vba.word.WrapFormat"
+ };
+ return aServiceNames;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Writer_SwVbaWrapFormat_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
+{
+ return cppu::acquire(new SwVbaWrapFormat(args, context));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/vbawrapformat.hxx b/sw/source/ui/vba/vbawrapformat.hxx
new file mode 100644
index 0000000000..ef28118ed9
--- /dev/null
+++ b/sw/source/ui/vba/vbawrapformat.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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_VBAWRAPFORMAT_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_VBAWRAPFORMAT_HXX
+
+#include <com/sun/star/drawing/XShape.hpp>
+#include <ooo/vba/word/XWrapFormat.hpp>
+#include <vbahelper/vbahelperinterface.hxx>
+
+typedef InheritedHelperInterfaceWeakImpl< ooo::vba::word::XWrapFormat > SwVbaWrapFormat_BASE;
+
+class SwVbaWrapFormat : public SwVbaWrapFormat_BASE
+{
+private:
+ css::uno::Reference< css::drawing::XShape > m_xShape;
+ css::uno::Reference< css::beans::XPropertySet > m_xPropertySet;
+ sal_Int32 mnWrapFormatType;
+ sal_Int32 mnSide;
+
+private:
+ /// @throws css::uno::RuntimeException
+ void makeWrap();
+ /// @throws css::uno::RuntimeException
+ float getDistance( const OUString& sName );
+ /// @throws css::uno::RuntimeException
+ void setDistance( const OUString& sName, float _distance );
+
+public:
+ SwVbaWrapFormat( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext );
+
+ virtual ::sal_Int32 SAL_CALL getType() override;
+ virtual void SAL_CALL setType( ::sal_Int32 _type ) override;
+ virtual ::sal_Int32 SAL_CALL getSide() override;
+ virtual void SAL_CALL setSide( ::sal_Int32 _side ) override;
+ virtual float SAL_CALL getDistanceTop() override;
+ virtual void SAL_CALL setDistanceTop( float _distancetop ) override;
+ virtual float SAL_CALL getDistanceBottom() override;
+ virtual void SAL_CALL setDistanceBottom( float _distancebottom ) override;
+ virtual float SAL_CALL getDistanceLeft() override;
+ virtual void SAL_CALL setDistanceLeft( float _distanceleft ) override;
+ virtual float SAL_CALL getDistanceRight() override;
+ virtual void SAL_CALL setDistanceRight( float _distanceright ) override;
+
+ virtual OUString getServiceImplName() override;
+ virtual css::uno::Sequence<OUString> getServiceNames() override;
+};
+
+#endif // INCLUDED_SW_SOURCE_UI_VBA_VBAWRAPFORMAT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/wordvbahelper.cxx b/sw/source/ui/vba/wordvbahelper.cxx
new file mode 100644
index 0000000000..5bf7e26c77
--- /dev/null
+++ b/sw/source/ui/vba/wordvbahelper.cxx
@@ -0,0 +1,176 @@
+/* -*- 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 <docsh.hxx>
+#include "wordvbahelper.hxx"
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <unotxdoc.hxx>
+#include <doc.hxx>
+#include <IDocumentLayoutAccess.hxx>
+#include <view.hxx>
+#include <viewsh.hxx>
+#include <comphelper/servicehelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::ooo::vba;
+
+namespace ooo::vba::word
+{
+
+SwDocShell* getDocShell( const uno::Reference< frame::XModel>& xModel )
+{
+ uno::Reference< lang::XUnoTunnel > xTunnel( xModel, uno::UNO_QUERY_THROW );
+ SwXTextDocument* pXDoc = comphelper::getFromUnoTunnel<SwXTextDocument>(xTunnel);
+ return pXDoc ? pXDoc->GetDocShell() : nullptr;
+}
+
+SwView* getView( const uno::Reference< frame::XModel>& xModel )
+{
+ SwDocShell* pDocShell = getDocShell( xModel );
+ return pDocShell? pDocShell->GetView() : nullptr;
+}
+
+uno::Reference< text::XTextViewCursor > getXTextViewCursor( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< frame::XController > xController = xModel->getCurrentController();
+ uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupp( xController, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextViewCursor > xTextViewCursor = xTextViewCursorSupp->getViewCursor();
+ return xTextViewCursor;
+}
+
+uno::Reference< style::XStyle > getCurrentPageStyle( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< beans::XPropertySet > xCursorProps( getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+ return getCurrentPageStyle( xModel, xCursorProps );
+}
+
+uno::Reference< style::XStyle > getCurrentPageStyle( const uno::Reference< frame::XModel >& xModel, const uno::Reference< beans::XPropertySet >& xProps )
+{
+ OUString aPageStyleName;
+ xProps->getPropertyValue("PageStyleName") >>= aPageStyleName;
+ uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW );
+ uno::Reference< container::XNameAccess > xPageStyles( xSytleFamNames->getByName("PageStyles"), uno::UNO_QUERY_THROW );
+ uno::Reference< style::XStyle > xStyle( xPageStyles->getByName( aPageStyleName ), uno::UNO_QUERY_THROW );
+
+ return xStyle;
+}
+
+sal_Int32 getPageCount( const uno::Reference< frame::XModel>& xModel )
+{
+ SwDocShell* pDocShell = getDocShell( xModel );
+ SwViewShell* pViewSh = pDocShell ? pDocShell->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() : nullptr;
+ return pViewSh ? pViewSh->GetPageCount() : 0;
+}
+
+uno::Reference< style::XStyle > getDefaultParagraphStyle( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< style::XStyleFamiliesSupplier > xSytleFamSupp( xModel, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XNameAccess > xSytleFamNames( xSytleFamSupp->getStyleFamilies(), uno::UNO_SET_THROW );
+ uno::Reference< container::XNameAccess > xParaStyles( xSytleFamNames->getByName("ParagraphStyles"), uno::UNO_QUERY_THROW );
+ uno::Reference< style::XStyle > xStyle( xParaStyles->getByName("Standard"), uno::UNO_QUERY_THROW );
+
+ return xStyle;
+}
+
+uno::Reference< text::XTextRange > getFirstObjectPosition( const uno::Reference< text::XText >& xText )
+{
+ // if the first object is table, get the position of first cell
+ uno::Reference< text::XTextRange > xTextRange;
+ uno::Reference< container::XEnumerationAccess > xParaAccess( xText, uno::UNO_QUERY_THROW );
+ uno::Reference< container::XEnumeration> xParaEnum = xParaAccess->createEnumeration();
+ if( xParaEnum->hasMoreElements() )
+ {
+ uno::Reference< lang::XServiceInfo > xServiceInfo( xParaEnum->nextElement(), uno::UNO_QUERY_THROW );
+ if( xServiceInfo->supportsService("com.sun.star.text.TextTable") )
+ {
+ uno::Reference< table::XCellRange > xCellRange( xServiceInfo, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XText> xFirstCellText( xCellRange->getCellByPosition(0, 0), uno::UNO_QUERY_THROW );
+ xTextRange = xFirstCellText->getStart();
+ }
+ }
+ if( !xTextRange.is() )
+ xTextRange = xText->getStart();
+ return xTextRange;
+}
+
+uno::Reference< text::XText > getCurrentXText( const uno::Reference< frame::XModel >& xModel )
+{
+ uno::Reference< text::XTextRange > xTextRange;
+ uno::Reference< text::XTextContent > xTextContent( xModel->getCurrentSelection(), uno::UNO_QUERY );
+ if( !xTextContent.is() )
+ {
+ uno::Reference< container::XIndexAccess > xIndexAccess( xModel->getCurrentSelection(), uno::UNO_QUERY );
+ if( xIndexAccess.is() )
+ {
+ xTextContent.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY );
+ }
+ }
+
+ if( xTextContent.is() )
+ xTextRange = xTextContent->getAnchor();
+
+ if( !xTextRange.is() )
+ xTextRange.set( getXTextViewCursor( xModel ), uno::UNO_QUERY_THROW );
+
+ uno::Reference< text::XText > xText;
+ try
+ {
+ xText = xTextRange->getText();
+ }
+ catch (const uno::RuntimeException&)
+ {
+ //catch exception "no text selection"
+ }
+ uno::Reference< beans::XPropertySet > xVCProps( xTextRange, uno::UNO_QUERY_THROW );
+ while( xVCProps->getPropertyValue("TextTable") >>= xTextContent )
+ {
+ xText = xTextContent->getAnchor()->getText();
+ xVCProps.set( xText->createTextCursor(), uno::UNO_QUERY_THROW );
+ }
+
+ if( !xText.is() )
+ throw uno::RuntimeException("no text selection" );
+
+ return xText;
+}
+
+bool gotoSelectedObjectAnchor( const uno::Reference< frame::XModel>& xModel )
+{
+ bool isObjectSelected = false;
+ uno::Reference< text::XTextContent > xTextContent( xModel->getCurrentSelection(), uno::UNO_QUERY );
+ if( xTextContent.is() )
+ {
+ uno::Reference< text::XTextRange > xTextRange( xTextContent->getAnchor(), uno::UNO_SET_THROW );
+ uno::Reference< view::XSelectionSupplier > xSelectSupp( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
+ xSelectSupp->select( uno::Any( xTextRange ) );
+ isObjectSelected = true;
+ }
+ return isObjectSelected;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/vba/wordvbahelper.hxx b/sw/source/ui/vba/wordvbahelper.hxx
new file mode 100644
index 0000000000..ba8f77885c
--- /dev/null
+++ b/sw/source/ui/vba/wordvbahelper.hxx
@@ -0,0 +1,63 @@
+/* -*- 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 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_VBA_WORDVBAHELPER_HXX
+#define INCLUDED_SW_SOURCE_UI_VBA_WORDVBAHELPER_HXX
+
+#include <vbahelper/vbahelper.hxx>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+class SwDocShell;
+class SwView;
+namespace ooo::vba::word
+ {
+ //css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException);
+ SwDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel );
+ SwView* getView( const css::uno::Reference< css::frame::XModel>& xModel );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XTextViewCursor > getXTextViewCursor( const css::uno::Reference< css::frame::XModel >& xModel );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::style::XStyle > getCurrentPageStyle( const css::uno::Reference< css::frame::XModel >& xModel );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::style::XStyle > getCurrentPageStyle( const css::uno::Reference< css::frame::XModel>& xModel, const css::uno::Reference< css::beans::XPropertySet >& xProps );
+ /// @throws css::uno::RuntimeException
+ sal_Int32 getPageCount( const css::uno::Reference< css::frame::XModel>& xModel );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::style::XStyle > getDefaultParagraphStyle( const css::uno::Reference< css::frame::XModel >& xModel );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XTextRange > getFirstObjectPosition( const css::uno::Reference< css::text::XText >& xText );
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::text::XText > getCurrentXText( const css::uno::Reference< css::frame::XModel>& xModel );
+ /// @throws css::uno::RuntimeException
+ bool gotoSelectedObjectAnchor( const css::uno::Reference< css::frame::XModel>& xModel );
+
+ enum E_DIRECTION
+ {
+ MOVE_LEFT = 1,
+ MOVE_RIGHT,
+ MOVE_UP,
+ MOVE_DOWN
+ };
+
+} // ooo::vba::word
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */